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 void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
1000 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
1001 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
1003 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1004 static bool rs6000_return_in_memory (const_tree, const_tree);
1005 static rtx rs6000_function_value (const_tree, const_tree, bool);
1006 static void rs6000_file_start (void);
1008 static int rs6000_elf_reloc_rw_mask (void);
1009 static void rs6000_elf_asm_out_constructor (rtx, int);
1010 static void rs6000_elf_asm_out_destructor (rtx, int);
1011 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1012 static void rs6000_elf_asm_init_sections (void);
1013 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1014 unsigned HOST_WIDE_INT);
1015 static void rs6000_elf_encode_section_info (tree, rtx, int)
1018 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1019 static void rs6000_alloc_sdmode_stack_slot (void);
1020 static void rs6000_instantiate_decls (void);
1022 static void rs6000_xcoff_asm_output_anchor (rtx);
1023 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1024 static void rs6000_xcoff_asm_init_sections (void);
1025 static int rs6000_xcoff_reloc_rw_mask (void);
1026 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1027 static section *rs6000_xcoff_select_section (tree, int,
1028 unsigned HOST_WIDE_INT);
1029 static void rs6000_xcoff_unique_section (tree, int);
1030 static section *rs6000_xcoff_select_rtx_section
1031 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1032 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1033 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1034 static void rs6000_xcoff_file_start (void);
1035 static void rs6000_xcoff_file_end (void);
1037 static int rs6000_variable_issue (FILE *, int, rtx, int);
1038 static int rs6000_register_move_cost (enum machine_mode,
1039 reg_class_t, reg_class_t);
1040 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1041 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1042 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1043 static int rs6000_debug_address_cost (rtx, bool);
1044 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1045 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1046 static void rs6000_sched_init (FILE *, int, int);
1047 static bool is_microcoded_insn (rtx);
1048 static bool is_nonpipeline_insn (rtx);
1049 static bool is_cracked_insn (rtx);
1050 static bool is_branch_slot_insn (rtx);
1051 static bool is_load_insn (rtx);
1052 static rtx get_store_dest (rtx pat);
1053 static bool is_store_insn (rtx);
1054 static bool set_to_load_agen (rtx,rtx);
1055 static bool adjacent_mem_locations (rtx,rtx);
1056 static int rs6000_adjust_priority (rtx, int);
1057 static int rs6000_issue_rate (void);
1058 static bool rs6000_is_costly_dependence (dep_t, int, int);
1059 static rtx get_next_active_insn (rtx, rtx);
1060 static bool insn_terminates_group_p (rtx , enum group_termination);
1061 static bool insn_must_be_first_in_group (rtx);
1062 static bool insn_must_be_last_in_group (rtx);
1063 static bool is_costly_group (rtx *, rtx);
1064 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1065 static int redefine_groups (FILE *, int, rtx, rtx);
1066 static int pad_groups (FILE *, int, rtx, rtx);
1067 static void rs6000_sched_finish (FILE *, int);
1068 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1069 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1070 static int rs6000_use_sched_lookahead (void);
1071 static int rs6000_use_sched_lookahead_guard (rtx);
1072 static void * rs6000_alloc_sched_context (void);
1073 static void rs6000_init_sched_context (void *, bool);
1074 static void rs6000_set_sched_context (void *);
1075 static void rs6000_free_sched_context (void *);
1076 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1077 static tree rs6000_builtin_mask_for_load (void);
1078 static tree rs6000_builtin_mul_widen_even (tree);
1079 static tree rs6000_builtin_mul_widen_odd (tree);
1080 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1081 static tree rs6000_builtin_vec_perm (tree, tree *);
1082 static bool rs6000_builtin_support_vector_misalignment (enum
1086 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1089 static void def_builtin (int, const char *, tree, int);
1090 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1091 static void rs6000_init_builtins (void);
1092 static tree rs6000_builtin_decl (unsigned, bool);
1094 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1095 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1096 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1097 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1098 static void altivec_init_builtins (void);
1099 static unsigned builtin_hash_function (const void *);
1100 static int builtin_hash_eq (const void *, const void *);
1101 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1102 enum machine_mode, enum machine_mode,
1103 enum rs6000_builtins, const char *name);
1104 static void rs6000_common_init_builtins (void);
1105 static void rs6000_init_libfuncs (void);
1107 static void paired_init_builtins (void);
1108 static rtx paired_expand_builtin (tree, rtx, bool *);
1109 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1110 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1111 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1113 static void enable_mask_for_builtins (struct builtin_description *, int,
1114 enum rs6000_builtins,
1115 enum rs6000_builtins);
1116 static void spe_init_builtins (void);
1117 static rtx spe_expand_builtin (tree, rtx, bool *);
1118 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1119 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1120 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1121 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1122 static rs6000_stack_t *rs6000_stack_info (void);
1123 static void debug_stack_info (rs6000_stack_t *);
1125 static rtx altivec_expand_builtin (tree, rtx, bool *);
1126 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1127 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1128 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1129 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1130 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1131 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1132 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1133 static rtx altivec_expand_vec_set_builtin (tree);
1134 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1135 static int get_element_number (tree, tree);
1136 static bool rs6000_handle_option (size_t, const char *, int);
1137 static void rs6000_parse_tls_size_option (void);
1138 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1139 static int first_altivec_reg_to_save (void);
1140 static unsigned int compute_vrsave_mask (void);
1141 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1142 static void is_altivec_return_reg (rtx, void *);
1143 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1144 int easy_vector_constant (rtx, enum machine_mode);
1145 static rtx rs6000_dwarf_register_span (rtx);
1146 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1147 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1148 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1149 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1150 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1151 static rtx rs6000_delegitimize_address (rtx);
1152 static rtx rs6000_tls_get_addr (void);
1153 static rtx rs6000_got_sym (void);
1154 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1155 static const char *rs6000_get_some_local_dynamic_name (void);
1156 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1157 static rtx rs6000_complex_function_value (enum machine_mode);
1158 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1159 enum machine_mode, const_tree);
1160 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1161 HOST_WIDE_INT, int);
1162 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1165 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1168 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1169 const_tree, HOST_WIDE_INT,
1171 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1172 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1173 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1175 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1177 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1178 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1179 enum machine_mode, tree,
1181 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1183 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1185 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1187 static void macho_branch_islands (void);
1188 static int no_previous_def (tree function_name);
1189 static tree get_prev_label (tree function_name);
1190 static void rs6000_darwin_file_start (void);
1193 static tree rs6000_build_builtin_va_list (void);
1194 static void rs6000_va_start (tree, rtx);
1195 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1196 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1197 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1198 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1199 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1200 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1202 static tree rs6000_stack_protect_fail (void);
1204 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1207 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1210 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1212 = rs6000_legitimize_reload_address;
1214 static bool rs6000_mode_dependent_address_p (const_rtx);
1215 static bool rs6000_mode_dependent_address (const_rtx);
1216 static bool rs6000_debug_mode_dependent_address (const_rtx);
1217 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1218 = rs6000_mode_dependent_address;
1220 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1221 enum machine_mode, rtx);
1222 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1225 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1226 enum machine_mode, rtx)
1227 = rs6000_secondary_reload_class;
1229 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1230 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1232 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1233 = rs6000_preferred_reload_class;
1235 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1238 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1242 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1244 = rs6000_secondary_memory_needed;
1246 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1249 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1253 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1256 = rs6000_cannot_change_mode_class;
1258 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1260 struct secondary_reload_info *);
1262 static const reg_class_t *rs6000_ira_cover_classes (void);
1264 const int INSN_NOT_AVAILABLE = -1;
1265 static enum machine_mode rs6000_eh_return_filter_mode (void);
1266 static bool rs6000_can_eliminate (const int, const int);
1267 static void rs6000_trampoline_init (rtx, tree, rtx);
1269 /* Hash table stuff for keeping track of TOC entries. */
1271 struct GTY(()) toc_hash_struct
1273 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1274 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1276 enum machine_mode key_mode;
1280 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1282 /* Hash table to keep track of the argument types for builtin functions. */
1284 struct GTY(()) builtin_hash_struct
1287 enum machine_mode mode[4]; /* return value + 3 arguments. */
1288 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1291 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1293 /* Default register names. */
1294 char rs6000_reg_names[][8] =
1296 "0", "1", "2", "3", "4", "5", "6", "7",
1297 "8", "9", "10", "11", "12", "13", "14", "15",
1298 "16", "17", "18", "19", "20", "21", "22", "23",
1299 "24", "25", "26", "27", "28", "29", "30", "31",
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 "mq", "lr", "ctr","ap",
1305 "0", "1", "2", "3", "4", "5", "6", "7",
1307 /* AltiVec registers. */
1308 "0", "1", "2", "3", "4", "5", "6", "7",
1309 "8", "9", "10", "11", "12", "13", "14", "15",
1310 "16", "17", "18", "19", "20", "21", "22", "23",
1311 "24", "25", "26", "27", "28", "29", "30", "31",
1313 /* SPE registers. */
1314 "spe_acc", "spefscr",
1315 /* Soft frame pointer. */
1319 #ifdef TARGET_REGNAMES
1320 static const char alt_reg_names[][8] =
1322 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1323 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1324 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1325 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1326 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1327 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1328 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1329 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1330 "mq", "lr", "ctr", "ap",
1331 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1333 /* AltiVec registers. */
1334 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1335 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1336 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1337 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1339 /* SPE registers. */
1340 "spe_acc", "spefscr",
1341 /* Soft frame pointer. */
1346 /* Table of valid machine attributes. */
1348 static const struct attribute_spec rs6000_attribute_table[] =
1350 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1351 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1352 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1353 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1354 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1355 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1356 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1357 SUBTARGET_ATTRIBUTE_TABLE,
1359 { NULL, 0, 0, false, false, false, NULL }
1362 #ifndef MASK_STRICT_ALIGN
1363 #define MASK_STRICT_ALIGN 0
1365 #ifndef TARGET_PROFILE_KERNEL
1366 #define TARGET_PROFILE_KERNEL 0
1369 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1370 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1372 /* Initialize the GCC target structure. */
1373 #undef TARGET_ATTRIBUTE_TABLE
1374 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1375 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1376 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1377 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1378 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1380 #undef TARGET_ASM_ALIGNED_DI_OP
1381 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1383 /* Default unaligned ops are only provided for ELF. Find the ops needed
1384 for non-ELF systems. */
1385 #ifndef OBJECT_FORMAT_ELF
1387 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1389 #undef TARGET_ASM_UNALIGNED_HI_OP
1390 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1391 #undef TARGET_ASM_UNALIGNED_SI_OP
1392 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1393 #undef TARGET_ASM_UNALIGNED_DI_OP
1394 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1397 #undef TARGET_ASM_UNALIGNED_HI_OP
1398 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1399 #undef TARGET_ASM_UNALIGNED_SI_OP
1400 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1401 #undef TARGET_ASM_UNALIGNED_DI_OP
1402 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1403 #undef TARGET_ASM_ALIGNED_DI_OP
1404 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1408 /* This hook deals with fixups for relocatable code and DI-mode objects
1410 #undef TARGET_ASM_INTEGER
1411 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1413 #ifdef HAVE_GAS_HIDDEN
1414 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1415 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1418 #undef TARGET_HAVE_TLS
1419 #define TARGET_HAVE_TLS HAVE_AS_TLS
1421 #undef TARGET_CANNOT_FORCE_CONST_MEM
1422 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1424 #undef TARGET_DELEGITIMIZE_ADDRESS
1425 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1427 #undef TARGET_ASM_FUNCTION_PROLOGUE
1428 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1429 #undef TARGET_ASM_FUNCTION_EPILOGUE
1430 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1432 #undef TARGET_LEGITIMIZE_ADDRESS
1433 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1435 #undef TARGET_SCHED_VARIABLE_ISSUE
1436 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1438 #undef TARGET_SCHED_ISSUE_RATE
1439 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1440 #undef TARGET_SCHED_ADJUST_COST
1441 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1442 #undef TARGET_SCHED_ADJUST_PRIORITY
1443 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1444 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1445 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1446 #undef TARGET_SCHED_INIT
1447 #define TARGET_SCHED_INIT rs6000_sched_init
1448 #undef TARGET_SCHED_FINISH
1449 #define TARGET_SCHED_FINISH rs6000_sched_finish
1450 #undef TARGET_SCHED_REORDER
1451 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1452 #undef TARGET_SCHED_REORDER2
1453 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1455 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1456 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1458 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1459 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1461 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1462 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1463 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1464 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1465 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1466 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1467 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1468 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1470 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1471 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1472 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1473 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1474 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1475 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1476 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1477 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1478 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1479 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1480 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1481 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1482 rs6000_builtin_support_vector_misalignment
1483 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1484 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1485 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1486 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1487 rs6000_builtin_vectorization_cost
1489 #undef TARGET_INIT_BUILTINS
1490 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1491 #undef TARGET_BUILTIN_DECL
1492 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1494 #undef TARGET_EXPAND_BUILTIN
1495 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1497 #undef TARGET_MANGLE_TYPE
1498 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1500 #undef TARGET_INIT_LIBFUNCS
1501 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1504 #undef TARGET_BINDS_LOCAL_P
1505 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1508 #undef TARGET_MS_BITFIELD_LAYOUT_P
1509 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1511 #undef TARGET_ASM_OUTPUT_MI_THUNK
1512 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1514 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1515 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1517 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1518 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1520 #undef TARGET_INVALID_WITHIN_DOLOOP
1521 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1523 #undef TARGET_REGISTER_MOVE_COST
1524 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1525 #undef TARGET_MEMORY_MOVE_COST
1526 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1527 #undef TARGET_RTX_COSTS
1528 #define TARGET_RTX_COSTS rs6000_rtx_costs
1529 #undef TARGET_ADDRESS_COST
1530 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1532 #undef TARGET_DWARF_REGISTER_SPAN
1533 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1535 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1536 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1538 /* On rs6000, function arguments are promoted, as are function return
1540 #undef TARGET_PROMOTE_FUNCTION_MODE
1541 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1543 #undef TARGET_RETURN_IN_MEMORY
1544 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1546 #undef TARGET_SETUP_INCOMING_VARARGS
1547 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1549 /* Always strict argument naming on rs6000. */
1550 #undef TARGET_STRICT_ARGUMENT_NAMING
1551 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1552 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1553 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1554 #undef TARGET_SPLIT_COMPLEX_ARG
1555 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1556 #undef TARGET_MUST_PASS_IN_STACK
1557 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1558 #undef TARGET_PASS_BY_REFERENCE
1559 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1560 #undef TARGET_ARG_PARTIAL_BYTES
1561 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1562 #undef TARGET_FUNCTION_ARG_ADVANCE
1563 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1564 #undef TARGET_FUNCTION_ARG
1565 #define TARGET_FUNCTION_ARG rs6000_function_arg
1567 #undef TARGET_BUILD_BUILTIN_VA_LIST
1568 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1570 #undef TARGET_EXPAND_BUILTIN_VA_START
1571 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1573 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1574 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1576 #undef TARGET_EH_RETURN_FILTER_MODE
1577 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1579 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1580 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1582 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1583 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1585 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1586 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1588 #undef TARGET_HANDLE_OPTION
1589 #define TARGET_HANDLE_OPTION rs6000_handle_option
1591 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1592 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1593 rs6000_builtin_vectorized_function
1595 #undef TARGET_DEFAULT_TARGET_FLAGS
1596 #define TARGET_DEFAULT_TARGET_FLAGS \
1599 #undef TARGET_STACK_PROTECT_FAIL
1600 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1602 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1603 The PowerPC architecture requires only weak consistency among
1604 processors--that is, memory accesses between processors need not be
1605 sequentially consistent and memory accesses among processors can occur
1606 in any order. The ability to order memory accesses weakly provides
1607 opportunities for more efficient use of the system bus. Unless a
1608 dependency exists, the 604e allows read operations to precede store
1610 #undef TARGET_RELAXED_ORDERING
1611 #define TARGET_RELAXED_ORDERING true
1614 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1615 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1618 /* Use a 32-bit anchor range. This leads to sequences like:
1620 addis tmp,anchor,high
1623 where tmp itself acts as an anchor, and can be shared between
1624 accesses to the same 64k page. */
1625 #undef TARGET_MIN_ANCHOR_OFFSET
1626 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1627 #undef TARGET_MAX_ANCHOR_OFFSET
1628 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1629 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1630 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1632 #undef TARGET_BUILTIN_RECIPROCAL
1633 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1635 #undef TARGET_EXPAND_TO_RTL_HOOK
1636 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1638 #undef TARGET_INSTANTIATE_DECLS
1639 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1641 #undef TARGET_SECONDARY_RELOAD
1642 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1644 #undef TARGET_IRA_COVER_CLASSES
1645 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1647 #undef TARGET_LEGITIMATE_ADDRESS_P
1648 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1650 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1651 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1653 #undef TARGET_CAN_ELIMINATE
1654 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1656 #undef TARGET_TRAMPOLINE_INIT
1657 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1659 #undef TARGET_FUNCTION_VALUE
1660 #define TARGET_FUNCTION_VALUE rs6000_function_value
1662 struct gcc_target targetm = TARGET_INITIALIZER;
1664 /* Return number of consecutive hard regs needed starting at reg REGNO
1665 to hold something of mode MODE.
1666 This is ordinarily the length in words of a value of mode MODE
1667 but can be less for certain modes in special long registers.
1669 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1670 scalar instructions. The upper 32 bits are only available to the
1673 POWER and PowerPC GPRs hold 32 bits worth;
1674 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1677 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1679 unsigned HOST_WIDE_INT reg_size;
1681 if (FP_REGNO_P (regno))
1682 reg_size = (VECTOR_MEM_VSX_P (mode)
1683 ? UNITS_PER_VSX_WORD
1684 : UNITS_PER_FP_WORD);
1686 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1687 reg_size = UNITS_PER_SPE_WORD;
1689 else if (ALTIVEC_REGNO_P (regno))
1690 reg_size = UNITS_PER_ALTIVEC_WORD;
1692 /* The value returned for SCmode in the E500 double case is 2 for
1693 ABI compatibility; storing an SCmode value in a single register
1694 would require function_arg and rs6000_spe_function_arg to handle
1695 SCmode so as to pass the value correctly in a pair of
1697 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1698 && !DECIMAL_FLOAT_MODE_P (mode))
1699 reg_size = UNITS_PER_FP_WORD;
1702 reg_size = UNITS_PER_WORD;
1704 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1707 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1710 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1712 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1714 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1715 implementations. Don't allow an item to be split between a FP register
1716 and an Altivec register. */
1717 if (VECTOR_MEM_VSX_P (mode))
1719 if (FP_REGNO_P (regno))
1720 return FP_REGNO_P (last_regno);
1722 if (ALTIVEC_REGNO_P (regno))
1723 return ALTIVEC_REGNO_P (last_regno);
1726 /* The GPRs can hold any mode, but values bigger than one register
1727 cannot go past R31. */
1728 if (INT_REGNO_P (regno))
1729 return INT_REGNO_P (last_regno);
1731 /* The float registers (except for VSX vector modes) can only hold floating
1732 modes and DImode. This excludes the 32-bit decimal float mode for
1734 if (FP_REGNO_P (regno))
1736 if (SCALAR_FLOAT_MODE_P (mode)
1737 && (mode != TDmode || (regno % 2) == 0)
1738 && FP_REGNO_P (last_regno))
1741 if (GET_MODE_CLASS (mode) == MODE_INT
1742 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1745 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1746 && PAIRED_VECTOR_MODE (mode))
1752 /* The CR register can only hold CC modes. */
1753 if (CR_REGNO_P (regno))
1754 return GET_MODE_CLASS (mode) == MODE_CC;
1756 if (CA_REGNO_P (regno))
1757 return mode == BImode;
1759 /* AltiVec only in AldyVec registers. */
1760 if (ALTIVEC_REGNO_P (regno))
1761 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1763 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1764 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1767 /* We cannot put TImode anywhere except general register and it must be able
1768 to fit within the register set. In the future, allow TImode in the
1769 Altivec or VSX registers. */
1771 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1774 /* Print interesting facts about registers. */
1776 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1780 for (r = first_regno; r <= last_regno; ++r)
1782 const char *comma = "";
1785 if (first_regno == last_regno)
1786 fprintf (stderr, "%s:\t", reg_name);
1788 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1791 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1792 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1796 fprintf (stderr, ",\n\t");
1801 if (rs6000_hard_regno_nregs[m][r] > 1)
1802 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1803 rs6000_hard_regno_nregs[m][r]);
1805 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1810 if (call_used_regs[r])
1814 fprintf (stderr, ",\n\t");
1819 len += fprintf (stderr, "%s%s", comma, "call-used");
1827 fprintf (stderr, ",\n\t");
1832 len += fprintf (stderr, "%s%s", comma, "fixed");
1838 fprintf (stderr, ",\n\t");
1842 fprintf (stderr, "%sregno = %d\n", comma, r);
1846 /* Print various interesting information with -mdebug=reg. */
1848 rs6000_debug_reg_global (void)
1850 const char *nl = (const char *)0;
1852 char costly_num[20];
1854 const char *costly_str;
1855 const char *nop_str;
1857 /* Map enum rs6000_vector to string. */
1858 static const char *rs6000_debug_vector_unit[] = {
1867 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1868 LAST_VIRTUAL_REGISTER);
1869 rs6000_debug_reg_print (0, 31, "gr");
1870 rs6000_debug_reg_print (32, 63, "fp");
1871 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1874 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1875 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1876 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1877 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1878 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1879 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1880 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1881 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1882 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1886 "d reg_class = %s\n"
1887 "f reg_class = %s\n"
1888 "v reg_class = %s\n"
1889 "wa reg_class = %s\n"
1890 "wd reg_class = %s\n"
1891 "wf reg_class = %s\n"
1892 "ws reg_class = %s\n\n",
1893 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1894 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1895 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1896 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1897 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1898 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1899 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1901 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1902 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1905 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1907 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1908 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1914 if (rs6000_recip_control)
1916 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1918 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1919 if (rs6000_recip_bits[m])
1922 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1924 (RS6000_RECIP_AUTO_RE_P (m)
1926 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1927 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1929 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1932 fputs ("\n", stderr);
1935 switch (rs6000_sched_costly_dep)
1937 case max_dep_latency:
1938 costly_str = "max_dep_latency";
1942 costly_str = "no_dep_costly";
1945 case all_deps_costly:
1946 costly_str = "all_deps_costly";
1949 case true_store_to_load_dep_costly:
1950 costly_str = "true_store_to_load_dep_costly";
1953 case store_to_load_dep_costly:
1954 costly_str = "store_to_load_dep_costly";
1958 costly_str = costly_num;
1959 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1963 switch (rs6000_sched_insert_nops)
1965 case sched_finish_regroup_exact:
1966 nop_str = "sched_finish_regroup_exact";
1969 case sched_finish_pad_groups:
1970 nop_str = "sched_finish_pad_groups";
1973 case sched_finish_none:
1974 nop_str = "sched_finish_none";
1979 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1984 "always_hint = %s\n"
1985 "align_branch_targets = %s\n"
1986 "sched_restricted_insns_priority = %d\n"
1987 "sched_costly_dep = %s\n"
1988 "sched_insert_nops = %s\n\n",
1989 rs6000_always_hint ? "true" : "false",
1990 rs6000_align_branch_targets ? "true" : "false",
1991 (int)rs6000_sched_restricted_insns_priority,
1992 costly_str, nop_str);
1995 /* Initialize the various global tables that are based on register size. */
1997 rs6000_init_hard_regno_mode_ok (void)
2003 /* Precalculate REGNO_REG_CLASS. */
2004 rs6000_regno_regclass[0] = GENERAL_REGS;
2005 for (r = 1; r < 32; ++r)
2006 rs6000_regno_regclass[r] = BASE_REGS;
2008 for (r = 32; r < 64; ++r)
2009 rs6000_regno_regclass[r] = FLOAT_REGS;
2011 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2012 rs6000_regno_regclass[r] = NO_REGS;
2014 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2015 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2017 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2018 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2019 rs6000_regno_regclass[r] = CR_REGS;
2021 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2022 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2023 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2024 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2025 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2026 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2027 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2028 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2029 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2030 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2032 /* Precalculate vector information, this must be set up before the
2033 rs6000_hard_regno_nregs_internal below. */
2034 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2036 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2037 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2038 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2041 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2042 rs6000_constraints[c] = NO_REGS;
2044 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2045 believes it can use native alignment or still uses 128-bit alignment. */
2046 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2057 /* V2DF mode, VSX only. */
2060 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2061 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2062 rs6000_vector_align[V2DFmode] = align64;
2065 /* V4SF mode, either VSX or Altivec. */
2068 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2069 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2070 rs6000_vector_align[V4SFmode] = align32;
2072 else if (TARGET_ALTIVEC)
2074 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2075 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2076 rs6000_vector_align[V4SFmode] = align32;
2079 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2083 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2084 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2085 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2086 rs6000_vector_align[V4SImode] = align32;
2087 rs6000_vector_align[V8HImode] = align32;
2088 rs6000_vector_align[V16QImode] = align32;
2092 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2093 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2094 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2098 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2099 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2100 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2104 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2105 Altivec doesn't have 64-bit support. */
2108 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2109 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2110 rs6000_vector_align[V2DImode] = align64;
2113 /* DFmode, see if we want to use the VSX unit. */
2114 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2116 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2117 rs6000_vector_mem[DFmode]
2118 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2119 rs6000_vector_align[DFmode] = align64;
2122 /* TODO add SPE and paired floating point vector support. */
2124 /* Register class constaints for the constraints that depend on compile
2126 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2127 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2129 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2130 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2134 /* At present, we just use VSX_REGS, but we have different constraints
2135 based on the use, in case we want to fine tune the default register
2136 class used. wa = any VSX register, wf = register class to use for
2137 V4SF, wd = register class to use for V2DF, and ws = register classs to
2138 use for DF scalars. */
2139 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2140 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2141 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2142 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2148 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2150 /* Set up the reload helper functions. */
2151 if (TARGET_VSX || TARGET_ALTIVEC)
2155 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2156 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2157 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2158 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2159 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2160 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2161 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2162 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2163 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2164 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2165 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2166 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2170 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2171 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2172 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2173 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2174 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2175 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2176 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2177 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2178 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2179 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2180 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2181 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2185 /* Precalculate HARD_REGNO_NREGS. */
2186 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2187 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2188 rs6000_hard_regno_nregs[m][r]
2189 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2191 /* Precalculate HARD_REGNO_MODE_OK. */
2192 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2193 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2194 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2195 rs6000_hard_regno_mode_ok_p[m][r] = true;
2197 /* Precalculate CLASS_MAX_NREGS sizes. */
2198 for (c = 0; c < LIM_REG_CLASSES; ++c)
2202 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2203 reg_size = UNITS_PER_VSX_WORD;
2205 else if (c == ALTIVEC_REGS)
2206 reg_size = UNITS_PER_ALTIVEC_WORD;
2208 else if (c == FLOAT_REGS)
2209 reg_size = UNITS_PER_FP_WORD;
2212 reg_size = UNITS_PER_WORD;
2214 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2215 rs6000_class_max_nregs[m][c]
2216 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2219 if (TARGET_E500_DOUBLE)
2220 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2222 /* Calculate which modes to automatically generate code to use a the
2223 reciprocal divide and square root instructions. In the future, possibly
2224 automatically generate the instructions even if the user did not specify
2225 -mrecip. The older machines double precision reciprocal sqrt estimate is
2226 not accurate enough. */
2227 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2229 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2231 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2232 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2233 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2234 if (VECTOR_UNIT_VSX_P (V2DFmode))
2235 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2237 if (TARGET_FRSQRTES)
2238 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2240 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2241 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2242 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2243 if (VECTOR_UNIT_VSX_P (V2DFmode))
2244 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2246 if (rs6000_recip_control)
2248 if (!TARGET_FUSED_MADD)
2249 warning (0, "-mrecip requires -mfused-madd");
2250 if (!flag_finite_math_only)
2251 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2252 if (flag_trapping_math)
2253 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2254 if (!flag_reciprocal_math)
2255 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2256 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2257 && flag_reciprocal_math)
2259 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2260 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2261 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2263 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2264 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2265 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2267 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2268 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2269 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2271 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2272 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2273 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2275 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2276 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2277 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2279 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2280 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2281 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2283 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2284 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2285 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2287 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2288 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2289 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2293 if (TARGET_DEBUG_REG)
2294 rs6000_debug_reg_global ();
2296 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2298 "SImode variable mult cost = %d\n"
2299 "SImode constant mult cost = %d\n"
2300 "SImode short constant mult cost = %d\n"
2301 "DImode multipliciation cost = %d\n"
2302 "SImode division cost = %d\n"
2303 "DImode division cost = %d\n"
2304 "Simple fp operation cost = %d\n"
2305 "DFmode multiplication cost = %d\n"
2306 "SFmode division cost = %d\n"
2307 "DFmode division cost = %d\n"
2308 "cache line size = %d\n"
2309 "l1 cache size = %d\n"
2310 "l2 cache size = %d\n"
2311 "simultaneous prefetches = %d\n"
2314 rs6000_cost->mulsi_const,
2315 rs6000_cost->mulsi_const9,
2323 rs6000_cost->cache_line_size,
2324 rs6000_cost->l1_cache_size,
2325 rs6000_cost->l2_cache_size,
2326 rs6000_cost->simultaneous_prefetches);
2330 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2333 darwin_rs6000_override_options (void)
2335 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2337 rs6000_altivec_abi = 1;
2338 TARGET_ALTIVEC_VRSAVE = 1;
2339 if (DEFAULT_ABI == ABI_DARWIN)
2341 if (MACHO_DYNAMIC_NO_PIC_P)
2344 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2347 else if (flag_pic == 1)
2352 darwin_one_byte_bool = 1;
2354 if (TARGET_64BIT && ! TARGET_POWERPC64)
2356 target_flags |= MASK_POWERPC64;
2357 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2361 rs6000_default_long_calls = 1;
2362 target_flags |= MASK_SOFT_FLOAT;
2365 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2367 if (!flag_mkernel && !flag_apple_kext
2369 && ! (target_flags_explicit & MASK_ALTIVEC))
2370 target_flags |= MASK_ALTIVEC;
2372 /* Unless the user (not the configurer) has explicitly overridden
2373 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2374 G4 unless targetting the kernel. */
2377 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2378 && ! (target_flags_explicit & MASK_ALTIVEC)
2379 && ! rs6000_select[1].string)
2381 target_flags |= MASK_ALTIVEC;
2386 /* If not otherwise specified by a target, make 'long double' equivalent to
2389 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2390 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2393 /* Override command line options. Mostly we process the processor
2394 type and sometimes adjust other TARGET_ options. */
2397 rs6000_override_options (const char *default_cpu)
2400 struct rs6000_cpu_select *ptr;
2403 /* Simplifications for entries below. */
2406 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2407 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2410 /* This table occasionally claims that a processor does not support
2411 a particular feature even though it does, but the feature is slower
2412 than the alternative. Thus, it shouldn't be relied on as a
2413 complete description of the processor's support.
2415 Please keep this list in order, and don't forget to update the
2416 documentation in invoke.texi when adding a new processor or
2420 const char *const name; /* Canonical processor name. */
2421 const enum processor_type processor; /* Processor type enum value. */
2422 const int target_enable; /* Target flags to enable. */
2423 } const processor_target_table[]
2424 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2425 {"403", PROCESSOR_PPC403,
2426 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2427 {"405", PROCESSOR_PPC405,
2428 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2429 {"405fp", PROCESSOR_PPC405,
2430 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2431 {"440", PROCESSOR_PPC440,
2432 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2433 {"440fp", PROCESSOR_PPC440,
2434 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2435 {"464", PROCESSOR_PPC440,
2436 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2437 {"464fp", PROCESSOR_PPC440,
2438 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2439 {"476", PROCESSOR_PPC476,
2440 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2441 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2442 {"476fp", PROCESSOR_PPC476,
2443 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2444 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2445 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2446 {"601", PROCESSOR_PPC601,
2447 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2448 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2449 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2450 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2451 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2452 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2453 {"620", PROCESSOR_PPC620,
2454 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2455 {"630", PROCESSOR_PPC630,
2456 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2457 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2458 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2459 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2460 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2461 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2462 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2463 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2464 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2466 /* 8548 has a dummy entry for now. */
2467 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2469 {"a2", PROCESSOR_PPCA2,
2470 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2471 | MASK_CMPB | MASK_NO_UPDATE },
2472 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2473 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2474 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2476 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2477 | MASK_PPC_GFXOPT | MASK_ISEL},
2478 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2479 {"970", PROCESSOR_POWER4,
2480 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2481 {"cell", PROCESSOR_CELL,
2482 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2483 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2484 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2485 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2486 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2487 {"G5", PROCESSOR_POWER4,
2488 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2489 {"titan", PROCESSOR_TITAN,
2490 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2491 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2492 {"power2", PROCESSOR_POWER,
2493 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2494 {"power3", PROCESSOR_PPC630,
2495 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2496 {"power4", PROCESSOR_POWER4,
2497 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2499 {"power5", PROCESSOR_POWER5,
2500 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2501 | MASK_MFCRF | MASK_POPCNTB},
2502 {"power5+", PROCESSOR_POWER5,
2503 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2504 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2505 {"power6", PROCESSOR_POWER6,
2506 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2507 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2508 | MASK_RECIP_PRECISION},
2509 {"power6x", PROCESSOR_POWER6,
2510 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2511 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2512 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2513 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
2514 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2515 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2516 | MASK_VSX | MASK_RECIP_PRECISION},
2517 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2518 {"powerpc64", PROCESSOR_POWERPC64,
2519 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2520 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2521 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2522 {"rios2", PROCESSOR_RIOS2,
2523 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2524 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2525 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2526 {"rs64", PROCESSOR_RS64A,
2527 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2530 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2532 /* Some OSs don't support saving the high part of 64-bit registers on
2533 context switch. Other OSs don't support saving Altivec registers.
2534 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2535 settings; if the user wants either, the user must explicitly specify
2536 them and we won't interfere with the user's specification. */
2539 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2540 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2541 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2542 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2543 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2544 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2545 | MASK_RECIP_PRECISION)
2548 /* Masks for instructions set at various powerpc ISAs. */
2550 ISA_2_1_MASKS = MASK_MFCRF,
2551 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2553 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2554 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2555 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2556 masks by server and embedded. */
2557 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2558 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2559 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2561 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2562 altivec is a win so enable it. */
2563 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2564 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2568 /* Numerous experiment shows that IRA based loop pressure
2569 calculation works better for RTL loop invariant motion on targets
2570 with enough (>= 32) registers. It is an expensive optimization.
2571 So it is on only for peak performance. */
2573 flag_ira_loop_pressure = 1;
2575 /* Set the pointer size. */
2578 rs6000_pmode = (int)DImode;
2579 rs6000_pointer_size = 64;
2583 rs6000_pmode = (int)SImode;
2584 rs6000_pointer_size = 32;
2587 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2588 #ifdef OS_MISSING_POWERPC64
2589 if (OS_MISSING_POWERPC64)
2590 set_masks &= ~MASK_POWERPC64;
2592 #ifdef OS_MISSING_ALTIVEC
2593 if (OS_MISSING_ALTIVEC)
2594 set_masks &= ~MASK_ALTIVEC;
2597 /* Don't override by the processor default if given explicitly. */
2598 set_masks &= ~target_flags_explicit;
2600 /* Identify the processor type. */
2601 rs6000_select[0].string = default_cpu;
2602 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2604 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2606 ptr = &rs6000_select[i];
2607 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2609 for (j = 0; j < ptt_size; j++)
2610 if (! strcmp (ptr->string, processor_target_table[j].name))
2612 if (ptr->set_tune_p)
2613 rs6000_cpu = processor_target_table[j].processor;
2615 if (ptr->set_arch_p)
2617 target_flags &= ~set_masks;
2618 target_flags |= (processor_target_table[j].target_enable
2625 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2629 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2630 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2633 error ("AltiVec not supported in this target");
2635 error ("Spe not supported in this target");
2638 /* Disable Cell microcode if we are optimizing for the Cell
2639 and not optimizing for size. */
2640 if (rs6000_gen_cell_microcode == -1)
2641 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2644 /* If we are optimizing big endian systems for space and it's OK to
2645 use instructions that would be microcoded on the Cell, use the
2646 load/store multiple and string instructions. */
2647 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2648 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2650 /* Don't allow -mmultiple or -mstring on little endian systems
2651 unless the cpu is a 750, because the hardware doesn't support the
2652 instructions used in little endian mode, and causes an alignment
2653 trap. The 750 does not cause an alignment trap (except when the
2654 target is unaligned). */
2656 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2658 if (TARGET_MULTIPLE)
2660 target_flags &= ~MASK_MULTIPLE;
2661 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2662 warning (0, "-mmultiple is not supported on little endian systems");
2667 target_flags &= ~MASK_STRING;
2668 if ((target_flags_explicit & MASK_STRING) != 0)
2669 warning (0, "-mstring is not supported on little endian systems");
2673 /* Add some warnings for VSX. */
2676 const char *msg = NULL;
2677 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2678 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2680 if (target_flags_explicit & MASK_VSX)
2681 msg = N_("-mvsx requires hardware floating point");
2683 target_flags &= ~ MASK_VSX;
2685 else if (TARGET_PAIRED_FLOAT)
2686 msg = N_("-mvsx and -mpaired are incompatible");
2687 /* The hardware will allow VSX and little endian, but until we make sure
2688 things like vector select, etc. work don't allow VSX on little endian
2689 systems at this point. */
2690 else if (!BYTES_BIG_ENDIAN)
2691 msg = N_("-mvsx used with little endian code");
2692 else if (TARGET_AVOID_XFORM > 0)
2693 msg = N_("-mvsx needs indexed addressing");
2694 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2696 if (target_flags_explicit & MASK_VSX)
2697 msg = N_("-mvsx and -mno-altivec are incompatible");
2699 msg = N_("-mno-altivec disables vsx");
2705 target_flags &= ~ MASK_VSX;
2706 target_flags_explicit |= MASK_VSX;
2710 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2711 unless the user explicitly used the -mno-<option> to disable the code. */
2713 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2714 else if (TARGET_POPCNTD)
2715 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2716 else if (TARGET_DFP)
2717 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2718 else if (TARGET_CMPB)
2719 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2720 else if (TARGET_POPCNTB || TARGET_FPRND)
2721 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2722 else if (TARGET_ALTIVEC)
2723 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2725 /* E500mc does "better" if we inline more aggressively. Respect the
2726 user's opinion, though. */
2727 if (rs6000_block_move_inline_limit == 0
2728 && (rs6000_cpu == PROCESSOR_PPCE500MC
2729 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2730 rs6000_block_move_inline_limit = 128;
2732 /* store_one_arg depends on expand_block_move to handle at least the
2733 size of reg_parm_stack_space. */
2734 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2735 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2737 /* Set debug flags */
2738 if (rs6000_debug_name)
2740 if (! strcmp (rs6000_debug_name, "all"))
2741 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2742 = rs6000_debug_addr = rs6000_debug_cost = 1;
2743 else if (! strcmp (rs6000_debug_name, "stack"))
2744 rs6000_debug_stack = 1;
2745 else if (! strcmp (rs6000_debug_name, "arg"))
2746 rs6000_debug_arg = 1;
2747 else if (! strcmp (rs6000_debug_name, "reg"))
2748 rs6000_debug_reg = 1;
2749 else if (! strcmp (rs6000_debug_name, "addr"))
2750 rs6000_debug_addr = 1;
2751 else if (! strcmp (rs6000_debug_name, "cost"))
2752 rs6000_debug_cost = 1;
2754 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2756 /* If the appropriate debug option is enabled, replace the target hooks
2757 with debug versions that call the real version and then prints
2758 debugging information. */
2759 if (TARGET_DEBUG_COST)
2761 targetm.rtx_costs = rs6000_debug_rtx_costs;
2762 targetm.address_cost = rs6000_debug_address_cost;
2763 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2766 if (TARGET_DEBUG_ADDR)
2768 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2769 targetm.legitimize_address = rs6000_debug_legitimize_address;
2770 rs6000_secondary_reload_class_ptr
2771 = rs6000_debug_secondary_reload_class;
2772 rs6000_secondary_memory_needed_ptr
2773 = rs6000_debug_secondary_memory_needed;
2774 rs6000_cannot_change_mode_class_ptr
2775 = rs6000_debug_cannot_change_mode_class;
2776 rs6000_preferred_reload_class_ptr
2777 = rs6000_debug_preferred_reload_class;
2778 rs6000_legitimize_reload_address_ptr
2779 = rs6000_debug_legitimize_reload_address;
2780 rs6000_mode_dependent_address_ptr
2781 = rs6000_debug_mode_dependent_address;
2785 if (rs6000_traceback_name)
2787 if (! strncmp (rs6000_traceback_name, "full", 4))
2788 rs6000_traceback = traceback_full;
2789 else if (! strncmp (rs6000_traceback_name, "part", 4))
2790 rs6000_traceback = traceback_part;
2791 else if (! strncmp (rs6000_traceback_name, "no", 2))
2792 rs6000_traceback = traceback_none;
2794 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2795 rs6000_traceback_name);
2798 if (rs6000_veclibabi_name)
2800 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2801 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2803 error ("unknown vectorization library ABI type (%s) for "
2804 "-mveclibabi= switch", rs6000_veclibabi_name);
2807 if (!rs6000_explicit_options.long_double)
2808 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2810 #ifndef POWERPC_LINUX
2811 if (!rs6000_explicit_options.ieee)
2812 rs6000_ieeequad = 1;
2815 /* Enable Altivec ABI for AIX -maltivec. */
2816 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2817 rs6000_altivec_abi = 1;
2819 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2820 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2821 be explicitly overridden in either case. */
2824 if (!rs6000_explicit_options.altivec_abi
2825 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2826 rs6000_altivec_abi = 1;
2828 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2829 if (!rs6000_explicit_options.vrsave)
2830 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2833 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2834 So far, the only darwin64 targets are also MACH-O. */
2836 && DEFAULT_ABI == ABI_DARWIN
2839 rs6000_darwin64_abi = 1;
2840 /* Default to natural alignment, for better performance. */
2841 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2844 /* Place FP constants in the constant pool instead of TOC
2845 if section anchors enabled. */
2846 if (flag_section_anchors)
2847 TARGET_NO_FP_IN_TOC = 1;
2849 /* Handle -mtls-size option. */
2850 rs6000_parse_tls_size_option ();
2852 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2853 SUBTARGET_OVERRIDE_OPTIONS;
2855 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2856 SUBSUBTARGET_OVERRIDE_OPTIONS;
2858 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2859 SUB3TARGET_OVERRIDE_OPTIONS;
2862 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2863 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2865 /* The e500 and e500mc do not have string instructions, and we set
2866 MASK_STRING above when optimizing for size. */
2867 if ((target_flags & MASK_STRING) != 0)
2868 target_flags = target_flags & ~MASK_STRING;
2870 else if (rs6000_select[1].string != NULL)
2872 /* For the powerpc-eabispe configuration, we set all these by
2873 default, so let's unset them if we manually set another
2874 CPU that is not the E500. */
2875 if (!rs6000_explicit_options.spe_abi)
2877 if (!rs6000_explicit_options.spe)
2879 if (!rs6000_explicit_options.float_gprs)
2880 rs6000_float_gprs = 0;
2881 if (!(target_flags_explicit & MASK_ISEL))
2882 target_flags &= ~MASK_ISEL;
2885 /* Detect invalid option combinations with E500. */
2888 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2889 && rs6000_cpu != PROCESSOR_POWER5
2890 && rs6000_cpu != PROCESSOR_POWER6
2891 && rs6000_cpu != PROCESSOR_POWER7
2892 && rs6000_cpu != PROCESSOR_PPCA2
2893 && rs6000_cpu != PROCESSOR_CELL);
2894 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2895 || rs6000_cpu == PROCESSOR_POWER5
2896 || rs6000_cpu == PROCESSOR_POWER7);
2897 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2898 || rs6000_cpu == PROCESSOR_POWER5
2899 || rs6000_cpu == PROCESSOR_POWER6
2900 || rs6000_cpu == PROCESSOR_POWER7
2901 || rs6000_cpu == PROCESSOR_PPCE500MC
2902 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2904 /* Allow debug switches to override the above settings. */
2905 if (TARGET_ALWAYS_HINT > 0)
2906 rs6000_always_hint = TARGET_ALWAYS_HINT;
2908 if (TARGET_SCHED_GROUPS > 0)
2909 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2911 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2912 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2914 rs6000_sched_restricted_insns_priority
2915 = (rs6000_sched_groups ? 1 : 0);
2917 /* Handle -msched-costly-dep option. */
2918 rs6000_sched_costly_dep
2919 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2921 if (rs6000_sched_costly_dep_str)
2923 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2924 rs6000_sched_costly_dep = no_dep_costly;
2925 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2926 rs6000_sched_costly_dep = all_deps_costly;
2927 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2928 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2929 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2930 rs6000_sched_costly_dep = store_to_load_dep_costly;
2932 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2933 atoi (rs6000_sched_costly_dep_str));
2936 /* Handle -minsert-sched-nops option. */
2937 rs6000_sched_insert_nops
2938 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2940 if (rs6000_sched_insert_nops_str)
2942 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2943 rs6000_sched_insert_nops = sched_finish_none;
2944 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2945 rs6000_sched_insert_nops = sched_finish_pad_groups;
2946 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2947 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2949 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2950 atoi (rs6000_sched_insert_nops_str));
2953 #ifdef TARGET_REGNAMES
2954 /* If the user desires alternate register names, copy in the
2955 alternate names now. */
2956 if (TARGET_REGNAMES)
2957 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2960 /* Set aix_struct_return last, after the ABI is determined.
2961 If -maix-struct-return or -msvr4-struct-return was explicitly
2962 used, don't override with the ABI default. */
2963 if (!rs6000_explicit_options.aix_struct_ret)
2964 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2967 /* IBM XL compiler defaults to unsigned bitfields. */
2968 if (TARGET_XL_COMPAT)
2969 flag_signed_bitfields = 0;
2972 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2973 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2976 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2978 /* We can only guarantee the availability of DI pseudo-ops when
2979 assembling for 64-bit targets. */
2982 targetm.asm_out.aligned_op.di = NULL;
2983 targetm.asm_out.unaligned_op.di = NULL;
2986 /* Set branch target alignment, if not optimizing for size. */
2989 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2990 aligned 8byte to avoid misprediction by the branch predictor. */
2991 if (rs6000_cpu == PROCESSOR_TITAN
2992 || rs6000_cpu == PROCESSOR_CELL)
2994 if (align_functions <= 0)
2995 align_functions = 8;
2996 if (align_jumps <= 0)
2998 if (align_loops <= 0)
3001 if (rs6000_align_branch_targets)
3003 if (align_functions <= 0)
3004 align_functions = 16;
3005 if (align_jumps <= 0)
3007 if (align_loops <= 0)
3010 if (align_jumps_max_skip <= 0)
3011 align_jumps_max_skip = 15;
3012 if (align_loops_max_skip <= 0)
3013 align_loops_max_skip = 15;
3016 /* Arrange to save and restore machine status around nested functions. */
3017 init_machine_status = rs6000_init_machine_status;
3019 /* We should always be splitting complex arguments, but we can't break
3020 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3021 if (DEFAULT_ABI != ABI_AIX)
3022 targetm.calls.split_complex_arg = NULL;
3024 /* Initialize rs6000_cost with the appropriate target costs. */
3026 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3030 case PROCESSOR_RIOS1:
3031 rs6000_cost = &rios1_cost;
3034 case PROCESSOR_RIOS2:
3035 rs6000_cost = &rios2_cost;
3038 case PROCESSOR_RS64A:
3039 rs6000_cost = &rs64a_cost;
3042 case PROCESSOR_MPCCORE:
3043 rs6000_cost = &mpccore_cost;
3046 case PROCESSOR_PPC403:
3047 rs6000_cost = &ppc403_cost;
3050 case PROCESSOR_PPC405:
3051 rs6000_cost = &ppc405_cost;
3054 case PROCESSOR_PPC440:
3055 rs6000_cost = &ppc440_cost;
3058 case PROCESSOR_PPC476:
3059 rs6000_cost = &ppc476_cost;
3062 case PROCESSOR_PPC601:
3063 rs6000_cost = &ppc601_cost;
3066 case PROCESSOR_PPC603:
3067 rs6000_cost = &ppc603_cost;
3070 case PROCESSOR_PPC604:
3071 rs6000_cost = &ppc604_cost;
3074 case PROCESSOR_PPC604e:
3075 rs6000_cost = &ppc604e_cost;
3078 case PROCESSOR_PPC620:
3079 rs6000_cost = &ppc620_cost;
3082 case PROCESSOR_PPC630:
3083 rs6000_cost = &ppc630_cost;
3086 case PROCESSOR_CELL:
3087 rs6000_cost = &ppccell_cost;
3090 case PROCESSOR_PPC750:
3091 case PROCESSOR_PPC7400:
3092 rs6000_cost = &ppc750_cost;
3095 case PROCESSOR_PPC7450:
3096 rs6000_cost = &ppc7450_cost;
3099 case PROCESSOR_PPC8540:
3100 rs6000_cost = &ppc8540_cost;
3103 case PROCESSOR_PPCE300C2:
3104 case PROCESSOR_PPCE300C3:
3105 rs6000_cost = &ppce300c2c3_cost;
3108 case PROCESSOR_PPCE500MC:
3109 rs6000_cost = &ppce500mc_cost;
3112 case PROCESSOR_PPCE500MC64:
3113 rs6000_cost = &ppce500mc64_cost;
3116 case PROCESSOR_TITAN:
3117 rs6000_cost = &titan_cost;
3120 case PROCESSOR_POWER4:
3121 case PROCESSOR_POWER5:
3122 rs6000_cost = &power4_cost;
3125 case PROCESSOR_POWER6:
3126 rs6000_cost = &power6_cost;
3129 case PROCESSOR_POWER7:
3130 rs6000_cost = &power7_cost;
3133 case PROCESSOR_PPCA2:
3134 rs6000_cost = &ppca2_cost;
3141 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3142 set_param_value ("simultaneous-prefetches",
3143 rs6000_cost->simultaneous_prefetches);
3144 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3145 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3146 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3147 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3148 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3149 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3151 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3152 can be optimized to ap = __builtin_next_arg (0). */
3153 if (DEFAULT_ABI != ABI_V4)
3154 targetm.expand_builtin_va_start = NULL;
3156 /* Set up single/double float flags.
3157 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3158 then set both flags. */
3159 if (TARGET_HARD_FLOAT && TARGET_FPRS
3160 && rs6000_single_float == 0 && rs6000_double_float == 0)
3161 rs6000_single_float = rs6000_double_float = 1;
3163 /* Reset single and double FP flags if target is E500. */
3166 rs6000_single_float = rs6000_double_float = 0;
3167 if (TARGET_E500_SINGLE)
3168 rs6000_single_float = 1;
3169 if (TARGET_E500_DOUBLE)
3170 rs6000_single_float = rs6000_double_float = 1;
3173 /* If not explicitly specified via option, decide whether to generate indexed
3174 load/store instructions. */
3175 if (TARGET_AVOID_XFORM == -1)
3176 /* Avoid indexed addressing when targeting Power6 in order to avoid
3177 the DERAT mispredict penalty. */
3178 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3180 /* Set the -mrecip options. */
3181 if (rs6000_recip_name)
3183 char *p = ASTRDUP (rs6000_recip_name);
3185 unsigned int mask, i;
3188 while ((q = strtok (p, ",")) != NULL)
3199 if (!strcmp (q, "default"))
3200 mask = ((TARGET_RECIP_PRECISION)
3201 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3204 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3205 if (!strcmp (q, recip_options[i].string))
3207 mask = recip_options[i].mask;
3211 if (i == ARRAY_SIZE (recip_options))
3213 error ("Unknown option for -mrecip=%s", q);
3220 rs6000_recip_control &= ~mask;
3222 rs6000_recip_control |= mask;
3226 rs6000_init_hard_regno_mode_ok ();
3229 /* Implement targetm.vectorize.builtin_mask_for_load. */
3231 rs6000_builtin_mask_for_load (void)
3233 if (TARGET_ALTIVEC || TARGET_VSX)
3234 return altivec_builtin_mask_for_load;
3239 /* Implement targetm.vectorize.builtin_conversion.
3240 Returns a decl of a function that implements conversion of an integer vector
3241 into a floating-point vector, or vice-versa. DEST_TYPE is the
3242 destination type and SRC_TYPE the source type of the conversion.
3243 Return NULL_TREE if it is not available. */
3245 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3247 enum tree_code code = (enum tree_code) tcode;
3251 case FIX_TRUNC_EXPR:
3252 switch (TYPE_MODE (dest_type))
3255 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3258 return TYPE_UNSIGNED (dest_type)
3259 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3260 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3263 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3266 return TYPE_UNSIGNED (dest_type)
3267 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3268 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3275 switch (TYPE_MODE (src_type))
3278 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3281 return TYPE_UNSIGNED (src_type)
3282 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3283 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3286 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3289 return TYPE_UNSIGNED (src_type)
3290 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3291 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3302 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3304 rs6000_builtin_mul_widen_even (tree type)
3306 if (!TARGET_ALTIVEC)
3309 switch (TYPE_MODE (type))
3312 return TYPE_UNSIGNED (type)
3313 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3314 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3317 return TYPE_UNSIGNED (type)
3318 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3319 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3325 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3327 rs6000_builtin_mul_widen_odd (tree type)
3329 if (!TARGET_ALTIVEC)
3332 switch (TYPE_MODE (type))
3335 return TYPE_UNSIGNED (type)
3336 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3337 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3340 return TYPE_UNSIGNED (type)
3341 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3342 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3349 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3350 after applying N number of iterations. This routine does not determine
3351 how may iterations are required to reach desired alignment. */
3354 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3361 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3364 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3374 /* Assuming that all other types are naturally aligned. CHECKME! */
3379 /* Return true if the vector misalignment factor is supported by the
3382 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3389 /* Return if movmisalign pattern is not supported for this mode. */
3390 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3393 if (misalignment == -1)
3395 /* Misalignment factor is unknown at compile time but we know
3396 it's word aligned. */
3397 if (rs6000_vector_alignment_reachable (type, is_packed))
3399 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3401 if (element_size == 64 || element_size == 32)
3408 /* VSX supports word-aligned vector. */
3409 if (misalignment % 4 == 0)
3415 /* Implement targetm.vectorize.builtin_vec_perm. */
3417 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3419 tree inner_type = TREE_TYPE (type);
3420 bool uns_p = TYPE_UNSIGNED (inner_type);
3423 *mask_element_type = unsigned_char_type_node;
3425 switch (TYPE_MODE (type))
3429 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3430 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3435 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3436 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3441 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3442 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3446 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3450 if (!TARGET_ALLOW_DF_PERMUTE)
3453 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3457 if (!TARGET_ALLOW_DF_PERMUTE)
3461 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3462 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3474 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3476 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3477 tree vectype, int misalign)
3481 switch (type_of_cost)
3491 case cond_branch_not_taken:
3495 case cond_branch_taken:
3498 case unaligned_load:
3499 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3501 elements = TYPE_VECTOR_SUBPARTS (vectype);
3503 /* Double word aligned. */
3511 /* Double word aligned. */
3515 /* Unknown misalignment. */
3528 /* Misaligned loads are not supported. */
3533 case unaligned_store:
3534 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3536 elements = TYPE_VECTOR_SUBPARTS (vectype);
3538 /* Double word aligned. */
3546 /* Double word aligned. */
3550 /* Unknown misalignment. */
3563 /* Misaligned stores are not supported. */
3573 /* Handle generic options of the form -mfoo=yes/no.
3574 NAME is the option name.
3575 VALUE is the option value.
3576 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3577 whether the option value is 'yes' or 'no' respectively. */
3579 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3583 else if (!strcmp (value, "yes"))
3585 else if (!strcmp (value, "no"))
3588 error ("unknown -m%s= option specified: '%s'", name, value);
3591 /* Validate and record the size specified with the -mtls-size option. */
3594 rs6000_parse_tls_size_option (void)
3596 if (rs6000_tls_size_string == 0)
3598 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3599 rs6000_tls_size = 16;
3600 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3601 rs6000_tls_size = 32;
3602 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3603 rs6000_tls_size = 64;
3605 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3609 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3611 if (DEFAULT_ABI == ABI_DARWIN)
3612 /* The Darwin libraries never set errno, so we might as well
3613 avoid calling them when that's the only reason we would. */
3614 flag_errno_math = 0;
3616 /* Double growth factor to counter reduced min jump length. */
3617 set_param_value ("max-grow-copy-bb-insns", 16);
3619 /* Enable section anchors by default.
3620 Skip section anchors for Objective C and Objective C++
3621 until front-ends fixed. */
3622 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3623 flag_section_anchors = 2;
3626 static enum fpu_type_t
3627 rs6000_parse_fpu_option (const char *option)
3629 if (!strcmp("none", option)) return FPU_NONE;
3630 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3631 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3632 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3633 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3634 error("unknown value %s for -mfpu", option);
3639 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3640 library with vectorized intrinsics. */
3643 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3646 const char *suffix = NULL;
3647 tree fntype, new_fndecl, bdecl = NULL_TREE;
3650 enum machine_mode el_mode, in_mode;
3653 /* Libmass is suitable for unsafe math only as it does not correctly support
3654 parts of IEEE with the required precision such as denormals. Only support
3655 it if we have VSX to use the simd d2 or f4 functions.
3656 XXX: Add variable length support. */
3657 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3660 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3661 n = TYPE_VECTOR_SUBPARTS (type_out);
3662 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3663 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3664 if (el_mode != in_mode
3668 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3670 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3673 case BUILT_IN_ATAN2:
3674 case BUILT_IN_HYPOT:
3680 case BUILT_IN_ACOSH:
3682 case BUILT_IN_ASINH:
3684 case BUILT_IN_ATANH:
3692 case BUILT_IN_EXPM1:
3693 case BUILT_IN_LGAMMA:
3694 case BUILT_IN_LOG10:
3695 case BUILT_IN_LOG1P:
3703 bdecl = implicit_built_in_decls[fn];
3704 suffix = "d2"; /* pow -> powd2 */
3705 if (el_mode != DFmode
3710 case BUILT_IN_ATAN2F:
3711 case BUILT_IN_HYPOTF:
3716 case BUILT_IN_ACOSF:
3717 case BUILT_IN_ACOSHF:
3718 case BUILT_IN_ASINF:
3719 case BUILT_IN_ASINHF:
3720 case BUILT_IN_ATANF:
3721 case BUILT_IN_ATANHF:
3722 case BUILT_IN_CBRTF:
3724 case BUILT_IN_COSHF:
3726 case BUILT_IN_ERFCF:
3727 case BUILT_IN_EXP2F:
3729 case BUILT_IN_EXPM1F:
3730 case BUILT_IN_LGAMMAF:
3731 case BUILT_IN_LOG10F:
3732 case BUILT_IN_LOG1PF:
3733 case BUILT_IN_LOG2F:
3736 case BUILT_IN_SINHF:
3737 case BUILT_IN_SQRTF:
3739 case BUILT_IN_TANHF:
3740 bdecl = implicit_built_in_decls[fn];
3741 suffix = "4"; /* powf -> powf4 */
3742 if (el_mode != SFmode
3754 gcc_assert (suffix != NULL);
3755 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3756 strcpy (name, bname + sizeof ("__builtin_") - 1);
3757 strcat (name, suffix);
3760 fntype = build_function_type_list (type_out, type_in, NULL);
3761 else if (n_args == 2)
3762 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3766 /* Build a function declaration for the vectorized function. */
3767 new_fndecl = build_decl (BUILTINS_LOCATION,
3768 FUNCTION_DECL, get_identifier (name), fntype);
3769 TREE_PUBLIC (new_fndecl) = 1;
3770 DECL_EXTERNAL (new_fndecl) = 1;
3771 DECL_IS_NOVOPS (new_fndecl) = 1;
3772 TREE_READONLY (new_fndecl) = 1;
3777 /* Returns a function decl for a vectorized version of the builtin function
3778 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3779 if it is not available. */
3782 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3785 enum machine_mode in_mode, out_mode;
3788 if (TREE_CODE (type_out) != VECTOR_TYPE
3789 || TREE_CODE (type_in) != VECTOR_TYPE
3790 || !TARGET_VECTORIZE_BUILTINS)
3793 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3794 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3795 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3796 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3798 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3800 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3803 case BUILT_IN_COPYSIGN:
3804 if (VECTOR_UNIT_VSX_P (V2DFmode)
3805 && out_mode == DFmode && out_n == 2
3806 && in_mode == DFmode && in_n == 2)
3807 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3809 case BUILT_IN_COPYSIGNF:
3810 if (out_mode != SFmode || out_n != 4
3811 || in_mode != SFmode || in_n != 4)
3813 if (VECTOR_UNIT_VSX_P (V4SFmode))
3814 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3815 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3816 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3819 if (VECTOR_UNIT_VSX_P (V2DFmode)
3820 && out_mode == DFmode && out_n == 2
3821 && in_mode == DFmode && in_n == 2)
3822 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3824 case BUILT_IN_SQRTF:
3825 if (VECTOR_UNIT_VSX_P (V4SFmode)
3826 && out_mode == SFmode && out_n == 4
3827 && in_mode == SFmode && in_n == 4)
3828 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3831 if (VECTOR_UNIT_VSX_P (V2DFmode)
3832 && out_mode == DFmode && out_n == 2
3833 && in_mode == DFmode && in_n == 2)
3834 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3836 case BUILT_IN_CEILF:
3837 if (out_mode != SFmode || out_n != 4
3838 || in_mode != SFmode || in_n != 4)
3840 if (VECTOR_UNIT_VSX_P (V4SFmode))
3841 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3842 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3843 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3845 case BUILT_IN_FLOOR:
3846 if (VECTOR_UNIT_VSX_P (V2DFmode)
3847 && out_mode == DFmode && out_n == 2
3848 && in_mode == DFmode && in_n == 2)
3849 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3851 case BUILT_IN_FLOORF:
3852 if (out_mode != SFmode || out_n != 4
3853 || in_mode != SFmode || in_n != 4)
3855 if (VECTOR_UNIT_VSX_P (V4SFmode))
3856 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3857 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3858 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3860 case BUILT_IN_TRUNC:
3861 if (VECTOR_UNIT_VSX_P (V2DFmode)
3862 && out_mode == DFmode && out_n == 2
3863 && in_mode == DFmode && in_n == 2)
3864 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3866 case BUILT_IN_TRUNCF:
3867 if (out_mode != SFmode || out_n != 4
3868 || in_mode != SFmode || in_n != 4)
3870 if (VECTOR_UNIT_VSX_P (V4SFmode))
3871 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3872 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3873 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3875 case BUILT_IN_NEARBYINT:
3876 if (VECTOR_UNIT_VSX_P (V2DFmode)
3877 && flag_unsafe_math_optimizations
3878 && out_mode == DFmode && out_n == 2
3879 && in_mode == DFmode && in_n == 2)
3880 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3882 case BUILT_IN_NEARBYINTF:
3883 if (VECTOR_UNIT_VSX_P (V4SFmode)
3884 && flag_unsafe_math_optimizations
3885 && out_mode == SFmode && out_n == 4
3886 && in_mode == SFmode && in_n == 4)
3887 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3890 if (VECTOR_UNIT_VSX_P (V2DFmode)
3891 && !flag_trapping_math
3892 && out_mode == DFmode && out_n == 2
3893 && in_mode == DFmode && in_n == 2)
3894 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3896 case BUILT_IN_RINTF:
3897 if (VECTOR_UNIT_VSX_P (V4SFmode)
3898 && !flag_trapping_math
3899 && out_mode == SFmode && out_n == 4
3900 && in_mode == SFmode && in_n == 4)
3901 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3908 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3910 enum rs6000_builtins fn
3911 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3914 case RS6000_BUILTIN_RSQRTF:
3915 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3916 && out_mode == SFmode && out_n == 4
3917 && in_mode == SFmode && in_n == 4)
3918 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3920 case RS6000_BUILTIN_RSQRT:
3921 if (VECTOR_UNIT_VSX_P (V2DFmode)
3922 && out_mode == DFmode && out_n == 2
3923 && in_mode == DFmode && in_n == 2)
3924 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3926 case RS6000_BUILTIN_RECIPF:
3927 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3928 && out_mode == SFmode && out_n == 4
3929 && in_mode == SFmode && in_n == 4)
3930 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3932 case RS6000_BUILTIN_RECIP:
3933 if (VECTOR_UNIT_VSX_P (V2DFmode)
3934 && out_mode == DFmode && out_n == 2
3935 && in_mode == DFmode && in_n == 2)
3936 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3943 /* Generate calls to libmass if appropriate. */
3944 if (rs6000_veclib_handler)
3945 return rs6000_veclib_handler (fndecl, type_out, type_in);
3951 /* Implement TARGET_HANDLE_OPTION. */
3954 rs6000_handle_option (size_t code, const char *arg, int value)
3956 enum fpu_type_t fpu_type = FPU_NONE;
3962 g_switch_value = value;
3963 g_switch_set = true;
3967 target_flags &= ~(MASK_POWER | MASK_POWER2
3968 | MASK_MULTIPLE | MASK_STRING);
3969 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3970 | MASK_MULTIPLE | MASK_STRING);
3972 case OPT_mno_powerpc:
3973 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3974 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3975 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3976 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3979 target_flags &= ~MASK_MINIMAL_TOC;
3980 TARGET_NO_FP_IN_TOC = 0;
3981 TARGET_NO_SUM_IN_TOC = 0;
3982 target_flags_explicit |= MASK_MINIMAL_TOC;
3983 #ifdef TARGET_USES_SYSV4_OPT
3984 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3985 just the same as -mminimal-toc. */
3986 target_flags |= MASK_MINIMAL_TOC;
3987 target_flags_explicit |= MASK_MINIMAL_TOC;
3991 #ifdef TARGET_USES_SYSV4_OPT
3993 /* Make -mtoc behave like -mminimal-toc. */
3994 target_flags |= MASK_MINIMAL_TOC;
3995 target_flags_explicit |= MASK_MINIMAL_TOC;
3999 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4001 if (strcmp (arg, "small") == 0)
4002 cmodel = CMODEL_SMALL;
4003 else if (strcmp (arg, "medium") == 0)
4004 cmodel = CMODEL_MEDIUM;
4005 else if (strcmp (arg, "large") == 0)
4006 cmodel = CMODEL_LARGE;
4009 error ("invalid option for -mcmodel: '%s'", arg);
4012 rs6000_explicit_options.cmodel = true;
4015 #ifdef TARGET_USES_AIX64_OPT
4020 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4021 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4022 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4025 #ifdef TARGET_USES_AIX64_OPT
4030 target_flags &= ~MASK_POWERPC64;
4031 target_flags_explicit |= MASK_POWERPC64;
4034 case OPT_minsert_sched_nops_:
4035 rs6000_sched_insert_nops_str = arg;
4038 case OPT_mminimal_toc:
4041 TARGET_NO_FP_IN_TOC = 0;
4042 TARGET_NO_SUM_IN_TOC = 0;
4049 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4050 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4057 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4058 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4062 case OPT_mpowerpc_gpopt:
4063 case OPT_mpowerpc_gfxopt:
4066 target_flags |= MASK_POWERPC;
4067 target_flags_explicit |= MASK_POWERPC;
4071 case OPT_maix_struct_return:
4072 case OPT_msvr4_struct_return:
4073 rs6000_explicit_options.aix_struct_ret = true;
4077 rs6000_explicit_options.vrsave = true;
4078 TARGET_ALTIVEC_VRSAVE = value;
4082 rs6000_explicit_options.vrsave = true;
4083 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4087 target_flags_explicit |= MASK_ISEL;
4089 rs6000_parse_yes_no_option ("isel", arg, &isel);
4091 target_flags |= MASK_ISEL;
4093 target_flags &= ~MASK_ISEL;
4097 rs6000_explicit_options.spe = true;
4102 rs6000_explicit_options.spe = true;
4103 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4107 rs6000_debug_name = arg;
4110 #ifdef TARGET_USES_SYSV4_OPT
4112 rs6000_abi_name = arg;
4116 rs6000_sdata_name = arg;
4119 case OPT_mtls_size_:
4120 rs6000_tls_size_string = arg;
4123 case OPT_mrelocatable:
4126 target_flags |= MASK_MINIMAL_TOC;
4127 target_flags_explicit |= MASK_MINIMAL_TOC;
4128 TARGET_NO_FP_IN_TOC = 1;
4132 case OPT_mrelocatable_lib:
4135 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4136 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4137 TARGET_NO_FP_IN_TOC = 1;
4141 target_flags &= ~MASK_RELOCATABLE;
4142 target_flags_explicit |= MASK_RELOCATABLE;
4148 if (!strcmp (arg, "altivec"))
4150 rs6000_explicit_options.altivec_abi = true;
4151 rs6000_altivec_abi = 1;
4153 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4156 else if (! strcmp (arg, "no-altivec"))
4158 rs6000_explicit_options.altivec_abi = true;
4159 rs6000_altivec_abi = 0;
4161 else if (! strcmp (arg, "spe"))
4163 rs6000_explicit_options.spe_abi = true;
4165 rs6000_altivec_abi = 0;
4166 if (!TARGET_SPE_ABI)
4167 error ("not configured for ABI: '%s'", arg);
4169 else if (! strcmp (arg, "no-spe"))
4171 rs6000_explicit_options.spe_abi = true;
4175 /* These are here for testing during development only, do not
4176 document in the manual please. */
4177 else if (! strcmp (arg, "d64"))
4179 rs6000_darwin64_abi = 1;
4180 warning (0, "Using darwin64 ABI");
4182 else if (! strcmp (arg, "d32"))
4184 rs6000_darwin64_abi = 0;
4185 warning (0, "Using old darwin ABI");
4188 else if (! strcmp (arg, "ibmlongdouble"))
4190 rs6000_explicit_options.ieee = true;
4191 rs6000_ieeequad = 0;
4192 warning (0, "Using IBM extended precision long double");
4194 else if (! strcmp (arg, "ieeelongdouble"))
4196 rs6000_explicit_options.ieee = true;
4197 rs6000_ieeequad = 1;
4198 warning (0, "Using IEEE extended precision long double");
4203 error ("unknown ABI specified: '%s'", arg);
4209 rs6000_select[1].string = arg;
4213 rs6000_select[2].string = arg;
4216 case OPT_mtraceback_:
4217 rs6000_traceback_name = arg;
4220 case OPT_mfloat_gprs_:
4221 rs6000_explicit_options.float_gprs = true;
4222 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4223 rs6000_float_gprs = 1;
4224 else if (! strcmp (arg, "double"))
4225 rs6000_float_gprs = 2;
4226 else if (! strcmp (arg, "no"))
4227 rs6000_float_gprs = 0;
4230 error ("invalid option for -mfloat-gprs: '%s'", arg);
4235 case OPT_mlong_double_:
4236 rs6000_explicit_options.long_double = true;
4237 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4238 if (value != 64 && value != 128)
4240 error ("Unknown switch -mlong-double-%s", arg);
4241 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4245 rs6000_long_double_type_size = value;
4248 case OPT_msched_costly_dep_:
4249 rs6000_sched_costly_dep_str = arg;
4253 rs6000_explicit_options.alignment = true;
4254 if (! strcmp (arg, "power"))
4256 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4257 some C library functions, so warn about it. The flag may be
4258 useful for performance studies from time to time though, so
4259 don't disable it entirely. */
4260 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4261 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4262 " it is incompatible with the installed C and C++ libraries");
4263 rs6000_alignment_flags = MASK_ALIGN_POWER;
4265 else if (! strcmp (arg, "natural"))
4266 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4269 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4274 case OPT_msingle_float:
4275 if (!TARGET_SINGLE_FPU)
4276 warning (0, "-msingle-float option equivalent to -mhard-float");
4277 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4278 rs6000_double_float = 0;
4279 target_flags &= ~MASK_SOFT_FLOAT;
4280 target_flags_explicit |= MASK_SOFT_FLOAT;
4283 case OPT_mdouble_float:
4284 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4285 rs6000_single_float = 1;
4286 target_flags &= ~MASK_SOFT_FLOAT;
4287 target_flags_explicit |= MASK_SOFT_FLOAT;
4290 case OPT_msimple_fpu:
4291 if (!TARGET_SINGLE_FPU)
4292 warning (0, "-msimple-fpu option ignored");
4295 case OPT_mhard_float:
4296 /* -mhard_float implies -msingle-float and -mdouble-float. */
4297 rs6000_single_float = rs6000_double_float = 1;
4300 case OPT_msoft_float:
4301 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4302 rs6000_single_float = rs6000_double_float = 0;
4306 fpu_type = rs6000_parse_fpu_option(arg);
4307 if (fpu_type != FPU_NONE)
4308 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4310 target_flags &= ~MASK_SOFT_FLOAT;
4311 target_flags_explicit |= MASK_SOFT_FLOAT;
4312 rs6000_xilinx_fpu = 1;
4313 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4314 rs6000_single_float = 1;
4315 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4316 rs6000_single_float = rs6000_double_float = 1;
4317 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4318 rs6000_simple_fpu = 1;
4322 /* -mfpu=none is equivalent to -msoft-float */
4323 target_flags |= MASK_SOFT_FLOAT;
4324 target_flags_explicit |= MASK_SOFT_FLOAT;
4325 rs6000_single_float = rs6000_double_float = 0;
4329 rs6000_recip_name = (value) ? "default" : "none";
4333 rs6000_recip_name = arg;
4339 /* Do anything needed at the start of the asm file. */
4342 rs6000_file_start (void)
4346 const char *start = buffer;
4347 struct rs6000_cpu_select *ptr;
4348 const char *default_cpu = TARGET_CPU_DEFAULT;
4349 FILE *file = asm_out_file;
4351 default_file_start ();
4353 #ifdef TARGET_BI_ARCH
4354 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4358 if (flag_verbose_asm)
4360 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4361 rs6000_select[0].string = default_cpu;
4363 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4365 ptr = &rs6000_select[i];
4366 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4368 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4373 if (PPC405_ERRATUM77)
4375 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4379 #ifdef USING_ELFOS_H
4380 switch (rs6000_sdata)
4382 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4383 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4384 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4385 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4388 if (rs6000_sdata && g_switch_value)
4390 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4400 #ifdef HAVE_AS_GNU_ATTRIBUTE
4401 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4403 fprintf (file, "\t.gnu_attribute 4, %d\n",
4404 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4405 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4407 fprintf (file, "\t.gnu_attribute 8, %d\n",
4408 (TARGET_ALTIVEC_ABI ? 2
4409 : TARGET_SPE_ABI ? 3
4411 fprintf (file, "\t.gnu_attribute 12, %d\n",
4412 aix_struct_return ? 2 : 1);
4417 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4419 switch_to_section (toc_section);
4420 switch_to_section (text_section);
4425 /* Return nonzero if this function is known to have a null epilogue. */
4428 direct_return (void)
4430 if (reload_completed)
4432 rs6000_stack_t *info = rs6000_stack_info ();
4434 if (info->first_gp_reg_save == 32
4435 && info->first_fp_reg_save == 64
4436 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4437 && ! info->lr_save_p
4438 && ! info->cr_save_p
4439 && info->vrsave_mask == 0
4447 /* Return the number of instructions it takes to form a constant in an
4448 integer register. */
4451 num_insns_constant_wide (HOST_WIDE_INT value)
4453 /* signed constant loadable with {cal|addi} */
4454 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4457 /* constant loadable with {cau|addis} */
4458 else if ((value & 0xffff) == 0
4459 && (value >> 31 == -1 || value >> 31 == 0))
4462 #if HOST_BITS_PER_WIDE_INT == 64
4463 else if (TARGET_POWERPC64)
4465 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4466 HOST_WIDE_INT high = value >> 31;
4468 if (high == 0 || high == -1)
4474 return num_insns_constant_wide (high) + 1;
4476 return num_insns_constant_wide (low) + 1;
4478 return (num_insns_constant_wide (high)
4479 + num_insns_constant_wide (low) + 1);
4488 num_insns_constant (rtx op, enum machine_mode mode)
4490 HOST_WIDE_INT low, high;
4492 switch (GET_CODE (op))
4495 #if HOST_BITS_PER_WIDE_INT == 64
4496 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4497 && mask64_operand (op, mode))
4501 return num_insns_constant_wide (INTVAL (op));
4504 if (mode == SFmode || mode == SDmode)
4509 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4510 if (DECIMAL_FLOAT_MODE_P (mode))
4511 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4513 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4514 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4517 if (mode == VOIDmode || mode == DImode)
4519 high = CONST_DOUBLE_HIGH (op);
4520 low = CONST_DOUBLE_LOW (op);
4527 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4528 if (DECIMAL_FLOAT_MODE_P (mode))
4529 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4531 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4532 high = l[WORDS_BIG_ENDIAN == 0];
4533 low = l[WORDS_BIG_ENDIAN != 0];
4537 return (num_insns_constant_wide (low)
4538 + num_insns_constant_wide (high));
4541 if ((high == 0 && low >= 0)
4542 || (high == -1 && low < 0))
4543 return num_insns_constant_wide (low);
4545 else if (mask64_operand (op, mode))
4549 return num_insns_constant_wide (high) + 1;
4552 return (num_insns_constant_wide (high)
4553 + num_insns_constant_wide (low) + 1);
4561 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4562 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4563 corresponding element of the vector, but for V4SFmode and V2SFmode,
4564 the corresponding "float" is interpreted as an SImode integer. */
4567 const_vector_elt_as_int (rtx op, unsigned int elt)
4569 rtx tmp = CONST_VECTOR_ELT (op, elt);
4570 if (GET_MODE (op) == V4SFmode
4571 || GET_MODE (op) == V2SFmode)
4572 tmp = gen_lowpart (SImode, tmp);
4573 return INTVAL (tmp);
4576 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4577 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4578 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4579 all items are set to the same value and contain COPIES replicas of the
4580 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4581 operand and the others are set to the value of the operand's msb. */
4584 vspltis_constant (rtx op, unsigned step, unsigned copies)
4586 enum machine_mode mode = GET_MODE (op);
4587 enum machine_mode inner = GET_MODE_INNER (mode);
4590 unsigned nunits = GET_MODE_NUNITS (mode);
4591 unsigned bitsize = GET_MODE_BITSIZE (inner);
4592 unsigned mask = GET_MODE_MASK (inner);
4594 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4595 HOST_WIDE_INT splat_val = val;
4596 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4598 /* Construct the value to be splatted, if possible. If not, return 0. */
4599 for (i = 2; i <= copies; i *= 2)
4601 HOST_WIDE_INT small_val;
4603 small_val = splat_val >> bitsize;
4605 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4607 splat_val = small_val;
4610 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4611 if (EASY_VECTOR_15 (splat_val))
4614 /* Also check if we can splat, and then add the result to itself. Do so if
4615 the value is positive, of if the splat instruction is using OP's mode;
4616 for splat_val < 0, the splat and the add should use the same mode. */
4617 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4618 && (splat_val >= 0 || (step == 1 && copies == 1)))
4621 /* Also check if are loading up the most significant bit which can be done by
4622 loading up -1 and shifting the value left by -1. */
4623 else if (EASY_VECTOR_MSB (splat_val, inner))
4629 /* Check if VAL is present in every STEP-th element, and the
4630 other elements are filled with its most significant bit. */
4631 for (i = 0; i < nunits - 1; ++i)
4633 HOST_WIDE_INT desired_val;
4634 if (((i + 1) & (step - 1)) == 0)
4637 desired_val = msb_val;
4639 if (desired_val != const_vector_elt_as_int (op, i))
4647 /* Return true if OP is of the given MODE and can be synthesized
4648 with a vspltisb, vspltish or vspltisw. */
4651 easy_altivec_constant (rtx op, enum machine_mode mode)
4653 unsigned step, copies;
4655 if (mode == VOIDmode)
4656 mode = GET_MODE (op);
4657 else if (mode != GET_MODE (op))
4660 /* Start with a vspltisw. */
4661 step = GET_MODE_NUNITS (mode) / 4;
4664 if (vspltis_constant (op, step, copies))
4667 /* Then try with a vspltish. */
4673 if (vspltis_constant (op, step, copies))
4676 /* And finally a vspltisb. */
4682 if (vspltis_constant (op, step, copies))
4688 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4689 result is OP. Abort if it is not possible. */
4692 gen_easy_altivec_constant (rtx op)
4694 enum machine_mode mode = GET_MODE (op);
4695 int nunits = GET_MODE_NUNITS (mode);
4696 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4697 unsigned step = nunits / 4;
4698 unsigned copies = 1;
4700 /* Start with a vspltisw. */
4701 if (vspltis_constant (op, step, copies))
4702 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4704 /* Then try with a vspltish. */
4710 if (vspltis_constant (op, step, copies))
4711 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4713 /* And finally a vspltisb. */
4719 if (vspltis_constant (op, step, copies))
4720 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4726 output_vec_const_move (rtx *operands)
4729 enum machine_mode mode;
4734 mode = GET_MODE (dest);
4736 if (TARGET_VSX && zero_constant (vec, mode))
4737 return "xxlxor %x0,%x0,%x0";
4742 if (zero_constant (vec, mode))
4743 return "vxor %0,%0,%0";
4745 splat_vec = gen_easy_altivec_constant (vec);
4746 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4747 operands[1] = XEXP (splat_vec, 0);
4748 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4751 switch (GET_MODE (splat_vec))
4754 return "vspltisw %0,%1";
4757 return "vspltish %0,%1";
4760 return "vspltisb %0,%1";
4767 gcc_assert (TARGET_SPE);
4769 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4770 pattern of V1DI, V4HI, and V2SF.
4772 FIXME: We should probably return # and add post reload
4773 splitters for these, but this way is so easy ;-). */
4774 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4775 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4776 operands[1] = CONST_VECTOR_ELT (vec, 0);
4777 operands[2] = CONST_VECTOR_ELT (vec, 1);
4779 return "li %0,%1\n\tevmergelo %0,%0,%0";
4781 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4784 /* Initialize TARGET of vector PAIRED to VALS. */
4787 paired_expand_vector_init (rtx target, rtx vals)
4789 enum machine_mode mode = GET_MODE (target);
4790 int n_elts = GET_MODE_NUNITS (mode);
4792 rtx x, new_rtx, tmp, constant_op, op1, op2;
4795 for (i = 0; i < n_elts; ++i)
4797 x = XVECEXP (vals, 0, i);
4798 if (!CONSTANT_P (x))
4803 /* Load from constant pool. */
4804 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4810 /* The vector is initialized only with non-constants. */
4811 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4812 XVECEXP (vals, 0, 1));
4814 emit_move_insn (target, new_rtx);
4818 /* One field is non-constant and the other one is a constant. Load the
4819 constant from the constant pool and use ps_merge instruction to
4820 construct the whole vector. */
4821 op1 = XVECEXP (vals, 0, 0);
4822 op2 = XVECEXP (vals, 0, 1);
4824 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4826 tmp = gen_reg_rtx (GET_MODE (constant_op));
4827 emit_move_insn (tmp, constant_op);
4829 if (CONSTANT_P (op1))
4830 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4832 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4834 emit_move_insn (target, new_rtx);
4838 paired_expand_vector_move (rtx operands[])
4840 rtx op0 = operands[0], op1 = operands[1];
4842 emit_move_insn (op0, op1);
4845 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4846 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4847 operands for the relation operation COND. This is a recursive
4851 paired_emit_vector_compare (enum rtx_code rcode,
4852 rtx dest, rtx op0, rtx op1,
4853 rtx cc_op0, rtx cc_op1)
4855 rtx tmp = gen_reg_rtx (V2SFmode);
4858 gcc_assert (TARGET_PAIRED_FLOAT);
4859 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4865 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4869 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4870 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4874 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4877 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4880 tmp1 = gen_reg_rtx (V2SFmode);
4881 max = gen_reg_rtx (V2SFmode);
4882 min = gen_reg_rtx (V2SFmode);
4883 gen_reg_rtx (V2SFmode);
4885 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4886 emit_insn (gen_selv2sf4
4887 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4888 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4889 emit_insn (gen_selv2sf4
4890 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4891 emit_insn (gen_subv2sf3 (tmp1, min, max));
4892 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4895 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4898 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4901 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4904 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4907 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4916 /* Emit vector conditional expression.
4917 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4918 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4921 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4922 rtx cond, rtx cc_op0, rtx cc_op1)
4924 enum rtx_code rcode = GET_CODE (cond);
4926 if (!TARGET_PAIRED_FLOAT)
4929 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4934 /* Initialize vector TARGET to VALS. */
4937 rs6000_expand_vector_init (rtx target, rtx vals)
4939 enum machine_mode mode = GET_MODE (target);
4940 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4941 int n_elts = GET_MODE_NUNITS (mode);
4942 int n_var = 0, one_var = -1;
4943 bool all_same = true, all_const_zero = true;
4947 for (i = 0; i < n_elts; ++i)
4949 x = XVECEXP (vals, 0, i);
4950 if (!CONSTANT_P (x))
4951 ++n_var, one_var = i;
4952 else if (x != CONST0_RTX (inner_mode))
4953 all_const_zero = false;
4955 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4961 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4962 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4963 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4965 /* Zero register. */
4966 emit_insn (gen_rtx_SET (VOIDmode, target,
4967 gen_rtx_XOR (mode, target, target)));
4970 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4972 /* Splat immediate. */
4973 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4978 /* Load from constant pool. */
4979 emit_move_insn (target, const_vec);
4984 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4985 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4989 rtx element = XVECEXP (vals, 0, 0);
4990 if (mode == V2DFmode)
4991 emit_insn (gen_vsx_splat_v2df (target, element));
4993 emit_insn (gen_vsx_splat_v2di (target, element));
4997 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4998 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4999 if (mode == V2DFmode)
5000 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5002 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5007 /* With single precision floating point on VSX, know that internally single
5008 precision is actually represented as a double, and either make 2 V2DF
5009 vectors, and convert these vectors to single precision, or do one
5010 conversion, and splat the result to the other elements. */
5011 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5015 rtx freg = gen_reg_rtx (V4SFmode);
5016 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5018 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5019 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5023 rtx dbl_even = gen_reg_rtx (V2DFmode);
5024 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5025 rtx flt_even = gen_reg_rtx (V4SFmode);
5026 rtx flt_odd = gen_reg_rtx (V4SFmode);
5028 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5029 copy_to_reg (XVECEXP (vals, 0, 0)),
5030 copy_to_reg (XVECEXP (vals, 0, 1))));
5031 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5032 copy_to_reg (XVECEXP (vals, 0, 2)),
5033 copy_to_reg (XVECEXP (vals, 0, 3))));
5034 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5035 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5036 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5041 /* Store value to stack temp. Load vector element. Splat. However, splat
5042 of 64-bit items is not supported on Altivec. */
5043 if (all_same && GET_MODE_SIZE (mode) <= 4)
5045 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5046 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5047 XVECEXP (vals, 0, 0));
5048 x = gen_rtx_UNSPEC (VOIDmode,
5049 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5050 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5052 gen_rtx_SET (VOIDmode,
5055 x = gen_rtx_VEC_SELECT (inner_mode, target,
5056 gen_rtx_PARALLEL (VOIDmode,
5057 gen_rtvec (1, const0_rtx)));
5058 emit_insn (gen_rtx_SET (VOIDmode, target,
5059 gen_rtx_VEC_DUPLICATE (mode, x)));
5063 /* One field is non-constant. Load constant then overwrite
5067 rtx copy = copy_rtx (vals);
5069 /* Load constant part of vector, substitute neighboring value for
5071 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5072 rs6000_expand_vector_init (target, copy);
5074 /* Insert variable. */
5075 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5079 /* Construct the vector in memory one field at a time
5080 and load the whole vector. */
5081 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5082 for (i = 0; i < n_elts; i++)
5083 emit_move_insn (adjust_address_nv (mem, inner_mode,
5084 i * GET_MODE_SIZE (inner_mode)),
5085 XVECEXP (vals, 0, i));
5086 emit_move_insn (target, mem);
5089 /* Set field ELT of TARGET to VAL. */
5092 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5094 enum machine_mode mode = GET_MODE (target);
5095 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5096 rtx reg = gen_reg_rtx (mode);
5098 int width = GET_MODE_SIZE (inner_mode);
5101 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5103 rtx (*set_func) (rtx, rtx, rtx, rtx)
5104 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5105 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5109 /* Load single variable value. */
5110 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5111 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5112 x = gen_rtx_UNSPEC (VOIDmode,
5113 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5114 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5116 gen_rtx_SET (VOIDmode,
5120 /* Linear sequence. */
5121 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5122 for (i = 0; i < 16; ++i)
5123 XVECEXP (mask, 0, i) = GEN_INT (i);
5125 /* Set permute mask to insert element into target. */
5126 for (i = 0; i < width; ++i)
5127 XVECEXP (mask, 0, elt*width + i)
5128 = GEN_INT (i + 0x10);
5129 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5130 x = gen_rtx_UNSPEC (mode,
5131 gen_rtvec (3, target, reg,
5132 force_reg (V16QImode, x)),
5134 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5137 /* Extract field ELT from VEC into TARGET. */
5140 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5142 enum machine_mode mode = GET_MODE (vec);
5143 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5146 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5148 rtx (*extract_func) (rtx, rtx, rtx)
5149 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5150 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5154 /* Allocate mode-sized buffer. */
5155 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5157 /* Add offset to field within buffer matching vector element. */
5158 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5160 /* Store single field into mode-sized buffer. */
5161 x = gen_rtx_UNSPEC (VOIDmode,
5162 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5163 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5165 gen_rtx_SET (VOIDmode,
5168 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5171 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5172 implement ANDing by the mask IN. */
5174 build_mask64_2_operands (rtx in, rtx *out)
5176 #if HOST_BITS_PER_WIDE_INT >= 64
5177 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5180 gcc_assert (GET_CODE (in) == CONST_INT);
5185 /* Assume c initially something like 0x00fff000000fffff. The idea
5186 is to rotate the word so that the middle ^^^^^^ group of zeros
5187 is at the MS end and can be cleared with an rldicl mask. We then
5188 rotate back and clear off the MS ^^ group of zeros with a
5190 c = ~c; /* c == 0xff000ffffff00000 */
5191 lsb = c & -c; /* lsb == 0x0000000000100000 */
5192 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5193 c = ~c; /* c == 0x00fff000000fffff */
5194 c &= -lsb; /* c == 0x00fff00000000000 */
5195 lsb = c & -c; /* lsb == 0x0000100000000000 */
5196 c = ~c; /* c == 0xff000fffffffffff */
5197 c &= -lsb; /* c == 0xff00000000000000 */
5199 while ((lsb >>= 1) != 0)
5200 shift++; /* shift == 44 on exit from loop */
5201 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5202 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5203 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5207 /* Assume c initially something like 0xff000f0000000000. The idea
5208 is to rotate the word so that the ^^^ middle group of zeros
5209 is at the LS end and can be cleared with an rldicr mask. We then
5210 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5212 lsb = c & -c; /* lsb == 0x0000010000000000 */
5213 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5214 c = ~c; /* c == 0x00fff0ffffffffff */
5215 c &= -lsb; /* c == 0x00fff00000000000 */
5216 lsb = c & -c; /* lsb == 0x0000100000000000 */
5217 c = ~c; /* c == 0xff000fffffffffff */
5218 c &= -lsb; /* c == 0xff00000000000000 */
5220 while ((lsb >>= 1) != 0)
5221 shift++; /* shift == 44 on exit from loop */
5222 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5223 m1 >>= shift; /* m1 == 0x0000000000000fff */
5224 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5227 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5228 masks will be all 1's. We are guaranteed more than one transition. */
5229 out[0] = GEN_INT (64 - shift);
5230 out[1] = GEN_INT (m1);
5231 out[2] = GEN_INT (shift);
5232 out[3] = GEN_INT (m2);
5240 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5243 invalid_e500_subreg (rtx op, enum machine_mode mode)
5245 if (TARGET_E500_DOUBLE)
5247 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5248 subreg:TI and reg:TF. Decimal float modes are like integer
5249 modes (only low part of each register used) for this
5251 if (GET_CODE (op) == SUBREG
5252 && (mode == SImode || mode == DImode || mode == TImode
5253 || mode == DDmode || mode == TDmode)
5254 && REG_P (SUBREG_REG (op))
5255 && (GET_MODE (SUBREG_REG (op)) == DFmode
5256 || GET_MODE (SUBREG_REG (op)) == TFmode))
5259 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5261 if (GET_CODE (op) == SUBREG
5262 && (mode == DFmode || mode == TFmode)
5263 && REG_P (SUBREG_REG (op))
5264 && (GET_MODE (SUBREG_REG (op)) == DImode
5265 || GET_MODE (SUBREG_REG (op)) == TImode
5266 || GET_MODE (SUBREG_REG (op)) == DDmode
5267 || GET_MODE (SUBREG_REG (op)) == TDmode))
5272 && GET_CODE (op) == SUBREG
5274 && REG_P (SUBREG_REG (op))
5275 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5281 /* AIX increases natural record alignment to doubleword if the first
5282 field is an FP double while the FP fields remain word aligned. */
5285 rs6000_special_round_type_align (tree type, unsigned int computed,
5286 unsigned int specified)
5288 unsigned int align = MAX (computed, specified);
5289 tree field = TYPE_FIELDS (type);
5291 /* Skip all non field decls */
5292 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5293 field = DECL_CHAIN (field);
5295 if (field != NULL && field != type)
5297 type = TREE_TYPE (field);
5298 while (TREE_CODE (type) == ARRAY_TYPE)
5299 type = TREE_TYPE (type);
5301 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5302 align = MAX (align, 64);
5308 /* Darwin increases record alignment to the natural alignment of
5312 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5313 unsigned int specified)
5315 unsigned int align = MAX (computed, specified);
5317 if (TYPE_PACKED (type))
5320 /* Find the first field, looking down into aggregates. */
5322 tree field = TYPE_FIELDS (type);
5323 /* Skip all non field decls */
5324 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5325 field = DECL_CHAIN (field);
5328 /* A packed field does not contribute any extra alignment. */
5329 if (DECL_PACKED (field))
5331 type = TREE_TYPE (field);
5332 while (TREE_CODE (type) == ARRAY_TYPE)
5333 type = TREE_TYPE (type);
5334 } while (AGGREGATE_TYPE_P (type));
5336 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5337 align = MAX (align, TYPE_ALIGN (type));
5342 /* Return 1 for an operand in small memory on V.4/eabi. */
5345 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5346 enum machine_mode mode ATTRIBUTE_UNUSED)
5351 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5354 if (DEFAULT_ABI != ABI_V4)
5357 /* Vector and float memory instructions have a limited offset on the
5358 SPE, so using a vector or float variable directly as an operand is
5361 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5364 if (GET_CODE (op) == SYMBOL_REF)
5367 else if (GET_CODE (op) != CONST
5368 || GET_CODE (XEXP (op, 0)) != PLUS
5369 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5370 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5375 rtx sum = XEXP (op, 0);
5376 HOST_WIDE_INT summand;
5378 /* We have to be careful here, because it is the referenced address
5379 that must be 32k from _SDA_BASE_, not just the symbol. */
5380 summand = INTVAL (XEXP (sum, 1));
5381 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5384 sym_ref = XEXP (sum, 0);
5387 return SYMBOL_REF_SMALL_P (sym_ref);
5393 /* Return true if either operand is a general purpose register. */
5396 gpr_or_gpr_p (rtx op0, rtx op1)
5398 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5399 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5403 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5406 reg_offset_addressing_ok_p (enum machine_mode mode)
5416 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5417 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5425 /* Paired vector modes. Only reg+reg addressing is valid. */
5426 if (TARGET_PAIRED_FLOAT)
5438 virtual_stack_registers_memory_p (rtx op)
5442 if (GET_CODE (op) == REG)
5443 regnum = REGNO (op);
5445 else if (GET_CODE (op) == PLUS
5446 && GET_CODE (XEXP (op, 0)) == REG
5447 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5448 regnum = REGNO (XEXP (op, 0));
5453 return (regnum >= FIRST_VIRTUAL_REGISTER
5454 && regnum <= LAST_VIRTUAL_REGISTER);
5458 constant_pool_expr_p (rtx op)
5462 split_const (op, &base, &offset);
5463 return (GET_CODE (base) == SYMBOL_REF
5464 && CONSTANT_POOL_ADDRESS_P (base)
5465 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5468 static rtx tocrel_base, tocrel_offset;
5471 toc_relative_expr_p (rtx op)
5473 if (GET_CODE (op) != CONST)
5476 split_const (op, &tocrel_base, &tocrel_offset);
5477 return (GET_CODE (tocrel_base) == UNSPEC
5478 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5482 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5485 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5486 && GET_CODE (XEXP (x, 0)) == REG
5487 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5488 || ((TARGET_MINIMAL_TOC
5489 || TARGET_CMODEL != CMODEL_SMALL)
5490 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5491 && toc_relative_expr_p (XEXP (x, 1)));
5495 legitimate_small_data_p (enum machine_mode mode, rtx x)
5497 return (DEFAULT_ABI == ABI_V4
5498 && !flag_pic && !TARGET_TOC
5499 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5500 && small_data_operand (x, mode));
5503 /* SPE offset addressing is limited to 5-bits worth of double words. */
5504 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5507 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5509 unsigned HOST_WIDE_INT offset, extra;
5511 if (GET_CODE (x) != PLUS)
5513 if (GET_CODE (XEXP (x, 0)) != REG)
5515 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5517 if (!reg_offset_addressing_ok_p (mode))
5518 return virtual_stack_registers_memory_p (x);
5519 if (legitimate_constant_pool_address_p (x, strict))
5521 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5524 offset = INTVAL (XEXP (x, 1));
5532 /* SPE vector modes. */
5533 return SPE_CONST_OFFSET_OK (offset);
5536 if (TARGET_E500_DOUBLE)
5537 return SPE_CONST_OFFSET_OK (offset);
5539 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5541 if (VECTOR_MEM_VSX_P (DFmode))
5546 /* On e500v2, we may have:
5548 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5550 Which gets addressed with evldd instructions. */
5551 if (TARGET_E500_DOUBLE)
5552 return SPE_CONST_OFFSET_OK (offset);
5554 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5556 else if (offset & 3)
5561 if (TARGET_E500_DOUBLE)
5562 return (SPE_CONST_OFFSET_OK (offset)
5563 && SPE_CONST_OFFSET_OK (offset + 8));
5567 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5569 else if (offset & 3)
5580 return (offset < 0x10000) && (offset + extra < 0x10000);
5584 legitimate_indexed_address_p (rtx x, int strict)
5588 if (GET_CODE (x) != PLUS)
5594 /* Recognize the rtl generated by reload which we know will later be
5595 replaced with proper base and index regs. */
5597 && reload_in_progress
5598 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5602 return (REG_P (op0) && REG_P (op1)
5603 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5604 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5605 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5606 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5610 avoiding_indexed_address_p (enum machine_mode mode)
5612 /* Avoid indexed addressing for modes that have non-indexed
5613 load/store instruction forms. */
5614 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5618 legitimate_indirect_address_p (rtx x, int strict)
5620 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5624 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5626 if (!TARGET_MACHO || !flag_pic
5627 || mode != SImode || GET_CODE (x) != MEM)
5631 if (GET_CODE (x) != LO_SUM)
5633 if (GET_CODE (XEXP (x, 0)) != REG)
5635 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5639 return CONSTANT_P (x);
5643 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5645 if (GET_CODE (x) != LO_SUM)
5647 if (GET_CODE (XEXP (x, 0)) != REG)
5649 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5651 /* Restrict addressing for DI because of our SUBREG hackery. */
5652 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5653 || mode == DDmode || mode == TDmode
5658 if (TARGET_ELF || TARGET_MACHO)
5660 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5664 if (GET_MODE_NUNITS (mode) != 1)
5666 if (GET_MODE_BITSIZE (mode) > 64
5667 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5668 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5669 && (mode == DFmode || mode == DDmode))))
5672 return CONSTANT_P (x);
5679 /* Try machine-dependent ways of modifying an illegitimate address
5680 to be legitimate. If we find one, return the new, valid address.
5681 This is used from only one place: `memory_address' in explow.c.
5683 OLDX is the address as it was before break_out_memory_refs was
5684 called. In some cases it is useful to look at this to decide what
5687 It is always safe for this function to do nothing. It exists to
5688 recognize opportunities to optimize the output.
5690 On RS/6000, first check for the sum of a register with a constant
5691 integer that is out of range. If so, generate code to add the
5692 constant with the low-order 16 bits masked to the register and force
5693 this result into another register (this can be done with `cau').
5694 Then generate an address of REG+(CONST&0xffff), allowing for the
5695 possibility of bit 16 being a one.
5697 Then check for the sum of a register and something not constant, try to
5698 load the other things into a register and return the sum. */
5701 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5702 enum machine_mode mode)
5704 unsigned int extra = 0;
5706 if (!reg_offset_addressing_ok_p (mode))
5708 if (virtual_stack_registers_memory_p (x))
5711 /* In theory we should not be seeing addresses of the form reg+0,
5712 but just in case it is generated, optimize it away. */
5713 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5714 return force_reg (Pmode, XEXP (x, 0));
5716 /* Make sure both operands are registers. */
5717 else if (GET_CODE (x) == PLUS)
5718 return gen_rtx_PLUS (Pmode,
5719 force_reg (Pmode, XEXP (x, 0)),
5720 force_reg (Pmode, XEXP (x, 1)));
5722 return force_reg (Pmode, x);
5724 if (GET_CODE (x) == SYMBOL_REF)
5726 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5728 return rs6000_legitimize_tls_address (x, model);
5738 if (!TARGET_POWERPC64)
5746 extra = TARGET_POWERPC64 ? 8 : 12;
5752 if (GET_CODE (x) == PLUS
5753 && GET_CODE (XEXP (x, 0)) == REG
5754 && GET_CODE (XEXP (x, 1)) == CONST_INT
5755 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5757 && !((TARGET_POWERPC64
5758 && (mode == DImode || mode == TImode)
5759 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5760 || SPE_VECTOR_MODE (mode)
5761 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5762 || mode == DImode || mode == DDmode
5763 || mode == TDmode))))
5765 HOST_WIDE_INT high_int, low_int;
5767 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5768 if (low_int >= 0x8000 - extra)
5770 high_int = INTVAL (XEXP (x, 1)) - low_int;
5771 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5772 GEN_INT (high_int)), 0);
5773 return plus_constant (sum, low_int);
5775 else if (GET_CODE (x) == PLUS
5776 && GET_CODE (XEXP (x, 0)) == REG
5777 && GET_CODE (XEXP (x, 1)) != CONST_INT
5778 && GET_MODE_NUNITS (mode) == 1
5779 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5781 || ((mode != DImode && mode != DFmode && mode != DDmode)
5782 || (TARGET_E500_DOUBLE && mode != DDmode)))
5783 && (TARGET_POWERPC64 || mode != DImode)
5784 && !avoiding_indexed_address_p (mode)
5789 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5790 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5792 else if (SPE_VECTOR_MODE (mode)
5793 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5794 || mode == DDmode || mode == TDmode
5795 || mode == DImode)))
5799 /* We accept [reg + reg] and [reg + OFFSET]. */
5801 if (GET_CODE (x) == PLUS)
5803 rtx op1 = XEXP (x, 0);
5804 rtx op2 = XEXP (x, 1);
5807 op1 = force_reg (Pmode, op1);
5809 if (GET_CODE (op2) != REG
5810 && (GET_CODE (op2) != CONST_INT
5811 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5812 || (GET_MODE_SIZE (mode) > 8
5813 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5814 op2 = force_reg (Pmode, op2);
5816 /* We can't always do [reg + reg] for these, because [reg +
5817 reg + offset] is not a legitimate addressing mode. */
5818 y = gen_rtx_PLUS (Pmode, op1, op2);
5820 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5821 return force_reg (Pmode, y);
5826 return force_reg (Pmode, x);
5832 && GET_CODE (x) != CONST_INT
5833 && GET_CODE (x) != CONST_DOUBLE
5835 && GET_MODE_NUNITS (mode) == 1
5836 && (GET_MODE_BITSIZE (mode) <= 32
5837 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5838 && (mode == DFmode || mode == DDmode))))
5840 rtx reg = gen_reg_rtx (Pmode);
5841 emit_insn (gen_elf_high (reg, x));
5842 return gen_rtx_LO_SUM (Pmode, reg, x);
5844 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5847 && ! MACHO_DYNAMIC_NO_PIC_P
5849 && GET_CODE (x) != CONST_INT
5850 && GET_CODE (x) != CONST_DOUBLE
5852 && GET_MODE_NUNITS (mode) == 1
5853 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5854 || (mode != DFmode && mode != DDmode))
5858 rtx reg = gen_reg_rtx (Pmode);
5859 emit_insn (gen_macho_high (reg, x));
5860 return gen_rtx_LO_SUM (Pmode, reg, x);
5863 && GET_CODE (x) == SYMBOL_REF
5864 && constant_pool_expr_p (x)
5865 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5867 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5868 return create_TOC_reference (x, reg);
5874 /* Debug version of rs6000_legitimize_address. */
5876 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5882 ret = rs6000_legitimize_address (x, oldx, mode);
5883 insns = get_insns ();
5889 "\nrs6000_legitimize_address: mode %s, old code %s, "
5890 "new code %s, modified\n",
5891 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5892 GET_RTX_NAME (GET_CODE (ret)));
5894 fprintf (stderr, "Original address:\n");
5897 fprintf (stderr, "oldx:\n");
5900 fprintf (stderr, "New address:\n");
5905 fprintf (stderr, "Insns added:\n");
5906 debug_rtx_list (insns, 20);
5912 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5913 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5924 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5925 We need to emit DTP-relative relocations. */
5928 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5933 fputs ("\t.long\t", file);
5936 fputs (DOUBLE_INT_ASM_OP, file);
5941 output_addr_const (file, x);
5942 fputs ("@dtprel+0x8000", file);
5945 /* In the name of slightly smaller debug output, and to cater to
5946 general assembler lossage, recognize various UNSPEC sequences
5947 and turn them back into a direct symbol reference. */
5950 rs6000_delegitimize_address (rtx orig_x)
5954 orig_x = delegitimize_mem_from_attrs (orig_x);
5959 if ((GET_CODE (x) == PLUS
5960 || GET_CODE (x) == LO_SUM)
5961 && GET_CODE (XEXP (x, 0)) == REG
5962 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5963 || TARGET_MINIMAL_TOC
5964 || TARGET_CMODEL != CMODEL_SMALL)
5965 && GET_CODE (XEXP (x, 1)) == CONST)
5967 y = XEXP (XEXP (x, 1), 0);
5968 if (GET_CODE (y) == UNSPEC
5969 && XINT (y, 1) == UNSPEC_TOCREL)
5971 y = XVECEXP (y, 0, 0);
5972 if (!MEM_P (orig_x))
5975 return replace_equiv_address_nv (orig_x, y);
5980 && GET_CODE (orig_x) == LO_SUM
5981 && GET_CODE (XEXP (x, 1)) == CONST)
5983 y = XEXP (XEXP (x, 1), 0);
5984 if (GET_CODE (y) == UNSPEC
5985 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5986 return XVECEXP (y, 0, 0);
5992 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5994 static GTY(()) rtx rs6000_tls_symbol;
5996 rs6000_tls_get_addr (void)
5998 if (!rs6000_tls_symbol)
5999 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6001 return rs6000_tls_symbol;
6004 /* Construct the SYMBOL_REF for TLS GOT references. */
6006 static GTY(()) rtx rs6000_got_symbol;
6008 rs6000_got_sym (void)
6010 if (!rs6000_got_symbol)
6012 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6013 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6014 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6017 return rs6000_got_symbol;
6020 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6021 this (thread-local) address. */
6024 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6028 dest = gen_reg_rtx (Pmode);
6029 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6035 tlsreg = gen_rtx_REG (Pmode, 13);
6036 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6040 tlsreg = gen_rtx_REG (Pmode, 2);
6041 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6045 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6049 tmp = gen_reg_rtx (Pmode);
6052 tlsreg = gen_rtx_REG (Pmode, 13);
6053 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6057 tlsreg = gen_rtx_REG (Pmode, 2);
6058 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6062 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6064 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6069 rtx r3, got, tga, tmp1, tmp2, call_insn;
6071 /* We currently use relocations like @got@tlsgd for tls, which
6072 means the linker will handle allocation of tls entries, placing
6073 them in the .got section. So use a pointer to the .got section,
6074 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6075 or to secondary GOT sections used by 32-bit -fPIC. */
6077 got = gen_rtx_REG (Pmode, 2);
6081 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6084 rtx gsym = rs6000_got_sym ();
6085 got = gen_reg_rtx (Pmode);
6087 rs6000_emit_move (got, gsym, Pmode);
6092 tmp1 = gen_reg_rtx (Pmode);
6093 tmp2 = gen_reg_rtx (Pmode);
6094 mem = gen_const_mem (Pmode, tmp1);
6095 lab = gen_label_rtx ();
6096 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6097 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6098 emit_move_insn (tmp2, mem);
6099 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6100 set_unique_reg_note (last, REG_EQUAL, gsym);
6105 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6107 r3 = gen_rtx_REG (Pmode, 3);
6108 tga = rs6000_tls_get_addr ();
6109 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6111 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6112 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6113 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6114 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6115 else if (DEFAULT_ABI == ABI_V4)
6116 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6119 call_insn = last_call_insn ();
6120 PATTERN (call_insn) = insn;
6121 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6122 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6123 pic_offset_table_rtx);
6125 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6127 r3 = gen_rtx_REG (Pmode, 3);
6128 tga = rs6000_tls_get_addr ();
6129 tmp1 = gen_reg_rtx (Pmode);
6130 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6132 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6133 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6134 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6135 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6136 else if (DEFAULT_ABI == ABI_V4)
6137 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6140 call_insn = last_call_insn ();
6141 PATTERN (call_insn) = insn;
6142 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6143 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6144 pic_offset_table_rtx);
6146 if (rs6000_tls_size == 16)
6149 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6151 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6153 else if (rs6000_tls_size == 32)
6155 tmp2 = gen_reg_rtx (Pmode);
6157 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6159 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6162 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6164 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6168 tmp2 = gen_reg_rtx (Pmode);
6170 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6172 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6174 insn = gen_rtx_SET (Pmode, dest,
6175 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6181 /* IE, or 64-bit offset LE. */
6182 tmp2 = gen_reg_rtx (Pmode);
6184 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6186 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6189 insn = gen_tls_tls_64 (dest, tmp2, addr);
6191 insn = gen_tls_tls_32 (dest, tmp2, addr);
6199 /* Return 1 if X contains a thread-local symbol. */
6202 rs6000_tls_referenced_p (rtx x)
6204 if (! TARGET_HAVE_TLS)
6207 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6210 /* Return 1 if *X is a thread-local symbol. This is the same as
6211 rs6000_tls_symbol_ref except for the type of the unused argument. */
6214 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6216 return RS6000_SYMBOL_REF_TLS_P (*x);
6219 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6220 replace the input X, or the original X if no replacement is called for.
6221 The output parameter *WIN is 1 if the calling macro should goto WIN,
6224 For RS/6000, we wish to handle large displacements off a base
6225 register by splitting the addend across an addiu/addis and the mem insn.
6226 This cuts number of extra insns needed from 3 to 1.
6228 On Darwin, we use this to generate code for floating point constants.
6229 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6230 The Darwin code is inside #if TARGET_MACHO because only then are the
6231 machopic_* functions defined. */
6233 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6234 int opnum, int type,
6235 int ind_levels ATTRIBUTE_UNUSED, int *win)
6237 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6239 /* We must recognize output that we have already generated ourselves. */
6240 if (GET_CODE (x) == PLUS
6241 && GET_CODE (XEXP (x, 0)) == PLUS
6242 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6243 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6244 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6246 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6247 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6248 opnum, (enum reload_type)type);
6253 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6254 if (GET_CODE (x) == LO_SUM
6255 && GET_CODE (XEXP (x, 0)) == HIGH)
6257 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6258 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6259 opnum, (enum reload_type)type);
6265 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6266 && GET_CODE (x) == LO_SUM
6267 && GET_CODE (XEXP (x, 0)) == PLUS
6268 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6269 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6270 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6271 && machopic_operand_p (XEXP (x, 1)))
6273 /* Result of previous invocation of this function on Darwin
6274 floating point constant. */
6275 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6276 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6277 opnum, (enum reload_type)type);
6283 if (TARGET_CMODEL != CMODEL_SMALL
6284 && GET_CODE (x) == LO_SUM
6285 && GET_CODE (XEXP (x, 0)) == PLUS
6286 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6287 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6288 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6289 && GET_CODE (XEXP (x, 1)) == CONST
6290 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6291 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6292 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6294 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6295 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6296 opnum, (enum reload_type) type);
6301 /* Force ld/std non-word aligned offset into base register by wrapping
6303 if (GET_CODE (x) == PLUS
6304 && GET_CODE (XEXP (x, 0)) == REG
6305 && REGNO (XEXP (x, 0)) < 32
6306 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6307 && GET_CODE (XEXP (x, 1)) == CONST_INT
6309 && (INTVAL (XEXP (x, 1)) & 3) != 0
6310 && VECTOR_MEM_NONE_P (mode)
6311 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6312 && TARGET_POWERPC64)
6314 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6315 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6316 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6317 opnum, (enum reload_type) type);
6322 if (GET_CODE (x) == PLUS
6323 && GET_CODE (XEXP (x, 0)) == REG
6324 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6325 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6326 && GET_CODE (XEXP (x, 1)) == CONST_INT
6328 && !SPE_VECTOR_MODE (mode)
6329 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6330 || mode == DDmode || mode == TDmode
6332 && VECTOR_MEM_NONE_P (mode))
6334 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6335 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6337 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6339 /* Check for 32-bit overflow. */
6340 if (high + low != val)
6346 /* Reload the high part into a base reg; leave the low part
6347 in the mem directly. */
6349 x = gen_rtx_PLUS (GET_MODE (x),
6350 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6354 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6355 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6356 opnum, (enum reload_type)type);
6361 if (GET_CODE (x) == SYMBOL_REF
6363 && VECTOR_MEM_NONE_P (mode)
6364 && !SPE_VECTOR_MODE (mode)
6366 && DEFAULT_ABI == ABI_DARWIN
6367 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6369 && DEFAULT_ABI == ABI_V4
6372 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6373 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6377 && (mode != DImode || TARGET_POWERPC64)
6378 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6379 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6384 rtx offset = machopic_gen_offset (x);
6385 x = gen_rtx_LO_SUM (GET_MODE (x),
6386 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6387 gen_rtx_HIGH (Pmode, offset)), offset);
6391 x = gen_rtx_LO_SUM (GET_MODE (x),
6392 gen_rtx_HIGH (Pmode, x), x);
6394 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6395 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6396 opnum, (enum reload_type)type);
6401 /* Reload an offset address wrapped by an AND that represents the
6402 masking of the lower bits. Strip the outer AND and let reload
6403 convert the offset address into an indirect address. For VSX,
6404 force reload to create the address with an AND in a separate
6405 register, because we can't guarantee an altivec register will
6407 if (VECTOR_MEM_ALTIVEC_P (mode)
6408 && GET_CODE (x) == AND
6409 && GET_CODE (XEXP (x, 0)) == PLUS
6410 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6411 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6412 && GET_CODE (XEXP (x, 1)) == CONST_INT
6413 && INTVAL (XEXP (x, 1)) == -16)
6422 && GET_CODE (x) == SYMBOL_REF
6423 && constant_pool_expr_p (x)
6424 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6426 x = create_TOC_reference (x, NULL_RTX);
6427 if (TARGET_CMODEL != CMODEL_SMALL)
6428 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6429 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6430 opnum, (enum reload_type) type);
6438 /* Debug version of rs6000_legitimize_reload_address. */
6440 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6441 int opnum, int type,
6442 int ind_levels, int *win)
6444 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6447 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6448 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6449 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6453 fprintf (stderr, "Same address returned\n");
6455 fprintf (stderr, "NULL returned\n");
6458 fprintf (stderr, "New address:\n");
6465 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6466 that is a valid memory address for an instruction.
6467 The MODE argument is the machine mode for the MEM expression
6468 that wants to use this address.
6470 On the RS/6000, there are four valid address: a SYMBOL_REF that
6471 refers to a constant pool entry of an address (or the sum of it
6472 plus a constant), a short (16-bit signed) constant plus a register,
6473 the sum of two registers, or a register indirect, possibly with an
6474 auto-increment. For DFmode, DDmode and DImode with a constant plus
6475 register, we must ensure that both words are addressable or PowerPC64
6476 with offset word aligned.
6478 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6479 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6480 because adjacent memory cells are accessed by adding word-sized offsets
6481 during assembly output. */
6483 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6485 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6487 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6488 if (VECTOR_MEM_ALTIVEC_P (mode)
6489 && GET_CODE (x) == AND
6490 && GET_CODE (XEXP (x, 1)) == CONST_INT
6491 && INTVAL (XEXP (x, 1)) == -16)
6494 if (RS6000_SYMBOL_REF_TLS_P (x))
6496 if (legitimate_indirect_address_p (x, reg_ok_strict))
6498 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6499 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6500 && !SPE_VECTOR_MODE (mode)
6503 /* Restrict addressing for DI because of our SUBREG hackery. */
6504 && !(TARGET_E500_DOUBLE
6505 && (mode == DFmode || mode == DDmode || mode == DImode))
6507 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6509 if (virtual_stack_registers_memory_p (x))
6511 if (reg_offset_p && legitimate_small_data_p (mode, x))
6513 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6515 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6518 && GET_CODE (x) == PLUS
6519 && GET_CODE (XEXP (x, 0)) == REG
6520 && (XEXP (x, 0) == virtual_stack_vars_rtx
6521 || XEXP (x, 0) == arg_pointer_rtx)
6522 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6524 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6529 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6531 || (mode != DFmode && mode != DDmode)
6532 || (TARGET_E500_DOUBLE && mode != DDmode))
6533 && (TARGET_POWERPC64 || mode != DImode)
6534 && !avoiding_indexed_address_p (mode)
6535 && legitimate_indexed_address_p (x, reg_ok_strict))
6537 if (GET_CODE (x) == PRE_MODIFY
6541 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6543 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6544 && (TARGET_POWERPC64 || mode != DImode)
6545 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6546 && !SPE_VECTOR_MODE (mode)
6547 /* Restrict addressing for DI because of our SUBREG hackery. */
6548 && !(TARGET_E500_DOUBLE
6549 && (mode == DFmode || mode == DDmode || mode == DImode))
6551 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6552 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6553 || (!avoiding_indexed_address_p (mode)
6554 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6555 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6557 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6562 /* Debug version of rs6000_legitimate_address_p. */
6564 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6567 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6569 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6570 "strict = %d, code = %s\n",
6571 ret ? "true" : "false",
6572 GET_MODE_NAME (mode),
6574 GET_RTX_NAME (GET_CODE (x)));
6580 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6583 rs6000_mode_dependent_address_p (const_rtx addr)
6585 return rs6000_mode_dependent_address_ptr (addr);
6588 /* Go to LABEL if ADDR (a legitimate address expression)
6589 has an effect that depends on the machine mode it is used for.
6591 On the RS/6000 this is true of all integral offsets (since AltiVec
6592 and VSX modes don't allow them) or is a pre-increment or decrement.
6594 ??? Except that due to conceptual problems in offsettable_address_p
6595 we can't really report the problems of integral offsets. So leave
6596 this assuming that the adjustable offset must be valid for the
6597 sub-words of a TFmode operand, which is what we had before. */
6600 rs6000_mode_dependent_address (const_rtx addr)
6602 switch (GET_CODE (addr))
6605 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6606 is considered a legitimate address before reload, so there
6607 are no offset restrictions in that case. Note that this
6608 condition is safe in strict mode because any address involving
6609 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6610 been rejected as illegitimate. */
6611 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6612 && XEXP (addr, 0) != arg_pointer_rtx
6613 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6615 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6616 return val + 12 + 0x8000 >= 0x10000;
6621 /* Anything in the constant pool is sufficiently aligned that
6622 all bytes have the same high part address. */
6623 return !legitimate_constant_pool_address_p (addr, false);
6625 /* Auto-increment cases are now treated generically in recog.c. */
6627 return TARGET_UPDATE;
6629 /* AND is only allowed in Altivec loads. */
6640 /* Debug version of rs6000_mode_dependent_address. */
6642 rs6000_debug_mode_dependent_address (const_rtx addr)
6644 bool ret = rs6000_mode_dependent_address (addr);
6646 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6647 ret ? "true" : "false");
6653 /* Implement FIND_BASE_TERM. */
6656 rs6000_find_base_term (rtx op)
6660 split_const (op, &base, &offset);
6661 if (GET_CODE (base) == UNSPEC)
6662 switch (XINT (base, 1))
6665 case UNSPEC_MACHOPIC_OFFSET:
6666 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6667 for aliasing purposes. */
6668 return XVECEXP (base, 0, 0);
6674 /* More elaborate version of recog's offsettable_memref_p predicate
6675 that works around the ??? note of rs6000_mode_dependent_address.
6676 In particular it accepts
6678 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6680 in 32-bit mode, that the recog predicate rejects. */
6683 rs6000_offsettable_memref_p (rtx op)
6688 /* First mimic offsettable_memref_p. */
6689 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6692 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6693 the latter predicate knows nothing about the mode of the memory
6694 reference and, therefore, assumes that it is the largest supported
6695 mode (TFmode). As a consequence, legitimate offsettable memory
6696 references are rejected. rs6000_legitimate_offset_address_p contains
6697 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6698 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6701 /* Change register usage conditional on target flags. */
6703 rs6000_conditional_register_usage (void)
6707 /* Set MQ register fixed (already call_used) if not POWER
6708 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6713 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6715 fixed_regs[13] = call_used_regs[13]
6716 = call_really_used_regs[13] = 1;
6718 /* Conditionally disable FPRs. */
6719 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6720 for (i = 32; i < 64; i++)
6721 fixed_regs[i] = call_used_regs[i]
6722 = call_really_used_regs[i] = 1;
6724 /* The TOC register is not killed across calls in a way that is
6725 visible to the compiler. */
6726 if (DEFAULT_ABI == ABI_AIX)
6727 call_really_used_regs[2] = 0;
6729 if (DEFAULT_ABI == ABI_V4
6730 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6732 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6734 if (DEFAULT_ABI == ABI_V4
6735 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6737 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6738 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6739 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6741 if (DEFAULT_ABI == ABI_DARWIN
6742 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6743 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6744 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6745 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6747 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6748 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6749 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6753 global_regs[SPEFSCR_REGNO] = 1;
6754 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6755 registers in prologues and epilogues. We no longer use r14
6756 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6757 pool for link-compatibility with older versions of GCC. Once
6758 "old" code has died out, we can return r14 to the allocation
6761 = call_used_regs[14]
6762 = call_really_used_regs[14] = 1;
6765 if (!TARGET_ALTIVEC && !TARGET_VSX)
6767 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6768 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6769 call_really_used_regs[VRSAVE_REGNO] = 1;
6772 if (TARGET_ALTIVEC || TARGET_VSX)
6773 global_regs[VSCR_REGNO] = 1;
6775 if (TARGET_ALTIVEC_ABI)
6777 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6778 call_used_regs[i] = call_really_used_regs[i] = 1;
6780 /* AIX reserves VR20:31 in non-extended ABI mode. */
6782 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6783 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6787 /* Try to output insns to set TARGET equal to the constant C if it can
6788 be done in less than N insns. Do all computations in MODE.
6789 Returns the place where the output has been placed if it can be
6790 done and the insns have been emitted. If it would take more than N
6791 insns, zero is returned and no insns and emitted. */
6794 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6795 rtx source, int n ATTRIBUTE_UNUSED)
6797 rtx result, insn, set;
6798 HOST_WIDE_INT c0, c1;
6805 dest = gen_reg_rtx (mode);
6806 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6810 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6812 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6813 GEN_INT (INTVAL (source)
6814 & (~ (HOST_WIDE_INT) 0xffff))));
6815 emit_insn (gen_rtx_SET (VOIDmode, dest,
6816 gen_rtx_IOR (SImode, copy_rtx (result),
6817 GEN_INT (INTVAL (source) & 0xffff))));
6822 switch (GET_CODE (source))
6825 c0 = INTVAL (source);
6830 #if HOST_BITS_PER_WIDE_INT >= 64
6831 c0 = CONST_DOUBLE_LOW (source);
6834 c0 = CONST_DOUBLE_LOW (source);
6835 c1 = CONST_DOUBLE_HIGH (source);
6843 result = rs6000_emit_set_long_const (dest, c0, c1);
6850 insn = get_last_insn ();
6851 set = single_set (insn);
6852 if (! CONSTANT_P (SET_SRC (set)))
6853 set_unique_reg_note (insn, REG_EQUAL, source);
6858 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6859 fall back to a straight forward decomposition. We do this to avoid
6860 exponential run times encountered when looking for longer sequences
6861 with rs6000_emit_set_const. */
6863 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6865 if (!TARGET_POWERPC64)
6867 rtx operand1, operand2;
6869 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6871 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6873 emit_move_insn (operand1, GEN_INT (c1));
6874 emit_move_insn (operand2, GEN_INT (c2));
6878 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6881 ud2 = (c1 & 0xffff0000) >> 16;
6882 #if HOST_BITS_PER_WIDE_INT >= 64
6886 ud4 = (c2 & 0xffff0000) >> 16;
6888 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6889 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6892 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6894 emit_move_insn (dest, GEN_INT (ud1));
6897 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6898 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6901 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6904 emit_move_insn (dest, GEN_INT (ud2 << 16));
6906 emit_move_insn (copy_rtx (dest),
6907 gen_rtx_IOR (DImode, copy_rtx (dest),
6910 else if (ud3 == 0 && ud4 == 0)
6912 gcc_assert (ud2 & 0x8000);
6913 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6916 emit_move_insn (copy_rtx (dest),
6917 gen_rtx_IOR (DImode, copy_rtx (dest),
6919 emit_move_insn (copy_rtx (dest),
6920 gen_rtx_ZERO_EXTEND (DImode,
6921 gen_lowpart (SImode,
6924 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6925 || (ud4 == 0 && ! (ud3 & 0x8000)))
6928 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6931 emit_move_insn (dest, GEN_INT (ud3 << 16));
6934 emit_move_insn (copy_rtx (dest),
6935 gen_rtx_IOR (DImode, copy_rtx (dest),
6937 emit_move_insn (copy_rtx (dest),
6938 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6941 emit_move_insn (copy_rtx (dest),
6942 gen_rtx_IOR (DImode, copy_rtx (dest),
6948 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6951 emit_move_insn (dest, GEN_INT (ud4 << 16));
6954 emit_move_insn (copy_rtx (dest),
6955 gen_rtx_IOR (DImode, copy_rtx (dest),
6958 emit_move_insn (copy_rtx (dest),
6959 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6962 emit_move_insn (copy_rtx (dest),
6963 gen_rtx_IOR (DImode, copy_rtx (dest),
6964 GEN_INT (ud2 << 16)));
6966 emit_move_insn (copy_rtx (dest),
6967 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6973 /* Helper for the following. Get rid of [r+r] memory refs
6974 in cases where it won't work (TImode, TFmode, TDmode). */
6977 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6979 if (reload_in_progress)
6982 if (GET_CODE (operands[0]) == MEM
6983 && GET_CODE (XEXP (operands[0], 0)) != REG
6984 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6986 = replace_equiv_address (operands[0],
6987 copy_addr_to_reg (XEXP (operands[0], 0)));
6989 if (GET_CODE (operands[1]) == MEM
6990 && GET_CODE (XEXP (operands[1], 0)) != REG
6991 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
6993 = replace_equiv_address (operands[1],
6994 copy_addr_to_reg (XEXP (operands[1], 0)));
6997 /* Return true if OP, a SYMBOL_REF, should be considered local when
6998 generating -mcmodel=medium code. */
7001 toc_relative_ok (rtx op)
7005 if (!SYMBOL_REF_LOCAL_P (op))
7008 /* This is a bit hard to explain. When building shared libraries,
7009 you are supposed to pass -fpic or -fPIC to the compiler.
7010 -fpic/-fPIC not only generate position independent code but also
7011 generate code that supports ELF shared library global function
7012 or variable overriding. ppc64 is always PIC and at least some of
7013 the ELF shared libaray semantics of global variables happen to be
7014 supported without -fpic/-fPIC. So people may not be careful
7015 about using -fPIC for shared libs.
7016 With -mcmodel=medium this situation changes. A shared library
7017 built without -fpic/-fPIC requires text relocs for global var
7018 access (and would fail to load since glibc ld.so doesn't support
7019 the required dynamic relocs). So avoid this potential
7020 problem by using -mcmodel=large access for global vars, unless
7021 we know we are compiling for an executable. */
7025 decl = SYMBOL_REF_DECL (op);
7026 if (!decl || !DECL_P (decl))
7028 if (!TREE_PUBLIC (decl))
7030 if (DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)
7033 /* If we get here we must have a global var. See binds_local_p. */
7034 return flag_whole_program;
7037 /* Return true if memory accesses to DECL are known to never straddle
7041 offsettable_ok_by_alignment (tree decl)
7043 unsigned HOST_WIDE_INT dsize, dalign;
7045 /* Presume any compiler generated symbol_ref is suitably aligned. */
7049 if (TREE_CODE (decl) != VAR_DECL
7050 && TREE_CODE (decl) != PARM_DECL
7051 && TREE_CODE (decl) != RESULT_DECL
7052 && TREE_CODE (decl) != FIELD_DECL)
7055 if (!DECL_SIZE_UNIT (decl))
7058 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7061 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7067 dalign = DECL_ALIGN_UNIT (decl);
7068 return dalign >= dsize;
7071 /* Emit a move from SOURCE to DEST in mode MODE. */
7073 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7077 operands[1] = source;
7079 if (TARGET_DEBUG_ADDR)
7082 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7083 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7084 GET_MODE_NAME (mode),
7087 can_create_pseudo_p ());
7089 fprintf (stderr, "source:\n");
7093 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7094 if (GET_CODE (operands[1]) == CONST_DOUBLE
7095 && ! FLOAT_MODE_P (mode)
7096 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7098 /* FIXME. This should never happen. */
7099 /* Since it seems that it does, do the safe thing and convert
7101 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7103 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7104 || FLOAT_MODE_P (mode)
7105 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7106 || CONST_DOUBLE_LOW (operands[1]) < 0)
7107 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7108 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7110 /* Check if GCC is setting up a block move that will end up using FP
7111 registers as temporaries. We must make sure this is acceptable. */
7112 if (GET_CODE (operands[0]) == MEM
7113 && GET_CODE (operands[1]) == MEM
7115 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7116 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7117 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7118 ? 32 : MEM_ALIGN (operands[0])))
7119 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7121 : MEM_ALIGN (operands[1]))))
7122 && ! MEM_VOLATILE_P (operands [0])
7123 && ! MEM_VOLATILE_P (operands [1]))
7125 emit_move_insn (adjust_address (operands[0], SImode, 0),
7126 adjust_address (operands[1], SImode, 0));
7127 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7128 adjust_address (copy_rtx (operands[1]), SImode, 4));
7132 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7133 && !gpc_reg_operand (operands[1], mode))
7134 operands[1] = force_reg (mode, operands[1]);
7136 if (mode == SFmode && ! TARGET_POWERPC
7137 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7138 && GET_CODE (operands[0]) == MEM)
7142 if (reload_in_progress || reload_completed)
7143 regnum = true_regnum (operands[1]);
7144 else if (GET_CODE (operands[1]) == REG)
7145 regnum = REGNO (operands[1]);
7149 /* If operands[1] is a register, on POWER it may have
7150 double-precision data in it, so truncate it to single
7152 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7155 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7156 : gen_reg_rtx (mode));
7157 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7158 operands[1] = newreg;
7162 /* Recognize the case where operand[1] is a reference to thread-local
7163 data and load its address to a register. */
7164 if (rs6000_tls_referenced_p (operands[1]))
7166 enum tls_model model;
7167 rtx tmp = operands[1];
7170 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7172 addend = XEXP (XEXP (tmp, 0), 1);
7173 tmp = XEXP (XEXP (tmp, 0), 0);
7176 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7177 model = SYMBOL_REF_TLS_MODEL (tmp);
7178 gcc_assert (model != 0);
7180 tmp = rs6000_legitimize_tls_address (tmp, model);
7183 tmp = gen_rtx_PLUS (mode, tmp, addend);
7184 tmp = force_operand (tmp, operands[0]);
7189 /* Handle the case where reload calls us with an invalid address. */
7190 if (reload_in_progress && mode == Pmode
7191 && (! general_operand (operands[1], mode)
7192 || ! nonimmediate_operand (operands[0], mode)))
7195 /* 128-bit constant floating-point values on Darwin should really be
7196 loaded as two parts. */
7197 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7198 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7200 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7201 know how to get a DFmode SUBREG of a TFmode. */
7202 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7203 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7204 simplify_gen_subreg (imode, operands[1], mode, 0),
7206 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7207 GET_MODE_SIZE (imode)),
7208 simplify_gen_subreg (imode, operands[1], mode,
7209 GET_MODE_SIZE (imode)),
7214 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7215 cfun->machine->sdmode_stack_slot =
7216 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7218 if (reload_in_progress
7220 && MEM_P (operands[0])
7221 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7222 && REG_P (operands[1]))
7224 if (FP_REGNO_P (REGNO (operands[1])))
7226 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7227 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7228 emit_insn (gen_movsd_store (mem, operands[1]));
7230 else if (INT_REGNO_P (REGNO (operands[1])))
7232 rtx mem = adjust_address_nv (operands[0], mode, 4);
7233 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7234 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7240 if (reload_in_progress
7242 && REG_P (operands[0])
7243 && MEM_P (operands[1])
7244 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7246 if (FP_REGNO_P (REGNO (operands[0])))
7248 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7249 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7250 emit_insn (gen_movsd_load (operands[0], mem));
7252 else if (INT_REGNO_P (REGNO (operands[0])))
7254 rtx mem = adjust_address_nv (operands[1], mode, 4);
7255 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7256 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7263 /* FIXME: In the long term, this switch statement should go away
7264 and be replaced by a sequence of tests based on things like
7270 if (CONSTANT_P (operands[1])
7271 && GET_CODE (operands[1]) != CONST_INT)
7272 operands[1] = force_const_mem (mode, operands[1]);
7277 rs6000_eliminate_indexed_memrefs (operands);
7284 if (CONSTANT_P (operands[1])
7285 && ! easy_fp_constant (operands[1], mode))
7286 operands[1] = force_const_mem (mode, operands[1]);
7299 if (CONSTANT_P (operands[1])
7300 && !easy_vector_constant (operands[1], mode))
7301 operands[1] = force_const_mem (mode, operands[1]);
7306 /* Use default pattern for address of ELF small data */
7309 && DEFAULT_ABI == ABI_V4
7310 && (GET_CODE (operands[1]) == SYMBOL_REF
7311 || GET_CODE (operands[1]) == CONST)
7312 && small_data_operand (operands[1], mode))
7314 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7318 if (DEFAULT_ABI == ABI_V4
7319 && mode == Pmode && mode == SImode
7320 && flag_pic == 1 && got_operand (operands[1], mode))
7322 emit_insn (gen_movsi_got (operands[0], operands[1]));
7326 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7330 && CONSTANT_P (operands[1])
7331 && GET_CODE (operands[1]) != HIGH
7332 && GET_CODE (operands[1]) != CONST_INT)
7334 rtx target = (!can_create_pseudo_p ()
7336 : gen_reg_rtx (mode));
7338 /* If this is a function address on -mcall-aixdesc,
7339 convert it to the address of the descriptor. */
7340 if (DEFAULT_ABI == ABI_AIX
7341 && GET_CODE (operands[1]) == SYMBOL_REF
7342 && XSTR (operands[1], 0)[0] == '.')
7344 const char *name = XSTR (operands[1], 0);
7346 while (*name == '.')
7348 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7349 CONSTANT_POOL_ADDRESS_P (new_ref)
7350 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7351 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7352 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7353 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7354 operands[1] = new_ref;
7357 if (DEFAULT_ABI == ABI_DARWIN)
7360 if (MACHO_DYNAMIC_NO_PIC_P)
7362 /* Take care of any required data indirection. */
7363 operands[1] = rs6000_machopic_legitimize_pic_address (
7364 operands[1], mode, operands[0]);
7365 if (operands[0] != operands[1])
7366 emit_insn (gen_rtx_SET (VOIDmode,
7367 operands[0], operands[1]));
7371 emit_insn (gen_macho_high (target, operands[1]));
7372 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7376 emit_insn (gen_elf_high (target, operands[1]));
7377 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7381 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7382 and we have put it in the TOC, we just need to make a TOC-relative
7385 && GET_CODE (operands[1]) == SYMBOL_REF
7386 && constant_pool_expr_p (operands[1])
7387 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7388 get_pool_mode (operands[1])))
7389 || (TARGET_CMODEL == CMODEL_MEDIUM
7390 && GET_CODE (operands[1]) == SYMBOL_REF
7391 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7392 && toc_relative_ok (operands[1])
7393 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7396 if (TARGET_CMODEL != CMODEL_SMALL)
7398 if (can_create_pseudo_p ())
7399 reg = gen_reg_rtx (Pmode);
7403 operands[1] = create_TOC_reference (operands[1], reg);
7405 else if (mode == Pmode
7406 && CONSTANT_P (operands[1])
7407 && ((GET_CODE (operands[1]) != CONST_INT
7408 && ! easy_fp_constant (operands[1], mode))
7409 || (GET_CODE (operands[1]) == CONST_INT
7410 && (num_insns_constant (operands[1], mode)
7411 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7412 || (GET_CODE (operands[0]) == REG
7413 && FP_REGNO_P (REGNO (operands[0]))))
7414 && GET_CODE (operands[1]) != HIGH
7415 && ! legitimate_constant_pool_address_p (operands[1], false)
7416 && ! toc_relative_expr_p (operands[1])
7417 && (TARGET_CMODEL == CMODEL_SMALL
7418 || can_create_pseudo_p ()
7419 || (REG_P (operands[0])
7420 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7424 /* Darwin uses a special PIC legitimizer. */
7425 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7428 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7430 if (operands[0] != operands[1])
7431 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7436 /* If we are to limit the number of things we put in the TOC and
7437 this is a symbol plus a constant we can add in one insn,
7438 just put the symbol in the TOC and add the constant. Don't do
7439 this if reload is in progress. */
7440 if (GET_CODE (operands[1]) == CONST
7441 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7442 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7443 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7444 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7445 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7446 && ! side_effects_p (operands[0]))
7449 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7450 rtx other = XEXP (XEXP (operands[1], 0), 1);
7452 sym = force_reg (mode, sym);
7453 emit_insn (gen_add3_insn (operands[0], sym, other));
7457 operands[1] = force_const_mem (mode, operands[1]);
7460 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7461 && constant_pool_expr_p (XEXP (operands[1], 0))
7462 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7463 get_pool_constant (XEXP (operands[1], 0)),
7464 get_pool_mode (XEXP (operands[1], 0))))
7468 if (TARGET_CMODEL != CMODEL_SMALL)
7470 if (can_create_pseudo_p ())
7471 reg = gen_reg_rtx (Pmode);
7475 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7476 operands[1] = gen_const_mem (mode, tocref);
7477 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7483 rs6000_eliminate_indexed_memrefs (operands);
7487 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7489 gen_rtx_SET (VOIDmode,
7490 operands[0], operands[1]),
7491 gen_rtx_CLOBBER (VOIDmode,
7492 gen_rtx_SCRATCH (SImode)))));
7498 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7501 /* Above, we may have called force_const_mem which may have returned
7502 an invalid address. If we can, fix this up; otherwise, reload will
7503 have to deal with it. */
7504 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7505 operands[1] = validize_mem (operands[1]);
7508 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7511 /* Nonzero if we can use a floating-point register to pass this arg. */
7512 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7513 (SCALAR_FLOAT_MODE_P (MODE) \
7514 && (CUM)->fregno <= FP_ARG_MAX_REG \
7515 && TARGET_HARD_FLOAT && TARGET_FPRS)
7517 /* Nonzero if we can use an AltiVec register to pass this arg. */
7518 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7519 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7520 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7521 && TARGET_ALTIVEC_ABI \
7524 /* Return a nonzero value to say to return the function value in
7525 memory, just as large structures are always returned. TYPE will be
7526 the data type of the value, and FNTYPE will be the type of the
7527 function doing the returning, or @code{NULL} for libcalls.
7529 The AIX ABI for the RS/6000 specifies that all structures are
7530 returned in memory. The Darwin ABI does the same.
7532 For the Darwin 64 Bit ABI, a function result can be returned in
7533 registers or in memory, depending on the size of the return data
7534 type. If it is returned in registers, the value occupies the same
7535 registers as it would if it were the first and only function
7536 argument. Otherwise, the function places its result in memory at
7537 the location pointed to by GPR3.
7539 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7540 but a draft put them in memory, and GCC used to implement the draft
7541 instead of the final standard. Therefore, aix_struct_return
7542 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7543 compatibility can change DRAFT_V4_STRUCT_RET to override the
7544 default, and -m switches get the final word. See
7545 rs6000_override_options for more details.
7547 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7548 long double support is enabled. These values are returned in memory.
7550 int_size_in_bytes returns -1 for variable size objects, which go in
7551 memory always. The cast to unsigned makes -1 > 8. */
7554 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7556 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7558 && rs6000_darwin64_abi
7559 && TREE_CODE (type) == RECORD_TYPE
7560 && int_size_in_bytes (type) > 0)
7562 CUMULATIVE_ARGS valcum;
7566 valcum.fregno = FP_ARG_MIN_REG;
7567 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7568 /* Do a trial code generation as if this were going to be passed
7569 as an argument; if any part goes in memory, we return NULL. */
7570 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7573 /* Otherwise fall through to more conventional ABI rules. */
7576 if (AGGREGATE_TYPE_P (type)
7577 && (aix_struct_return
7578 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7581 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7582 modes only exist for GCC vector types if -maltivec. */
7583 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7584 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7587 /* Return synthetic vectors in memory. */
7588 if (TREE_CODE (type) == VECTOR_TYPE
7589 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7591 static bool warned_for_return_big_vectors = false;
7592 if (!warned_for_return_big_vectors)
7594 warning (0, "GCC vector returned by reference: "
7595 "non-standard ABI extension with no compatibility guarantee");
7596 warned_for_return_big_vectors = true;
7601 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7607 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7608 for a call to a function whose data type is FNTYPE.
7609 For a library call, FNTYPE is 0.
7611 For incoming args we set the number of arguments in the prototype large
7612 so we never return a PARALLEL. */
7615 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7616 rtx libname ATTRIBUTE_UNUSED, int incoming,
7617 int libcall, int n_named_args)
7619 static CUMULATIVE_ARGS zero_cumulative;
7621 *cum = zero_cumulative;
7623 cum->fregno = FP_ARG_MIN_REG;
7624 cum->vregno = ALTIVEC_ARG_MIN_REG;
7625 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7626 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7627 ? CALL_LIBCALL : CALL_NORMAL);
7628 cum->sysv_gregno = GP_ARG_MIN_REG;
7629 cum->stdarg = stdarg_p (fntype);
7631 cum->nargs_prototype = 0;
7632 if (incoming || cum->prototype)
7633 cum->nargs_prototype = n_named_args;
7635 /* Check for a longcall attribute. */
7636 if ((!fntype && rs6000_default_long_calls)
7638 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7639 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7640 cum->call_cookie |= CALL_LONG;
7642 if (TARGET_DEBUG_ARG)
7644 fprintf (stderr, "\ninit_cumulative_args:");
7647 tree ret_type = TREE_TYPE (fntype);
7648 fprintf (stderr, " ret code = %s,",
7649 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7652 if (cum->call_cookie & CALL_LONG)
7653 fprintf (stderr, " longcall,");
7655 fprintf (stderr, " proto = %d, nargs = %d\n",
7656 cum->prototype, cum->nargs_prototype);
7661 && TARGET_ALTIVEC_ABI
7662 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7664 error ("cannot return value in vector register because"
7665 " altivec instructions are disabled, use -maltivec"
7670 /* Return true if TYPE must be passed on the stack and not in registers. */
7673 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7675 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7676 return must_pass_in_stack_var_size (mode, type);
7678 return must_pass_in_stack_var_size_or_pad (mode, type);
7681 /* If defined, a C expression which determines whether, and in which
7682 direction, to pad out an argument with extra space. The value
7683 should be of type `enum direction': either `upward' to pad above
7684 the argument, `downward' to pad below, or `none' to inhibit
7687 For the AIX ABI structs are always stored left shifted in their
7691 function_arg_padding (enum machine_mode mode, const_tree type)
7693 #ifndef AGGREGATE_PADDING_FIXED
7694 #define AGGREGATE_PADDING_FIXED 0
7696 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7697 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7700 if (!AGGREGATE_PADDING_FIXED)
7702 /* GCC used to pass structures of the same size as integer types as
7703 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7704 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7705 passed padded downward, except that -mstrict-align further
7706 muddied the water in that multi-component structures of 2 and 4
7707 bytes in size were passed padded upward.
7709 The following arranges for best compatibility with previous
7710 versions of gcc, but removes the -mstrict-align dependency. */
7711 if (BYTES_BIG_ENDIAN)
7713 HOST_WIDE_INT size = 0;
7715 if (mode == BLKmode)
7717 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7718 size = int_size_in_bytes (type);
7721 size = GET_MODE_SIZE (mode);
7723 if (size == 1 || size == 2 || size == 4)
7729 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7731 if (type != 0 && AGGREGATE_TYPE_P (type))
7735 /* Fall back to the default. */
7736 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7739 /* If defined, a C expression that gives the alignment boundary, in bits,
7740 of an argument with the specified mode and type. If it is not defined,
7741 PARM_BOUNDARY is used for all arguments.
7743 V.4 wants long longs and doubles to be double word aligned. Just
7744 testing the mode size is a boneheaded way to do this as it means
7745 that other types such as complex int are also double word aligned.
7746 However, we're stuck with this because changing the ABI might break
7747 existing library interfaces.
7749 Doubleword align SPE vectors.
7750 Quadword align Altivec vectors.
7751 Quadword align large synthetic vector types. */
7754 function_arg_boundary (enum machine_mode mode, const_tree type)
7756 if (DEFAULT_ABI == ABI_V4
7757 && (GET_MODE_SIZE (mode) == 8
7758 || (TARGET_HARD_FLOAT
7760 && (mode == TFmode || mode == TDmode))))
7762 else if (SPE_VECTOR_MODE (mode)
7763 || (type && TREE_CODE (type) == VECTOR_TYPE
7764 && int_size_in_bytes (type) >= 8
7765 && int_size_in_bytes (type) < 16))
7767 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7768 || (type && TREE_CODE (type) == VECTOR_TYPE
7769 && int_size_in_bytes (type) >= 16))
7771 else if (TARGET_MACHO
7772 && rs6000_darwin64_abi
7774 && type && TYPE_ALIGN (type) > 64)
7777 return PARM_BOUNDARY;
7780 /* For a function parm of MODE and TYPE, return the starting word in
7781 the parameter area. NWORDS of the parameter area are already used. */
7784 rs6000_parm_start (enum machine_mode mode, const_tree type,
7785 unsigned int nwords)
7788 unsigned int parm_offset;
7790 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7791 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7792 return nwords + (-(parm_offset + nwords) & align);
7795 /* Compute the size (in words) of a function argument. */
7797 static unsigned long
7798 rs6000_arg_size (enum machine_mode mode, const_tree type)
7802 if (mode != BLKmode)
7803 size = GET_MODE_SIZE (mode);
7805 size = int_size_in_bytes (type);
7808 return (size + 3) >> 2;
7810 return (size + 7) >> 3;
7813 /* Use this to flush pending int fields. */
7816 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7817 HOST_WIDE_INT bitpos, int final)
7819 unsigned int startbit, endbit;
7820 int intregs, intoffset;
7821 enum machine_mode mode;
7823 /* Handle the situations where a float is taking up the first half
7824 of the GPR, and the other half is empty (typically due to
7825 alignment restrictions). We can detect this by a 8-byte-aligned
7826 int field, or by seeing that this is the final flush for this
7827 argument. Count the word and continue on. */
7828 if (cum->floats_in_gpr == 1
7829 && (cum->intoffset % 64 == 0
7830 || (cum->intoffset == -1 && final)))
7833 cum->floats_in_gpr = 0;
7836 if (cum->intoffset == -1)
7839 intoffset = cum->intoffset;
7840 cum->intoffset = -1;
7841 cum->floats_in_gpr = 0;
7843 if (intoffset % BITS_PER_WORD != 0)
7845 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7847 if (mode == BLKmode)
7849 /* We couldn't find an appropriate mode, which happens,
7850 e.g., in packed structs when there are 3 bytes to load.
7851 Back intoffset back to the beginning of the word in this
7853 intoffset = intoffset & -BITS_PER_WORD;
7857 startbit = intoffset & -BITS_PER_WORD;
7858 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7859 intregs = (endbit - startbit) / BITS_PER_WORD;
7860 cum->words += intregs;
7861 /* words should be unsigned. */
7862 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7864 int pad = (endbit/BITS_PER_WORD) - cum->words;
7869 /* The darwin64 ABI calls for us to recurse down through structs,
7870 looking for elements passed in registers. Unfortunately, we have
7871 to track int register count here also because of misalignments
7872 in powerpc alignment mode. */
7875 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7877 HOST_WIDE_INT startbitpos)
7881 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7882 if (TREE_CODE (f) == FIELD_DECL)
7884 HOST_WIDE_INT bitpos = startbitpos;
7885 tree ftype = TREE_TYPE (f);
7886 enum machine_mode mode;
7887 if (ftype == error_mark_node)
7889 mode = TYPE_MODE (ftype);
7891 if (DECL_SIZE (f) != 0
7892 && host_integerp (bit_position (f), 1))
7893 bitpos += int_bit_position (f);
7895 /* ??? FIXME: else assume zero offset. */
7897 if (TREE_CODE (ftype) == RECORD_TYPE)
7898 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7899 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7901 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7902 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7903 /* Single-precision floats present a special problem for
7904 us, because they are smaller than an 8-byte GPR, and so
7905 the structure-packing rules combined with the standard
7906 varargs behavior mean that we want to pack float/float
7907 and float/int combinations into a single register's
7908 space. This is complicated by the arg advance flushing,
7909 which works on arbitrarily large groups of int-type
7913 if (cum->floats_in_gpr == 1)
7915 /* Two floats in a word; count the word and reset
7918 cum->floats_in_gpr = 0;
7920 else if (bitpos % 64 == 0)
7922 /* A float at the beginning of an 8-byte word;
7923 count it and put off adjusting cum->words until
7924 we see if a arg advance flush is going to do it
7926 cum->floats_in_gpr++;
7930 /* The float is at the end of a word, preceded
7931 by integer fields, so the arg advance flush
7932 just above has already set cum->words and
7933 everything is taken care of. */
7937 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7939 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7941 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7945 else if (cum->intoffset == -1)
7946 cum->intoffset = bitpos;
7950 /* Check for an item that needs to be considered specially under the darwin 64
7951 bit ABI. These are record types where the mode is BLK or the structure is
7954 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7956 return rs6000_darwin64_abi
7957 && ((mode == BLKmode
7958 && TREE_CODE (type) == RECORD_TYPE
7959 && int_size_in_bytes (type) > 0)
7960 || (type && TREE_CODE (type) == RECORD_TYPE
7961 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7964 /* Update the data in CUM to advance over an argument
7965 of mode MODE and data type TYPE.
7966 (TYPE is null for libcalls where that information may not be available.)
7968 Note that for args passed by reference, function_arg will be called
7969 with MODE and TYPE set to that of the pointer to the arg, not the arg
7973 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7974 const_tree type, bool named, int depth)
7977 /* Only tick off an argument if we're not recursing. */
7979 cum->nargs_prototype--;
7981 if (TARGET_ALTIVEC_ABI
7982 && (ALTIVEC_VECTOR_MODE (mode)
7983 || VSX_VECTOR_MODE (mode)
7984 || (type && TREE_CODE (type) == VECTOR_TYPE
7985 && int_size_in_bytes (type) == 16)))
7989 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7992 if (!TARGET_ALTIVEC)
7993 error ("cannot pass argument in vector register because"
7994 " altivec instructions are disabled, use -maltivec"
7997 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7998 even if it is going to be passed in a vector register.
7999 Darwin does the same for variable-argument functions. */
8000 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8001 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8011 /* Vector parameters must be 16-byte aligned. This places
8012 them at 2 mod 4 in terms of words in 32-bit mode, since
8013 the parameter save area starts at offset 24 from the
8014 stack. In 64-bit mode, they just have to start on an
8015 even word, since the parameter save area is 16-byte
8016 aligned. Space for GPRs is reserved even if the argument
8017 will be passed in memory. */
8019 align = (2 - cum->words) & 3;
8021 align = cum->words & 1;
8022 cum->words += align + rs6000_arg_size (mode, type);
8024 if (TARGET_DEBUG_ARG)
8026 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8028 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8029 cum->nargs_prototype, cum->prototype,
8030 GET_MODE_NAME (mode));
8034 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8036 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8039 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8041 int size = int_size_in_bytes (type);
8042 /* Variable sized types have size == -1 and are
8043 treated as if consisting entirely of ints.
8044 Pad to 16 byte boundary if needed. */
8045 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8046 && (cum->words % 2) != 0)
8048 /* For varargs, we can just go up by the size of the struct. */
8050 cum->words += (size + 7) / 8;
8053 /* It is tempting to say int register count just goes up by
8054 sizeof(type)/8, but this is wrong in a case such as
8055 { int; double; int; } [powerpc alignment]. We have to
8056 grovel through the fields for these too. */
8058 cum->floats_in_gpr = 0;
8059 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8060 rs6000_darwin64_record_arg_advance_flush (cum,
8061 size * BITS_PER_UNIT, 1);
8063 if (TARGET_DEBUG_ARG)
8065 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8066 cum->words, TYPE_ALIGN (type), size);
8068 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8069 cum->nargs_prototype, cum->prototype,
8070 GET_MODE_NAME (mode));
8073 else if (DEFAULT_ABI == ABI_V4)
8075 if (TARGET_HARD_FLOAT && TARGET_FPRS
8076 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8077 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8078 || (mode == TFmode && !TARGET_IEEEQUAD)
8079 || mode == SDmode || mode == DDmode || mode == TDmode))
8081 /* _Decimal128 must use an even/odd register pair. This assumes
8082 that the register number is odd when fregno is odd. */
8083 if (mode == TDmode && (cum->fregno % 2) == 1)
8086 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8087 <= FP_ARG_V4_MAX_REG)
8088 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8091 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8092 if (mode == DFmode || mode == TFmode
8093 || mode == DDmode || mode == TDmode)
8094 cum->words += cum->words & 1;
8095 cum->words += rs6000_arg_size (mode, type);
8100 int n_words = rs6000_arg_size (mode, type);
8101 int gregno = cum->sysv_gregno;
8103 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8104 (r7,r8) or (r9,r10). As does any other 2 word item such
8105 as complex int due to a historical mistake. */
8107 gregno += (1 - gregno) & 1;
8109 /* Multi-reg args are not split between registers and stack. */
8110 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8112 /* Long long and SPE vectors are aligned on the stack.
8113 So are other 2 word items such as complex int due to
8114 a historical mistake. */
8116 cum->words += cum->words & 1;
8117 cum->words += n_words;
8120 /* Note: continuing to accumulate gregno past when we've started
8121 spilling to the stack indicates the fact that we've started
8122 spilling to the stack to expand_builtin_saveregs. */
8123 cum->sysv_gregno = gregno + n_words;
8126 if (TARGET_DEBUG_ARG)
8128 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8129 cum->words, cum->fregno);
8130 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8131 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8132 fprintf (stderr, "mode = %4s, named = %d\n",
8133 GET_MODE_NAME (mode), named);
8138 int n_words = rs6000_arg_size (mode, type);
8139 int start_words = cum->words;
8140 int align_words = rs6000_parm_start (mode, type, start_words);
8142 cum->words = align_words + n_words;
8144 if (SCALAR_FLOAT_MODE_P (mode)
8145 && TARGET_HARD_FLOAT && TARGET_FPRS)
8147 /* _Decimal128 must be passed in an even/odd float register pair.
8148 This assumes that the register number is odd when fregno is
8150 if (mode == TDmode && (cum->fregno % 2) == 1)
8152 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8155 if (TARGET_DEBUG_ARG)
8157 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8158 cum->words, cum->fregno);
8159 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8160 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8161 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8162 named, align_words - start_words, depth);
8168 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8169 const_tree type, bool named)
8171 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8175 spe_build_register_parallel (enum machine_mode mode, int gregno)
8182 r1 = gen_rtx_REG (DImode, gregno);
8183 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8184 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
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 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8195 r1 = gen_rtx_REG (DImode, gregno);
8196 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8197 r3 = gen_rtx_REG (DImode, gregno + 2);
8198 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8199 r5 = gen_rtx_REG (DImode, gregno + 4);
8200 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8201 r7 = gen_rtx_REG (DImode, gregno + 6);
8202 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8203 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8210 /* Determine where to put a SIMD argument on the SPE. */
8212 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8215 int gregno = cum->sysv_gregno;
8217 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8218 are passed and returned in a pair of GPRs for ABI compatibility. */
8219 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8220 || mode == DCmode || mode == TCmode))
8222 int n_words = rs6000_arg_size (mode, type);
8224 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8226 gregno += (1 - gregno) & 1;
8228 /* Multi-reg args are not split between registers and stack. */
8229 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8232 return spe_build_register_parallel (mode, gregno);
8236 int n_words = rs6000_arg_size (mode, type);
8238 /* SPE vectors are put in odd registers. */
8239 if (n_words == 2 && (gregno & 1) == 0)
8242 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8245 enum machine_mode m = SImode;
8247 r1 = gen_rtx_REG (m, gregno);
8248 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8249 r2 = gen_rtx_REG (m, gregno + 1);
8250 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8251 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8258 if (gregno <= GP_ARG_MAX_REG)
8259 return gen_rtx_REG (mode, gregno);
8265 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8266 structure between cum->intoffset and bitpos to integer registers. */
8269 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8270 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8272 enum machine_mode mode;
8274 unsigned int startbit, endbit;
8275 int this_regno, intregs, intoffset;
8278 if (cum->intoffset == -1)
8281 intoffset = cum->intoffset;
8282 cum->intoffset = -1;
8284 /* If this is the trailing part of a word, try to only load that
8285 much into the register. Otherwise load the whole register. Note
8286 that in the latter case we may pick up unwanted bits. It's not a
8287 problem at the moment but may wish to revisit. */
8289 if (intoffset % BITS_PER_WORD != 0)
8291 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8293 if (mode == BLKmode)
8295 /* We couldn't find an appropriate mode, which happens,
8296 e.g., in packed structs when there are 3 bytes to load.
8297 Back intoffset back to the beginning of the word in this
8299 intoffset = intoffset & -BITS_PER_WORD;
8306 startbit = intoffset & -BITS_PER_WORD;
8307 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8308 intregs = (endbit - startbit) / BITS_PER_WORD;
8309 this_regno = cum->words + intoffset / BITS_PER_WORD;
8311 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8314 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8318 intoffset /= BITS_PER_UNIT;
8321 regno = GP_ARG_MIN_REG + this_regno;
8322 reg = gen_rtx_REG (mode, regno);
8324 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8327 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8331 while (intregs > 0);
8334 /* Recursive workhorse for the following. */
8337 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8338 HOST_WIDE_INT startbitpos, rtx rvec[],
8343 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8344 if (TREE_CODE (f) == FIELD_DECL)
8346 HOST_WIDE_INT bitpos = startbitpos;
8347 tree ftype = TREE_TYPE (f);
8348 enum machine_mode mode;
8349 if (ftype == error_mark_node)
8351 mode = TYPE_MODE (ftype);
8353 if (DECL_SIZE (f) != 0
8354 && host_integerp (bit_position (f), 1))
8355 bitpos += int_bit_position (f);
8357 /* ??? FIXME: else assume zero offset. */
8359 if (TREE_CODE (ftype) == RECORD_TYPE)
8360 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8361 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8366 case SCmode: mode = SFmode; break;
8367 case DCmode: mode = DFmode; break;
8368 case TCmode: mode = TFmode; break;
8372 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8374 = gen_rtx_EXPR_LIST (VOIDmode,
8375 gen_rtx_REG (mode, cum->fregno++),
8376 GEN_INT (bitpos / BITS_PER_UNIT));
8377 if (mode == TFmode || mode == TDmode)
8380 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8382 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8384 = gen_rtx_EXPR_LIST (VOIDmode,
8385 gen_rtx_REG (mode, cum->vregno++),
8386 GEN_INT (bitpos / BITS_PER_UNIT));
8388 else if (cum->intoffset == -1)
8389 cum->intoffset = bitpos;
8393 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8394 the register(s) to be used for each field and subfield of a struct
8395 being passed by value, along with the offset of where the
8396 register's value may be found in the block. FP fields go in FP
8397 register, vector fields go in vector registers, and everything
8398 else goes in int registers, packed as in memory.
8400 This code is also used for function return values. RETVAL indicates
8401 whether this is the case.
8403 Much of this is taken from the SPARC V9 port, which has a similar
8404 calling convention. */
8407 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8408 bool named, bool retval)
8410 rtx rvec[FIRST_PSEUDO_REGISTER];
8411 int k = 1, kbase = 1;
8412 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8413 /* This is a copy; modifications are not visible to our caller. */
8414 CUMULATIVE_ARGS copy_cum = *orig_cum;
8415 CUMULATIVE_ARGS *cum = ©_cum;
8417 /* Pad to 16 byte boundary if needed. */
8418 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8419 && (cum->words % 2) != 0)
8426 /* Put entries into rvec[] for individual FP and vector fields, and
8427 for the chunks of memory that go in int regs. Note we start at
8428 element 1; 0 is reserved for an indication of using memory, and
8429 may or may not be filled in below. */
8430 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8431 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8433 /* If any part of the struct went on the stack put all of it there.
8434 This hack is because the generic code for
8435 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8436 parts of the struct are not at the beginning. */
8440 return NULL_RTX; /* doesn't go in registers at all */
8442 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8444 if (k > 1 || cum->use_stack)
8445 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8450 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8453 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8458 rtx rvec[GP_ARG_NUM_REG + 1];
8460 if (align_words >= GP_ARG_NUM_REG)
8463 n_units = rs6000_arg_size (mode, type);
8465 /* Optimize the simple case where the arg fits in one gpr, except in
8466 the case of BLKmode due to assign_parms assuming that registers are
8467 BITS_PER_WORD wide. */
8469 || (n_units == 1 && mode != BLKmode))
8470 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8473 if (align_words + n_units > GP_ARG_NUM_REG)
8474 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8475 using a magic NULL_RTX component.
8476 This is not strictly correct. Only some of the arg belongs in
8477 memory, not all of it. However, the normal scheme using
8478 function_arg_partial_nregs can result in unusual subregs, eg.
8479 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8480 store the whole arg to memory is often more efficient than code
8481 to store pieces, and we know that space is available in the right
8482 place for the whole arg. */
8483 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8488 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8489 rtx off = GEN_INT (i++ * 4);
8490 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8492 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8494 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8497 /* Determine where to put an argument to a function.
8498 Value is zero to push the argument on the stack,
8499 or a hard register in which to store the argument.
8501 MODE is the argument's machine mode.
8502 TYPE is the data type of the argument (as a tree).
8503 This is null for libcalls where that information may
8505 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8506 the preceding args and about the function being called. It is
8507 not modified in this routine.
8508 NAMED is nonzero if this argument is a named parameter
8509 (otherwise it is an extra parameter matching an ellipsis).
8511 On RS/6000 the first eight words of non-FP are normally in registers
8512 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8513 Under V.4, the first 8 FP args are in registers.
8515 If this is floating-point and no prototype is specified, we use
8516 both an FP and integer register (or possibly FP reg and stack). Library
8517 functions (when CALL_LIBCALL is set) always have the proper types for args,
8518 so we can pass the FP value just in one register. emit_library_function
8519 doesn't support PARALLEL anyway.
8521 Note that for args passed by reference, function_arg will be called
8522 with MODE and TYPE set to that of the pointer to the arg, not the arg
8526 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8527 const_tree type, bool named)
8529 enum rs6000_abi abi = DEFAULT_ABI;
8531 /* Return a marker to indicate whether CR1 needs to set or clear the
8532 bit that V.4 uses to say fp args were passed in registers.
8533 Assume that we don't need the marker for software floating point,
8534 or compiler generated library calls. */
8535 if (mode == VOIDmode)
8538 && (cum->call_cookie & CALL_LIBCALL) == 0
8540 || (cum->nargs_prototype < 0
8541 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8543 /* For the SPE, we need to crxor CR6 always. */
8545 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8546 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8547 return GEN_INT (cum->call_cookie
8548 | ((cum->fregno == FP_ARG_MIN_REG)
8549 ? CALL_V4_SET_FP_ARGS
8550 : CALL_V4_CLEAR_FP_ARGS));
8553 return GEN_INT (cum->call_cookie);
8556 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8558 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8559 if (rslt != NULL_RTX)
8561 /* Else fall through to usual handling. */
8564 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8565 if (TARGET_64BIT && ! cum->prototype)
8567 /* Vector parameters get passed in vector register
8568 and also in GPRs or memory, in absence of prototype. */
8571 align_words = (cum->words + 1) & ~1;
8573 if (align_words >= GP_ARG_NUM_REG)
8579 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8581 return gen_rtx_PARALLEL (mode,
8583 gen_rtx_EXPR_LIST (VOIDmode,
8585 gen_rtx_EXPR_LIST (VOIDmode,
8586 gen_rtx_REG (mode, cum->vregno),
8590 return gen_rtx_REG (mode, cum->vregno);
8591 else if (TARGET_ALTIVEC_ABI
8592 && (ALTIVEC_VECTOR_MODE (mode)
8593 || VSX_VECTOR_MODE (mode)
8594 || (type && TREE_CODE (type) == VECTOR_TYPE
8595 && int_size_in_bytes (type) == 16)))
8597 if (named || abi == ABI_V4)
8601 /* Vector parameters to varargs functions under AIX or Darwin
8602 get passed in memory and possibly also in GPRs. */
8603 int align, align_words, n_words;
8604 enum machine_mode part_mode;
8606 /* Vector parameters must be 16-byte aligned. This places them at
8607 2 mod 4 in terms of words in 32-bit mode, since the parameter
8608 save area starts at offset 24 from the stack. In 64-bit mode,
8609 they just have to start on an even word, since the parameter
8610 save area is 16-byte aligned. */
8612 align = (2 - cum->words) & 3;
8614 align = cum->words & 1;
8615 align_words = cum->words + align;
8617 /* Out of registers? Memory, then. */
8618 if (align_words >= GP_ARG_NUM_REG)
8621 if (TARGET_32BIT && TARGET_POWERPC64)
8622 return rs6000_mixed_function_arg (mode, type, align_words);
8624 /* The vector value goes in GPRs. Only the part of the
8625 value in GPRs is reported here. */
8627 n_words = rs6000_arg_size (mode, type);
8628 if (align_words + n_words > GP_ARG_NUM_REG)
8629 /* Fortunately, there are only two possibilities, the value
8630 is either wholly in GPRs or half in GPRs and half not. */
8633 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8636 else if (TARGET_SPE_ABI && TARGET_SPE
8637 && (SPE_VECTOR_MODE (mode)
8638 || (TARGET_E500_DOUBLE && (mode == DFmode
8641 || mode == TCmode))))
8642 return rs6000_spe_function_arg (cum, mode, type);
8644 else if (abi == ABI_V4)
8646 if (TARGET_HARD_FLOAT && TARGET_FPRS
8647 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8648 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8649 || (mode == TFmode && !TARGET_IEEEQUAD)
8650 || mode == SDmode || mode == DDmode || mode == TDmode))
8652 /* _Decimal128 must use an even/odd register pair. This assumes
8653 that the register number is odd when fregno is odd. */
8654 if (mode == TDmode && (cum->fregno % 2) == 1)
8657 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8658 <= FP_ARG_V4_MAX_REG)
8659 return gen_rtx_REG (mode, cum->fregno);
8665 int n_words = rs6000_arg_size (mode, type);
8666 int gregno = cum->sysv_gregno;
8668 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8669 (r7,r8) or (r9,r10). As does any other 2 word item such
8670 as complex int due to a historical mistake. */
8672 gregno += (1 - gregno) & 1;
8674 /* Multi-reg args are not split between registers and stack. */
8675 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8678 if (TARGET_32BIT && TARGET_POWERPC64)
8679 return rs6000_mixed_function_arg (mode, type,
8680 gregno - GP_ARG_MIN_REG);
8681 return gen_rtx_REG (mode, gregno);
8686 int align_words = rs6000_parm_start (mode, type, cum->words);
8688 /* _Decimal128 must be passed in an even/odd float register pair.
8689 This assumes that the register number is odd when fregno is odd. */
8690 if (mode == TDmode && (cum->fregno % 2) == 1)
8693 if (USE_FP_FOR_ARG_P (cum, mode, type))
8695 rtx rvec[GP_ARG_NUM_REG + 1];
8699 enum machine_mode fmode = mode;
8700 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8702 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8704 /* Currently, we only ever need one reg here because complex
8705 doubles are split. */
8706 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8707 && (fmode == TFmode || fmode == TDmode));
8709 /* Long double or _Decimal128 split over regs and memory. */
8710 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8713 /* Do we also need to pass this arg in the parameter save
8716 && (cum->nargs_prototype <= 0
8717 || (DEFAULT_ABI == ABI_AIX
8719 && align_words >= GP_ARG_NUM_REG)));
8721 if (!needs_psave && mode == fmode)
8722 return gen_rtx_REG (fmode, cum->fregno);
8727 /* Describe the part that goes in gprs or the stack.
8728 This piece must come first, before the fprs. */
8729 if (align_words < GP_ARG_NUM_REG)
8731 unsigned long n_words = rs6000_arg_size (mode, type);
8733 if (align_words + n_words > GP_ARG_NUM_REG
8734 || (TARGET_32BIT && TARGET_POWERPC64))
8736 /* If this is partially on the stack, then we only
8737 include the portion actually in registers here. */
8738 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8741 if (align_words + n_words > GP_ARG_NUM_REG)
8742 /* Not all of the arg fits in gprs. Say that it
8743 goes in memory too, using a magic NULL_RTX
8744 component. Also see comment in
8745 rs6000_mixed_function_arg for why the normal
8746 function_arg_partial_nregs scheme doesn't work
8748 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8752 r = gen_rtx_REG (rmode,
8753 GP_ARG_MIN_REG + align_words);
8754 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8755 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8757 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8761 /* The whole arg fits in gprs. */
8762 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8763 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8767 /* It's entirely in memory. */
8768 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8771 /* Describe where this piece goes in the fprs. */
8772 r = gen_rtx_REG (fmode, cum->fregno);
8773 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8775 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8777 else if (align_words < GP_ARG_NUM_REG)
8779 if (TARGET_32BIT && TARGET_POWERPC64)
8780 return rs6000_mixed_function_arg (mode, type, align_words);
8782 if (mode == BLKmode)
8785 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8792 /* For an arg passed partly in registers and partly in memory, this is
8793 the number of bytes passed in registers. For args passed entirely in
8794 registers or entirely in memory, zero. When an arg is described by a
8795 PARALLEL, perhaps using more than one register type, this function
8796 returns the number of bytes used by the first element of the PARALLEL. */
8799 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8800 tree type, bool named)
8805 if (DEFAULT_ABI == ABI_V4)
8808 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8809 && cum->nargs_prototype >= 0)
8812 /* In this complicated case we just disable the partial_nregs code. */
8813 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8816 align_words = rs6000_parm_start (mode, type, cum->words);
8818 if (USE_FP_FOR_ARG_P (cum, mode, type))
8820 /* If we are passing this arg in the fixed parameter save area
8821 (gprs or memory) as well as fprs, then this function should
8822 return the number of partial bytes passed in the parameter
8823 save area rather than partial bytes passed in fprs. */
8825 && (cum->nargs_prototype <= 0
8826 || (DEFAULT_ABI == ABI_AIX
8828 && align_words >= GP_ARG_NUM_REG)))
8830 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8831 > FP_ARG_MAX_REG + 1)
8832 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8833 else if (cum->nargs_prototype >= 0)
8837 if (align_words < GP_ARG_NUM_REG
8838 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8839 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8841 if (ret != 0 && TARGET_DEBUG_ARG)
8842 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8847 /* A C expression that indicates when an argument must be passed by
8848 reference. If nonzero for an argument, a copy of that argument is
8849 made in memory and a pointer to the argument is passed instead of
8850 the argument itself. The pointer is passed in whatever way is
8851 appropriate for passing a pointer to that type.
8853 Under V.4, aggregates and long double are passed by reference.
8855 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8856 reference unless the AltiVec vector extension ABI is in force.
8858 As an extension to all ABIs, variable sized types are passed by
8862 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8863 enum machine_mode mode, const_tree type,
8864 bool named ATTRIBUTE_UNUSED)
8866 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8868 if (TARGET_DEBUG_ARG)
8869 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8876 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8878 if (TARGET_DEBUG_ARG)
8879 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8883 if (int_size_in_bytes (type) < 0)
8885 if (TARGET_DEBUG_ARG)
8886 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8890 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8891 modes only exist for GCC vector types if -maltivec. */
8892 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8894 if (TARGET_DEBUG_ARG)
8895 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8899 /* Pass synthetic vectors in memory. */
8900 if (TREE_CODE (type) == VECTOR_TYPE
8901 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8903 static bool warned_for_pass_big_vectors = false;
8904 if (TARGET_DEBUG_ARG)
8905 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8906 if (!warned_for_pass_big_vectors)
8908 warning (0, "GCC vector passed by reference: "
8909 "non-standard ABI extension with no compatibility guarantee");
8910 warned_for_pass_big_vectors = true;
8919 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8922 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8927 for (i = 0; i < nregs; i++)
8929 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8930 if (reload_completed)
8932 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8935 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8936 i * GET_MODE_SIZE (reg_mode));
8939 tem = replace_equiv_address (tem, XEXP (tem, 0));
8943 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8947 /* Perform any needed actions needed for a function that is receiving a
8948 variable number of arguments.
8952 MODE and TYPE are the mode and type of the current parameter.
8954 PRETEND_SIZE is a variable that should be set to the amount of stack
8955 that must be pushed by the prolog to pretend that our caller pushed
8958 Normally, this macro will push all remaining incoming registers on the
8959 stack and set PRETEND_SIZE to the length of the registers pushed. */
8962 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8963 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8966 CUMULATIVE_ARGS next_cum;
8967 int reg_size = TARGET_32BIT ? 4 : 8;
8968 rtx save_area = NULL_RTX, mem;
8969 int first_reg_offset;
8972 /* Skip the last named argument. */
8974 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8976 if (DEFAULT_ABI == ABI_V4)
8978 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8982 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8983 HOST_WIDE_INT offset = 0;
8985 /* Try to optimize the size of the varargs save area.
8986 The ABI requires that ap.reg_save_area is doubleword
8987 aligned, but we don't need to allocate space for all
8988 the bytes, only those to which we actually will save
8990 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8991 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8992 if (TARGET_HARD_FLOAT && TARGET_FPRS
8993 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8994 && cfun->va_list_fpr_size)
8997 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8998 * UNITS_PER_FP_WORD;
8999 if (cfun->va_list_fpr_size
9000 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9001 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9003 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9004 * UNITS_PER_FP_WORD;
9008 offset = -((first_reg_offset * reg_size) & ~7);
9009 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9011 gpr_reg_num = cfun->va_list_gpr_size;
9012 if (reg_size == 4 && (first_reg_offset & 1))
9015 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9018 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9020 - (int) (GP_ARG_NUM_REG * reg_size);
9022 if (gpr_size + fpr_size)
9025 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9026 gcc_assert (GET_CODE (reg_save_area) == MEM);
9027 reg_save_area = XEXP (reg_save_area, 0);
9028 if (GET_CODE (reg_save_area) == PLUS)
9030 gcc_assert (XEXP (reg_save_area, 0)
9031 == virtual_stack_vars_rtx);
9032 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9033 offset += INTVAL (XEXP (reg_save_area, 1));
9036 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9039 cfun->machine->varargs_save_offset = offset;
9040 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9045 first_reg_offset = next_cum.words;
9046 save_area = virtual_incoming_args_rtx;
9048 if (targetm.calls.must_pass_in_stack (mode, type))
9049 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9052 set = get_varargs_alias_set ();
9053 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9054 && cfun->va_list_gpr_size)
9056 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9058 if (va_list_gpr_counter_field)
9060 /* V4 va_list_gpr_size counts number of registers needed. */
9061 if (nregs > cfun->va_list_gpr_size)
9062 nregs = cfun->va_list_gpr_size;
9066 /* char * va_list instead counts number of bytes needed. */
9067 if (nregs > cfun->va_list_gpr_size / reg_size)
9068 nregs = cfun->va_list_gpr_size / reg_size;
9071 mem = gen_rtx_MEM (BLKmode,
9072 plus_constant (save_area,
9073 first_reg_offset * reg_size));
9074 MEM_NOTRAP_P (mem) = 1;
9075 set_mem_alias_set (mem, set);
9076 set_mem_align (mem, BITS_PER_WORD);
9078 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9082 /* Save FP registers if needed. */
9083 if (DEFAULT_ABI == ABI_V4
9084 && TARGET_HARD_FLOAT && TARGET_FPRS
9086 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9087 && cfun->va_list_fpr_size)
9089 int fregno = next_cum.fregno, nregs;
9090 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9091 rtx lab = gen_label_rtx ();
9092 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9093 * UNITS_PER_FP_WORD);
9096 (gen_rtx_SET (VOIDmode,
9098 gen_rtx_IF_THEN_ELSE (VOIDmode,
9099 gen_rtx_NE (VOIDmode, cr1,
9101 gen_rtx_LABEL_REF (VOIDmode, lab),
9105 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9106 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9108 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9110 plus_constant (save_area, off));
9111 MEM_NOTRAP_P (mem) = 1;
9112 set_mem_alias_set (mem, set);
9113 set_mem_align (mem, GET_MODE_ALIGNMENT (
9114 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9115 ? DFmode : SFmode));
9116 emit_move_insn (mem, gen_rtx_REG (
9117 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9118 ? DFmode : SFmode, fregno));
9125 /* Create the va_list data type. */
9128 rs6000_build_builtin_va_list (void)
9130 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9132 /* For AIX, prefer 'char *' because that's what the system
9133 header files like. */
9134 if (DEFAULT_ABI != ABI_V4)
9135 return build_pointer_type (char_type_node);
9137 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9138 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9139 get_identifier ("__va_list_tag"), record);
9141 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9142 unsigned_char_type_node);
9143 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9144 unsigned_char_type_node);
9145 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9147 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9148 get_identifier ("reserved"), short_unsigned_type_node);
9149 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9150 get_identifier ("overflow_arg_area"),
9152 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9153 get_identifier ("reg_save_area"),
9156 va_list_gpr_counter_field = f_gpr;
9157 va_list_fpr_counter_field = f_fpr;
9159 DECL_FIELD_CONTEXT (f_gpr) = record;
9160 DECL_FIELD_CONTEXT (f_fpr) = record;
9161 DECL_FIELD_CONTEXT (f_res) = record;
9162 DECL_FIELD_CONTEXT (f_ovf) = record;
9163 DECL_FIELD_CONTEXT (f_sav) = record;
9165 TREE_CHAIN (record) = type_decl;
9166 TYPE_NAME (record) = type_decl;
9167 TYPE_FIELDS (record) = f_gpr;
9168 DECL_CHAIN (f_gpr) = f_fpr;
9169 DECL_CHAIN (f_fpr) = f_res;
9170 DECL_CHAIN (f_res) = f_ovf;
9171 DECL_CHAIN (f_ovf) = f_sav;
9173 layout_type (record);
9175 /* The correct type is an array type of one element. */
9176 return build_array_type (record, build_index_type (size_zero_node));
9179 /* Implement va_start. */
9182 rs6000_va_start (tree valist, rtx nextarg)
9184 HOST_WIDE_INT words, n_gpr, n_fpr;
9185 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9186 tree gpr, fpr, ovf, sav, t;
9188 /* Only SVR4 needs something special. */
9189 if (DEFAULT_ABI != ABI_V4)
9191 std_expand_builtin_va_start (valist, nextarg);
9195 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9196 f_fpr = DECL_CHAIN (f_gpr);
9197 f_res = DECL_CHAIN (f_fpr);
9198 f_ovf = DECL_CHAIN (f_res);
9199 f_sav = DECL_CHAIN (f_ovf);
9201 valist = build_va_arg_indirect_ref (valist);
9202 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9203 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9205 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9207 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9210 /* Count number of gp and fp argument registers used. */
9211 words = crtl->args.info.words;
9212 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9214 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9217 if (TARGET_DEBUG_ARG)
9218 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9219 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9220 words, n_gpr, n_fpr);
9222 if (cfun->va_list_gpr_size)
9224 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9225 build_int_cst (NULL_TREE, n_gpr));
9226 TREE_SIDE_EFFECTS (t) = 1;
9227 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9230 if (cfun->va_list_fpr_size)
9232 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9233 build_int_cst (NULL_TREE, n_fpr));
9234 TREE_SIDE_EFFECTS (t) = 1;
9235 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9238 /* Find the overflow area. */
9239 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9241 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9242 size_int (words * UNITS_PER_WORD));
9243 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9244 TREE_SIDE_EFFECTS (t) = 1;
9245 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9247 /* If there were no va_arg invocations, don't set up the register
9249 if (!cfun->va_list_gpr_size
9250 && !cfun->va_list_fpr_size
9251 && n_gpr < GP_ARG_NUM_REG
9252 && n_fpr < FP_ARG_V4_MAX_REG)
9255 /* Find the register save area. */
9256 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9257 if (cfun->machine->varargs_save_offset)
9258 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9259 size_int (cfun->machine->varargs_save_offset));
9260 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9261 TREE_SIDE_EFFECTS (t) = 1;
9262 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9265 /* Implement va_arg. */
9268 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9271 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9272 tree gpr, fpr, ovf, sav, reg, t, u;
9273 int size, rsize, n_reg, sav_ofs, sav_scale;
9274 tree lab_false, lab_over, addr;
9276 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9280 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9282 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9283 return build_va_arg_indirect_ref (t);
9286 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9287 earlier version of gcc, with the property that it always applied alignment
9288 adjustments to the va-args (even for zero-sized types). The cheapest way
9289 to deal with this is to replicate the effect of the part of
9290 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9292 We don't need to check for pass-by-reference because of the test above.
9293 We can return a simplifed answer, since we know there's no offset to add. */
9296 && rs6000_darwin64_abi
9297 && integer_zerop (TYPE_SIZE (type)))
9299 unsigned HOST_WIDE_INT align, boundary;
9300 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9301 align = PARM_BOUNDARY / BITS_PER_UNIT;
9302 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9303 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9304 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9305 boundary /= BITS_PER_UNIT;
9306 if (boundary > align)
9309 /* This updates arg ptr by the amount that would be necessary
9310 to align the zero-sized (but not zero-alignment) item. */
9311 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9312 fold_build2 (POINTER_PLUS_EXPR,
9314 valist_tmp, size_int (boundary - 1)));
9315 gimplify_and_add (t, pre_p);
9317 t = fold_convert (sizetype, valist_tmp);
9318 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9319 fold_convert (TREE_TYPE (valist),
9320 fold_build2 (BIT_AND_EXPR, sizetype, t,
9321 size_int (-boundary))));
9322 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9323 gimplify_and_add (t, pre_p);
9325 /* Since it is zero-sized there's no increment for the item itself. */
9326 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9327 return build_va_arg_indirect_ref (valist_tmp);
9330 if (DEFAULT_ABI != ABI_V4)
9332 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9334 tree elem_type = TREE_TYPE (type);
9335 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9336 int elem_size = GET_MODE_SIZE (elem_mode);
9338 if (elem_size < UNITS_PER_WORD)
9340 tree real_part, imag_part;
9341 gimple_seq post = NULL;
9343 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9345 /* Copy the value into a temporary, lest the formal temporary
9346 be reused out from under us. */
9347 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9348 gimple_seq_add_seq (pre_p, post);
9350 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9353 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9357 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9360 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9361 f_fpr = DECL_CHAIN (f_gpr);
9362 f_res = DECL_CHAIN (f_fpr);
9363 f_ovf = DECL_CHAIN (f_res);
9364 f_sav = DECL_CHAIN (f_ovf);
9366 valist = build_va_arg_indirect_ref (valist);
9367 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9368 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9370 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9372 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9375 size = int_size_in_bytes (type);
9376 rsize = (size + 3) / 4;
9379 if (TARGET_HARD_FLOAT && TARGET_FPRS
9380 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9381 || (TARGET_DOUBLE_FLOAT
9382 && (TYPE_MODE (type) == DFmode
9383 || TYPE_MODE (type) == TFmode
9384 || TYPE_MODE (type) == SDmode
9385 || TYPE_MODE (type) == DDmode
9386 || TYPE_MODE (type) == TDmode))))
9388 /* FP args go in FP registers, if present. */
9390 n_reg = (size + 7) / 8;
9391 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9392 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9393 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9398 /* Otherwise into GP registers. */
9407 /* Pull the value out of the saved registers.... */
9410 addr = create_tmp_var (ptr_type_node, "addr");
9412 /* AltiVec vectors never go in registers when -mabi=altivec. */
9413 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9417 lab_false = create_artificial_label (input_location);
9418 lab_over = create_artificial_label (input_location);
9420 /* Long long and SPE vectors are aligned in the registers.
9421 As are any other 2 gpr item such as complex int due to a
9422 historical mistake. */
9424 if (n_reg == 2 && reg == gpr)
9427 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9428 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9429 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9430 unshare_expr (reg), u);
9432 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9433 reg number is 0 for f1, so we want to make it odd. */
9434 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9436 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9437 build_int_cst (TREE_TYPE (reg), 1));
9438 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9441 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9442 t = build2 (GE_EXPR, boolean_type_node, u, t);
9443 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9444 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9445 gimplify_and_add (t, pre_p);
9449 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9451 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9452 build_int_cst (TREE_TYPE (reg), n_reg));
9453 u = fold_convert (sizetype, u);
9454 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9455 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9457 /* _Decimal32 varargs are located in the second word of the 64-bit
9458 FP register for 32-bit binaries. */
9459 if (!TARGET_POWERPC64
9460 && TARGET_HARD_FLOAT && TARGET_FPRS
9461 && TYPE_MODE (type) == SDmode)
9462 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9464 gimplify_assign (addr, t, pre_p);
9466 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9468 stmt = gimple_build_label (lab_false);
9469 gimple_seq_add_stmt (pre_p, stmt);
9471 if ((n_reg == 2 && !regalign) || n_reg > 2)
9473 /* Ensure that we don't find any more args in regs.
9474 Alignment has taken care of for special cases. */
9475 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9479 /* ... otherwise out of the overflow area. */
9481 /* Care for on-stack alignment if needed. */
9485 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9486 t = fold_convert (sizetype, t);
9487 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9489 t = fold_convert (TREE_TYPE (ovf), t);
9491 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9493 gimplify_assign (unshare_expr (addr), t, pre_p);
9495 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9496 gimplify_assign (unshare_expr (ovf), t, pre_p);
9500 stmt = gimple_build_label (lab_over);
9501 gimple_seq_add_stmt (pre_p, stmt);
9504 if (STRICT_ALIGNMENT
9505 && (TYPE_ALIGN (type)
9506 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9508 /* The value (of type complex double, for example) may not be
9509 aligned in memory in the saved registers, so copy via a
9510 temporary. (This is the same code as used for SPARC.) */
9511 tree tmp = create_tmp_var (type, "va_arg_tmp");
9512 tree dest_addr = build_fold_addr_expr (tmp);
9514 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9515 3, dest_addr, addr, size_int (rsize * 4));
9517 gimplify_and_add (copy, pre_p);
9521 addr = fold_convert (ptrtype, addr);
9522 return build_va_arg_indirect_ref (addr);
9528 def_builtin (int mask, const char *name, tree type, int code)
9530 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9533 if (rs6000_builtin_decls[code])
9534 fatal_error ("internal error: builtin function to %s already processed.",
9537 rs6000_builtin_decls[code] = t =
9538 add_builtin_function (name, type, code, BUILT_IN_MD,
9541 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9542 switch (builtin_classify[code])
9547 /* assume builtin can do anything. */
9548 case RS6000_BTC_MISC:
9551 /* const function, function only depends on the inputs. */
9552 case RS6000_BTC_CONST:
9553 TREE_READONLY (t) = 1;
9554 TREE_NOTHROW (t) = 1;
9557 /* pure function, function can read global memory. */
9558 case RS6000_BTC_PURE:
9559 DECL_PURE_P (t) = 1;
9560 TREE_NOTHROW (t) = 1;
9563 /* Function is a math function. If rounding mode is on, then treat
9564 the function as not reading global memory, but it can have
9565 arbitrary side effects. If it is off, then assume the function is
9566 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9567 attribute in builtin-attribute.def that is used for the math
9569 case RS6000_BTC_FP_PURE:
9570 TREE_NOTHROW (t) = 1;
9571 if (flag_rounding_math)
9573 DECL_PURE_P (t) = 1;
9574 DECL_IS_NOVOPS (t) = 1;
9577 TREE_READONLY (t) = 1;
9583 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9585 static const struct builtin_description bdesc_3arg[] =
9587 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9588 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9589 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9590 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9591 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9592 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9593 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9594 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9595 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9596 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9597 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9598 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9599 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9600 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9601 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9602 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9603 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9604 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9605 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9606 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9607 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9608 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9609 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9610 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9611 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9612 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9613 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9614 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9615 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9616 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9617 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9620 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9621 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9623 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9624 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9625 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9626 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9627 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9628 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9629 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9630 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9631 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9632 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9633 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9634 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9635 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9636 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9637 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9639 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9640 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9641 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9642 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9644 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9645 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9646 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9647 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9649 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9650 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9652 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9653 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9654 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9655 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9656 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9657 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9658 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9659 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9660 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9661 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9663 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9664 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9665 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9666 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9667 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9668 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9669 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9670 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9671 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9672 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9674 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9675 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9676 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9677 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9678 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9679 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9680 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9681 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9682 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9684 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9685 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9686 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9687 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9688 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9689 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9690 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9692 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9693 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9694 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9695 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9696 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9697 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9698 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9699 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9700 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9703 /* DST operations: void foo (void *, const int, const char). */
9705 static const struct builtin_description bdesc_dst[] =
9707 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9708 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9709 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9710 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9712 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9713 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9714 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9715 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9718 /* Simple binary operations: VECc = foo (VECa, VECb). */
9720 static struct builtin_description bdesc_2arg[] =
9722 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9723 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9724 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9725 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9726 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9727 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9728 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9729 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9730 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9731 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9732 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9733 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9734 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9735 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9736 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9737 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9738 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9739 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9740 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9741 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9742 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9743 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9744 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9745 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9746 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9747 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9748 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9749 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9750 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9751 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9752 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9753 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9754 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9755 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9756 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9757 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9758 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9759 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9760 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9761 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9762 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9763 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9764 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9765 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9766 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9767 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9769 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9770 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9771 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9772 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9773 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9774 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9775 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9776 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9777 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9782 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9783 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9784 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9785 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9786 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9787 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9788 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9789 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9790 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9791 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9792 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9793 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9794 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9795 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9796 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9797 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9798 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9799 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9800 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9801 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9802 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9803 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9804 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9805 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9806 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9807 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9808 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9809 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9810 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9811 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9812 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9813 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9814 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9815 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9816 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9817 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9818 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9819 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9820 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9821 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9822 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9823 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9824 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9825 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9826 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9827 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9828 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9829 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9830 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9831 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9832 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9833 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9834 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9835 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9836 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9837 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9838 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9840 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9841 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9842 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9843 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9844 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9845 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9846 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9847 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9848 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9849 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9850 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9851 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9853 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9854 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9855 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9856 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9857 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9858 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9859 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9860 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9861 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9862 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9863 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9864 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9866 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9867 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9868 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9869 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9870 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9871 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9873 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9874 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9875 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9876 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9877 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9878 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9879 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9880 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9881 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9882 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9883 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9884 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9886 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9887 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9899 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9900 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9907 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9911 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9912 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9926 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9927 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9942 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9943 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9960 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9961 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9995 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9996 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10014 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10016 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10017 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10019 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10020 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10021 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10022 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10023 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10024 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10025 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10026 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10027 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10028 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10030 /* Place holder, leave as first spe builtin. */
10031 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10032 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10033 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10034 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10035 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10036 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10037 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10038 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10039 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10040 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10041 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10042 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10043 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10044 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10045 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10046 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10047 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10048 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10049 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10050 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10051 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10052 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10053 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10054 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10055 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10056 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10057 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10058 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10059 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10060 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10061 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10062 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10063 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10064 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10065 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10066 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10067 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10068 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10069 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10070 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10071 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10072 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10073 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10074 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10075 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10076 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10077 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10078 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10079 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10080 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10081 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10082 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10083 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10084 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10085 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10086 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10087 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10088 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10089 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10090 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10091 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10092 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10093 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10094 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10095 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10096 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10097 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10098 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10099 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10100 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10101 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10102 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10103 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10104 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10105 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10106 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10107 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10108 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10109 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10110 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10111 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10112 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10113 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10114 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10115 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10116 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10117 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10118 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10119 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10120 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10121 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10122 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10123 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10124 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10125 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10126 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10127 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10128 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10129 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10130 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10131 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10132 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10133 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10134 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10135 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10136 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10137 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10138 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10139 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10141 /* SPE binary operations expecting a 5-bit unsigned literal. */
10142 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10144 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10145 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10146 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10147 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10148 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10149 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10150 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10151 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10152 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10153 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10154 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10155 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10156 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10157 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10158 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10159 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10160 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10161 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10162 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10163 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10164 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10165 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10166 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10167 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10168 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10169 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10171 /* Place-holder. Leave as last binary SPE builtin. */
10172 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10175 /* AltiVec predicates. */
10177 struct builtin_description_predicates
10179 const unsigned int mask;
10180 const enum insn_code icode;
10181 const char *const name;
10182 const enum rs6000_builtins code;
10185 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10187 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10188 ALTIVEC_BUILTIN_VCMPBFP_P },
10189 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10190 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10191 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10192 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10193 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10194 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10195 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10196 ALTIVEC_BUILTIN_VCMPEQUW_P },
10197 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10198 ALTIVEC_BUILTIN_VCMPGTSW_P },
10199 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10200 ALTIVEC_BUILTIN_VCMPGTUW_P },
10201 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10202 ALTIVEC_BUILTIN_VCMPEQUH_P },
10203 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10204 ALTIVEC_BUILTIN_VCMPGTSH_P },
10205 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10206 ALTIVEC_BUILTIN_VCMPGTUH_P },
10207 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10208 ALTIVEC_BUILTIN_VCMPEQUB_P },
10209 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10210 ALTIVEC_BUILTIN_VCMPGTSB_P },
10211 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10212 ALTIVEC_BUILTIN_VCMPGTUB_P },
10214 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10215 VSX_BUILTIN_XVCMPEQSP_P },
10216 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10217 VSX_BUILTIN_XVCMPGESP_P },
10218 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10219 VSX_BUILTIN_XVCMPGTSP_P },
10220 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10221 VSX_BUILTIN_XVCMPEQDP_P },
10222 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10223 VSX_BUILTIN_XVCMPGEDP_P },
10224 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10225 VSX_BUILTIN_XVCMPGTDP_P },
10227 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10228 ALTIVEC_BUILTIN_VCMPEQ_P },
10229 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10230 ALTIVEC_BUILTIN_VCMPGT_P },
10231 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10232 ALTIVEC_BUILTIN_VCMPGE_P }
10235 /* SPE predicates. */
10236 static struct builtin_description bdesc_spe_predicates[] =
10238 /* Place-holder. Leave as first. */
10239 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10240 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10241 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10242 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10243 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10244 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10245 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10246 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10247 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10248 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10249 /* Place-holder. Leave as last. */
10250 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10253 /* SPE evsel predicates. */
10254 static struct builtin_description bdesc_spe_evsel[] =
10256 /* Place-holder. Leave as first. */
10257 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10258 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10259 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10260 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10261 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10262 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10263 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10264 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10265 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10266 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10267 /* Place-holder. Leave as last. */
10268 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10271 /* PAIRED predicates. */
10272 static const struct builtin_description bdesc_paired_preds[] =
10274 /* Place-holder. Leave as first. */
10275 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10276 /* Place-holder. Leave as last. */
10277 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10280 /* ABS* operations. */
10282 static const struct builtin_description bdesc_abs[] =
10284 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10285 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10286 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10287 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10288 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10289 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10290 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10291 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10292 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10293 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10294 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10297 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10300 static struct builtin_description bdesc_1arg[] =
10302 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10303 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10304 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10305 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10306 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10307 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10308 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10309 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10310 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10311 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10312 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10313 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10314 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10315 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10316 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10317 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10318 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10319 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10321 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10322 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10323 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10324 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10325 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10326 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10327 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10329 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10330 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10331 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10332 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10333 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10334 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10335 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10337 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10338 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10339 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10340 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10341 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10342 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10344 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10345 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10346 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10347 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10348 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10349 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10351 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10352 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10353 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10354 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10356 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10357 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10358 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10359 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10360 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10361 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10362 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10363 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10364 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10366 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10367 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10368 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10369 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10370 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10371 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10372 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10373 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10374 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10376 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10377 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10378 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10379 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10380 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10403 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10404 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10405 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10407 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10408 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10409 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10410 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10412 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10413 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10414 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10415 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10416 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10417 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10418 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10419 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10420 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10421 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10422 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10423 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10424 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10425 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10426 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10427 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10428 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10429 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10430 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10431 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10432 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10433 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10434 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10435 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10436 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10437 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10438 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10439 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10440 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10441 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10443 /* Place-holder. Leave as last unary SPE builtin. */
10444 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10446 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10447 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10448 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10449 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10450 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10454 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10457 tree arg0 = CALL_EXPR_ARG (exp, 0);
10458 rtx op0 = expand_normal (arg0);
10459 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10460 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10462 if (icode == CODE_FOR_nothing)
10463 /* Builtin not supported on this processor. */
10466 /* If we got invalid arguments bail out before generating bad rtl. */
10467 if (arg0 == error_mark_node)
10470 if (icode == CODE_FOR_altivec_vspltisb
10471 || icode == CODE_FOR_altivec_vspltish
10472 || icode == CODE_FOR_altivec_vspltisw
10473 || icode == CODE_FOR_spe_evsplatfi
10474 || icode == CODE_FOR_spe_evsplati)
10476 /* Only allow 5-bit *signed* literals. */
10477 if (GET_CODE (op0) != CONST_INT
10478 || INTVAL (op0) > 15
10479 || INTVAL (op0) < -16)
10481 error ("argument 1 must be a 5-bit signed literal");
10487 || GET_MODE (target) != tmode
10488 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10489 target = gen_reg_rtx (tmode);
10491 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10492 op0 = copy_to_mode_reg (mode0, op0);
10494 pat = GEN_FCN (icode) (target, op0);
10503 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10505 rtx pat, scratch1, scratch2;
10506 tree arg0 = CALL_EXPR_ARG (exp, 0);
10507 rtx op0 = expand_normal (arg0);
10508 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10509 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10511 /* If we have invalid arguments, bail out before generating bad rtl. */
10512 if (arg0 == error_mark_node)
10516 || GET_MODE (target) != tmode
10517 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10518 target = gen_reg_rtx (tmode);
10520 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10521 op0 = copy_to_mode_reg (mode0, op0);
10523 scratch1 = gen_reg_rtx (mode0);
10524 scratch2 = gen_reg_rtx (mode0);
10526 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10535 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10538 tree arg0 = CALL_EXPR_ARG (exp, 0);
10539 tree arg1 = CALL_EXPR_ARG (exp, 1);
10540 rtx op0 = expand_normal (arg0);
10541 rtx op1 = expand_normal (arg1);
10542 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10543 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10544 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10546 if (icode == CODE_FOR_nothing)
10547 /* Builtin not supported on this processor. */
10550 /* If we got invalid arguments bail out before generating bad rtl. */
10551 if (arg0 == error_mark_node || arg1 == error_mark_node)
10554 if (icode == CODE_FOR_altivec_vcfux
10555 || icode == CODE_FOR_altivec_vcfsx
10556 || icode == CODE_FOR_altivec_vctsxs
10557 || icode == CODE_FOR_altivec_vctuxs
10558 || icode == CODE_FOR_altivec_vspltb
10559 || icode == CODE_FOR_altivec_vsplth
10560 || icode == CODE_FOR_altivec_vspltw
10561 || icode == CODE_FOR_spe_evaddiw
10562 || icode == CODE_FOR_spe_evldd
10563 || icode == CODE_FOR_spe_evldh
10564 || icode == CODE_FOR_spe_evldw
10565 || icode == CODE_FOR_spe_evlhhesplat
10566 || icode == CODE_FOR_spe_evlhhossplat
10567 || icode == CODE_FOR_spe_evlhhousplat
10568 || icode == CODE_FOR_spe_evlwhe
10569 || icode == CODE_FOR_spe_evlwhos
10570 || icode == CODE_FOR_spe_evlwhou
10571 || icode == CODE_FOR_spe_evlwhsplat
10572 || icode == CODE_FOR_spe_evlwwsplat
10573 || icode == CODE_FOR_spe_evrlwi
10574 || icode == CODE_FOR_spe_evslwi
10575 || icode == CODE_FOR_spe_evsrwis
10576 || icode == CODE_FOR_spe_evsubifw
10577 || icode == CODE_FOR_spe_evsrwiu)
10579 /* Only allow 5-bit unsigned literals. */
10581 if (TREE_CODE (arg1) != INTEGER_CST
10582 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10584 error ("argument 2 must be a 5-bit unsigned literal");
10590 || GET_MODE (target) != tmode
10591 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10592 target = gen_reg_rtx (tmode);
10594 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10595 op0 = copy_to_mode_reg (mode0, op0);
10596 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10597 op1 = copy_to_mode_reg (mode1, op1);
10599 pat = GEN_FCN (icode) (target, op0, op1);
10608 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10611 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10612 tree arg0 = CALL_EXPR_ARG (exp, 1);
10613 tree arg1 = CALL_EXPR_ARG (exp, 2);
10614 rtx op0 = expand_normal (arg0);
10615 rtx op1 = expand_normal (arg1);
10616 enum machine_mode tmode = SImode;
10617 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10618 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10621 if (TREE_CODE (cr6_form) != INTEGER_CST)
10623 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10627 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10629 gcc_assert (mode0 == mode1);
10631 /* If we have invalid arguments, bail out before generating bad rtl. */
10632 if (arg0 == error_mark_node || arg1 == error_mark_node)
10636 || GET_MODE (target) != tmode
10637 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10638 target = gen_reg_rtx (tmode);
10640 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10641 op0 = copy_to_mode_reg (mode0, op0);
10642 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10643 op1 = copy_to_mode_reg (mode1, op1);
10645 scratch = gen_reg_rtx (mode0);
10647 pat = GEN_FCN (icode) (scratch, op0, op1);
10652 /* The vec_any* and vec_all* predicates use the same opcodes for two
10653 different operations, but the bits in CR6 will be different
10654 depending on what information we want. So we have to play tricks
10655 with CR6 to get the right bits out.
10657 If you think this is disgusting, look at the specs for the
10658 AltiVec predicates. */
10660 switch (cr6_form_int)
10663 emit_insn (gen_cr6_test_for_zero (target));
10666 emit_insn (gen_cr6_test_for_zero_reverse (target));
10669 emit_insn (gen_cr6_test_for_lt (target));
10672 emit_insn (gen_cr6_test_for_lt_reverse (target));
10675 error ("argument 1 of __builtin_altivec_predicate is out of range");
10683 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10686 tree arg0 = CALL_EXPR_ARG (exp, 0);
10687 tree arg1 = CALL_EXPR_ARG (exp, 1);
10688 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10689 enum machine_mode mode0 = Pmode;
10690 enum machine_mode mode1 = Pmode;
10691 rtx op0 = expand_normal (arg0);
10692 rtx op1 = expand_normal (arg1);
10694 if (icode == CODE_FOR_nothing)
10695 /* Builtin not supported on this processor. */
10698 /* If we got invalid arguments bail out before generating bad rtl. */
10699 if (arg0 == error_mark_node || arg1 == error_mark_node)
10703 || GET_MODE (target) != tmode
10704 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10705 target = gen_reg_rtx (tmode);
10707 op1 = copy_to_mode_reg (mode1, op1);
10709 if (op0 == const0_rtx)
10711 addr = gen_rtx_MEM (tmode, op1);
10715 op0 = copy_to_mode_reg (mode0, op0);
10716 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10719 pat = GEN_FCN (icode) (target, addr);
10729 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10732 tree arg0 = CALL_EXPR_ARG (exp, 0);
10733 tree arg1 = CALL_EXPR_ARG (exp, 1);
10734 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10735 enum machine_mode mode0 = Pmode;
10736 enum machine_mode mode1 = Pmode;
10737 rtx op0 = expand_normal (arg0);
10738 rtx op1 = expand_normal (arg1);
10740 if (icode == CODE_FOR_nothing)
10741 /* Builtin not supported on this processor. */
10744 /* If we got invalid arguments bail out before generating bad rtl. */
10745 if (arg0 == error_mark_node || arg1 == error_mark_node)
10749 || GET_MODE (target) != tmode
10750 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10751 target = gen_reg_rtx (tmode);
10753 op1 = copy_to_mode_reg (mode1, op1);
10755 if (op0 == const0_rtx)
10757 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10761 op0 = copy_to_mode_reg (mode0, op0);
10762 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10765 pat = GEN_FCN (icode) (target, addr);
10775 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10777 tree arg0 = CALL_EXPR_ARG (exp, 0);
10778 tree arg1 = CALL_EXPR_ARG (exp, 1);
10779 tree arg2 = CALL_EXPR_ARG (exp, 2);
10780 rtx op0 = expand_normal (arg0);
10781 rtx op1 = expand_normal (arg1);
10782 rtx op2 = expand_normal (arg2);
10784 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10785 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10786 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10788 /* Invalid arguments. Bail before doing anything stoopid! */
10789 if (arg0 == error_mark_node
10790 || arg1 == error_mark_node
10791 || arg2 == error_mark_node)
10794 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10795 op0 = copy_to_mode_reg (mode2, op0);
10796 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10797 op1 = copy_to_mode_reg (mode0, op1);
10798 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10799 op2 = copy_to_mode_reg (mode1, op2);
10801 pat = GEN_FCN (icode) (op1, op2, op0);
10808 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10810 tree arg0 = CALL_EXPR_ARG (exp, 0);
10811 tree arg1 = CALL_EXPR_ARG (exp, 1);
10812 tree arg2 = CALL_EXPR_ARG (exp, 2);
10813 rtx op0 = expand_normal (arg0);
10814 rtx op1 = expand_normal (arg1);
10815 rtx op2 = expand_normal (arg2);
10817 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10818 enum machine_mode mode1 = Pmode;
10819 enum machine_mode mode2 = Pmode;
10821 /* Invalid arguments. Bail before doing anything stoopid! */
10822 if (arg0 == error_mark_node
10823 || arg1 == error_mark_node
10824 || arg2 == error_mark_node)
10827 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10828 op0 = copy_to_mode_reg (tmode, op0);
10830 op2 = copy_to_mode_reg (mode2, op2);
10832 if (op1 == const0_rtx)
10834 addr = gen_rtx_MEM (tmode, op2);
10838 op1 = copy_to_mode_reg (mode1, op1);
10839 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10842 pat = GEN_FCN (icode) (addr, op0);
10849 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10851 tree arg0 = CALL_EXPR_ARG (exp, 0);
10852 tree arg1 = CALL_EXPR_ARG (exp, 1);
10853 tree arg2 = CALL_EXPR_ARG (exp, 2);
10854 rtx op0 = expand_normal (arg0);
10855 rtx op1 = expand_normal (arg1);
10856 rtx op2 = expand_normal (arg2);
10858 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10859 enum machine_mode mode1 = Pmode;
10860 enum machine_mode mode2 = Pmode;
10862 /* Invalid arguments. Bail before doing anything stoopid! */
10863 if (arg0 == error_mark_node
10864 || arg1 == error_mark_node
10865 || arg2 == error_mark_node)
10868 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10869 op0 = copy_to_mode_reg (tmode, op0);
10871 op2 = copy_to_mode_reg (mode2, op2);
10873 if (op1 == const0_rtx)
10875 addr = gen_rtx_MEM (tmode, op2);
10879 op1 = copy_to_mode_reg (mode1, op1);
10880 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10883 pat = GEN_FCN (icode) (addr, op0);
10890 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10893 tree arg0 = CALL_EXPR_ARG (exp, 0);
10894 tree arg1 = CALL_EXPR_ARG (exp, 1);
10895 tree arg2 = CALL_EXPR_ARG (exp, 2);
10896 rtx op0 = expand_normal (arg0);
10897 rtx op1 = expand_normal (arg1);
10898 rtx op2 = expand_normal (arg2);
10899 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10900 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10901 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10902 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10904 if (icode == CODE_FOR_nothing)
10905 /* Builtin not supported on this processor. */
10908 /* If we got invalid arguments bail out before generating bad rtl. */
10909 if (arg0 == error_mark_node
10910 || arg1 == error_mark_node
10911 || arg2 == error_mark_node)
10916 case CODE_FOR_altivec_vsldoi_v4sf:
10917 case CODE_FOR_altivec_vsldoi_v4si:
10918 case CODE_FOR_altivec_vsldoi_v8hi:
10919 case CODE_FOR_altivec_vsldoi_v16qi:
10920 /* Only allow 4-bit unsigned literals. */
10922 if (TREE_CODE (arg2) != INTEGER_CST
10923 || TREE_INT_CST_LOW (arg2) & ~0xf)
10925 error ("argument 3 must be a 4-bit unsigned literal");
10930 case CODE_FOR_vsx_xxpermdi_v2df:
10931 case CODE_FOR_vsx_xxpermdi_v2di:
10932 case CODE_FOR_vsx_xxsldwi_v16qi:
10933 case CODE_FOR_vsx_xxsldwi_v8hi:
10934 case CODE_FOR_vsx_xxsldwi_v4si:
10935 case CODE_FOR_vsx_xxsldwi_v4sf:
10936 case CODE_FOR_vsx_xxsldwi_v2di:
10937 case CODE_FOR_vsx_xxsldwi_v2df:
10938 /* Only allow 2-bit unsigned literals. */
10940 if (TREE_CODE (arg2) != INTEGER_CST
10941 || TREE_INT_CST_LOW (arg2) & ~0x3)
10943 error ("argument 3 must be a 2-bit unsigned literal");
10948 case CODE_FOR_vsx_set_v2df:
10949 case CODE_FOR_vsx_set_v2di:
10950 /* Only allow 1-bit unsigned literals. */
10952 if (TREE_CODE (arg2) != INTEGER_CST
10953 || TREE_INT_CST_LOW (arg2) & ~0x1)
10955 error ("argument 3 must be a 1-bit unsigned literal");
10965 || GET_MODE (target) != tmode
10966 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10967 target = gen_reg_rtx (tmode);
10969 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10970 op0 = copy_to_mode_reg (mode0, op0);
10971 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10972 op1 = copy_to_mode_reg (mode1, op1);
10973 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10974 op2 = copy_to_mode_reg (mode2, op2);
10976 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10977 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10979 pat = GEN_FCN (icode) (target, op0, op1, op2);
10987 /* Expand the lvx builtins. */
10989 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10991 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10992 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10994 enum machine_mode tmode, mode0;
10996 enum insn_code icode;
11000 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11001 icode = CODE_FOR_vector_load_v16qi;
11003 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11004 icode = CODE_FOR_vector_load_v8hi;
11006 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11007 icode = CODE_FOR_vector_load_v4si;
11009 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11010 icode = CODE_FOR_vector_load_v4sf;
11013 *expandedp = false;
11019 arg0 = CALL_EXPR_ARG (exp, 0);
11020 op0 = expand_normal (arg0);
11021 tmode = insn_data[icode].operand[0].mode;
11022 mode0 = insn_data[icode].operand[1].mode;
11025 || GET_MODE (target) != tmode
11026 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11027 target = gen_reg_rtx (tmode);
11029 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11030 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11032 pat = GEN_FCN (icode) (target, op0);
11039 /* Expand the stvx builtins. */
11041 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11044 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11045 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11047 enum machine_mode mode0, mode1;
11049 enum insn_code icode;
11053 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11054 icode = CODE_FOR_vector_store_v16qi;
11056 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11057 icode = CODE_FOR_vector_store_v8hi;
11059 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11060 icode = CODE_FOR_vector_store_v4si;
11062 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11063 icode = CODE_FOR_vector_store_v4sf;
11066 *expandedp = false;
11070 arg0 = CALL_EXPR_ARG (exp, 0);
11071 arg1 = CALL_EXPR_ARG (exp, 1);
11072 op0 = expand_normal (arg0);
11073 op1 = expand_normal (arg1);
11074 mode0 = insn_data[icode].operand[0].mode;
11075 mode1 = insn_data[icode].operand[1].mode;
11077 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11078 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11079 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11080 op1 = copy_to_mode_reg (mode1, op1);
11082 pat = GEN_FCN (icode) (op0, op1);
11090 /* Expand the dst builtins. */
11092 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11095 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11096 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11097 tree arg0, arg1, arg2;
11098 enum machine_mode mode0, mode1;
11099 rtx pat, op0, op1, op2;
11100 const struct builtin_description *d;
11103 *expandedp = false;
11105 /* Handle DST variants. */
11107 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11108 if (d->code == fcode)
11110 arg0 = CALL_EXPR_ARG (exp, 0);
11111 arg1 = CALL_EXPR_ARG (exp, 1);
11112 arg2 = CALL_EXPR_ARG (exp, 2);
11113 op0 = expand_normal (arg0);
11114 op1 = expand_normal (arg1);
11115 op2 = expand_normal (arg2);
11116 mode0 = insn_data[d->icode].operand[0].mode;
11117 mode1 = insn_data[d->icode].operand[1].mode;
11119 /* Invalid arguments, bail out before generating bad rtl. */
11120 if (arg0 == error_mark_node
11121 || arg1 == error_mark_node
11122 || arg2 == error_mark_node)
11127 if (TREE_CODE (arg2) != INTEGER_CST
11128 || TREE_INT_CST_LOW (arg2) & ~0x3)
11130 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11134 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11135 op0 = copy_to_mode_reg (Pmode, op0);
11136 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11137 op1 = copy_to_mode_reg (mode1, op1);
11139 pat = GEN_FCN (d->icode) (op0, op1, op2);
11149 /* Expand vec_init builtin. */
11151 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11153 enum machine_mode tmode = TYPE_MODE (type);
11154 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11155 int i, n_elt = GET_MODE_NUNITS (tmode);
11156 rtvec v = rtvec_alloc (n_elt);
11158 gcc_assert (VECTOR_MODE_P (tmode));
11159 gcc_assert (n_elt == call_expr_nargs (exp));
11161 for (i = 0; i < n_elt; ++i)
11163 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11164 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11167 if (!target || !register_operand (target, tmode))
11168 target = gen_reg_rtx (tmode);
11170 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11174 /* Return the integer constant in ARG. Constrain it to be in the range
11175 of the subparts of VEC_TYPE; issue an error if not. */
11178 get_element_number (tree vec_type, tree arg)
11180 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11182 if (!host_integerp (arg, 1)
11183 || (elt = tree_low_cst (arg, 1), elt > max))
11185 error ("selector must be an integer constant in the range 0..%wi", max);
11192 /* Expand vec_set builtin. */
11194 altivec_expand_vec_set_builtin (tree exp)
11196 enum machine_mode tmode, mode1;
11197 tree arg0, arg1, arg2;
11201 arg0 = CALL_EXPR_ARG (exp, 0);
11202 arg1 = CALL_EXPR_ARG (exp, 1);
11203 arg2 = CALL_EXPR_ARG (exp, 2);
11205 tmode = TYPE_MODE (TREE_TYPE (arg0));
11206 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11207 gcc_assert (VECTOR_MODE_P (tmode));
11209 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11210 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11211 elt = get_element_number (TREE_TYPE (arg0), arg2);
11213 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11214 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11216 op0 = force_reg (tmode, op0);
11217 op1 = force_reg (mode1, op1);
11219 rs6000_expand_vector_set (op0, op1, elt);
11224 /* Expand vec_ext builtin. */
11226 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11228 enum machine_mode tmode, mode0;
11233 arg0 = CALL_EXPR_ARG (exp, 0);
11234 arg1 = CALL_EXPR_ARG (exp, 1);
11236 op0 = expand_normal (arg0);
11237 elt = get_element_number (TREE_TYPE (arg0), arg1);
11239 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11240 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11241 gcc_assert (VECTOR_MODE_P (mode0));
11243 op0 = force_reg (mode0, op0);
11245 if (optimize || !target || !register_operand (target, tmode))
11246 target = gen_reg_rtx (tmode);
11248 rs6000_expand_vector_extract (target, op0, elt);
11253 /* Expand the builtin in EXP and store the result in TARGET. Store
11254 true in *EXPANDEDP if we found a builtin to expand. */
11256 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11258 const struct builtin_description *d;
11259 const struct builtin_description_predicates *dp;
11261 enum insn_code icode;
11262 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11265 enum machine_mode tmode, mode0;
11266 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11268 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11269 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11270 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11271 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11274 error ("unresolved overload for Altivec builtin %qF", fndecl);
11278 target = altivec_expand_ld_builtin (exp, target, expandedp);
11282 target = altivec_expand_st_builtin (exp, target, expandedp);
11286 target = altivec_expand_dst_builtin (exp, target, expandedp);
11294 case ALTIVEC_BUILTIN_STVX:
11295 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11296 case ALTIVEC_BUILTIN_STVEBX:
11297 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11298 case ALTIVEC_BUILTIN_STVEHX:
11299 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11300 case ALTIVEC_BUILTIN_STVEWX:
11301 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11302 case ALTIVEC_BUILTIN_STVXL:
11303 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11305 case ALTIVEC_BUILTIN_STVLX:
11306 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11307 case ALTIVEC_BUILTIN_STVLXL:
11308 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11309 case ALTIVEC_BUILTIN_STVRX:
11310 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11311 case ALTIVEC_BUILTIN_STVRXL:
11312 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11314 case ALTIVEC_BUILTIN_MFVSCR:
11315 icode = CODE_FOR_altivec_mfvscr;
11316 tmode = insn_data[icode].operand[0].mode;
11319 || GET_MODE (target) != tmode
11320 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11321 target = gen_reg_rtx (tmode);
11323 pat = GEN_FCN (icode) (target);
11329 case ALTIVEC_BUILTIN_MTVSCR:
11330 icode = CODE_FOR_altivec_mtvscr;
11331 arg0 = CALL_EXPR_ARG (exp, 0);
11332 op0 = expand_normal (arg0);
11333 mode0 = insn_data[icode].operand[0].mode;
11335 /* If we got invalid arguments bail out before generating bad rtl. */
11336 if (arg0 == error_mark_node)
11339 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11340 op0 = copy_to_mode_reg (mode0, op0);
11342 pat = GEN_FCN (icode) (op0);
11347 case ALTIVEC_BUILTIN_DSSALL:
11348 emit_insn (gen_altivec_dssall ());
11351 case ALTIVEC_BUILTIN_DSS:
11352 icode = CODE_FOR_altivec_dss;
11353 arg0 = CALL_EXPR_ARG (exp, 0);
11355 op0 = expand_normal (arg0);
11356 mode0 = insn_data[icode].operand[0].mode;
11358 /* If we got invalid arguments bail out before generating bad rtl. */
11359 if (arg0 == error_mark_node)
11362 if (TREE_CODE (arg0) != INTEGER_CST
11363 || TREE_INT_CST_LOW (arg0) & ~0x3)
11365 error ("argument to dss must be a 2-bit unsigned literal");
11369 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11370 op0 = copy_to_mode_reg (mode0, op0);
11372 emit_insn (gen_altivec_dss (op0));
11375 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11376 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11377 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11378 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11379 case VSX_BUILTIN_VEC_INIT_V2DF:
11380 case VSX_BUILTIN_VEC_INIT_V2DI:
11381 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11383 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11384 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11385 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11386 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11387 case VSX_BUILTIN_VEC_SET_V2DF:
11388 case VSX_BUILTIN_VEC_SET_V2DI:
11389 return altivec_expand_vec_set_builtin (exp);
11391 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11392 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11393 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11394 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11395 case VSX_BUILTIN_VEC_EXT_V2DF:
11396 case VSX_BUILTIN_VEC_EXT_V2DI:
11397 return altivec_expand_vec_ext_builtin (exp, target);
11401 /* Fall through. */
11404 /* Expand abs* operations. */
11406 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11407 if (d->code == fcode)
11408 return altivec_expand_abs_builtin (d->icode, exp, target);
11410 /* Expand the AltiVec predicates. */
11411 dp = bdesc_altivec_preds;
11412 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11413 if (dp->code == fcode)
11414 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11416 /* LV* are funky. We initialized them differently. */
11419 case ALTIVEC_BUILTIN_LVSL:
11420 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11421 exp, target, false);
11422 case ALTIVEC_BUILTIN_LVSR:
11423 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11424 exp, target, false);
11425 case ALTIVEC_BUILTIN_LVEBX:
11426 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11427 exp, target, false);
11428 case ALTIVEC_BUILTIN_LVEHX:
11429 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11430 exp, target, false);
11431 case ALTIVEC_BUILTIN_LVEWX:
11432 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11433 exp, target, false);
11434 case ALTIVEC_BUILTIN_LVXL:
11435 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11436 exp, target, false);
11437 case ALTIVEC_BUILTIN_LVX:
11438 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11439 exp, target, false);
11440 case ALTIVEC_BUILTIN_LVLX:
11441 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11442 exp, target, true);
11443 case ALTIVEC_BUILTIN_LVLXL:
11444 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11445 exp, target, true);
11446 case ALTIVEC_BUILTIN_LVRX:
11447 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11448 exp, target, true);
11449 case ALTIVEC_BUILTIN_LVRXL:
11450 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11451 exp, target, true);
11454 /* Fall through. */
11457 *expandedp = false;
11461 /* Expand the builtin in EXP and store the result in TARGET. Store
11462 true in *EXPANDEDP if we found a builtin to expand. */
11464 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11466 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11467 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11468 const struct builtin_description *d;
11475 case PAIRED_BUILTIN_STX:
11476 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11477 case PAIRED_BUILTIN_LX:
11478 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11481 /* Fall through. */
11484 /* Expand the paired predicates. */
11485 d = bdesc_paired_preds;
11486 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11487 if (d->code == fcode)
11488 return paired_expand_predicate_builtin (d->icode, exp, target);
11490 *expandedp = false;
11494 /* Binops that need to be initialized manually, but can be expanded
11495 automagically by rs6000_expand_binop_builtin. */
11496 static struct builtin_description bdesc_2arg_spe[] =
11498 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11499 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11500 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11501 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11502 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11503 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11504 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11505 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11506 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11507 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11508 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11509 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11510 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11511 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11512 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11513 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11514 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11515 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11516 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11517 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11518 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11519 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11522 /* Expand the builtin in EXP and store the result in TARGET. Store
11523 true in *EXPANDEDP if we found a builtin to expand.
11525 This expands the SPE builtins that are not simple unary and binary
11528 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11530 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11532 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11533 enum insn_code icode;
11534 enum machine_mode tmode, mode0;
11536 struct builtin_description *d;
11541 /* Syntax check for a 5-bit unsigned immediate. */
11544 case SPE_BUILTIN_EVSTDD:
11545 case SPE_BUILTIN_EVSTDH:
11546 case SPE_BUILTIN_EVSTDW:
11547 case SPE_BUILTIN_EVSTWHE:
11548 case SPE_BUILTIN_EVSTWHO:
11549 case SPE_BUILTIN_EVSTWWE:
11550 case SPE_BUILTIN_EVSTWWO:
11551 arg1 = CALL_EXPR_ARG (exp, 2);
11552 if (TREE_CODE (arg1) != INTEGER_CST
11553 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11555 error ("argument 2 must be a 5-bit unsigned literal");
11563 /* The evsplat*i instructions are not quite generic. */
11566 case SPE_BUILTIN_EVSPLATFI:
11567 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11569 case SPE_BUILTIN_EVSPLATI:
11570 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11576 d = (struct builtin_description *) bdesc_2arg_spe;
11577 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11578 if (d->code == fcode)
11579 return rs6000_expand_binop_builtin (d->icode, exp, target);
11581 d = (struct builtin_description *) bdesc_spe_predicates;
11582 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11583 if (d->code == fcode)
11584 return spe_expand_predicate_builtin (d->icode, exp, target);
11586 d = (struct builtin_description *) bdesc_spe_evsel;
11587 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11588 if (d->code == fcode)
11589 return spe_expand_evsel_builtin (d->icode, exp, target);
11593 case SPE_BUILTIN_EVSTDDX:
11594 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11595 case SPE_BUILTIN_EVSTDHX:
11596 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11597 case SPE_BUILTIN_EVSTDWX:
11598 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11599 case SPE_BUILTIN_EVSTWHEX:
11600 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11601 case SPE_BUILTIN_EVSTWHOX:
11602 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11603 case SPE_BUILTIN_EVSTWWEX:
11604 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11605 case SPE_BUILTIN_EVSTWWOX:
11606 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11607 case SPE_BUILTIN_EVSTDD:
11608 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11609 case SPE_BUILTIN_EVSTDH:
11610 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11611 case SPE_BUILTIN_EVSTDW:
11612 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11613 case SPE_BUILTIN_EVSTWHE:
11614 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11615 case SPE_BUILTIN_EVSTWHO:
11616 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11617 case SPE_BUILTIN_EVSTWWE:
11618 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11619 case SPE_BUILTIN_EVSTWWO:
11620 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11621 case SPE_BUILTIN_MFSPEFSCR:
11622 icode = CODE_FOR_spe_mfspefscr;
11623 tmode = insn_data[icode].operand[0].mode;
11626 || GET_MODE (target) != tmode
11627 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11628 target = gen_reg_rtx (tmode);
11630 pat = GEN_FCN (icode) (target);
11635 case SPE_BUILTIN_MTSPEFSCR:
11636 icode = CODE_FOR_spe_mtspefscr;
11637 arg0 = CALL_EXPR_ARG (exp, 0);
11638 op0 = expand_normal (arg0);
11639 mode0 = insn_data[icode].operand[0].mode;
11641 if (arg0 == error_mark_node)
11644 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11645 op0 = copy_to_mode_reg (mode0, op0);
11647 pat = GEN_FCN (icode) (op0);
11655 *expandedp = false;
11660 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11662 rtx pat, scratch, tmp;
11663 tree form = CALL_EXPR_ARG (exp, 0);
11664 tree arg0 = CALL_EXPR_ARG (exp, 1);
11665 tree arg1 = CALL_EXPR_ARG (exp, 2);
11666 rtx op0 = expand_normal (arg0);
11667 rtx op1 = expand_normal (arg1);
11668 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11669 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11671 enum rtx_code code;
11673 if (TREE_CODE (form) != INTEGER_CST)
11675 error ("argument 1 of __builtin_paired_predicate must be a constant");
11679 form_int = TREE_INT_CST_LOW (form);
11681 gcc_assert (mode0 == mode1);
11683 if (arg0 == error_mark_node || arg1 == error_mark_node)
11687 || GET_MODE (target) != SImode
11688 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11689 target = gen_reg_rtx (SImode);
11690 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11691 op0 = copy_to_mode_reg (mode0, op0);
11692 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11693 op1 = copy_to_mode_reg (mode1, op1);
11695 scratch = gen_reg_rtx (CCFPmode);
11697 pat = GEN_FCN (icode) (scratch, op0, op1);
11719 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11722 error ("argument 1 of __builtin_paired_predicate is out of range");
11726 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11727 emit_move_insn (target, tmp);
11732 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11734 rtx pat, scratch, tmp;
11735 tree form = CALL_EXPR_ARG (exp, 0);
11736 tree arg0 = CALL_EXPR_ARG (exp, 1);
11737 tree arg1 = CALL_EXPR_ARG (exp, 2);
11738 rtx op0 = expand_normal (arg0);
11739 rtx op1 = expand_normal (arg1);
11740 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11741 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11743 enum rtx_code code;
11745 if (TREE_CODE (form) != INTEGER_CST)
11747 error ("argument 1 of __builtin_spe_predicate must be a constant");
11751 form_int = TREE_INT_CST_LOW (form);
11753 gcc_assert (mode0 == mode1);
11755 if (arg0 == error_mark_node || arg1 == error_mark_node)
11759 || GET_MODE (target) != SImode
11760 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11761 target = gen_reg_rtx (SImode);
11763 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11764 op0 = copy_to_mode_reg (mode0, op0);
11765 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11766 op1 = copy_to_mode_reg (mode1, op1);
11768 scratch = gen_reg_rtx (CCmode);
11770 pat = GEN_FCN (icode) (scratch, op0, op1);
11775 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11776 _lower_. We use one compare, but look in different bits of the
11777 CR for each variant.
11779 There are 2 elements in each SPE simd type (upper/lower). The CR
11780 bits are set as follows:
11782 BIT0 | BIT 1 | BIT 2 | BIT 3
11783 U | L | (U | L) | (U & L)
11785 So, for an "all" relationship, BIT 3 would be set.
11786 For an "any" relationship, BIT 2 would be set. Etc.
11788 Following traditional nomenclature, these bits map to:
11790 BIT0 | BIT 1 | BIT 2 | BIT 3
11793 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11798 /* All variant. OV bit. */
11800 /* We need to get to the OV bit, which is the ORDERED bit. We
11801 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11802 that's ugly and will make validate_condition_mode die.
11803 So let's just use another pattern. */
11804 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11806 /* Any variant. EQ bit. */
11810 /* Upper variant. LT bit. */
11814 /* Lower variant. GT bit. */
11819 error ("argument 1 of __builtin_spe_predicate is out of range");
11823 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11824 emit_move_insn (target, tmp);
11829 /* The evsel builtins look like this:
11831 e = __builtin_spe_evsel_OP (a, b, c, d);
11833 and work like this:
11835 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11836 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11840 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11843 tree arg0 = CALL_EXPR_ARG (exp, 0);
11844 tree arg1 = CALL_EXPR_ARG (exp, 1);
11845 tree arg2 = CALL_EXPR_ARG (exp, 2);
11846 tree arg3 = CALL_EXPR_ARG (exp, 3);
11847 rtx op0 = expand_normal (arg0);
11848 rtx op1 = expand_normal (arg1);
11849 rtx op2 = expand_normal (arg2);
11850 rtx op3 = expand_normal (arg3);
11851 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11852 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11854 gcc_assert (mode0 == mode1);
11856 if (arg0 == error_mark_node || arg1 == error_mark_node
11857 || arg2 == error_mark_node || arg3 == error_mark_node)
11861 || GET_MODE (target) != mode0
11862 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11863 target = gen_reg_rtx (mode0);
11865 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11866 op0 = copy_to_mode_reg (mode0, op0);
11867 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11868 op1 = copy_to_mode_reg (mode0, op1);
11869 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11870 op2 = copy_to_mode_reg (mode0, op2);
11871 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11872 op3 = copy_to_mode_reg (mode0, op3);
11874 /* Generate the compare. */
11875 scratch = gen_reg_rtx (CCmode);
11876 pat = GEN_FCN (icode) (scratch, op0, op1);
11881 if (mode0 == V2SImode)
11882 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11884 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11889 /* Expand an expression EXP that calls a built-in function,
11890 with result going to TARGET if that's convenient
11891 (and in mode MODE if that's convenient).
11892 SUBTARGET may be used as the target for computing one of EXP's operands.
11893 IGNORE is nonzero if the value is to be ignored. */
11896 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11897 enum machine_mode mode ATTRIBUTE_UNUSED,
11898 int ignore ATTRIBUTE_UNUSED)
11900 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11901 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11902 const struct builtin_description *d;
11909 case RS6000_BUILTIN_RECIP:
11910 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11912 case RS6000_BUILTIN_RECIPF:
11913 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11915 case RS6000_BUILTIN_RSQRTF:
11916 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11918 case RS6000_BUILTIN_RSQRT:
11919 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11921 case RS6000_BUILTIN_BSWAP_HI:
11922 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11924 case POWER7_BUILTIN_BPERMD:
11925 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11926 ? CODE_FOR_bpermd_di
11927 : CODE_FOR_bpermd_si), exp, target);
11929 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11930 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11932 int icode = (int) CODE_FOR_altivec_lvsr;
11933 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11934 enum machine_mode mode = insn_data[icode].operand[1].mode;
11938 gcc_assert (TARGET_ALTIVEC);
11940 arg = CALL_EXPR_ARG (exp, 0);
11941 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11942 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11943 addr = memory_address (mode, op);
11944 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11948 /* For the load case need to negate the address. */
11949 op = gen_reg_rtx (GET_MODE (addr));
11950 emit_insn (gen_rtx_SET (VOIDmode, op,
11951 gen_rtx_NEG (GET_MODE (addr), addr)));
11953 op = gen_rtx_MEM (mode, op);
11956 || GET_MODE (target) != tmode
11957 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11958 target = gen_reg_rtx (tmode);
11960 /*pat = gen_altivec_lvsr (target, op);*/
11961 pat = GEN_FCN (icode) (target, op);
11969 case ALTIVEC_BUILTIN_VCFUX:
11970 case ALTIVEC_BUILTIN_VCFSX:
11971 case ALTIVEC_BUILTIN_VCTUXS:
11972 case ALTIVEC_BUILTIN_VCTSXS:
11973 /* FIXME: There's got to be a nicer way to handle this case than
11974 constructing a new CALL_EXPR. */
11975 if (call_expr_nargs (exp) == 1)
11977 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11978 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11986 if (TARGET_ALTIVEC)
11988 ret = altivec_expand_builtin (exp, target, &success);
11995 ret = spe_expand_builtin (exp, target, &success);
12000 if (TARGET_PAIRED_FLOAT)
12002 ret = paired_expand_builtin (exp, target, &success);
12008 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12010 /* Handle simple unary operations. */
12011 d = (struct builtin_description *) bdesc_1arg;
12012 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12013 if (d->code == fcode)
12014 return rs6000_expand_unop_builtin (d->icode, exp, target);
12016 /* Handle simple binary operations. */
12017 d = (struct builtin_description *) bdesc_2arg;
12018 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12019 if (d->code == fcode)
12020 return rs6000_expand_binop_builtin (d->icode, exp, target);
12022 /* Handle simple ternary operations. */
12024 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12025 if (d->code == fcode)
12026 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12028 gcc_unreachable ();
12032 rs6000_init_builtins (void)
12037 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12038 V2SF_type_node = build_vector_type (float_type_node, 2);
12039 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12040 V2DF_type_node = build_vector_type (double_type_node, 2);
12041 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12042 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12043 V4SF_type_node = build_vector_type (float_type_node, 4);
12044 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12045 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12047 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12048 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12049 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12050 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12052 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12053 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12054 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12055 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12057 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12058 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12059 'vector unsigned short'. */
12061 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12062 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12063 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12064 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12065 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12067 long_integer_type_internal_node = long_integer_type_node;
12068 long_unsigned_type_internal_node = long_unsigned_type_node;
12069 intQI_type_internal_node = intQI_type_node;
12070 uintQI_type_internal_node = unsigned_intQI_type_node;
12071 intHI_type_internal_node = intHI_type_node;
12072 uintHI_type_internal_node = unsigned_intHI_type_node;
12073 intSI_type_internal_node = intSI_type_node;
12074 uintSI_type_internal_node = unsigned_intSI_type_node;
12075 intDI_type_internal_node = intDI_type_node;
12076 uintDI_type_internal_node = unsigned_intDI_type_node;
12077 float_type_internal_node = float_type_node;
12078 double_type_internal_node = float_type_node;
12079 void_type_internal_node = void_type_node;
12081 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12083 builtin_mode_to_type[QImode][0] = integer_type_node;
12084 builtin_mode_to_type[HImode][0] = integer_type_node;
12085 builtin_mode_to_type[SImode][0] = intSI_type_node;
12086 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12087 builtin_mode_to_type[DImode][0] = intDI_type_node;
12088 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12089 builtin_mode_to_type[SFmode][0] = float_type_node;
12090 builtin_mode_to_type[DFmode][0] = double_type_node;
12091 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12092 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12093 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12094 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12095 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12096 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12097 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12098 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12099 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12100 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12101 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12102 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12103 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12105 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12106 get_identifier ("__bool char"),
12107 bool_char_type_node);
12108 TYPE_NAME (bool_char_type_node) = tdecl;
12109 (*lang_hooks.decls.pushdecl) (tdecl);
12110 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12111 get_identifier ("__bool short"),
12112 bool_short_type_node);
12113 TYPE_NAME (bool_short_type_node) = tdecl;
12114 (*lang_hooks.decls.pushdecl) (tdecl);
12115 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12116 get_identifier ("__bool int"),
12117 bool_int_type_node);
12118 TYPE_NAME (bool_int_type_node) = tdecl;
12119 (*lang_hooks.decls.pushdecl) (tdecl);
12120 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12122 TYPE_NAME (pixel_type_node) = tdecl;
12123 (*lang_hooks.decls.pushdecl) (tdecl);
12125 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12126 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12127 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12128 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12129 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12131 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12132 get_identifier ("__vector unsigned char"),
12133 unsigned_V16QI_type_node);
12134 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12135 (*lang_hooks.decls.pushdecl) (tdecl);
12136 tdecl = build_decl (BUILTINS_LOCATION,
12137 TYPE_DECL, get_identifier ("__vector signed char"),
12139 TYPE_NAME (V16QI_type_node) = tdecl;
12140 (*lang_hooks.decls.pushdecl) (tdecl);
12141 tdecl = build_decl (BUILTINS_LOCATION,
12142 TYPE_DECL, get_identifier ("__vector __bool char"),
12143 bool_V16QI_type_node);
12144 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12145 (*lang_hooks.decls.pushdecl) (tdecl);
12147 tdecl = build_decl (BUILTINS_LOCATION,
12148 TYPE_DECL, get_identifier ("__vector unsigned short"),
12149 unsigned_V8HI_type_node);
12150 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12151 (*lang_hooks.decls.pushdecl) (tdecl);
12152 tdecl = build_decl (BUILTINS_LOCATION,
12153 TYPE_DECL, get_identifier ("__vector signed short"),
12155 TYPE_NAME (V8HI_type_node) = tdecl;
12156 (*lang_hooks.decls.pushdecl) (tdecl);
12157 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12158 get_identifier ("__vector __bool short"),
12159 bool_V8HI_type_node);
12160 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12161 (*lang_hooks.decls.pushdecl) (tdecl);
12163 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12164 get_identifier ("__vector unsigned int"),
12165 unsigned_V4SI_type_node);
12166 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12167 (*lang_hooks.decls.pushdecl) (tdecl);
12168 tdecl = build_decl (BUILTINS_LOCATION,
12169 TYPE_DECL, get_identifier ("__vector signed int"),
12171 TYPE_NAME (V4SI_type_node) = tdecl;
12172 (*lang_hooks.decls.pushdecl) (tdecl);
12173 tdecl = build_decl (BUILTINS_LOCATION,
12174 TYPE_DECL, get_identifier ("__vector __bool int"),
12175 bool_V4SI_type_node);
12176 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12177 (*lang_hooks.decls.pushdecl) (tdecl);
12179 tdecl = build_decl (BUILTINS_LOCATION,
12180 TYPE_DECL, get_identifier ("__vector float"),
12182 TYPE_NAME (V4SF_type_node) = tdecl;
12183 (*lang_hooks.decls.pushdecl) (tdecl);
12184 tdecl = build_decl (BUILTINS_LOCATION,
12185 TYPE_DECL, get_identifier ("__vector __pixel"),
12186 pixel_V8HI_type_node);
12187 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12188 (*lang_hooks.decls.pushdecl) (tdecl);
12192 tdecl = build_decl (BUILTINS_LOCATION,
12193 TYPE_DECL, get_identifier ("__vector double"),
12195 TYPE_NAME (V2DF_type_node) = tdecl;
12196 (*lang_hooks.decls.pushdecl) (tdecl);
12198 tdecl = build_decl (BUILTINS_LOCATION,
12199 TYPE_DECL, get_identifier ("__vector long"),
12201 TYPE_NAME (V2DI_type_node) = tdecl;
12202 (*lang_hooks.decls.pushdecl) (tdecl);
12204 tdecl = build_decl (BUILTINS_LOCATION,
12205 TYPE_DECL, get_identifier ("__vector unsigned long"),
12206 unsigned_V2DI_type_node);
12207 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12208 (*lang_hooks.decls.pushdecl) (tdecl);
12210 tdecl = build_decl (BUILTINS_LOCATION,
12211 TYPE_DECL, get_identifier ("__vector __bool long"),
12212 bool_V2DI_type_node);
12213 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12214 (*lang_hooks.decls.pushdecl) (tdecl);
12217 if (TARGET_PAIRED_FLOAT)
12218 paired_init_builtins ();
12220 spe_init_builtins ();
12221 if (TARGET_ALTIVEC)
12222 altivec_init_builtins ();
12223 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12224 rs6000_common_init_builtins ();
12227 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12228 RS6000_BUILTIN_RECIP,
12229 "__builtin_recipdiv");
12230 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12231 RS6000_BUILTIN_RECIP);
12235 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12236 RS6000_BUILTIN_RECIPF,
12237 "__builtin_recipdivf");
12238 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12239 RS6000_BUILTIN_RECIPF);
12241 if (TARGET_FRSQRTE)
12243 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12244 RS6000_BUILTIN_RSQRT,
12245 "__builtin_rsqrt");
12246 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12247 RS6000_BUILTIN_RSQRT);
12249 if (TARGET_FRSQRTES)
12251 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12252 RS6000_BUILTIN_RSQRTF,
12253 "__builtin_rsqrtf");
12254 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12255 RS6000_BUILTIN_RSQRTF);
12257 if (TARGET_POPCNTD)
12259 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12260 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12261 POWER7_BUILTIN_BPERMD,
12262 "__builtin_bpermd");
12263 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12264 POWER7_BUILTIN_BPERMD);
12266 if (TARGET_POWERPC)
12268 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12269 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12270 unsigned_intHI_type_node,
12272 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12273 RS6000_BUILTIN_BSWAP_HI);
12277 /* AIX libm provides clog as __clog. */
12278 if (built_in_decls [BUILT_IN_CLOG])
12279 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12282 #ifdef SUBTARGET_INIT_BUILTINS
12283 SUBTARGET_INIT_BUILTINS;
12287 /* Returns the rs6000 builtin decl for CODE. */
12290 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12292 if (code >= RS6000_BUILTIN_COUNT)
12293 return error_mark_node;
12295 return rs6000_builtin_decls[code];
12298 /* Search through a set of builtins and enable the mask bits.
12299 DESC is an array of builtins.
12300 SIZE is the total number of builtins.
12301 START is the builtin enum at which to start.
12302 END is the builtin enum at which to end. */
12304 enable_mask_for_builtins (struct builtin_description *desc, int size,
12305 enum rs6000_builtins start,
12306 enum rs6000_builtins end)
12310 for (i = 0; i < size; ++i)
12311 if (desc[i].code == start)
12317 for (; i < size; ++i)
12319 /* Flip all the bits on. */
12320 desc[i].mask = target_flags;
12321 if (desc[i].code == end)
12327 spe_init_builtins (void)
12329 tree endlink = void_list_node;
12330 tree puint_type_node = build_pointer_type (unsigned_type_node);
12331 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12332 struct builtin_description *d;
12335 tree v2si_ftype_4_v2si
12336 = build_function_type
12337 (opaque_V2SI_type_node,
12338 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12339 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12340 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12341 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12344 tree v2sf_ftype_4_v2sf
12345 = build_function_type
12346 (opaque_V2SF_type_node,
12347 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12348 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12349 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12350 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12353 tree int_ftype_int_v2si_v2si
12354 = build_function_type
12355 (integer_type_node,
12356 tree_cons (NULL_TREE, integer_type_node,
12357 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12358 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12361 tree int_ftype_int_v2sf_v2sf
12362 = build_function_type
12363 (integer_type_node,
12364 tree_cons (NULL_TREE, integer_type_node,
12365 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12366 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12369 tree void_ftype_v2si_puint_int
12370 = build_function_type (void_type_node,
12371 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12372 tree_cons (NULL_TREE, puint_type_node,
12373 tree_cons (NULL_TREE,
12377 tree void_ftype_v2si_puint_char
12378 = build_function_type (void_type_node,
12379 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12380 tree_cons (NULL_TREE, puint_type_node,
12381 tree_cons (NULL_TREE,
12385 tree void_ftype_v2si_pv2si_int
12386 = build_function_type (void_type_node,
12387 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12388 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12389 tree_cons (NULL_TREE,
12393 tree void_ftype_v2si_pv2si_char
12394 = build_function_type (void_type_node,
12395 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12396 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12397 tree_cons (NULL_TREE,
12401 tree void_ftype_int
12402 = build_function_type (void_type_node,
12403 tree_cons (NULL_TREE, integer_type_node, endlink));
12405 tree int_ftype_void
12406 = build_function_type (integer_type_node, endlink);
12408 tree v2si_ftype_pv2si_int
12409 = build_function_type (opaque_V2SI_type_node,
12410 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12411 tree_cons (NULL_TREE, integer_type_node,
12414 tree v2si_ftype_puint_int
12415 = build_function_type (opaque_V2SI_type_node,
12416 tree_cons (NULL_TREE, puint_type_node,
12417 tree_cons (NULL_TREE, integer_type_node,
12420 tree v2si_ftype_pushort_int
12421 = build_function_type (opaque_V2SI_type_node,
12422 tree_cons (NULL_TREE, pushort_type_node,
12423 tree_cons (NULL_TREE, integer_type_node,
12426 tree v2si_ftype_signed_char
12427 = build_function_type (opaque_V2SI_type_node,
12428 tree_cons (NULL_TREE, signed_char_type_node,
12431 /* The initialization of the simple binary and unary builtins is
12432 done in rs6000_common_init_builtins, but we have to enable the
12433 mask bits here manually because we have run out of `target_flags'
12434 bits. We really need to redesign this mask business. */
12436 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12437 ARRAY_SIZE (bdesc_2arg),
12438 SPE_BUILTIN_EVADDW,
12439 SPE_BUILTIN_EVXOR);
12440 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12441 ARRAY_SIZE (bdesc_1arg),
12443 SPE_BUILTIN_EVSUBFUSIAAW);
12444 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12445 ARRAY_SIZE (bdesc_spe_predicates),
12446 SPE_BUILTIN_EVCMPEQ,
12447 SPE_BUILTIN_EVFSTSTLT);
12448 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12449 ARRAY_SIZE (bdesc_spe_evsel),
12450 SPE_BUILTIN_EVSEL_CMPGTS,
12451 SPE_BUILTIN_EVSEL_FSTSTEQ);
12453 (*lang_hooks.decls.pushdecl)
12454 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12455 get_identifier ("__ev64_opaque__"),
12456 opaque_V2SI_type_node));
12458 /* Initialize irregular SPE builtins. */
12460 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12461 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12462 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12463 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12464 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12465 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12466 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12467 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12468 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12469 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12470 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12471 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12472 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12473 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12474 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12475 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12476 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12477 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12480 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12481 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12482 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12483 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12484 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12485 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12486 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12487 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12488 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12489 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12490 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12491 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12492 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12493 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12494 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12495 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12496 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12497 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12498 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12499 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12500 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12501 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12504 d = (struct builtin_description *) bdesc_spe_predicates;
12505 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12509 switch (insn_data[d->icode].operand[1].mode)
12512 type = int_ftype_int_v2si_v2si;
12515 type = int_ftype_int_v2sf_v2sf;
12518 gcc_unreachable ();
12521 def_builtin (d->mask, d->name, type, d->code);
12524 /* Evsel predicates. */
12525 d = (struct builtin_description *) bdesc_spe_evsel;
12526 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12530 switch (insn_data[d->icode].operand[1].mode)
12533 type = v2si_ftype_4_v2si;
12536 type = v2sf_ftype_4_v2sf;
12539 gcc_unreachable ();
12542 def_builtin (d->mask, d->name, type, d->code);
12547 paired_init_builtins (void)
12549 const struct builtin_description *d;
12551 tree endlink = void_list_node;
12553 tree int_ftype_int_v2sf_v2sf
12554 = build_function_type
12555 (integer_type_node,
12556 tree_cons (NULL_TREE, integer_type_node,
12557 tree_cons (NULL_TREE, V2SF_type_node,
12558 tree_cons (NULL_TREE, V2SF_type_node,
12560 tree pcfloat_type_node =
12561 build_pointer_type (build_qualified_type
12562 (float_type_node, TYPE_QUAL_CONST));
12564 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12565 long_integer_type_node,
12568 tree void_ftype_v2sf_long_pcfloat =
12569 build_function_type_list (void_type_node,
12571 long_integer_type_node,
12576 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12577 PAIRED_BUILTIN_LX);
12580 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12581 PAIRED_BUILTIN_STX);
12584 d = bdesc_paired_preds;
12585 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12589 switch (insn_data[d->icode].operand[1].mode)
12592 type = int_ftype_int_v2sf_v2sf;
12595 gcc_unreachable ();
12598 def_builtin (d->mask, d->name, type, d->code);
12603 altivec_init_builtins (void)
12605 const struct builtin_description *d;
12606 const struct builtin_description_predicates *dp;
12610 tree pfloat_type_node = build_pointer_type (float_type_node);
12611 tree pint_type_node = build_pointer_type (integer_type_node);
12612 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12613 tree pchar_type_node = build_pointer_type (char_type_node);
12615 tree pvoid_type_node = build_pointer_type (void_type_node);
12617 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12618 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12619 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12620 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12622 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12624 tree int_ftype_opaque
12625 = build_function_type_list (integer_type_node,
12626 opaque_V4SI_type_node, NULL_TREE);
12627 tree opaque_ftype_opaque
12628 = build_function_type (integer_type_node,
12630 tree opaque_ftype_opaque_int
12631 = build_function_type_list (opaque_V4SI_type_node,
12632 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12633 tree opaque_ftype_opaque_opaque_int
12634 = build_function_type_list (opaque_V4SI_type_node,
12635 opaque_V4SI_type_node, opaque_V4SI_type_node,
12636 integer_type_node, NULL_TREE);
12637 tree int_ftype_int_opaque_opaque
12638 = build_function_type_list (integer_type_node,
12639 integer_type_node, opaque_V4SI_type_node,
12640 opaque_V4SI_type_node, NULL_TREE);
12641 tree int_ftype_int_v4si_v4si
12642 = build_function_type_list (integer_type_node,
12643 integer_type_node, V4SI_type_node,
12644 V4SI_type_node, NULL_TREE);
12645 tree v4sf_ftype_pcfloat
12646 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12647 tree void_ftype_pfloat_v4sf
12648 = build_function_type_list (void_type_node,
12649 pfloat_type_node, V4SF_type_node, NULL_TREE);
12650 tree v4si_ftype_pcint
12651 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12652 tree void_ftype_pint_v4si
12653 = build_function_type_list (void_type_node,
12654 pint_type_node, V4SI_type_node, NULL_TREE);
12655 tree v8hi_ftype_pcshort
12656 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12657 tree void_ftype_pshort_v8hi
12658 = build_function_type_list (void_type_node,
12659 pshort_type_node, V8HI_type_node, NULL_TREE);
12660 tree v16qi_ftype_pcchar
12661 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12662 tree void_ftype_pchar_v16qi
12663 = build_function_type_list (void_type_node,
12664 pchar_type_node, V16QI_type_node, NULL_TREE);
12665 tree void_ftype_v4si
12666 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12667 tree v8hi_ftype_void
12668 = build_function_type (V8HI_type_node, void_list_node);
12669 tree void_ftype_void
12670 = build_function_type (void_type_node, void_list_node);
12671 tree void_ftype_int
12672 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12674 tree opaque_ftype_long_pcvoid
12675 = build_function_type_list (opaque_V4SI_type_node,
12676 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12677 tree v16qi_ftype_long_pcvoid
12678 = build_function_type_list (V16QI_type_node,
12679 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12680 tree v8hi_ftype_long_pcvoid
12681 = build_function_type_list (V8HI_type_node,
12682 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12683 tree v4si_ftype_long_pcvoid
12684 = build_function_type_list (V4SI_type_node,
12685 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12687 tree void_ftype_opaque_long_pvoid
12688 = build_function_type_list (void_type_node,
12689 opaque_V4SI_type_node, long_integer_type_node,
12690 pvoid_type_node, NULL_TREE);
12691 tree void_ftype_v4si_long_pvoid
12692 = build_function_type_list (void_type_node,
12693 V4SI_type_node, long_integer_type_node,
12694 pvoid_type_node, NULL_TREE);
12695 tree void_ftype_v16qi_long_pvoid
12696 = build_function_type_list (void_type_node,
12697 V16QI_type_node, long_integer_type_node,
12698 pvoid_type_node, NULL_TREE);
12699 tree void_ftype_v8hi_long_pvoid
12700 = build_function_type_list (void_type_node,
12701 V8HI_type_node, long_integer_type_node,
12702 pvoid_type_node, NULL_TREE);
12703 tree int_ftype_int_v8hi_v8hi
12704 = build_function_type_list (integer_type_node,
12705 integer_type_node, V8HI_type_node,
12706 V8HI_type_node, NULL_TREE);
12707 tree int_ftype_int_v16qi_v16qi
12708 = build_function_type_list (integer_type_node,
12709 integer_type_node, V16QI_type_node,
12710 V16QI_type_node, NULL_TREE);
12711 tree int_ftype_int_v4sf_v4sf
12712 = build_function_type_list (integer_type_node,
12713 integer_type_node, V4SF_type_node,
12714 V4SF_type_node, NULL_TREE);
12715 tree int_ftype_int_v2df_v2df
12716 = build_function_type_list (integer_type_node,
12717 integer_type_node, V2DF_type_node,
12718 V2DF_type_node, NULL_TREE);
12719 tree v4si_ftype_v4si
12720 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12721 tree v8hi_ftype_v8hi
12722 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12723 tree v16qi_ftype_v16qi
12724 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12725 tree v4sf_ftype_v4sf
12726 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12727 tree v2df_ftype_v2df
12728 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12729 tree void_ftype_pcvoid_int_int
12730 = build_function_type_list (void_type_node,
12731 pcvoid_type_node, integer_type_node,
12732 integer_type_node, NULL_TREE);
12734 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12735 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12736 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12737 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12738 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12739 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12740 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12741 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12742 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12743 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12744 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12745 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12746 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12747 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12748 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12749 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12750 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12751 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12752 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12753 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12754 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12755 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12756 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12757 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12758 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12759 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12760 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12761 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12762 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12763 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12764 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12765 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12766 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12767 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12768 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12769 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12770 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12771 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12772 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12773 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12774 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12775 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12776 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12777 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12778 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12779 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12781 if (rs6000_cpu == PROCESSOR_CELL)
12783 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12785 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12788 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12789 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12790 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12791 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12798 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12799 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12800 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12801 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12803 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12804 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12805 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12807 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12808 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12809 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12810 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12811 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12812 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12813 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12814 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12815 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12816 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12817 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12818 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12820 /* Add the DST variants. */
12822 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12823 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12825 /* Initialize the predicates. */
12826 dp = bdesc_altivec_preds;
12827 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12829 enum machine_mode mode1;
12831 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12832 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12833 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12834 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12839 mode1 = insn_data[dp->icode].operand[1].mode;
12844 type = int_ftype_int_opaque_opaque;
12847 type = int_ftype_int_v4si_v4si;
12850 type = int_ftype_int_v8hi_v8hi;
12853 type = int_ftype_int_v16qi_v16qi;
12856 type = int_ftype_int_v4sf_v4sf;
12859 type = int_ftype_int_v2df_v2df;
12862 gcc_unreachable ();
12865 def_builtin (dp->mask, dp->name, type, dp->code);
12868 /* Initialize the abs* operators. */
12870 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12872 enum machine_mode mode0;
12875 mode0 = insn_data[d->icode].operand[0].mode;
12880 type = v4si_ftype_v4si;
12883 type = v8hi_ftype_v8hi;
12886 type = v16qi_ftype_v16qi;
12889 type = v4sf_ftype_v4sf;
12892 type = v2df_ftype_v2df;
12895 gcc_unreachable ();
12898 def_builtin (d->mask, d->name, type, d->code);
12901 if (TARGET_ALTIVEC)
12905 /* Initialize target builtin that implements
12906 targetm.vectorize.builtin_mask_for_load. */
12908 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12909 v16qi_ftype_long_pcvoid,
12910 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12911 BUILT_IN_MD, NULL, NULL_TREE);
12912 TREE_READONLY (decl) = 1;
12913 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12914 altivec_builtin_mask_for_load = decl;
12917 /* Access to the vec_init patterns. */
12918 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12919 integer_type_node, integer_type_node,
12920 integer_type_node, NULL_TREE);
12921 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12922 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12924 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12925 short_integer_type_node,
12926 short_integer_type_node,
12927 short_integer_type_node,
12928 short_integer_type_node,
12929 short_integer_type_node,
12930 short_integer_type_node,
12931 short_integer_type_node, NULL_TREE);
12932 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12933 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12935 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12936 char_type_node, char_type_node,
12937 char_type_node, char_type_node,
12938 char_type_node, char_type_node,
12939 char_type_node, char_type_node,
12940 char_type_node, char_type_node,
12941 char_type_node, char_type_node,
12942 char_type_node, char_type_node,
12943 char_type_node, NULL_TREE);
12944 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12945 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12947 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12948 float_type_node, float_type_node,
12949 float_type_node, NULL_TREE);
12950 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12951 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12955 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12956 double_type_node, NULL_TREE);
12957 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12958 VSX_BUILTIN_VEC_INIT_V2DF);
12960 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12961 intDI_type_node, NULL_TREE);
12962 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12963 VSX_BUILTIN_VEC_INIT_V2DI);
12966 /* Access to the vec_set patterns. */
12967 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12969 integer_type_node, NULL_TREE);
12970 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12971 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12973 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12975 integer_type_node, NULL_TREE);
12976 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12977 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12979 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12981 integer_type_node, NULL_TREE);
12982 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12983 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12985 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12987 integer_type_node, NULL_TREE);
12988 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12989 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12993 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12995 integer_type_node, NULL_TREE);
12996 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12997 VSX_BUILTIN_VEC_SET_V2DF);
12999 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13001 integer_type_node, NULL_TREE);
13002 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13003 VSX_BUILTIN_VEC_SET_V2DI);
13006 /* Access to the vec_extract patterns. */
13007 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13008 integer_type_node, NULL_TREE);
13009 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13010 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13012 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13013 integer_type_node, NULL_TREE);
13014 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13015 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13017 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13018 integer_type_node, NULL_TREE);
13019 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13020 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13022 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13023 integer_type_node, NULL_TREE);
13024 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13025 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13029 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13030 integer_type_node, NULL_TREE);
13031 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13032 VSX_BUILTIN_VEC_EXT_V2DF);
13034 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13035 integer_type_node, NULL_TREE);
13036 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13037 VSX_BUILTIN_VEC_EXT_V2DI);
13041 /* Hash function for builtin functions with up to 3 arguments and a return
13044 builtin_hash_function (const void *hash_entry)
13048 const struct builtin_hash_struct *bh =
13049 (const struct builtin_hash_struct *) hash_entry;
13051 for (i = 0; i < 4; i++)
13053 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13054 ret = (ret * 2) + bh->uns_p[i];
13060 /* Compare builtin hash entries H1 and H2 for equivalence. */
13062 builtin_hash_eq (const void *h1, const void *h2)
13064 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13065 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13067 return ((p1->mode[0] == p2->mode[0])
13068 && (p1->mode[1] == p2->mode[1])
13069 && (p1->mode[2] == p2->mode[2])
13070 && (p1->mode[3] == p2->mode[3])
13071 && (p1->uns_p[0] == p2->uns_p[0])
13072 && (p1->uns_p[1] == p2->uns_p[1])
13073 && (p1->uns_p[2] == p2->uns_p[2])
13074 && (p1->uns_p[3] == p2->uns_p[3]));
13077 /* Map types for builtin functions with an explicit return type and up to 3
13078 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13079 of the argument. */
13081 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13082 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13083 enum rs6000_builtins builtin, const char *name)
13085 struct builtin_hash_struct h;
13086 struct builtin_hash_struct *h2;
13090 tree ret_type = NULL_TREE;
13091 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13094 /* Create builtin_hash_table. */
13095 if (builtin_hash_table == NULL)
13096 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13097 builtin_hash_eq, NULL);
13099 h.type = NULL_TREE;
13100 h.mode[0] = mode_ret;
13101 h.mode[1] = mode_arg0;
13102 h.mode[2] = mode_arg1;
13103 h.mode[3] = mode_arg2;
13109 /* If the builtin is a type that produces unsigned results or takes unsigned
13110 arguments, and it is returned as a decl for the vectorizer (such as
13111 widening multiplies, permute), make sure the arguments and return value
13112 are type correct. */
13115 /* unsigned 2 argument functions. */
13116 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13117 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13118 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13119 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13125 /* unsigned 3 argument functions. */
13126 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13127 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13128 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13129 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13130 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13131 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13132 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13133 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13134 case VSX_BUILTIN_VPERM_16QI_UNS:
13135 case VSX_BUILTIN_VPERM_8HI_UNS:
13136 case VSX_BUILTIN_VPERM_4SI_UNS:
13137 case VSX_BUILTIN_VPERM_2DI_UNS:
13138 case VSX_BUILTIN_XXSEL_16QI_UNS:
13139 case VSX_BUILTIN_XXSEL_8HI_UNS:
13140 case VSX_BUILTIN_XXSEL_4SI_UNS:
13141 case VSX_BUILTIN_XXSEL_2DI_UNS:
13148 /* signed permute functions with unsigned char mask. */
13149 case ALTIVEC_BUILTIN_VPERM_16QI:
13150 case ALTIVEC_BUILTIN_VPERM_8HI:
13151 case ALTIVEC_BUILTIN_VPERM_4SI:
13152 case ALTIVEC_BUILTIN_VPERM_4SF:
13153 case ALTIVEC_BUILTIN_VPERM_2DI:
13154 case ALTIVEC_BUILTIN_VPERM_2DF:
13155 case VSX_BUILTIN_VPERM_16QI:
13156 case VSX_BUILTIN_VPERM_8HI:
13157 case VSX_BUILTIN_VPERM_4SI:
13158 case VSX_BUILTIN_VPERM_4SF:
13159 case VSX_BUILTIN_VPERM_2DI:
13160 case VSX_BUILTIN_VPERM_2DF:
13164 /* unsigned args, signed return. */
13165 case VSX_BUILTIN_XVCVUXDDP_UNS:
13166 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13170 /* signed args, unsigned return. */
13171 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13172 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13180 /* Figure out how many args are present. */
13181 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13185 fatal_error ("internal error: builtin function %s had no type", name);
13187 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13188 if (!ret_type && h.uns_p[0])
13189 ret_type = builtin_mode_to_type[h.mode[0]][0];
13192 fatal_error ("internal error: builtin function %s had an unexpected "
13193 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13195 for (i = 0; i < num_args; i++)
13197 int m = (int) h.mode[i+1];
13198 int uns_p = h.uns_p[i+1];
13200 arg_type[i] = builtin_mode_to_type[m][uns_p];
13201 if (!arg_type[i] && uns_p)
13202 arg_type[i] = builtin_mode_to_type[m][0];
13205 fatal_error ("internal error: builtin function %s, argument %d "
13206 "had unexpected argument type %s", name, i,
13207 GET_MODE_NAME (m));
13210 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13211 if (*found == NULL)
13213 h2 = ggc_alloc_builtin_hash_struct ();
13215 *found = (void *)h2;
13216 args = void_list_node;
13218 for (i = num_args - 1; i >= 0; i--)
13219 args = tree_cons (NULL_TREE, arg_type[i], args);
13221 h2->type = build_function_type (ret_type, args);
13224 return ((struct builtin_hash_struct *)(*found))->type;
13228 rs6000_common_init_builtins (void)
13230 const struct builtin_description *d;
13233 tree opaque_ftype_opaque = NULL_TREE;
13234 tree opaque_ftype_opaque_opaque = NULL_TREE;
13235 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13236 tree v2si_ftype_qi = NULL_TREE;
13237 tree v2si_ftype_v2si_qi = NULL_TREE;
13238 tree v2si_ftype_int_qi = NULL_TREE;
13240 if (!TARGET_PAIRED_FLOAT)
13242 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13243 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13246 /* Add the ternary operators. */
13248 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13251 int mask = d->mask;
13253 if ((mask != 0 && (mask & target_flags) == 0)
13254 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13257 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13258 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13259 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13260 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13262 if (! (type = opaque_ftype_opaque_opaque_opaque))
13263 type = opaque_ftype_opaque_opaque_opaque
13264 = build_function_type_list (opaque_V4SI_type_node,
13265 opaque_V4SI_type_node,
13266 opaque_V4SI_type_node,
13267 opaque_V4SI_type_node,
13272 enum insn_code icode = d->icode;
13273 if (d->name == 0 || icode == CODE_FOR_nothing)
13276 type = builtin_function_type (insn_data[icode].operand[0].mode,
13277 insn_data[icode].operand[1].mode,
13278 insn_data[icode].operand[2].mode,
13279 insn_data[icode].operand[3].mode,
13283 def_builtin (d->mask, d->name, type, d->code);
13286 /* Add the binary operators. */
13288 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13290 enum machine_mode mode0, mode1, mode2;
13292 int mask = d->mask;
13294 if ((mask != 0 && (mask & target_flags) == 0)
13295 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13298 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13299 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13300 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13301 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13303 if (! (type = opaque_ftype_opaque_opaque))
13304 type = opaque_ftype_opaque_opaque
13305 = build_function_type_list (opaque_V4SI_type_node,
13306 opaque_V4SI_type_node,
13307 opaque_V4SI_type_node,
13312 enum insn_code icode = d->icode;
13313 if (d->name == 0 || icode == CODE_FOR_nothing)
13316 mode0 = insn_data[icode].operand[0].mode;
13317 mode1 = insn_data[icode].operand[1].mode;
13318 mode2 = insn_data[icode].operand[2].mode;
13320 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13322 if (! (type = v2si_ftype_v2si_qi))
13323 type = v2si_ftype_v2si_qi
13324 = build_function_type_list (opaque_V2SI_type_node,
13325 opaque_V2SI_type_node,
13330 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13331 && mode2 == QImode)
13333 if (! (type = v2si_ftype_int_qi))
13334 type = v2si_ftype_int_qi
13335 = build_function_type_list (opaque_V2SI_type_node,
13342 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13346 def_builtin (d->mask, d->name, type, d->code);
13349 /* Add the simple unary operators. */
13350 d = (struct builtin_description *) bdesc_1arg;
13351 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13353 enum machine_mode mode0, mode1;
13355 int mask = d->mask;
13357 if ((mask != 0 && (mask & target_flags) == 0)
13358 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13361 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13362 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13363 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13364 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13366 if (! (type = opaque_ftype_opaque))
13367 type = opaque_ftype_opaque
13368 = build_function_type_list (opaque_V4SI_type_node,
13369 opaque_V4SI_type_node,
13374 enum insn_code icode = d->icode;
13375 if (d->name == 0 || icode == CODE_FOR_nothing)
13378 mode0 = insn_data[icode].operand[0].mode;
13379 mode1 = insn_data[icode].operand[1].mode;
13381 if (mode0 == V2SImode && mode1 == QImode)
13383 if (! (type = v2si_ftype_qi))
13384 type = v2si_ftype_qi
13385 = build_function_type_list (opaque_V2SI_type_node,
13391 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13395 def_builtin (d->mask, d->name, type, d->code);
13400 rs6000_init_libfuncs (void)
13402 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13403 && !TARGET_POWER2 && !TARGET_POWERPC)
13405 /* AIX library routines for float->int conversion. */
13406 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13407 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13408 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13409 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13412 if (!TARGET_IEEEQUAD)
13413 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13414 if (!TARGET_XL_COMPAT)
13416 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13417 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13418 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13419 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13421 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13423 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13424 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13425 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13426 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13427 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13428 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13429 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13431 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13432 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13433 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13434 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13435 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13436 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13437 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13438 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13441 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13442 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13446 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13447 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13448 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13449 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13453 /* 32-bit SVR4 quad floating point routines. */
13455 set_optab_libfunc (add_optab, TFmode, "_q_add");
13456 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13457 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13458 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13459 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13460 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13461 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13463 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13464 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13465 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13466 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13467 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13468 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13470 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13471 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13472 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13473 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13474 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13475 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13476 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13477 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13482 /* Expand a block clear operation, and return 1 if successful. Return 0
13483 if we should let the compiler generate normal code.
13485 operands[0] is the destination
13486 operands[1] is the length
13487 operands[3] is the alignment */
13490 expand_block_clear (rtx operands[])
13492 rtx orig_dest = operands[0];
13493 rtx bytes_rtx = operands[1];
13494 rtx align_rtx = operands[3];
13495 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13496 HOST_WIDE_INT align;
13497 HOST_WIDE_INT bytes;
13502 /* If this is not a fixed size move, just call memcpy */
13506 /* This must be a fixed size alignment */
13507 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13508 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13510 /* Anything to clear? */
13511 bytes = INTVAL (bytes_rtx);
13515 /* Use the builtin memset after a point, to avoid huge code bloat.
13516 When optimize_size, avoid any significant code bloat; calling
13517 memset is about 4 instructions, so allow for one instruction to
13518 load zero and three to do clearing. */
13519 if (TARGET_ALTIVEC && align >= 128)
13521 else if (TARGET_POWERPC64 && align >= 32)
13523 else if (TARGET_SPE && align >= 64)
13528 if (optimize_size && bytes > 3 * clear_step)
13530 if (! optimize_size && bytes > 8 * clear_step)
13533 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13535 enum machine_mode mode = BLKmode;
13538 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13543 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13548 else if (bytes >= 8 && TARGET_POWERPC64
13549 /* 64-bit loads and stores require word-aligned
13551 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13556 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13557 { /* move 4 bytes */
13561 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13562 { /* move 2 bytes */
13566 else /* move 1 byte at a time */
13572 dest = adjust_address (orig_dest, mode, offset);
13574 emit_move_insn (dest, CONST0_RTX (mode));
13581 /* Expand a block move operation, and return 1 if successful. Return 0
13582 if we should let the compiler generate normal code.
13584 operands[0] is the destination
13585 operands[1] is the source
13586 operands[2] is the length
13587 operands[3] is the alignment */
13589 #define MAX_MOVE_REG 4
13592 expand_block_move (rtx operands[])
13594 rtx orig_dest = operands[0];
13595 rtx orig_src = operands[1];
13596 rtx bytes_rtx = operands[2];
13597 rtx align_rtx = operands[3];
13598 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13603 rtx stores[MAX_MOVE_REG];
13606 /* If this is not a fixed size move, just call memcpy */
13610 /* This must be a fixed size alignment */
13611 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13612 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13614 /* Anything to move? */
13615 bytes = INTVAL (bytes_rtx);
13619 if (bytes > rs6000_block_move_inline_limit)
13622 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13625 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13626 rtx (*mov) (rtx, rtx);
13628 enum machine_mode mode = BLKmode;
13631 /* Altivec first, since it will be faster than a string move
13632 when it applies, and usually not significantly larger. */
13633 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13637 gen_func.mov = gen_movv4si;
13639 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13643 gen_func.mov = gen_movv2si;
13645 else if (TARGET_STRING
13646 && bytes > 24 /* move up to 32 bytes at a time */
13652 && ! fixed_regs[10]
13653 && ! fixed_regs[11]
13654 && ! fixed_regs[12])
13656 move_bytes = (bytes > 32) ? 32 : bytes;
13657 gen_func.movmemsi = gen_movmemsi_8reg;
13659 else if (TARGET_STRING
13660 && bytes > 16 /* move up to 24 bytes at a time */
13666 && ! fixed_regs[10])
13668 move_bytes = (bytes > 24) ? 24 : bytes;
13669 gen_func.movmemsi = gen_movmemsi_6reg;
13671 else if (TARGET_STRING
13672 && bytes > 8 /* move up to 16 bytes at a time */
13676 && ! fixed_regs[8])
13678 move_bytes = (bytes > 16) ? 16 : bytes;
13679 gen_func.movmemsi = gen_movmemsi_4reg;
13681 else if (bytes >= 8 && TARGET_POWERPC64
13682 /* 64-bit loads and stores require word-aligned
13684 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13688 gen_func.mov = gen_movdi;
13690 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13691 { /* move up to 8 bytes at a time */
13692 move_bytes = (bytes > 8) ? 8 : bytes;
13693 gen_func.movmemsi = gen_movmemsi_2reg;
13695 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13696 { /* move 4 bytes */
13699 gen_func.mov = gen_movsi;
13701 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13702 { /* move 2 bytes */
13705 gen_func.mov = gen_movhi;
13707 else if (TARGET_STRING && bytes > 1)
13708 { /* move up to 4 bytes at a time */
13709 move_bytes = (bytes > 4) ? 4 : bytes;
13710 gen_func.movmemsi = gen_movmemsi_1reg;
13712 else /* move 1 byte at a time */
13716 gen_func.mov = gen_movqi;
13719 src = adjust_address (orig_src, mode, offset);
13720 dest = adjust_address (orig_dest, mode, offset);
13722 if (mode != BLKmode)
13724 rtx tmp_reg = gen_reg_rtx (mode);
13726 emit_insn ((*gen_func.mov) (tmp_reg, src));
13727 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13730 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13733 for (i = 0; i < num_reg; i++)
13734 emit_insn (stores[i]);
13738 if (mode == BLKmode)
13740 /* Move the address into scratch registers. The movmemsi
13741 patterns require zero offset. */
13742 if (!REG_P (XEXP (src, 0)))
13744 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13745 src = replace_equiv_address (src, src_reg);
13747 set_mem_size (src, GEN_INT (move_bytes));
13749 if (!REG_P (XEXP (dest, 0)))
13751 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13752 dest = replace_equiv_address (dest, dest_reg);
13754 set_mem_size (dest, GEN_INT (move_bytes));
13756 emit_insn ((*gen_func.movmemsi) (dest, src,
13757 GEN_INT (move_bytes & 31),
13766 /* Return a string to perform a load_multiple operation.
13767 operands[0] is the vector.
13768 operands[1] is the source address.
13769 operands[2] is the first destination register. */
13772 rs6000_output_load_multiple (rtx operands[3])
13774 /* We have to handle the case where the pseudo used to contain the address
13775 is assigned to one of the output registers. */
13777 int words = XVECLEN (operands[0], 0);
13780 if (XVECLEN (operands[0], 0) == 1)
13781 return "{l|lwz} %2,0(%1)";
13783 for (i = 0; i < words; i++)
13784 if (refers_to_regno_p (REGNO (operands[2]) + i,
13785 REGNO (operands[2]) + i + 1, operands[1], 0))
13789 xop[0] = GEN_INT (4 * (words-1));
13790 xop[1] = operands[1];
13791 xop[2] = operands[2];
13792 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13797 xop[0] = GEN_INT (4 * (words-1));
13798 xop[1] = operands[1];
13799 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13800 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);
13805 for (j = 0; j < words; j++)
13808 xop[0] = GEN_INT (j * 4);
13809 xop[1] = operands[1];
13810 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13811 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13813 xop[0] = GEN_INT (i * 4);
13814 xop[1] = operands[1];
13815 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13820 return "{lsi|lswi} %2,%1,%N0";
13824 /* A validation routine: say whether CODE, a condition code, and MODE
13825 match. The other alternatives either don't make sense or should
13826 never be generated. */
13829 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13831 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13832 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13833 && GET_MODE_CLASS (mode) == MODE_CC);
13835 /* These don't make sense. */
13836 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13837 || mode != CCUNSmode);
13839 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13840 || mode == CCUNSmode);
13842 gcc_assert (mode == CCFPmode
13843 || (code != ORDERED && code != UNORDERED
13844 && code != UNEQ && code != LTGT
13845 && code != UNGT && code != UNLT
13846 && code != UNGE && code != UNLE));
13848 /* These should never be generated except for
13849 flag_finite_math_only. */
13850 gcc_assert (mode != CCFPmode
13851 || flag_finite_math_only
13852 || (code != LE && code != GE
13853 && code != UNEQ && code != LTGT
13854 && code != UNGT && code != UNLT));
13856 /* These are invalid; the information is not there. */
13857 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13861 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13862 mask required to convert the result of a rotate insn into a shift
13863 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13866 includes_lshift_p (rtx shiftop, rtx andop)
13868 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13870 shift_mask <<= INTVAL (shiftop);
13872 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13875 /* Similar, but for right shift. */
13878 includes_rshift_p (rtx shiftop, rtx andop)
13880 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13882 shift_mask >>= INTVAL (shiftop);
13884 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13887 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13888 to perform a left shift. It must have exactly SHIFTOP least
13889 significant 0's, then one or more 1's, then zero or more 0's. */
13892 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13894 if (GET_CODE (andop) == CONST_INT)
13896 HOST_WIDE_INT c, lsb, shift_mask;
13898 c = INTVAL (andop);
13899 if (c == 0 || c == ~0)
13903 shift_mask <<= INTVAL (shiftop);
13905 /* Find the least significant one bit. */
13908 /* It must coincide with the LSB of the shift mask. */
13909 if (-lsb != shift_mask)
13912 /* Invert to look for the next transition (if any). */
13915 /* Remove the low group of ones (originally low group of zeros). */
13918 /* Again find the lsb, and check we have all 1's above. */
13922 else if (GET_CODE (andop) == CONST_DOUBLE
13923 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13925 HOST_WIDE_INT low, high, lsb;
13926 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13928 low = CONST_DOUBLE_LOW (andop);
13929 if (HOST_BITS_PER_WIDE_INT < 64)
13930 high = CONST_DOUBLE_HIGH (andop);
13932 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13933 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13936 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13938 shift_mask_high = ~0;
13939 if (INTVAL (shiftop) > 32)
13940 shift_mask_high <<= INTVAL (shiftop) - 32;
13942 lsb = high & -high;
13944 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13950 lsb = high & -high;
13951 return high == -lsb;
13954 shift_mask_low = ~0;
13955 shift_mask_low <<= INTVAL (shiftop);
13959 if (-lsb != shift_mask_low)
13962 if (HOST_BITS_PER_WIDE_INT < 64)
13967 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13969 lsb = high & -high;
13970 return high == -lsb;
13974 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13980 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13981 to perform a left shift. It must have SHIFTOP or more least
13982 significant 0's, with the remainder of the word 1's. */
13985 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13987 if (GET_CODE (andop) == CONST_INT)
13989 HOST_WIDE_INT c, lsb, shift_mask;
13992 shift_mask <<= INTVAL (shiftop);
13993 c = INTVAL (andop);
13995 /* Find the least significant one bit. */
13998 /* It must be covered by the shift mask.
13999 This test also rejects c == 0. */
14000 if ((lsb & shift_mask) == 0)
14003 /* Check we have all 1's above the transition, and reject all 1's. */
14004 return c == -lsb && lsb != 1;
14006 else if (GET_CODE (andop) == CONST_DOUBLE
14007 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14009 HOST_WIDE_INT low, lsb, shift_mask_low;
14011 low = CONST_DOUBLE_LOW (andop);
14013 if (HOST_BITS_PER_WIDE_INT < 64)
14015 HOST_WIDE_INT high, shift_mask_high;
14017 high = CONST_DOUBLE_HIGH (andop);
14021 shift_mask_high = ~0;
14022 if (INTVAL (shiftop) > 32)
14023 shift_mask_high <<= INTVAL (shiftop) - 32;
14025 lsb = high & -high;
14027 if ((lsb & shift_mask_high) == 0)
14030 return high == -lsb;
14036 shift_mask_low = ~0;
14037 shift_mask_low <<= INTVAL (shiftop);
14041 if ((lsb & shift_mask_low) == 0)
14044 return low == -lsb && lsb != 1;
14050 /* Return 1 if operands will generate a valid arguments to rlwimi
14051 instruction for insert with right shift in 64-bit mode. The mask may
14052 not start on the first bit or stop on the last bit because wrap-around
14053 effects of instruction do not correspond to semantics of RTL insn. */
14056 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14058 if (INTVAL (startop) > 32
14059 && INTVAL (startop) < 64
14060 && INTVAL (sizeop) > 1
14061 && INTVAL (sizeop) + INTVAL (startop) < 64
14062 && INTVAL (shiftop) > 0
14063 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14064 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14070 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14071 for lfq and stfq insns iff the registers are hard registers. */
14074 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14076 /* We might have been passed a SUBREG. */
14077 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14080 /* We might have been passed non floating point registers. */
14081 if (!FP_REGNO_P (REGNO (reg1))
14082 || !FP_REGNO_P (REGNO (reg2)))
14085 return (REGNO (reg1) == REGNO (reg2) - 1);
14088 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14089 addr1 and addr2 must be in consecutive memory locations
14090 (addr2 == addr1 + 8). */
14093 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14096 unsigned int reg1, reg2;
14097 int offset1, offset2;
14099 /* The mems cannot be volatile. */
14100 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14103 addr1 = XEXP (mem1, 0);
14104 addr2 = XEXP (mem2, 0);
14106 /* Extract an offset (if used) from the first addr. */
14107 if (GET_CODE (addr1) == PLUS)
14109 /* If not a REG, return zero. */
14110 if (GET_CODE (XEXP (addr1, 0)) != REG)
14114 reg1 = REGNO (XEXP (addr1, 0));
14115 /* The offset must be constant! */
14116 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14118 offset1 = INTVAL (XEXP (addr1, 1));
14121 else if (GET_CODE (addr1) != REG)
14125 reg1 = REGNO (addr1);
14126 /* This was a simple (mem (reg)) expression. Offset is 0. */
14130 /* And now for the second addr. */
14131 if (GET_CODE (addr2) == PLUS)
14133 /* If not a REG, return zero. */
14134 if (GET_CODE (XEXP (addr2, 0)) != REG)
14138 reg2 = REGNO (XEXP (addr2, 0));
14139 /* The offset must be constant. */
14140 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14142 offset2 = INTVAL (XEXP (addr2, 1));
14145 else if (GET_CODE (addr2) != REG)
14149 reg2 = REGNO (addr2);
14150 /* This was a simple (mem (reg)) expression. Offset is 0. */
14154 /* Both of these must have the same base register. */
14158 /* The offset for the second addr must be 8 more than the first addr. */
14159 if (offset2 != offset1 + 8)
14162 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14169 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14171 static bool eliminated = false;
14174 if (mode != SDmode)
14175 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14178 rtx mem = cfun->machine->sdmode_stack_slot;
14179 gcc_assert (mem != NULL_RTX);
14183 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14184 cfun->machine->sdmode_stack_slot = mem;
14190 if (TARGET_DEBUG_ADDR)
14192 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14193 GET_MODE_NAME (mode));
14195 fprintf (stderr, "\tNULL_RTX\n");
14204 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14206 /* Don't walk into types. */
14207 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14209 *walk_subtrees = 0;
14213 switch (TREE_CODE (*tp))
14222 case VIEW_CONVERT_EXPR:
14223 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14233 enum reload_reg_type {
14235 VECTOR_REGISTER_TYPE,
14236 OTHER_REGISTER_TYPE
14239 static enum reload_reg_type
14240 rs6000_reload_register_type (enum reg_class rclass)
14246 return GPR_REGISTER_TYPE;
14251 return VECTOR_REGISTER_TYPE;
14254 return OTHER_REGISTER_TYPE;
14258 /* Inform reload about cases where moving X with a mode MODE to a register in
14259 RCLASS requires an extra scratch or immediate register. Return the class
14260 needed for the immediate register.
14262 For VSX and Altivec, we may need a register to convert sp+offset into
14266 rs6000_secondary_reload (bool in_p,
14268 reg_class_t rclass_i,
14269 enum machine_mode mode,
14270 secondary_reload_info *sri)
14272 enum reg_class rclass = (enum reg_class) rclass_i;
14273 reg_class_t ret = ALL_REGS;
14274 enum insn_code icode;
14275 bool default_p = false;
14277 sri->icode = CODE_FOR_nothing;
14279 /* Convert vector loads and stores into gprs to use an additional base
14281 icode = rs6000_vector_reload[mode][in_p != false];
14282 if (icode != CODE_FOR_nothing)
14285 sri->icode = CODE_FOR_nothing;
14286 sri->extra_cost = 0;
14288 if (GET_CODE (x) == MEM)
14290 rtx addr = XEXP (x, 0);
14292 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14293 an extra register in that case, but it would need an extra
14294 register if the addressing is reg+reg or (reg+reg)&(-16). */
14295 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14297 if (!legitimate_indirect_address_p (addr, false)
14298 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14300 sri->icode = icode;
14301 /* account for splitting the loads, and converting the
14302 address from reg+reg to reg. */
14303 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14304 + ((GET_CODE (addr) == AND) ? 1 : 0));
14307 /* Loads to and stores from vector registers can only do reg+reg
14308 addressing. Altivec registers can also do (reg+reg)&(-16). */
14309 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14310 || rclass == FLOAT_REGS || rclass == NO_REGS)
14312 if (!VECTOR_MEM_ALTIVEC_P (mode)
14313 && GET_CODE (addr) == AND
14314 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14315 && INTVAL (XEXP (addr, 1)) == -16
14316 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14317 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14319 sri->icode = icode;
14320 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14323 else if (!legitimate_indirect_address_p (addr, false)
14324 && (rclass == NO_REGS
14325 || !legitimate_indexed_address_p (addr, false)))
14327 sri->icode = icode;
14328 sri->extra_cost = 1;
14331 icode = CODE_FOR_nothing;
14333 /* Any other loads, including to pseudo registers which haven't been
14334 assigned to a register yet, default to require a scratch
14338 sri->icode = icode;
14339 sri->extra_cost = 2;
14342 else if (REG_P (x))
14344 int regno = true_regnum (x);
14346 icode = CODE_FOR_nothing;
14347 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14351 enum reg_class xclass = REGNO_REG_CLASS (regno);
14352 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14353 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14355 /* If memory is needed, use default_secondary_reload to create the
14357 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14370 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14372 gcc_assert (ret != ALL_REGS);
14374 if (TARGET_DEBUG_ADDR)
14377 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14379 reg_class_names[ret],
14380 in_p ? "true" : "false",
14381 reg_class_names[rclass],
14382 GET_MODE_NAME (mode));
14385 fprintf (stderr, ", default secondary reload");
14387 if (sri->icode != CODE_FOR_nothing)
14388 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14389 insn_data[sri->icode].name, sri->extra_cost);
14391 fprintf (stderr, "\n");
14399 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14400 to SP+reg addressing. */
14403 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14405 int regno = true_regnum (reg);
14406 enum machine_mode mode = GET_MODE (reg);
14407 enum reg_class rclass;
14409 rtx and_op2 = NULL_RTX;
14412 rtx scratch_or_premodify = scratch;
14416 if (TARGET_DEBUG_ADDR)
14418 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14419 store_p ? "store" : "load");
14420 fprintf (stderr, "reg:\n");
14422 fprintf (stderr, "mem:\n");
14424 fprintf (stderr, "scratch:\n");
14425 debug_rtx (scratch);
14428 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14429 gcc_assert (GET_CODE (mem) == MEM);
14430 rclass = REGNO_REG_CLASS (regno);
14431 addr = XEXP (mem, 0);
14435 /* GPRs can handle reg + small constant, all other addresses need to use
14436 the scratch register. */
14439 if (GET_CODE (addr) == AND)
14441 and_op2 = XEXP (addr, 1);
14442 addr = XEXP (addr, 0);
14445 if (GET_CODE (addr) == PRE_MODIFY)
14447 scratch_or_premodify = XEXP (addr, 0);
14448 gcc_assert (REG_P (scratch_or_premodify));
14449 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14450 addr = XEXP (addr, 1);
14453 if (GET_CODE (addr) == PLUS
14454 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14455 || and_op2 != NULL_RTX))
14457 addr_op1 = XEXP (addr, 0);
14458 addr_op2 = XEXP (addr, 1);
14459 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14461 if (!REG_P (addr_op2)
14462 && (GET_CODE (addr_op2) != CONST_INT
14463 || !satisfies_constraint_I (addr_op2)))
14465 if (TARGET_DEBUG_ADDR)
14468 "\nMove plus addr to register %s, mode = %s: ",
14469 rs6000_reg_names[REGNO (scratch)],
14470 GET_MODE_NAME (mode));
14471 debug_rtx (addr_op2);
14473 rs6000_emit_move (scratch, addr_op2, Pmode);
14474 addr_op2 = scratch;
14477 emit_insn (gen_rtx_SET (VOIDmode,
14478 scratch_or_premodify,
14479 gen_rtx_PLUS (Pmode,
14483 addr = scratch_or_premodify;
14484 scratch_or_premodify = scratch;
14486 else if (!legitimate_indirect_address_p (addr, false)
14487 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14489 if (TARGET_DEBUG_ADDR)
14491 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14492 rs6000_reg_names[REGNO (scratch_or_premodify)],
14493 GET_MODE_NAME (mode));
14496 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14497 addr = scratch_or_premodify;
14498 scratch_or_premodify = scratch;
14502 /* Float/Altivec registers can only handle reg+reg addressing. Move
14503 other addresses into a scratch register. */
14508 /* With float regs, we need to handle the AND ourselves, since we can't
14509 use the Altivec instruction with an implicit AND -16. Allow scalar
14510 loads to float registers to use reg+offset even if VSX. */
14511 if (GET_CODE (addr) == AND
14512 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14513 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14514 || INTVAL (XEXP (addr, 1)) != -16
14515 || !VECTOR_MEM_ALTIVEC_P (mode)))
14517 and_op2 = XEXP (addr, 1);
14518 addr = XEXP (addr, 0);
14521 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14522 as the address later. */
14523 if (GET_CODE (addr) == PRE_MODIFY
14524 && (!VECTOR_MEM_VSX_P (mode)
14525 || and_op2 != NULL_RTX
14526 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14528 scratch_or_premodify = XEXP (addr, 0);
14529 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14531 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14532 addr = XEXP (addr, 1);
14535 if (legitimate_indirect_address_p (addr, false) /* reg */
14536 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14537 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14538 || (GET_CODE (addr) == AND /* Altivec memory */
14539 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14540 && INTVAL (XEXP (addr, 1)) == -16
14541 && VECTOR_MEM_ALTIVEC_P (mode))
14542 || (rclass == FLOAT_REGS /* legacy float mem */
14543 && GET_MODE_SIZE (mode) == 8
14544 && and_op2 == NULL_RTX
14545 && scratch_or_premodify == scratch
14546 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14549 else if (GET_CODE (addr) == PLUS)
14551 addr_op1 = XEXP (addr, 0);
14552 addr_op2 = XEXP (addr, 1);
14553 gcc_assert (REG_P (addr_op1));
14555 if (TARGET_DEBUG_ADDR)
14557 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14558 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14559 debug_rtx (addr_op2);
14561 rs6000_emit_move (scratch, addr_op2, Pmode);
14562 emit_insn (gen_rtx_SET (VOIDmode,
14563 scratch_or_premodify,
14564 gen_rtx_PLUS (Pmode,
14567 addr = scratch_or_premodify;
14568 scratch_or_premodify = scratch;
14571 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14572 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14574 if (TARGET_DEBUG_ADDR)
14576 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14577 rs6000_reg_names[REGNO (scratch_or_premodify)],
14578 GET_MODE_NAME (mode));
14582 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14583 addr = scratch_or_premodify;
14584 scratch_or_premodify = scratch;
14588 gcc_unreachable ();
14593 gcc_unreachable ();
14596 /* If the original address involved a pre-modify that we couldn't use the VSX
14597 memory instruction with update, and we haven't taken care of already,
14598 store the address in the pre-modify register and use that as the
14600 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14602 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14603 addr = scratch_or_premodify;
14606 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14607 memory instruction, recreate the AND now, including the clobber which is
14608 generated by the general ANDSI3/ANDDI3 patterns for the
14609 andi. instruction. */
14610 if (and_op2 != NULL_RTX)
14612 if (! legitimate_indirect_address_p (addr, false))
14614 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14618 if (TARGET_DEBUG_ADDR)
14620 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14621 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14622 debug_rtx (and_op2);
14625 and_rtx = gen_rtx_SET (VOIDmode,
14627 gen_rtx_AND (Pmode,
14631 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14632 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14633 gen_rtvec (2, and_rtx, cc_clobber)));
14637 /* Adjust the address if it changed. */
14638 if (addr != XEXP (mem, 0))
14640 mem = change_address (mem, mode, addr);
14641 if (TARGET_DEBUG_ADDR)
14642 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14645 /* Now create the move. */
14647 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14649 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14654 /* Target hook to return the cover classes for Integrated Register Allocator.
14655 Cover classes is a set of non-intersected register classes covering all hard
14656 registers used for register allocation purpose. Any move between two
14657 registers of a cover class should be cheaper than load or store of the
14658 registers. The value is array of register classes with LIM_REG_CLASSES used
14661 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14662 account for the Altivec and Floating registers being subsets of the VSX
14663 register set under VSX, but distinct register sets on pre-VSX machines. */
14665 static const reg_class_t *
14666 rs6000_ira_cover_classes (void)
14668 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14669 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14671 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14674 /* Allocate a 64-bit stack slot to be used for copying SDmode
14675 values through if this function has any SDmode references. */
14678 rs6000_alloc_sdmode_stack_slot (void)
14682 gimple_stmt_iterator gsi;
14684 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14687 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14689 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14692 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14693 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14699 /* Check for any SDmode parameters of the function. */
14700 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14702 if (TREE_TYPE (t) == error_mark_node)
14705 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14706 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14708 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14709 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14717 rs6000_instantiate_decls (void)
14719 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14720 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14723 /* Given an rtx X being reloaded into a reg required to be
14724 in class CLASS, return the class of reg to actually use.
14725 In general this is just CLASS; but on some machines
14726 in some cases it is preferable to use a more restrictive class.
14728 On the RS/6000, we have to return NO_REGS when we want to reload a
14729 floating-point CONST_DOUBLE to force it to be copied to memory.
14731 We also don't want to reload integer values into floating-point
14732 registers if we can at all help it. In fact, this can
14733 cause reload to die, if it tries to generate a reload of CTR
14734 into a FP register and discovers it doesn't have the memory location
14737 ??? Would it be a good idea to have reload do the converse, that is
14738 try to reload floating modes into FP registers if possible?
14741 static enum reg_class
14742 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14744 enum machine_mode mode = GET_MODE (x);
14746 if (VECTOR_UNIT_VSX_P (mode)
14747 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14750 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14751 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14752 && easy_vector_constant (x, mode))
14753 return ALTIVEC_REGS;
14755 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14758 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14759 return GENERAL_REGS;
14761 /* For VSX, prefer the traditional registers for 64-bit values because we can
14762 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14763 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14764 prefer Altivec loads.. */
14765 if (rclass == VSX_REGS)
14767 if (GET_MODE_SIZE (mode) <= 8)
14770 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14771 return ALTIVEC_REGS;
14779 /* Debug version of rs6000_preferred_reload_class. */
14780 static enum reg_class
14781 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14783 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14786 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14788 reg_class_names[ret], reg_class_names[rclass],
14789 GET_MODE_NAME (GET_MODE (x)));
14795 /* If we are copying between FP or AltiVec registers and anything else, we need
14796 a memory location. The exception is when we are targeting ppc64 and the
14797 move to/from fpr to gpr instructions are available. Also, under VSX, you
14798 can copy vector registers from the FP register set to the Altivec register
14799 set and vice versa. */
14802 rs6000_secondary_memory_needed (enum reg_class class1,
14803 enum reg_class class2,
14804 enum machine_mode mode)
14806 if (class1 == class2)
14809 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14810 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14811 between these classes. But we need memory for other things that can go in
14812 FLOAT_REGS like SFmode. */
14814 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14815 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14816 || class1 == FLOAT_REGS))
14817 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14818 && class2 != FLOAT_REGS);
14820 if (class1 == VSX_REGS || class2 == VSX_REGS)
14823 if (class1 == FLOAT_REGS
14824 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14825 || ((mode != DFmode)
14826 && (mode != DDmode)
14827 && (mode != DImode))))
14830 if (class2 == FLOAT_REGS
14831 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14832 || ((mode != DFmode)
14833 && (mode != DDmode)
14834 && (mode != DImode))))
14837 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14843 /* Debug version of rs6000_secondary_memory_needed. */
14845 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14846 enum reg_class class2,
14847 enum machine_mode mode)
14849 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14852 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14853 "class2 = %s, mode = %s\n",
14854 ret ? "true" : "false", reg_class_names[class1],
14855 reg_class_names[class2], GET_MODE_NAME (mode));
14860 /* Return the register class of a scratch register needed to copy IN into
14861 or out of a register in RCLASS in MODE. If it can be done directly,
14862 NO_REGS is returned. */
14864 static enum reg_class
14865 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14870 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14872 && MACHOPIC_INDIRECT
14876 /* We cannot copy a symbolic operand directly into anything
14877 other than BASE_REGS for TARGET_ELF. So indicate that a
14878 register from BASE_REGS is needed as an intermediate
14881 On Darwin, pic addresses require a load from memory, which
14882 needs a base register. */
14883 if (rclass != BASE_REGS
14884 && (GET_CODE (in) == SYMBOL_REF
14885 || GET_CODE (in) == HIGH
14886 || GET_CODE (in) == LABEL_REF
14887 || GET_CODE (in) == CONST))
14891 if (GET_CODE (in) == REG)
14893 regno = REGNO (in);
14894 if (regno >= FIRST_PSEUDO_REGISTER)
14896 regno = true_regnum (in);
14897 if (regno >= FIRST_PSEUDO_REGISTER)
14901 else if (GET_CODE (in) == SUBREG)
14903 regno = true_regnum (in);
14904 if (regno >= FIRST_PSEUDO_REGISTER)
14910 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14912 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14913 || (regno >= 0 && INT_REGNO_P (regno)))
14916 /* Constants, memory, and FP registers can go into FP registers. */
14917 if ((regno == -1 || FP_REGNO_P (regno))
14918 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14919 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14921 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14924 && (regno == -1 || VSX_REGNO_P (regno))
14925 && VSX_REG_CLASS_P (rclass))
14928 /* Memory, and AltiVec registers can go into AltiVec registers. */
14929 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14930 && rclass == ALTIVEC_REGS)
14933 /* We can copy among the CR registers. */
14934 if ((rclass == CR_REGS || rclass == CR0_REGS)
14935 && regno >= 0 && CR_REGNO_P (regno))
14938 /* Otherwise, we need GENERAL_REGS. */
14939 return GENERAL_REGS;
14942 /* Debug version of rs6000_secondary_reload_class. */
14943 static enum reg_class
14944 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14945 enum machine_mode mode, rtx in)
14947 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14949 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14950 "mode = %s, input rtx:\n",
14951 reg_class_names[ret], reg_class_names[rclass],
14952 GET_MODE_NAME (mode));
14958 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14961 rs6000_cannot_change_mode_class (enum machine_mode from,
14962 enum machine_mode to,
14963 enum reg_class rclass)
14965 unsigned from_size = GET_MODE_SIZE (from);
14966 unsigned to_size = GET_MODE_SIZE (to);
14968 if (from_size != to_size)
14970 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14971 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14972 && reg_classes_intersect_p (xclass, rclass));
14975 if (TARGET_E500_DOUBLE
14976 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14977 || (((to) == TFmode) + ((from) == TFmode)) == 1
14978 || (((to) == DDmode) + ((from) == DDmode)) == 1
14979 || (((to) == TDmode) + ((from) == TDmode)) == 1
14980 || (((to) == DImode) + ((from) == DImode)) == 1))
14983 /* Since the VSX register set includes traditional floating point registers
14984 and altivec registers, just check for the size being different instead of
14985 trying to check whether the modes are vector modes. Otherwise it won't
14986 allow say DF and DI to change classes. */
14987 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14988 return (from_size != 8 && from_size != 16);
14990 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14991 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14994 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14995 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15001 /* Debug version of rs6000_cannot_change_mode_class. */
15003 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15004 enum machine_mode to,
15005 enum reg_class rclass)
15007 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15010 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15011 "to = %s, rclass = %s\n",
15012 ret ? "true" : "false",
15013 GET_MODE_NAME (from), GET_MODE_NAME (to),
15014 reg_class_names[rclass]);
15019 /* Given a comparison operation, return the bit number in CCR to test. We
15020 know this is a valid comparison.
15022 SCC_P is 1 if this is for an scc. That means that %D will have been
15023 used instead of %C, so the bits will be in different places.
15025 Return -1 if OP isn't a valid comparison for some reason. */
15028 ccr_bit (rtx op, int scc_p)
15030 enum rtx_code code = GET_CODE (op);
15031 enum machine_mode cc_mode;
15036 if (!COMPARISON_P (op))
15039 reg = XEXP (op, 0);
15041 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15043 cc_mode = GET_MODE (reg);
15044 cc_regnum = REGNO (reg);
15045 base_bit = 4 * (cc_regnum - CR0_REGNO);
15047 validate_condition_mode (code, cc_mode);
15049 /* When generating a sCOND operation, only positive conditions are
15052 || code == EQ || code == GT || code == LT || code == UNORDERED
15053 || code == GTU || code == LTU);
15058 return scc_p ? base_bit + 3 : base_bit + 2;
15060 return base_bit + 2;
15061 case GT: case GTU: case UNLE:
15062 return base_bit + 1;
15063 case LT: case LTU: case UNGE:
15065 case ORDERED: case UNORDERED:
15066 return base_bit + 3;
15069 /* If scc, we will have done a cror to put the bit in the
15070 unordered position. So test that bit. For integer, this is ! LT
15071 unless this is an scc insn. */
15072 return scc_p ? base_bit + 3 : base_bit;
15075 return scc_p ? base_bit + 3 : base_bit + 1;
15078 gcc_unreachable ();
15082 /* Return the GOT register. */
15085 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15087 /* The second flow pass currently (June 1999) can't update
15088 regs_ever_live without disturbing other parts of the compiler, so
15089 update it here to make the prolog/epilogue code happy. */
15090 if (!can_create_pseudo_p ()
15091 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15092 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15094 crtl->uses_pic_offset_table = 1;
15096 return pic_offset_table_rtx;
15099 /* Function to init struct machine_function.
15100 This will be called, via a pointer variable,
15101 from push_function_context. */
15103 static struct machine_function *
15104 rs6000_init_machine_status (void)
15106 return ggc_alloc_cleared_machine_function ();
15109 /* These macros test for integers and extract the low-order bits. */
15111 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15112 && GET_MODE (X) == VOIDmode)
15114 #define INT_LOWPART(X) \
15115 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15118 extract_MB (rtx op)
15121 unsigned long val = INT_LOWPART (op);
15123 /* If the high bit is zero, the value is the first 1 bit we find
15125 if ((val & 0x80000000) == 0)
15127 gcc_assert (val & 0xffffffff);
15130 while (((val <<= 1) & 0x80000000) == 0)
15135 /* If the high bit is set and the low bit is not, or the mask is all
15136 1's, the value is zero. */
15137 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15140 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15143 while (((val >>= 1) & 1) != 0)
15150 extract_ME (rtx op)
15153 unsigned long val = INT_LOWPART (op);
15155 /* If the low bit is zero, the value is the first 1 bit we find from
15157 if ((val & 1) == 0)
15159 gcc_assert (val & 0xffffffff);
15162 while (((val >>= 1) & 1) == 0)
15168 /* If the low bit is set and the high bit is not, or the mask is all
15169 1's, the value is 31. */
15170 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15173 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15176 while (((val <<= 1) & 0x80000000) != 0)
15182 /* Locate some local-dynamic symbol still in use by this function
15183 so that we can print its name in some tls_ld pattern. */
15185 static const char *
15186 rs6000_get_some_local_dynamic_name (void)
15190 if (cfun->machine->some_ld_name)
15191 return cfun->machine->some_ld_name;
15193 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15195 && for_each_rtx (&PATTERN (insn),
15196 rs6000_get_some_local_dynamic_name_1, 0))
15197 return cfun->machine->some_ld_name;
15199 gcc_unreachable ();
15202 /* Helper function for rs6000_get_some_local_dynamic_name. */
15205 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15209 if (GET_CODE (x) == SYMBOL_REF)
15211 const char *str = XSTR (x, 0);
15212 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15214 cfun->machine->some_ld_name = str;
15222 /* Write out a function code label. */
15225 rs6000_output_function_entry (FILE *file, const char *fname)
15227 if (fname[0] != '.')
15229 switch (DEFAULT_ABI)
15232 gcc_unreachable ();
15238 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15247 RS6000_OUTPUT_BASENAME (file, fname);
15250 /* Print an operand. Recognize special options, documented below. */
15253 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15254 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15256 #define SMALL_DATA_RELOC "sda21"
15257 #define SMALL_DATA_REG 0
15261 print_operand (FILE *file, rtx x, int code)
15265 unsigned HOST_WIDE_INT uval;
15270 /* Write out an instruction after the call which may be replaced
15271 with glue code by the loader. This depends on the AIX version. */
15272 asm_fprintf (file, RS6000_CALL_GLUE);
15275 /* %a is output_address. */
15278 /* If X is a constant integer whose low-order 5 bits are zero,
15279 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15280 in the AIX assembler where "sri" with a zero shift count
15281 writes a trash instruction. */
15282 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15289 /* If constant, low-order 16 bits of constant, unsigned.
15290 Otherwise, write normally. */
15292 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15294 print_operand (file, x, 0);
15298 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15299 for 64-bit mask direction. */
15300 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15303 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15307 /* X is a CR register. Print the number of the GT bit of the CR. */
15308 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15309 output_operand_lossage ("invalid %%c value");
15311 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15315 /* Like 'J' but get to the GT bit only. */
15316 gcc_assert (GET_CODE (x) == REG);
15318 /* Bit 1 is GT bit. */
15319 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15321 /* Add one for shift count in rlinm for scc. */
15322 fprintf (file, "%d", i + 1);
15326 /* X is a CR register. Print the number of the EQ bit of the CR */
15327 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15328 output_operand_lossage ("invalid %%E value");
15330 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15334 /* X is a CR register. Print the shift count needed to move it
15335 to the high-order four bits. */
15336 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15337 output_operand_lossage ("invalid %%f value");
15339 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15343 /* Similar, but print the count for the rotate in the opposite
15345 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15346 output_operand_lossage ("invalid %%F value");
15348 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15352 /* X is a constant integer. If it is negative, print "m",
15353 otherwise print "z". This is to make an aze or ame insn. */
15354 if (GET_CODE (x) != CONST_INT)
15355 output_operand_lossage ("invalid %%G value");
15356 else if (INTVAL (x) >= 0)
15363 /* If constant, output low-order five bits. Otherwise, write
15366 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15368 print_operand (file, x, 0);
15372 /* If constant, output low-order six bits. Otherwise, write
15375 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15377 print_operand (file, x, 0);
15381 /* Print `i' if this is a constant, else nothing. */
15387 /* Write the bit number in CCR for jump. */
15388 i = ccr_bit (x, 0);
15390 output_operand_lossage ("invalid %%j code");
15392 fprintf (file, "%d", i);
15396 /* Similar, but add one for shift count in rlinm for scc and pass
15397 scc flag to `ccr_bit'. */
15398 i = ccr_bit (x, 1);
15400 output_operand_lossage ("invalid %%J code");
15402 /* If we want bit 31, write a shift count of zero, not 32. */
15403 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15407 /* X must be a constant. Write the 1's complement of the
15410 output_operand_lossage ("invalid %%k value");
15412 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15416 /* X must be a symbolic constant on ELF. Write an
15417 expression suitable for an 'addi' that adds in the low 16
15418 bits of the MEM. */
15419 if (GET_CODE (x) == CONST)
15421 if (GET_CODE (XEXP (x, 0)) != PLUS
15422 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15423 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15424 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15425 output_operand_lossage ("invalid %%K value");
15427 print_operand_address (file, x);
15428 fputs ("@l", file);
15431 /* %l is output_asm_label. */
15434 /* Write second word of DImode or DFmode reference. Works on register
15435 or non-indexed memory only. */
15436 if (GET_CODE (x) == REG)
15437 fputs (reg_names[REGNO (x) + 1], file);
15438 else if (GET_CODE (x) == MEM)
15440 /* Handle possible auto-increment. Since it is pre-increment and
15441 we have already done it, we can just use an offset of word. */
15442 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15443 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15444 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15446 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15447 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15450 output_address (XEXP (adjust_address_nv (x, SImode,
15454 if (small_data_operand (x, GET_MODE (x)))
15455 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15456 reg_names[SMALL_DATA_REG]);
15461 /* MB value for a mask operand. */
15462 if (! mask_operand (x, SImode))
15463 output_operand_lossage ("invalid %%m value");
15465 fprintf (file, "%d", extract_MB (x));
15469 /* ME value for a mask operand. */
15470 if (! mask_operand (x, SImode))
15471 output_operand_lossage ("invalid %%M value");
15473 fprintf (file, "%d", extract_ME (x));
15476 /* %n outputs the negative of its operand. */
15479 /* Write the number of elements in the vector times 4. */
15480 if (GET_CODE (x) != PARALLEL)
15481 output_operand_lossage ("invalid %%N value");
15483 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15487 /* Similar, but subtract 1 first. */
15488 if (GET_CODE (x) != PARALLEL)
15489 output_operand_lossage ("invalid %%O value");
15491 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15495 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15497 || INT_LOWPART (x) < 0
15498 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15499 output_operand_lossage ("invalid %%p value");
15501 fprintf (file, "%d", i);
15505 /* The operand must be an indirect memory reference. The result
15506 is the register name. */
15507 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15508 || REGNO (XEXP (x, 0)) >= 32)
15509 output_operand_lossage ("invalid %%P value");
15511 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15515 /* This outputs the logical code corresponding to a boolean
15516 expression. The expression may have one or both operands
15517 negated (if one, only the first one). For condition register
15518 logical operations, it will also treat the negated
15519 CR codes as NOTs, but not handle NOTs of them. */
15521 const char *const *t = 0;
15523 enum rtx_code code = GET_CODE (x);
15524 static const char * const tbl[3][3] = {
15525 { "and", "andc", "nor" },
15526 { "or", "orc", "nand" },
15527 { "xor", "eqv", "xor" } };
15531 else if (code == IOR)
15533 else if (code == XOR)
15536 output_operand_lossage ("invalid %%q value");
15538 if (GET_CODE (XEXP (x, 0)) != NOT)
15542 if (GET_CODE (XEXP (x, 1)) == NOT)
15560 /* X is a CR register. Print the mask for `mtcrf'. */
15561 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15562 output_operand_lossage ("invalid %%R value");
15564 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15568 /* Low 5 bits of 32 - value */
15570 output_operand_lossage ("invalid %%s value");
15572 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15576 /* PowerPC64 mask position. All 0's is excluded.
15577 CONST_INT 32-bit mask is considered sign-extended so any
15578 transition must occur within the CONST_INT, not on the boundary. */
15579 if (! mask64_operand (x, DImode))
15580 output_operand_lossage ("invalid %%S value");
15582 uval = INT_LOWPART (x);
15584 if (uval & 1) /* Clear Left */
15586 #if HOST_BITS_PER_WIDE_INT > 64
15587 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15591 else /* Clear Right */
15594 #if HOST_BITS_PER_WIDE_INT > 64
15595 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15601 gcc_assert (i >= 0);
15602 fprintf (file, "%d", i);
15606 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15607 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15609 /* Bit 3 is OV bit. */
15610 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15612 /* If we want bit 31, write a shift count of zero, not 32. */
15613 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15617 /* Print the symbolic name of a branch target register. */
15618 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15619 && REGNO (x) != CTR_REGNO))
15620 output_operand_lossage ("invalid %%T value");
15621 else if (REGNO (x) == LR_REGNO)
15622 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15624 fputs ("ctr", file);
15628 /* High-order 16 bits of constant for use in unsigned operand. */
15630 output_operand_lossage ("invalid %%u value");
15632 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15633 (INT_LOWPART (x) >> 16) & 0xffff);
15637 /* High-order 16 bits of constant for use in signed operand. */
15639 output_operand_lossage ("invalid %%v value");
15641 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15642 (INT_LOWPART (x) >> 16) & 0xffff);
15646 /* Print `u' if this has an auto-increment or auto-decrement. */
15647 if (GET_CODE (x) == MEM
15648 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15649 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15650 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15655 /* Print the trap code for this operand. */
15656 switch (GET_CODE (x))
15659 fputs ("eq", file); /* 4 */
15662 fputs ("ne", file); /* 24 */
15665 fputs ("lt", file); /* 16 */
15668 fputs ("le", file); /* 20 */
15671 fputs ("gt", file); /* 8 */
15674 fputs ("ge", file); /* 12 */
15677 fputs ("llt", file); /* 2 */
15680 fputs ("lle", file); /* 6 */
15683 fputs ("lgt", file); /* 1 */
15686 fputs ("lge", file); /* 5 */
15689 gcc_unreachable ();
15694 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15697 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15698 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15700 print_operand (file, x, 0);
15704 /* MB value for a PowerPC64 rldic operand. */
15705 val = (GET_CODE (x) == CONST_INT
15706 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15711 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15712 if ((val <<= 1) < 0)
15715 #if HOST_BITS_PER_WIDE_INT == 32
15716 if (GET_CODE (x) == CONST_INT && i >= 0)
15717 i += 32; /* zero-extend high-part was all 0's */
15718 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15720 val = CONST_DOUBLE_LOW (x);
15726 for ( ; i < 64; i++)
15727 if ((val <<= 1) < 0)
15732 fprintf (file, "%d", i + 1);
15736 /* X is a FPR or Altivec register used in a VSX context. */
15737 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15738 output_operand_lossage ("invalid %%x value");
15741 int reg = REGNO (x);
15742 int vsx_reg = (FP_REGNO_P (reg)
15744 : reg - FIRST_ALTIVEC_REGNO + 32);
15746 #ifdef TARGET_REGNAMES
15747 if (TARGET_REGNAMES)
15748 fprintf (file, "%%vs%d", vsx_reg);
15751 fprintf (file, "%d", vsx_reg);
15756 if (GET_CODE (x) == MEM
15757 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15758 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15759 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15764 /* Like 'L', for third word of TImode */
15765 if (GET_CODE (x) == REG)
15766 fputs (reg_names[REGNO (x) + 2], file);
15767 else if (GET_CODE (x) == MEM)
15769 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15770 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15771 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15772 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15773 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15775 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15776 if (small_data_operand (x, GET_MODE (x)))
15777 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15778 reg_names[SMALL_DATA_REG]);
15783 /* X is a SYMBOL_REF. Write out the name preceded by a
15784 period and without any trailing data in brackets. Used for function
15785 names. If we are configured for System V (or the embedded ABI) on
15786 the PowerPC, do not emit the period, since those systems do not use
15787 TOCs and the like. */
15788 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15790 /* Mark the decl as referenced so that cgraph will output the
15792 if (SYMBOL_REF_DECL (x))
15793 mark_decl_referenced (SYMBOL_REF_DECL (x));
15795 /* For macho, check to see if we need a stub. */
15798 const char *name = XSTR (x, 0);
15800 if (darwin_emit_branch_islands
15801 && MACHOPIC_INDIRECT
15802 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15803 name = machopic_indirection_name (x, /*stub_p=*/true);
15805 assemble_name (file, name);
15807 else if (!DOT_SYMBOLS)
15808 assemble_name (file, XSTR (x, 0));
15810 rs6000_output_function_entry (file, XSTR (x, 0));
15814 /* Like 'L', for last word of TImode. */
15815 if (GET_CODE (x) == REG)
15816 fputs (reg_names[REGNO (x) + 3], file);
15817 else if (GET_CODE (x) == MEM)
15819 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15820 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15821 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15822 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15823 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15825 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15826 if (small_data_operand (x, GET_MODE (x)))
15827 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15828 reg_names[SMALL_DATA_REG]);
15832 /* Print AltiVec or SPE memory operand. */
15837 gcc_assert (GET_CODE (x) == MEM);
15841 /* Ugly hack because %y is overloaded. */
15842 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15843 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15844 || GET_MODE (x) == TFmode
15845 || GET_MODE (x) == TImode))
15847 /* Handle [reg]. */
15848 if (GET_CODE (tmp) == REG)
15850 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15853 /* Handle [reg+UIMM]. */
15854 else if (GET_CODE (tmp) == PLUS &&
15855 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15859 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15861 x = INTVAL (XEXP (tmp, 1));
15862 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15866 /* Fall through. Must be [reg+reg]. */
15868 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15869 && GET_CODE (tmp) == AND
15870 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15871 && INTVAL (XEXP (tmp, 1)) == -16)
15872 tmp = XEXP (tmp, 0);
15873 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15874 && GET_CODE (tmp) == PRE_MODIFY)
15875 tmp = XEXP (tmp, 1);
15876 if (GET_CODE (tmp) == REG)
15877 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15880 if (!GET_CODE (tmp) == PLUS
15881 || !REG_P (XEXP (tmp, 0))
15882 || !REG_P (XEXP (tmp, 1)))
15884 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15888 if (REGNO (XEXP (tmp, 0)) == 0)
15889 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15890 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15892 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15893 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15899 if (GET_CODE (x) == REG)
15900 fprintf (file, "%s", reg_names[REGNO (x)]);
15901 else if (GET_CODE (x) == MEM)
15903 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15904 know the width from the mode. */
15905 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15906 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15907 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15908 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15909 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15910 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15911 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15912 output_address (XEXP (XEXP (x, 0), 1));
15914 output_address (XEXP (x, 0));
15917 output_addr_const (file, x);
15921 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15925 output_operand_lossage ("invalid %%xn code");
15929 /* Print the address of an operand. */
15932 print_operand_address (FILE *file, rtx x)
15934 if (GET_CODE (x) == REG)
15935 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15936 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15937 || GET_CODE (x) == LABEL_REF)
15939 output_addr_const (file, x);
15940 if (small_data_operand (x, GET_MODE (x)))
15941 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15942 reg_names[SMALL_DATA_REG]);
15944 gcc_assert (!TARGET_TOC);
15946 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15948 gcc_assert (REG_P (XEXP (x, 0)));
15949 if (REGNO (XEXP (x, 0)) == 0)
15950 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15951 reg_names[ REGNO (XEXP (x, 0)) ]);
15953 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15954 reg_names[ REGNO (XEXP (x, 1)) ]);
15956 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15957 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15958 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15960 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15961 && CONSTANT_P (XEXP (x, 1)))
15963 fprintf (file, "lo16(");
15964 output_addr_const (file, XEXP (x, 1));
15965 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15968 else if (legitimate_constant_pool_address_p (x, true))
15970 /* This hack along with a corresponding hack in
15971 rs6000_output_addr_const_extra arranges to output addends
15972 where the assembler expects to find them. eg.
15974 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15975 without this hack would be output as "x@toc+8@l(9)". We
15976 want "x+8@toc@l(9)". */
15977 output_addr_const (file, tocrel_base);
15978 if (GET_CODE (x) == LO_SUM)
15979 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15981 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15984 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15985 && CONSTANT_P (XEXP (x, 1)))
15987 output_addr_const (file, XEXP (x, 1));
15988 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15992 gcc_unreachable ();
15995 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15998 rs6000_output_addr_const_extra (FILE *file, rtx x)
16000 if (GET_CODE (x) == UNSPEC)
16001 switch (XINT (x, 1))
16003 case UNSPEC_TOCREL:
16004 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16005 output_addr_const (file, XVECEXP (x, 0, 0));
16006 if (x == tocrel_base && tocrel_offset != const0_rtx)
16008 if (INTVAL (tocrel_offset) >= 0)
16009 fprintf (file, "+");
16010 output_addr_const (file, tocrel_offset);
16012 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16015 assemble_name (file, toc_label_name);
16017 else if (TARGET_ELF)
16018 fputs ("@toc", file);
16022 case UNSPEC_MACHOPIC_OFFSET:
16023 output_addr_const (file, XVECEXP (x, 0, 0));
16025 machopic_output_function_base_name (file);
16032 /* Target hook for assembling integer objects. The PowerPC version has
16033 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16034 is defined. It also needs to handle DI-mode objects on 64-bit
16038 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16040 #ifdef RELOCATABLE_NEEDS_FIXUP
16041 /* Special handling for SI values. */
16042 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16044 static int recurse = 0;
16046 /* For -mrelocatable, we mark all addresses that need to be fixed up
16047 in the .fixup section. */
16048 if (TARGET_RELOCATABLE
16049 && in_section != toc_section
16050 && in_section != text_section
16051 && !unlikely_text_section_p (in_section)
16053 && GET_CODE (x) != CONST_INT
16054 && GET_CODE (x) != CONST_DOUBLE
16060 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16062 ASM_OUTPUT_LABEL (asm_out_file, buf);
16063 fprintf (asm_out_file, "\t.long\t(");
16064 output_addr_const (asm_out_file, x);
16065 fprintf (asm_out_file, ")@fixup\n");
16066 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16067 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16068 fprintf (asm_out_file, "\t.long\t");
16069 assemble_name (asm_out_file, buf);
16070 fprintf (asm_out_file, "\n\t.previous\n");
16074 /* Remove initial .'s to turn a -mcall-aixdesc function
16075 address into the address of the descriptor, not the function
16077 else if (GET_CODE (x) == SYMBOL_REF
16078 && XSTR (x, 0)[0] == '.'
16079 && DEFAULT_ABI == ABI_AIX)
16081 const char *name = XSTR (x, 0);
16082 while (*name == '.')
16085 fprintf (asm_out_file, "\t.long\t%s\n", name);
16089 #endif /* RELOCATABLE_NEEDS_FIXUP */
16090 return default_assemble_integer (x, size, aligned_p);
16093 #ifdef HAVE_GAS_HIDDEN
16094 /* Emit an assembler directive to set symbol visibility for DECL to
16095 VISIBILITY_TYPE. */
16098 rs6000_assemble_visibility (tree decl, int vis)
16100 /* Functions need to have their entry point symbol visibility set as
16101 well as their descriptor symbol visibility. */
16102 if (DEFAULT_ABI == ABI_AIX
16104 && TREE_CODE (decl) == FUNCTION_DECL)
16106 static const char * const visibility_types[] = {
16107 NULL, "internal", "hidden", "protected"
16110 const char *name, *type;
16112 name = ((* targetm.strip_name_encoding)
16113 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16114 type = visibility_types[vis];
16116 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16117 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16120 default_assemble_visibility (decl, vis);
16125 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16127 /* Reversal of FP compares takes care -- an ordered compare
16128 becomes an unordered compare and vice versa. */
16129 if (mode == CCFPmode
16130 && (!flag_finite_math_only
16131 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16132 || code == UNEQ || code == LTGT))
16133 return reverse_condition_maybe_unordered (code);
16135 return reverse_condition (code);
16138 /* Generate a compare for CODE. Return a brand-new rtx that
16139 represents the result of the compare. */
16142 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16144 enum machine_mode comp_mode;
16145 rtx compare_result;
16146 enum rtx_code code = GET_CODE (cmp);
16147 rtx op0 = XEXP (cmp, 0);
16148 rtx op1 = XEXP (cmp, 1);
16150 if (FLOAT_MODE_P (mode))
16151 comp_mode = CCFPmode;
16152 else if (code == GTU || code == LTU
16153 || code == GEU || code == LEU)
16154 comp_mode = CCUNSmode;
16155 else if ((code == EQ || code == NE)
16156 && GET_CODE (op0) == SUBREG
16157 && GET_CODE (op1) == SUBREG
16158 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16159 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16160 /* These are unsigned values, perhaps there will be a later
16161 ordering compare that can be shared with this one.
16162 Unfortunately we cannot detect the signedness of the operands
16163 for non-subregs. */
16164 comp_mode = CCUNSmode;
16166 comp_mode = CCmode;
16168 /* First, the compare. */
16169 compare_result = gen_reg_rtx (comp_mode);
16171 /* E500 FP compare instructions on the GPRs. Yuck! */
16172 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16173 && FLOAT_MODE_P (mode))
16175 rtx cmp, or_result, compare_result2;
16176 enum machine_mode op_mode = GET_MODE (op0);
16178 if (op_mode == VOIDmode)
16179 op_mode = GET_MODE (op1);
16181 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16182 This explains the following mess. */
16186 case EQ: case UNEQ: case NE: case LTGT:
16190 cmp = (flag_finite_math_only && !flag_trapping_math)
16191 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16192 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16196 cmp = (flag_finite_math_only && !flag_trapping_math)
16197 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16198 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16202 cmp = (flag_finite_math_only && !flag_trapping_math)
16203 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16204 : gen_cmptfeq_gpr (compare_result, op0, op1);
16208 gcc_unreachable ();
16212 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16216 cmp = (flag_finite_math_only && !flag_trapping_math)
16217 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16218 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16222 cmp = (flag_finite_math_only && !flag_trapping_math)
16223 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16224 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16228 cmp = (flag_finite_math_only && !flag_trapping_math)
16229 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16230 : gen_cmptfgt_gpr (compare_result, op0, op1);
16234 gcc_unreachable ();
16238 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16242 cmp = (flag_finite_math_only && !flag_trapping_math)
16243 ? gen_tstsflt_gpr (compare_result, op0, op1)
16244 : gen_cmpsflt_gpr (compare_result, op0, op1);
16248 cmp = (flag_finite_math_only && !flag_trapping_math)
16249 ? gen_tstdflt_gpr (compare_result, op0, op1)
16250 : gen_cmpdflt_gpr (compare_result, op0, op1);
16254 cmp = (flag_finite_math_only && !flag_trapping_math)
16255 ? gen_tsttflt_gpr (compare_result, op0, op1)
16256 : gen_cmptflt_gpr (compare_result, op0, op1);
16260 gcc_unreachable ();
16264 gcc_unreachable ();
16267 /* Synthesize LE and GE from LT/GT || EQ. */
16268 if (code == LE || code == GE || code == LEU || code == GEU)
16274 case LE: code = LT; break;
16275 case GE: code = GT; break;
16276 case LEU: code = LT; break;
16277 case GEU: code = GT; break;
16278 default: gcc_unreachable ();
16281 compare_result2 = gen_reg_rtx (CCFPmode);
16287 cmp = (flag_finite_math_only && !flag_trapping_math)
16288 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16289 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16293 cmp = (flag_finite_math_only && !flag_trapping_math)
16294 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16295 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16299 cmp = (flag_finite_math_only && !flag_trapping_math)
16300 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16301 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16305 gcc_unreachable ();
16309 /* OR them together. */
16310 or_result = gen_reg_rtx (CCFPmode);
16311 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16313 compare_result = or_result;
16318 if (code == NE || code == LTGT)
16328 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16329 CLOBBERs to match cmptf_internal2 pattern. */
16330 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16331 && GET_MODE (op0) == TFmode
16332 && !TARGET_IEEEQUAD
16333 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16334 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16336 gen_rtx_SET (VOIDmode,
16338 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 (DFmode)),
16343 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16344 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16345 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16346 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16347 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16348 else if (GET_CODE (op1) == UNSPEC
16349 && XINT (op1, 1) == UNSPEC_SP_TEST)
16351 rtx op1b = XVECEXP (op1, 0, 0);
16352 comp_mode = CCEQmode;
16353 compare_result = gen_reg_rtx (CCEQmode);
16355 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16357 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16360 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16361 gen_rtx_COMPARE (comp_mode, op0, op1)));
16364 /* Some kinds of FP comparisons need an OR operation;
16365 under flag_finite_math_only we don't bother. */
16366 if (FLOAT_MODE_P (mode)
16367 && !flag_finite_math_only
16368 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16369 && (code == LE || code == GE
16370 || code == UNEQ || code == LTGT
16371 || code == UNGT || code == UNLT))
16373 enum rtx_code or1, or2;
16374 rtx or1_rtx, or2_rtx, compare2_rtx;
16375 rtx or_result = gen_reg_rtx (CCEQmode);
16379 case LE: or1 = LT; or2 = EQ; break;
16380 case GE: or1 = GT; or2 = EQ; break;
16381 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16382 case LTGT: or1 = LT; or2 = GT; break;
16383 case UNGT: or1 = UNORDERED; or2 = GT; break;
16384 case UNLT: or1 = UNORDERED; or2 = LT; break;
16385 default: gcc_unreachable ();
16387 validate_condition_mode (or1, comp_mode);
16388 validate_condition_mode (or2, comp_mode);
16389 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16390 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16391 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16392 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16394 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16396 compare_result = or_result;
16400 validate_condition_mode (code, GET_MODE (compare_result));
16402 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16406 /* Emit the RTL for an sISEL pattern. */
16409 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16411 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16415 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16418 enum machine_mode op_mode;
16419 enum rtx_code cond_code;
16420 rtx result = operands[0];
16422 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16424 rs6000_emit_sISEL (mode, operands);
16428 condition_rtx = rs6000_generate_compare (operands[1], mode);
16429 cond_code = GET_CODE (condition_rtx);
16431 if (FLOAT_MODE_P (mode)
16432 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16436 PUT_MODE (condition_rtx, SImode);
16437 t = XEXP (condition_rtx, 0);
16439 gcc_assert (cond_code == NE || cond_code == EQ);
16441 if (cond_code == NE)
16442 emit_insn (gen_e500_flip_gt_bit (t, t));
16444 emit_insn (gen_move_from_CR_gt_bit (result, t));
16448 if (cond_code == NE
16449 || cond_code == GE || cond_code == LE
16450 || cond_code == GEU || cond_code == LEU
16451 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16453 rtx not_result = gen_reg_rtx (CCEQmode);
16454 rtx not_op, rev_cond_rtx;
16455 enum machine_mode cc_mode;
16457 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16459 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16460 SImode, XEXP (condition_rtx, 0), const0_rtx);
16461 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16462 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16463 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16466 op_mode = GET_MODE (XEXP (operands[1], 0));
16467 if (op_mode == VOIDmode)
16468 op_mode = GET_MODE (XEXP (operands[1], 1));
16470 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16472 PUT_MODE (condition_rtx, DImode);
16473 convert_move (result, condition_rtx, 0);
16477 PUT_MODE (condition_rtx, SImode);
16478 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16482 /* Emit a branch of kind CODE to location LOC. */
16485 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16487 rtx condition_rtx, loc_ref;
16489 condition_rtx = rs6000_generate_compare (operands[0], mode);
16490 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16491 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16492 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16493 loc_ref, pc_rtx)));
16496 /* Return the string to output a conditional branch to LABEL, which is
16497 the operand number of the label, or -1 if the branch is really a
16498 conditional return.
16500 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16501 condition code register and its mode specifies what kind of
16502 comparison we made.
16504 REVERSED is nonzero if we should reverse the sense of the comparison.
16506 INSN is the insn. */
16509 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16511 static char string[64];
16512 enum rtx_code code = GET_CODE (op);
16513 rtx cc_reg = XEXP (op, 0);
16514 enum machine_mode mode = GET_MODE (cc_reg);
16515 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16516 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16517 int really_reversed = reversed ^ need_longbranch;
16523 validate_condition_mode (code, mode);
16525 /* Work out which way this really branches. We could use
16526 reverse_condition_maybe_unordered here always but this
16527 makes the resulting assembler clearer. */
16528 if (really_reversed)
16530 /* Reversal of FP compares takes care -- an ordered compare
16531 becomes an unordered compare and vice versa. */
16532 if (mode == CCFPmode)
16533 code = reverse_condition_maybe_unordered (code);
16535 code = reverse_condition (code);
16538 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16540 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16545 /* Opposite of GT. */
16554 gcc_unreachable ();
16560 /* Not all of these are actually distinct opcodes, but
16561 we distinguish them for clarity of the resulting assembler. */
16562 case NE: case LTGT:
16563 ccode = "ne"; break;
16564 case EQ: case UNEQ:
16565 ccode = "eq"; break;
16567 ccode = "ge"; break;
16568 case GT: case GTU: case UNGT:
16569 ccode = "gt"; break;
16571 ccode = "le"; break;
16572 case LT: case LTU: case UNLT:
16573 ccode = "lt"; break;
16574 case UNORDERED: ccode = "un"; break;
16575 case ORDERED: ccode = "nu"; break;
16576 case UNGE: ccode = "nl"; break;
16577 case UNLE: ccode = "ng"; break;
16579 gcc_unreachable ();
16582 /* Maybe we have a guess as to how likely the branch is.
16583 The old mnemonics don't have a way to specify this information. */
16585 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16586 if (note != NULL_RTX)
16588 /* PROB is the difference from 50%. */
16589 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16591 /* Only hint for highly probable/improbable branches on newer
16592 cpus as static prediction overrides processor dynamic
16593 prediction. For older cpus we may as well always hint, but
16594 assume not taken for branches that are very close to 50% as a
16595 mispredicted taken branch is more expensive than a
16596 mispredicted not-taken branch. */
16597 if (rs6000_always_hint
16598 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16599 && br_prob_note_reliable_p (note)))
16601 if (abs (prob) > REG_BR_PROB_BASE / 20
16602 && ((prob > 0) ^ need_longbranch))
16610 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16612 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16614 /* We need to escape any '%' characters in the reg_names string.
16615 Assume they'd only be the first character.... */
16616 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16618 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16622 /* If the branch distance was too far, we may have to use an
16623 unconditional branch to go the distance. */
16624 if (need_longbranch)
16625 s += sprintf (s, ",$+8\n\tb %s", label);
16627 s += sprintf (s, ",%s", label);
16633 /* Return the string to flip the GT bit on a CR. */
16635 output_e500_flip_gt_bit (rtx dst, rtx src)
16637 static char string[64];
16640 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16641 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16644 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16645 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16647 sprintf (string, "crnot %d,%d", a, b);
16651 /* Return insn for VSX or Altivec comparisons. */
16654 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16657 enum machine_mode mode = GET_MODE (op0);
16665 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16671 mask = gen_reg_rtx (mode);
16672 emit_insn (gen_rtx_SET (VOIDmode,
16674 gen_rtx_fmt_ee (code, mode, op0, op1)));
16681 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16682 DMODE is expected destination mode. This is a recursive function. */
16685 rs6000_emit_vector_compare (enum rtx_code rcode,
16687 enum machine_mode dmode)
16690 bool swap_operands = false;
16691 bool try_again = false;
16693 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16694 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16696 /* See if the comparison works as is. */
16697 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16705 swap_operands = true;
16710 swap_operands = true;
16718 /* Invert condition and try again.
16719 e.g., A != B becomes ~(A==B). */
16721 enum rtx_code rev_code;
16722 enum insn_code nor_code;
16725 rev_code = reverse_condition_maybe_unordered (rcode);
16726 if (rev_code == UNKNOWN)
16729 nor_code = optab_handler (one_cmpl_optab, dmode);
16730 if (nor_code == CODE_FOR_nothing)
16733 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16737 mask = gen_reg_rtx (dmode);
16738 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16746 /* Try GT/GTU/LT/LTU OR EQ */
16749 enum insn_code ior_code;
16750 enum rtx_code new_code;
16771 gcc_unreachable ();
16774 ior_code = optab_handler (ior_optab, dmode);
16775 if (ior_code == CODE_FOR_nothing)
16778 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16782 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16786 mask = gen_reg_rtx (dmode);
16787 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16805 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16810 /* You only get two chances. */
16814 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16815 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16816 operands for the relation operation COND. */
16819 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16820 rtx cond, rtx cc_op0, rtx cc_op1)
16822 enum machine_mode dest_mode = GET_MODE (dest);
16823 enum rtx_code rcode = GET_CODE (cond);
16824 enum machine_mode cc_mode = CCmode;
16828 bool invert_move = false;
16830 if (VECTOR_UNIT_NONE_P (dest_mode))
16835 /* Swap operands if we can, and fall back to doing the operation as
16836 specified, and doing a NOR to invert the test. */
16842 /* Invert condition and try again.
16843 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16844 invert_move = true;
16845 rcode = reverse_condition_maybe_unordered (rcode);
16846 if (rcode == UNKNOWN)
16850 /* Mark unsigned tests with CCUNSmode. */
16855 cc_mode = CCUNSmode;
16862 /* Get the vector mask for the given relational operations. */
16863 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16871 op_true = op_false;
16875 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16876 emit_insn (gen_rtx_SET (VOIDmode,
16878 gen_rtx_IF_THEN_ELSE (dest_mode,
16885 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16886 operands of the last comparison is nonzero/true, FALSE_COND if it
16887 is zero/false. Return 0 if the hardware has no such operation. */
16890 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16892 enum rtx_code code = GET_CODE (op);
16893 rtx op0 = XEXP (op, 0);
16894 rtx op1 = XEXP (op, 1);
16895 REAL_VALUE_TYPE c1;
16896 enum machine_mode compare_mode = GET_MODE (op0);
16897 enum machine_mode result_mode = GET_MODE (dest);
16899 bool is_against_zero;
16901 /* These modes should always match. */
16902 if (GET_MODE (op1) != compare_mode
16903 /* In the isel case however, we can use a compare immediate, so
16904 op1 may be a small constant. */
16905 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16907 if (GET_MODE (true_cond) != result_mode)
16909 if (GET_MODE (false_cond) != result_mode)
16912 /* First, work out if the hardware can do this at all, or
16913 if it's too slow.... */
16914 if (!FLOAT_MODE_P (compare_mode))
16917 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16920 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16921 && SCALAR_FLOAT_MODE_P (compare_mode))
16924 is_against_zero = op1 == CONST0_RTX (compare_mode);
16926 /* A floating-point subtract might overflow, underflow, or produce
16927 an inexact result, thus changing the floating-point flags, so it
16928 can't be generated if we care about that. It's safe if one side
16929 of the construct is zero, since then no subtract will be
16931 if (SCALAR_FLOAT_MODE_P (compare_mode)
16932 && flag_trapping_math && ! is_against_zero)
16935 /* Eliminate half of the comparisons by switching operands, this
16936 makes the remaining code simpler. */
16937 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16938 || code == LTGT || code == LT || code == UNLE)
16940 code = reverse_condition_maybe_unordered (code);
16942 true_cond = false_cond;
16946 /* UNEQ and LTGT take four instructions for a comparison with zero,
16947 it'll probably be faster to use a branch here too. */
16948 if (code == UNEQ && HONOR_NANS (compare_mode))
16951 if (GET_CODE (op1) == CONST_DOUBLE)
16952 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16954 /* We're going to try to implement comparisons by performing
16955 a subtract, then comparing against zero. Unfortunately,
16956 Inf - Inf is NaN which is not zero, and so if we don't
16957 know that the operand is finite and the comparison
16958 would treat EQ different to UNORDERED, we can't do it. */
16959 if (HONOR_INFINITIES (compare_mode)
16960 && code != GT && code != UNGE
16961 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16962 /* Constructs of the form (a OP b ? a : b) are safe. */
16963 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16964 || (! rtx_equal_p (op0, true_cond)
16965 && ! rtx_equal_p (op1, true_cond))))
16968 /* At this point we know we can use fsel. */
16970 /* Reduce the comparison to a comparison against zero. */
16971 if (! is_against_zero)
16973 temp = gen_reg_rtx (compare_mode);
16974 emit_insn (gen_rtx_SET (VOIDmode, temp,
16975 gen_rtx_MINUS (compare_mode, op0, op1)));
16977 op1 = CONST0_RTX (compare_mode);
16980 /* If we don't care about NaNs we can reduce some of the comparisons
16981 down to faster ones. */
16982 if (! HONOR_NANS (compare_mode))
16988 true_cond = false_cond;
17001 /* Now, reduce everything down to a GE. */
17008 temp = gen_reg_rtx (compare_mode);
17009 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17014 temp = gen_reg_rtx (compare_mode);
17015 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17020 temp = gen_reg_rtx (compare_mode);
17021 emit_insn (gen_rtx_SET (VOIDmode, temp,
17022 gen_rtx_NEG (compare_mode,
17023 gen_rtx_ABS (compare_mode, op0))));
17028 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17029 temp = gen_reg_rtx (result_mode);
17030 emit_insn (gen_rtx_SET (VOIDmode, temp,
17031 gen_rtx_IF_THEN_ELSE (result_mode,
17032 gen_rtx_GE (VOIDmode,
17034 true_cond, false_cond)));
17035 false_cond = true_cond;
17038 temp = gen_reg_rtx (compare_mode);
17039 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17044 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17045 temp = gen_reg_rtx (result_mode);
17046 emit_insn (gen_rtx_SET (VOIDmode, temp,
17047 gen_rtx_IF_THEN_ELSE (result_mode,
17048 gen_rtx_GE (VOIDmode,
17050 true_cond, false_cond)));
17051 true_cond = false_cond;
17054 temp = gen_reg_rtx (compare_mode);
17055 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17060 gcc_unreachable ();
17063 emit_insn (gen_rtx_SET (VOIDmode, dest,
17064 gen_rtx_IF_THEN_ELSE (result_mode,
17065 gen_rtx_GE (VOIDmode,
17067 true_cond, false_cond)));
17071 /* Same as above, but for ints (isel). */
17074 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17076 rtx condition_rtx, cr;
17077 enum machine_mode mode = GET_MODE (dest);
17078 enum rtx_code cond_code;
17079 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17082 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17085 /* We still have to do the compare, because isel doesn't do a
17086 compare, it just looks at the CRx bits set by a previous compare
17088 condition_rtx = rs6000_generate_compare (op, mode);
17089 cond_code = GET_CODE (condition_rtx);
17090 cr = XEXP (condition_rtx, 0);
17091 signedp = GET_MODE (cr) == CCmode;
17093 isel_func = (mode == SImode
17094 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17095 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17099 case LT: case GT: case LTU: case GTU: case EQ:
17100 /* isel handles these directly. */
17104 /* We need to swap the sense of the comparison. */
17107 true_cond = false_cond;
17109 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17114 false_cond = force_reg (mode, false_cond);
17115 if (true_cond != const0_rtx)
17116 true_cond = force_reg (mode, true_cond);
17118 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17124 output_isel (rtx *operands)
17126 enum rtx_code code;
17128 code = GET_CODE (operands[1]);
17130 gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
17132 return "isel %0,%2,%3,%j1";
17136 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17138 enum machine_mode mode = GET_MODE (op0);
17142 /* VSX/altivec have direct min/max insns. */
17143 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
17145 emit_insn (gen_rtx_SET (VOIDmode,
17147 gen_rtx_fmt_ee (code, mode, op0, op1)));
17151 if (code == SMAX || code == SMIN)
17156 if (code == SMAX || code == UMAX)
17157 target = emit_conditional_move (dest, c, op0, op1, mode,
17158 op0, op1, mode, 0);
17160 target = emit_conditional_move (dest, c, op0, op1, mode,
17161 op1, op0, mode, 0);
17162 gcc_assert (target);
17163 if (target != dest)
17164 emit_move_insn (dest, target);
17167 /* Emit instructions to perform a load-reserved/store-conditional operation.
17168 The operation performed is an atomic
17169 (set M (CODE:MODE M OP))
17170 If not NULL, BEFORE is atomically set to M before the operation, and
17171 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17172 If SYNC_P then a memory barrier is emitted before the operation.
17173 Either OP or M may be wrapped in a NOT operation. */
17176 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17177 rtx m, rtx op, rtx before_param, rtx after_param,
17180 enum machine_mode used_mode;
17181 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17184 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17185 rtx shift = NULL_RTX;
17188 emit_insn (gen_lwsync ());
17192 /* If this is smaller than SImode, we'll have to use SImode with
17194 if (mode == QImode || mode == HImode)
17198 if (MEM_ALIGN (used_m) >= 32)
17201 if (BYTES_BIG_ENDIAN)
17202 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17204 shift = GEN_INT (ishift);
17205 used_m = change_address (used_m, SImode, 0);
17209 rtx addrSI, aligned_addr;
17210 int shift_mask = mode == QImode ? 0x18 : 0x10;
17212 addrSI = gen_lowpart_common (SImode,
17213 force_reg (Pmode, XEXP (used_m, 0)));
17214 addrSI = force_reg (SImode, addrSI);
17215 shift = gen_reg_rtx (SImode);
17217 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17218 GEN_INT (shift_mask)));
17219 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17221 aligned_addr = expand_binop (Pmode, and_optab,
17223 GEN_INT (-4), NULL_RTX,
17224 1, OPTAB_LIB_WIDEN);
17225 used_m = change_address (used_m, SImode, aligned_addr);
17226 set_mem_align (used_m, 32);
17228 /* It's safe to keep the old alias set of USED_M, because
17229 the operation is atomic and only affects the original
17233 if (GET_CODE (op) == NOT)
17235 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17236 oldop = gen_rtx_NOT (SImode, oldop);
17239 oldop = lowpart_subreg (SImode, op, mode);
17245 newop = expand_binop (SImode, and_optab,
17246 oldop, GEN_INT (imask), NULL_RTX,
17247 1, OPTAB_LIB_WIDEN);
17248 emit_insn (gen_ashlsi3 (newop, newop, shift));
17251 case NOT: /* NAND */
17252 newop = expand_binop (SImode, ior_optab,
17253 oldop, GEN_INT (~imask), NULL_RTX,
17254 1, OPTAB_LIB_WIDEN);
17255 emit_insn (gen_rotlsi3 (newop, newop, shift));
17259 newop = expand_binop (SImode, ior_optab,
17260 oldop, GEN_INT (~imask), NULL_RTX,
17261 1, OPTAB_LIB_WIDEN);
17262 emit_insn (gen_rotlsi3 (newop, newop, shift));
17270 newop = expand_binop (SImode, and_optab,
17271 oldop, GEN_INT (imask), NULL_RTX,
17272 1, OPTAB_LIB_WIDEN);
17273 emit_insn (gen_ashlsi3 (newop, newop, shift));
17275 mask = gen_reg_rtx (SImode);
17276 emit_move_insn (mask, GEN_INT (imask));
17277 emit_insn (gen_ashlsi3 (mask, mask, shift));
17280 newop = gen_rtx_PLUS (SImode, m, newop);
17282 newop = gen_rtx_MINUS (SImode, m, newop);
17283 newop = gen_rtx_AND (SImode, newop, mask);
17284 newop = gen_rtx_IOR (SImode, newop,
17285 gen_rtx_AND (SImode,
17286 gen_rtx_NOT (SImode, mask),
17292 gcc_unreachable ();
17296 used_mode = SImode;
17297 before = gen_reg_rtx (used_mode);
17298 after = gen_reg_rtx (used_mode);
17303 before = before_param;
17304 after = after_param;
17306 if (before == NULL_RTX)
17307 before = gen_reg_rtx (used_mode);
17308 if (after == NULL_RTX)
17309 after = gen_reg_rtx (used_mode);
17312 if ((code == PLUS || code == MINUS)
17313 && used_mode != mode)
17314 the_op = op; /* Computed above. */
17315 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17316 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17317 else if (code == NOT)
17318 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17319 gen_rtx_NOT (used_mode, m),
17320 gen_rtx_NOT (used_mode, op));
17322 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17324 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17325 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17326 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17327 gen_rtx_UNSPEC (used_mode,
17328 gen_rtvec (1, the_op),
17330 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17332 if ((code == PLUS || code == MINUS) && used_mode != mode)
17333 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17334 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17336 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17337 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17339 /* Shift and mask the return values properly. */
17340 if (used_mode != mode && before_param)
17342 emit_insn (gen_lshrsi3 (before, before, shift));
17343 convert_move (before_param, before, 1);
17346 if (used_mode != mode && after_param)
17348 emit_insn (gen_lshrsi3 (after, after, shift));
17349 convert_move (after_param, after, 1);
17352 /* The previous sequence will end with a branch that's dependent on
17353 the conditional store, so placing an isync will ensure that no
17354 other instructions (especially, no load or store instructions)
17355 can start before the atomic operation completes. */
17357 emit_insn (gen_isync ());
17360 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17361 COND is true. Mark the jump as unlikely to be taken. */
17364 emit_unlikely_jump (rtx cond, rtx label)
17366 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17369 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17370 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17371 add_reg_note (x, REG_BR_PROB, very_unlikely);
17374 /* A subroutine of the atomic operation splitters. Emit a load-locked
17375 instruction in MODE. */
17378 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17380 rtx (*fn) (rtx, rtx) = NULL;
17381 if (mode == SImode)
17382 fn = gen_load_locked_si;
17383 else if (mode == DImode)
17384 fn = gen_load_locked_di;
17385 emit_insn (fn (reg, mem));
17388 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17389 instruction in MODE. */
17392 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17394 rtx (*fn) (rtx, rtx, rtx) = NULL;
17395 if (mode == SImode)
17396 fn = gen_store_conditional_si;
17397 else if (mode == DImode)
17398 fn = gen_store_conditional_di;
17400 /* Emit sync before stwcx. to address PPC405 Erratum. */
17401 if (PPC405_ERRATUM77)
17402 emit_insn (gen_memory_barrier ());
17404 emit_insn (fn (res, mem, val));
17407 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17408 to perform. MEM is the memory on which to operate. VAL is the second
17409 operand of the binary operator. BEFORE and AFTER are optional locations to
17410 return the value of MEM either before of after the operation. SCRATCH is
17411 a scratch register. */
17414 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17415 rtx before, rtx after, rtx scratch)
17417 enum machine_mode mode = GET_MODE (mem);
17418 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17420 emit_insn (gen_lwsync ());
17422 label = gen_label_rtx ();
17423 emit_label (label);
17424 label = gen_rtx_LABEL_REF (VOIDmode, label);
17426 if (before == NULL_RTX)
17428 emit_load_locked (mode, before, mem);
17431 x = gen_rtx_IOR (mode,
17432 gen_rtx_NOT (mode, before),
17433 gen_rtx_NOT (mode, val));
17434 else if (code == AND)
17435 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17437 x = gen_rtx_fmt_ee (code, mode, before, val);
17439 if (after != NULL_RTX)
17440 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17441 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17443 emit_store_conditional (mode, cond, mem, scratch);
17445 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17446 emit_unlikely_jump (x, label);
17448 emit_insn (gen_isync ());
17451 /* Expand an atomic compare and swap operation. MEM is the memory on which
17452 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17453 value to be stored. SCRATCH is a scratch GPR. */
17456 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17459 enum machine_mode mode = GET_MODE (mem);
17460 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17462 emit_insn (gen_lwsync ());
17464 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17465 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17466 emit_label (XEXP (label1, 0));
17468 emit_load_locked (mode, retval, mem);
17470 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17471 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17473 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17474 emit_unlikely_jump (x, label2);
17476 emit_move_insn (scratch, newval);
17477 emit_store_conditional (mode, cond, mem, scratch);
17479 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17480 emit_unlikely_jump (x, label1);
17482 emit_insn (gen_isync ());
17483 emit_label (XEXP (label2, 0));
17486 /* Expand an atomic test and set operation. MEM is the memory on which
17487 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17490 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17492 enum machine_mode mode = GET_MODE (mem);
17493 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17495 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17496 emit_label (XEXP (label, 0));
17498 emit_load_locked (mode, retval, mem);
17499 emit_move_insn (scratch, val);
17500 emit_store_conditional (mode, cond, mem, scratch);
17502 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17503 emit_unlikely_jump (x, label);
17505 emit_insn (gen_isync ());
17509 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17511 enum machine_mode mode = GET_MODE (mem);
17512 rtx addrSI, align, wdst, shift, mask;
17513 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17514 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17516 /* Shift amount for subword relative to aligned word. */
17517 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17518 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17519 shift = gen_reg_rtx (SImode);
17520 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17521 GEN_INT (shift_mask)));
17522 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17524 /* Shift and mask old value into position within word. */
17525 oldval = convert_modes (SImode, mode, oldval, 1);
17526 oldval = expand_binop (SImode, and_optab,
17527 oldval, GEN_INT (imask), NULL_RTX,
17528 1, OPTAB_LIB_WIDEN);
17529 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17531 /* Shift and mask new value into position within word. */
17532 newval = convert_modes (SImode, mode, newval, 1);
17533 newval = expand_binop (SImode, and_optab,
17534 newval, GEN_INT (imask), NULL_RTX,
17535 1, OPTAB_LIB_WIDEN);
17536 emit_insn (gen_ashlsi3 (newval, newval, shift));
17538 /* Mask for insertion. */
17539 mask = gen_reg_rtx (SImode);
17540 emit_move_insn (mask, GEN_INT (imask));
17541 emit_insn (gen_ashlsi3 (mask, mask, shift));
17543 /* Address of aligned word containing subword. */
17544 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17545 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17546 mem = change_address (mem, SImode, align);
17547 set_mem_align (mem, 32);
17548 MEM_VOLATILE_P (mem) = 1;
17550 wdst = gen_reg_rtx (SImode);
17551 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17552 oldval, newval, mem));
17554 /* Shift the result back. */
17555 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17557 emit_move_insn (dst, gen_lowpart (mode, wdst));
17561 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17562 rtx oldval, rtx newval, rtx mem,
17565 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17567 emit_insn (gen_lwsync ());
17568 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17569 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17570 emit_label (XEXP (label1, 0));
17572 emit_load_locked (SImode, scratch, mem);
17574 /* Mask subword within loaded value for comparison with oldval.
17575 Use UNSPEC_AND to avoid clobber.*/
17576 emit_insn (gen_rtx_SET (SImode, dest,
17577 gen_rtx_UNSPEC (SImode,
17578 gen_rtvec (2, scratch, mask),
17581 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17582 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17584 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17585 emit_unlikely_jump (x, label2);
17587 /* Clear subword within loaded value for insertion of new value. */
17588 emit_insn (gen_rtx_SET (SImode, scratch,
17589 gen_rtx_AND (SImode,
17590 gen_rtx_NOT (SImode, mask), scratch)));
17591 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17592 emit_store_conditional (SImode, cond, mem, scratch);
17594 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17595 emit_unlikely_jump (x, label1);
17597 emit_insn (gen_isync ());
17598 emit_label (XEXP (label2, 0));
17602 /* Emit instructions to move SRC to DST. Called by splitters for
17603 multi-register moves. It will emit at most one instruction for
17604 each register that is accessed; that is, it won't emit li/lis pairs
17605 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17609 rs6000_split_multireg_move (rtx dst, rtx src)
17611 /* The register number of the first register being moved. */
17613 /* The mode that is to be moved. */
17614 enum machine_mode mode;
17615 /* The mode that the move is being done in, and its size. */
17616 enum machine_mode reg_mode;
17618 /* The number of registers that will be moved. */
17621 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17622 mode = GET_MODE (dst);
17623 nregs = hard_regno_nregs[reg][mode];
17624 if (FP_REGNO_P (reg))
17625 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17626 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17627 else if (ALTIVEC_REGNO_P (reg))
17628 reg_mode = V16QImode;
17629 else if (TARGET_E500_DOUBLE && mode == TFmode)
17632 reg_mode = word_mode;
17633 reg_mode_size = GET_MODE_SIZE (reg_mode);
17635 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17637 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17639 /* Move register range backwards, if we might have destructive
17642 for (i = nregs - 1; i >= 0; i--)
17643 emit_insn (gen_rtx_SET (VOIDmode,
17644 simplify_gen_subreg (reg_mode, dst, mode,
17645 i * reg_mode_size),
17646 simplify_gen_subreg (reg_mode, src, mode,
17647 i * reg_mode_size)));
17653 bool used_update = false;
17654 rtx restore_basereg = NULL_RTX;
17656 if (MEM_P (src) && INT_REGNO_P (reg))
17660 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17661 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17664 breg = XEXP (XEXP (src, 0), 0);
17665 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17666 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17667 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17668 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17669 src = replace_equiv_address (src, breg);
17671 else if (! rs6000_offsettable_memref_p (src))
17673 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17675 rtx basereg = XEXP (XEXP (src, 0), 0);
17678 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17679 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17680 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17681 used_update = true;
17684 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17685 XEXP (XEXP (src, 0), 1)));
17686 src = replace_equiv_address (src, basereg);
17690 rtx basereg = gen_rtx_REG (Pmode, reg);
17691 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17692 src = replace_equiv_address (src, basereg);
17696 breg = XEXP (src, 0);
17697 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17698 breg = XEXP (breg, 0);
17700 /* If the base register we are using to address memory is
17701 also a destination reg, then change that register last. */
17703 && REGNO (breg) >= REGNO (dst)
17704 && REGNO (breg) < REGNO (dst) + nregs)
17705 j = REGNO (breg) - REGNO (dst);
17707 else if (MEM_P (dst) && INT_REGNO_P (reg))
17711 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17712 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17715 breg = XEXP (XEXP (dst, 0), 0);
17716 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17717 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17718 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17720 /* We have to update the breg before doing the store.
17721 Use store with update, if available. */
17725 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17726 emit_insn (TARGET_32BIT
17727 ? (TARGET_POWERPC64
17728 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17729 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17730 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17731 used_update = true;
17734 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17735 dst = replace_equiv_address (dst, breg);
17737 else if (!rs6000_offsettable_memref_p (dst)
17738 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17740 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17742 rtx basereg = XEXP (XEXP (dst, 0), 0);
17745 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17746 emit_insn (gen_rtx_SET (VOIDmode,
17747 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17748 used_update = true;
17751 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17752 XEXP (XEXP (dst, 0), 1)));
17753 dst = replace_equiv_address (dst, basereg);
17757 rtx basereg = XEXP (XEXP (dst, 0), 0);
17758 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17759 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17761 && REG_P (offsetreg)
17762 && REGNO (basereg) != REGNO (offsetreg));
17763 if (REGNO (basereg) == 0)
17765 rtx tmp = offsetreg;
17766 offsetreg = basereg;
17769 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17770 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17771 dst = replace_equiv_address (dst, basereg);
17774 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17775 gcc_assert (rs6000_offsettable_memref_p (dst));
17778 for (i = 0; i < nregs; i++)
17780 /* Calculate index to next subword. */
17785 /* If compiler already emitted move of first word by
17786 store with update, no need to do anything. */
17787 if (j == 0 && used_update)
17790 emit_insn (gen_rtx_SET (VOIDmode,
17791 simplify_gen_subreg (reg_mode, dst, mode,
17792 j * reg_mode_size),
17793 simplify_gen_subreg (reg_mode, src, mode,
17794 j * reg_mode_size)));
17796 if (restore_basereg != NULL_RTX)
17797 emit_insn (restore_basereg);
17802 /* This page contains routines that are used to determine what the
17803 function prologue and epilogue code will do and write them out. */
17805 /* Return the first fixed-point register that is required to be
17806 saved. 32 if none. */
17809 first_reg_to_save (void)
17813 /* Find lowest numbered live register. */
17814 for (first_reg = 13; first_reg <= 31; first_reg++)
17815 if (df_regs_ever_live_p (first_reg)
17816 && (! call_used_regs[first_reg]
17817 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17818 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17819 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17820 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17825 && crtl->uses_pic_offset_table
17826 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17827 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17833 /* Similar, for FP regs. */
17836 first_fp_reg_to_save (void)
17840 /* Find lowest numbered live register. */
17841 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17842 if (df_regs_ever_live_p (first_reg))
17848 /* Similar, for AltiVec regs. */
17851 first_altivec_reg_to_save (void)
17855 /* Stack frame remains as is unless we are in AltiVec ABI. */
17856 if (! TARGET_ALTIVEC_ABI)
17857 return LAST_ALTIVEC_REGNO + 1;
17859 /* On Darwin, the unwind routines are compiled without
17860 TARGET_ALTIVEC, and use save_world to save/restore the
17861 altivec registers when necessary. */
17862 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17863 && ! TARGET_ALTIVEC)
17864 return FIRST_ALTIVEC_REGNO + 20;
17866 /* Find lowest numbered live register. */
17867 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17868 if (df_regs_ever_live_p (i))
17874 /* Return a 32-bit mask of the AltiVec registers we need to set in
17875 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17876 the 32-bit word is 0. */
17878 static unsigned int
17879 compute_vrsave_mask (void)
17881 unsigned int i, mask = 0;
17883 /* On Darwin, the unwind routines are compiled without
17884 TARGET_ALTIVEC, and use save_world to save/restore the
17885 call-saved altivec registers when necessary. */
17886 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17887 && ! TARGET_ALTIVEC)
17890 /* First, find out if we use _any_ altivec registers. */
17891 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17892 if (df_regs_ever_live_p (i))
17893 mask |= ALTIVEC_REG_BIT (i);
17898 /* Next, remove the argument registers from the set. These must
17899 be in the VRSAVE mask set by the caller, so we don't need to add
17900 them in again. More importantly, the mask we compute here is
17901 used to generate CLOBBERs in the set_vrsave insn, and we do not
17902 wish the argument registers to die. */
17903 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17904 mask &= ~ALTIVEC_REG_BIT (i);
17906 /* Similarly, remove the return value from the set. */
17909 diddle_return_value (is_altivec_return_reg, &yes);
17911 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17917 /* For a very restricted set of circumstances, we can cut down the
17918 size of prologues/epilogues by calling our own save/restore-the-world
17922 compute_save_world_info (rs6000_stack_t *info_ptr)
17924 info_ptr->world_save_p = 1;
17925 info_ptr->world_save_p
17926 = (WORLD_SAVE_P (info_ptr)
17927 && DEFAULT_ABI == ABI_DARWIN
17928 && ! (cfun->calls_setjmp && flag_exceptions)
17929 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17930 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17931 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17932 && info_ptr->cr_save_p);
17934 /* This will not work in conjunction with sibcalls. Make sure there
17935 are none. (This check is expensive, but seldom executed.) */
17936 if (WORLD_SAVE_P (info_ptr))
17939 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17940 if ( GET_CODE (insn) == CALL_INSN
17941 && SIBLING_CALL_P (insn))
17943 info_ptr->world_save_p = 0;
17948 if (WORLD_SAVE_P (info_ptr))
17950 /* Even if we're not touching VRsave, make sure there's room on the
17951 stack for it, if it looks like we're calling SAVE_WORLD, which
17952 will attempt to save it. */
17953 info_ptr->vrsave_size = 4;
17955 /* If we are going to save the world, we need to save the link register too. */
17956 info_ptr->lr_save_p = 1;
17958 /* "Save" the VRsave register too if we're saving the world. */
17959 if (info_ptr->vrsave_mask == 0)
17960 info_ptr->vrsave_mask = compute_vrsave_mask ();
17962 /* Because the Darwin register save/restore routines only handle
17963 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17965 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17966 && (info_ptr->first_altivec_reg_save
17967 >= FIRST_SAVED_ALTIVEC_REGNO));
17974 is_altivec_return_reg (rtx reg, void *xyes)
17976 bool *yes = (bool *) xyes;
17977 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17982 /* Calculate the stack information for the current function. This is
17983 complicated by having two separate calling sequences, the AIX calling
17984 sequence and the V.4 calling sequence.
17986 AIX (and Darwin/Mac OS X) stack frames look like:
17988 SP----> +---------------------------------------+
17989 | back chain to caller | 0 0
17990 +---------------------------------------+
17991 | saved CR | 4 8 (8-11)
17992 +---------------------------------------+
17994 +---------------------------------------+
17995 | reserved for compilers | 12 24
17996 +---------------------------------------+
17997 | reserved for binders | 16 32
17998 +---------------------------------------+
17999 | saved TOC pointer | 20 40
18000 +---------------------------------------+
18001 | Parameter save area (P) | 24 48
18002 +---------------------------------------+
18003 | Alloca space (A) | 24+P etc.
18004 +---------------------------------------+
18005 | Local variable space (L) | 24+P+A
18006 +---------------------------------------+
18007 | Float/int conversion temporary (X) | 24+P+A+L
18008 +---------------------------------------+
18009 | Save area for AltiVec registers (W) | 24+P+A+L+X
18010 +---------------------------------------+
18011 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18012 +---------------------------------------+
18013 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18014 +---------------------------------------+
18015 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18016 +---------------------------------------+
18017 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18018 +---------------------------------------+
18019 old SP->| back chain to caller's caller |
18020 +---------------------------------------+
18022 The required alignment for AIX configurations is two words (i.e., 8
18026 V.4 stack frames look like:
18028 SP----> +---------------------------------------+
18029 | back chain to caller | 0
18030 +---------------------------------------+
18031 | caller's saved LR | 4
18032 +---------------------------------------+
18033 | Parameter save area (P) | 8
18034 +---------------------------------------+
18035 | Alloca space (A) | 8+P
18036 +---------------------------------------+
18037 | Varargs save area (V) | 8+P+A
18038 +---------------------------------------+
18039 | Local variable space (L) | 8+P+A+V
18040 +---------------------------------------+
18041 | Float/int conversion temporary (X) | 8+P+A+V+L
18042 +---------------------------------------+
18043 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18044 +---------------------------------------+
18045 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18046 +---------------------------------------+
18047 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18048 +---------------------------------------+
18049 | SPE: area for 64-bit GP registers |
18050 +---------------------------------------+
18051 | SPE alignment padding |
18052 +---------------------------------------+
18053 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18054 +---------------------------------------+
18055 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18056 +---------------------------------------+
18057 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18058 +---------------------------------------+
18059 old SP->| back chain to caller's caller |
18060 +---------------------------------------+
18062 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18063 given. (But note below and in sysv4.h that we require only 8 and
18064 may round up the size of our stack frame anyways. The historical
18065 reason is early versions of powerpc-linux which didn't properly
18066 align the stack at program startup. A happy side-effect is that
18067 -mno-eabi libraries can be used with -meabi programs.)
18069 The EABI configuration defaults to the V.4 layout. However,
18070 the stack alignment requirements may differ. If -mno-eabi is not
18071 given, the required stack alignment is 8 bytes; if -mno-eabi is
18072 given, the required alignment is 16 bytes. (But see V.4 comment
18075 #ifndef ABI_STACK_BOUNDARY
18076 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18079 static rs6000_stack_t *
18080 rs6000_stack_info (void)
18082 static rs6000_stack_t info;
18083 rs6000_stack_t *info_ptr = &info;
18084 int reg_size = TARGET_32BIT ? 4 : 8;
18088 HOST_WIDE_INT non_fixed_size;
18090 memset (&info, 0, sizeof (info));
18094 /* Cache value so we don't rescan instruction chain over and over. */
18095 if (cfun->machine->insn_chain_scanned_p == 0)
18096 cfun->machine->insn_chain_scanned_p
18097 = spe_func_has_64bit_regs_p () + 1;
18098 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18101 /* Select which calling sequence. */
18102 info_ptr->abi = DEFAULT_ABI;
18104 /* Calculate which registers need to be saved & save area size. */
18105 info_ptr->first_gp_reg_save = first_reg_to_save ();
18106 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18107 even if it currently looks like we won't. Reload may need it to
18108 get at a constant; if so, it will have already created a constant
18109 pool entry for it. */
18110 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18111 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18112 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18113 && crtl->uses_const_pool
18114 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18115 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18117 first_gp = info_ptr->first_gp_reg_save;
18119 info_ptr->gp_size = reg_size * (32 - first_gp);
18121 /* For the SPE, we have an additional upper 32-bits on each GPR.
18122 Ideally we should save the entire 64-bits only when the upper
18123 half is used in SIMD instructions. Since we only record
18124 registers live (not the size they are used in), this proves
18125 difficult because we'd have to traverse the instruction chain at
18126 the right time, taking reload into account. This is a real pain,
18127 so we opt to save the GPRs in 64-bits always if but one register
18128 gets used in 64-bits. Otherwise, all the registers in the frame
18129 get saved in 32-bits.
18131 So... since when we save all GPRs (except the SP) in 64-bits, the
18132 traditional GP save area will be empty. */
18133 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18134 info_ptr->gp_size = 0;
18136 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18137 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18139 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18140 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18141 - info_ptr->first_altivec_reg_save);
18143 /* Does this function call anything? */
18144 info_ptr->calls_p = (! current_function_is_leaf
18145 || cfun->machine->ra_needs_full_frame);
18147 /* Determine if we need to save the link register. */
18148 if ((DEFAULT_ABI == ABI_AIX
18150 && !TARGET_PROFILE_KERNEL)
18151 #ifdef TARGET_RELOCATABLE
18152 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18154 || (info_ptr->first_fp_reg_save != 64
18155 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
18156 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18157 || info_ptr->calls_p
18158 || rs6000_ra_ever_killed ())
18160 info_ptr->lr_save_p = 1;
18161 df_set_regs_ever_live (LR_REGNO, true);
18164 /* Determine if we need to save the condition code registers. */
18165 if (df_regs_ever_live_p (CR2_REGNO)
18166 || df_regs_ever_live_p (CR3_REGNO)
18167 || df_regs_ever_live_p (CR4_REGNO))
18169 info_ptr->cr_save_p = 1;
18170 if (DEFAULT_ABI == ABI_V4)
18171 info_ptr->cr_size = reg_size;
18174 /* If the current function calls __builtin_eh_return, then we need
18175 to allocate stack space for registers that will hold data for
18176 the exception handler. */
18177 if (crtl->calls_eh_return)
18180 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18183 /* SPE saves EH registers in 64-bits. */
18184 ehrd_size = i * (TARGET_SPE_ABI
18185 && info_ptr->spe_64bit_regs_used != 0
18186 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18191 /* Determine various sizes. */
18192 info_ptr->reg_size = reg_size;
18193 info_ptr->fixed_size = RS6000_SAVE_AREA;
18194 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18195 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18196 TARGET_ALTIVEC ? 16 : 8);
18197 if (FRAME_GROWS_DOWNWARD)
18198 info_ptr->vars_size
18199 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18200 + info_ptr->parm_size,
18201 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18202 - (info_ptr->fixed_size + info_ptr->vars_size
18203 + info_ptr->parm_size);
18205 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18206 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18208 info_ptr->spe_gp_size = 0;
18210 if (TARGET_ALTIVEC_ABI)
18211 info_ptr->vrsave_mask = compute_vrsave_mask ();
18213 info_ptr->vrsave_mask = 0;
18215 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18216 info_ptr->vrsave_size = 4;
18218 info_ptr->vrsave_size = 0;
18220 compute_save_world_info (info_ptr);
18222 /* Calculate the offsets. */
18223 switch (DEFAULT_ABI)
18227 gcc_unreachable ();
18231 info_ptr->fp_save_offset = - info_ptr->fp_size;
18232 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18234 if (TARGET_ALTIVEC_ABI)
18236 info_ptr->vrsave_save_offset
18237 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18239 /* Align stack so vector save area is on a quadword boundary.
18240 The padding goes above the vectors. */
18241 if (info_ptr->altivec_size != 0)
18242 info_ptr->altivec_padding_size
18243 = info_ptr->vrsave_save_offset & 0xF;
18245 info_ptr->altivec_padding_size = 0;
18247 info_ptr->altivec_save_offset
18248 = info_ptr->vrsave_save_offset
18249 - info_ptr->altivec_padding_size
18250 - info_ptr->altivec_size;
18251 gcc_assert (info_ptr->altivec_size == 0
18252 || info_ptr->altivec_save_offset % 16 == 0);
18254 /* Adjust for AltiVec case. */
18255 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18258 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18259 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18260 info_ptr->lr_save_offset = 2*reg_size;
18264 info_ptr->fp_save_offset = - info_ptr->fp_size;
18265 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18266 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18268 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18270 /* Align stack so SPE GPR save area is aligned on a
18271 double-word boundary. */
18272 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18273 info_ptr->spe_padding_size
18274 = 8 - (-info_ptr->cr_save_offset % 8);
18276 info_ptr->spe_padding_size = 0;
18278 info_ptr->spe_gp_save_offset
18279 = info_ptr->cr_save_offset
18280 - info_ptr->spe_padding_size
18281 - info_ptr->spe_gp_size;
18283 /* Adjust for SPE case. */
18284 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18286 else if (TARGET_ALTIVEC_ABI)
18288 info_ptr->vrsave_save_offset
18289 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18291 /* Align stack so vector save area is on a quadword boundary. */
18292 if (info_ptr->altivec_size != 0)
18293 info_ptr->altivec_padding_size
18294 = 16 - (-info_ptr->vrsave_save_offset % 16);
18296 info_ptr->altivec_padding_size = 0;
18298 info_ptr->altivec_save_offset
18299 = info_ptr->vrsave_save_offset
18300 - info_ptr->altivec_padding_size
18301 - info_ptr->altivec_size;
18303 /* Adjust for AltiVec case. */
18304 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18307 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18308 info_ptr->ehrd_offset -= ehrd_size;
18309 info_ptr->lr_save_offset = reg_size;
18313 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18314 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18315 + info_ptr->gp_size
18316 + info_ptr->altivec_size
18317 + info_ptr->altivec_padding_size
18318 + info_ptr->spe_gp_size
18319 + info_ptr->spe_padding_size
18321 + info_ptr->cr_size
18322 + info_ptr->vrsave_size,
18325 non_fixed_size = (info_ptr->vars_size
18326 + info_ptr->parm_size
18327 + info_ptr->save_size);
18329 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18330 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18332 /* Determine if we need to allocate any stack frame:
18334 For AIX we need to push the stack if a frame pointer is needed
18335 (because the stack might be dynamically adjusted), if we are
18336 debugging, if we make calls, or if the sum of fp_save, gp_save,
18337 and local variables are more than the space needed to save all
18338 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18339 + 18*8 = 288 (GPR13 reserved).
18341 For V.4 we don't have the stack cushion that AIX uses, but assume
18342 that the debugger can handle stackless frames. */
18344 if (info_ptr->calls_p)
18345 info_ptr->push_p = 1;
18347 else if (DEFAULT_ABI == ABI_V4)
18348 info_ptr->push_p = non_fixed_size != 0;
18350 else if (frame_pointer_needed)
18351 info_ptr->push_p = 1;
18353 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18354 info_ptr->push_p = 1;
18357 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18359 /* Zero offsets if we're not saving those registers. */
18360 if (info_ptr->fp_size == 0)
18361 info_ptr->fp_save_offset = 0;
18363 if (info_ptr->gp_size == 0)
18364 info_ptr->gp_save_offset = 0;
18366 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18367 info_ptr->altivec_save_offset = 0;
18369 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18370 info_ptr->vrsave_save_offset = 0;
18372 if (! TARGET_SPE_ABI
18373 || info_ptr->spe_64bit_regs_used == 0
18374 || info_ptr->spe_gp_size == 0)
18375 info_ptr->spe_gp_save_offset = 0;
18377 if (! info_ptr->lr_save_p)
18378 info_ptr->lr_save_offset = 0;
18380 if (! info_ptr->cr_save_p)
18381 info_ptr->cr_save_offset = 0;
18386 /* Return true if the current function uses any GPRs in 64-bit SIMD
18390 spe_func_has_64bit_regs_p (void)
18394 /* Functions that save and restore all the call-saved registers will
18395 need to save/restore the registers in 64-bits. */
18396 if (crtl->calls_eh_return
18397 || cfun->calls_setjmp
18398 || crtl->has_nonlocal_goto)
18401 insns = get_insns ();
18403 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18409 /* FIXME: This should be implemented with attributes...
18411 (set_attr "spe64" "true")....then,
18412 if (get_spe64(insn)) return true;
18414 It's the only reliable way to do the stuff below. */
18416 i = PATTERN (insn);
18417 if (GET_CODE (i) == SET)
18419 enum machine_mode mode = GET_MODE (SET_SRC (i));
18421 if (SPE_VECTOR_MODE (mode))
18423 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18433 debug_stack_info (rs6000_stack_t *info)
18435 const char *abi_string;
18438 info = rs6000_stack_info ();
18440 fprintf (stderr, "\nStack information for function %s:\n",
18441 ((current_function_decl && DECL_NAME (current_function_decl))
18442 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18447 default: abi_string = "Unknown"; break;
18448 case ABI_NONE: abi_string = "NONE"; break;
18449 case ABI_AIX: abi_string = "AIX"; break;
18450 case ABI_DARWIN: abi_string = "Darwin"; break;
18451 case ABI_V4: abi_string = "V.4"; break;
18454 fprintf (stderr, "\tABI = %5s\n", abi_string);
18456 if (TARGET_ALTIVEC_ABI)
18457 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18459 if (TARGET_SPE_ABI)
18460 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18462 if (info->first_gp_reg_save != 32)
18463 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18465 if (info->first_fp_reg_save != 64)
18466 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18468 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18469 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18470 info->first_altivec_reg_save);
18472 if (info->lr_save_p)
18473 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18475 if (info->cr_save_p)
18476 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18478 if (info->vrsave_mask)
18479 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18482 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18485 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18487 if (info->gp_save_offset)
18488 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18490 if (info->fp_save_offset)
18491 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18493 if (info->altivec_save_offset)
18494 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18495 info->altivec_save_offset);
18497 if (info->spe_gp_save_offset)
18498 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18499 info->spe_gp_save_offset);
18501 if (info->vrsave_save_offset)
18502 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18503 info->vrsave_save_offset);
18505 if (info->lr_save_offset)
18506 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18508 if (info->cr_save_offset)
18509 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18511 if (info->varargs_save_offset)
18512 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18514 if (info->total_size)
18515 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18518 if (info->vars_size)
18519 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18522 if (info->parm_size)
18523 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18525 if (info->fixed_size)
18526 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18529 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18531 if (info->spe_gp_size)
18532 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18535 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18537 if (info->altivec_size)
18538 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18540 if (info->vrsave_size)
18541 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18543 if (info->altivec_padding_size)
18544 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18545 info->altivec_padding_size);
18547 if (info->spe_padding_size)
18548 fprintf (stderr, "\tspe_padding_size = %5d\n",
18549 info->spe_padding_size);
18552 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18554 if (info->save_size)
18555 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18557 if (info->reg_size != 4)
18558 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18560 fprintf (stderr, "\n");
18564 rs6000_return_addr (int count, rtx frame)
18566 /* Currently we don't optimize very well between prolog and body
18567 code and for PIC code the code can be actually quite bad, so
18568 don't try to be too clever here. */
18569 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18571 cfun->machine->ra_needs_full_frame = 1;
18578 plus_constant (copy_to_reg
18579 (gen_rtx_MEM (Pmode,
18580 memory_address (Pmode, frame))),
18581 RETURN_ADDRESS_OFFSET)));
18584 cfun->machine->ra_need_lr = 1;
18585 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18588 /* Say whether a function is a candidate for sibcall handling or not.
18589 We do not allow indirect calls to be optimized into sibling calls.
18590 Also, we can't do it if there are any vector parameters; there's
18591 nowhere to put the VRsave code so it works; note that functions with
18592 vector parameters are required to have a prototype, so the argument
18593 type info must be available here. (The tail recursion case can work
18594 with vector parameters, but there's no way to distinguish here.) */
18596 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18601 if (TARGET_ALTIVEC_VRSAVE)
18603 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18604 type; type = TREE_CHAIN (type))
18606 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18610 if (DEFAULT_ABI == ABI_DARWIN
18611 || ((*targetm.binds_local_p) (decl)
18612 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18614 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18616 if (!lookup_attribute ("longcall", attr_list)
18617 || lookup_attribute ("shortcall", attr_list))
18624 /* NULL if INSN insn is valid within a low-overhead loop.
18625 Otherwise return why doloop cannot be applied.
18626 PowerPC uses the COUNT register for branch on table instructions. */
18628 static const char *
18629 rs6000_invalid_within_doloop (const_rtx insn)
18632 return "Function call in the loop.";
18635 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18636 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18637 return "Computed branch in the loop.";
18643 rs6000_ra_ever_killed (void)
18649 if (cfun->is_thunk)
18652 if (cfun->machine->lr_save_state)
18653 return cfun->machine->lr_save_state - 1;
18655 /* regs_ever_live has LR marked as used if any sibcalls are present,
18656 but this should not force saving and restoring in the
18657 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18658 clobbers LR, so that is inappropriate. */
18660 /* Also, the prologue can generate a store into LR that
18661 doesn't really count, like this:
18664 bcl to set PIC register
18668 When we're called from the epilogue, we need to avoid counting
18669 this as a store. */
18671 push_topmost_sequence ();
18672 top = get_insns ();
18673 pop_topmost_sequence ();
18674 reg = gen_rtx_REG (Pmode, LR_REGNO);
18676 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18682 if (!SIBLING_CALL_P (insn))
18685 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18687 else if (set_of (reg, insn) != NULL_RTX
18688 && !prologue_epilogue_contains (insn))
18695 /* Emit instructions needed to load the TOC register.
18696 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18697 a constant pool; or for SVR4 -fpic. */
18700 rs6000_emit_load_toc_table (int fromprolog)
18703 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18705 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18708 rtx lab, tmp1, tmp2, got;
18710 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18711 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18713 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18715 got = rs6000_got_sym ();
18716 tmp1 = tmp2 = dest;
18719 tmp1 = gen_reg_rtx (Pmode);
18720 tmp2 = gen_reg_rtx (Pmode);
18722 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18723 emit_move_insn (tmp1,
18724 gen_rtx_REG (Pmode, LR_REGNO));
18725 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18726 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18728 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18730 emit_insn (gen_load_toc_v4_pic_si ());
18731 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18733 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18736 rtx temp0 = (fromprolog
18737 ? gen_rtx_REG (Pmode, 0)
18738 : gen_reg_rtx (Pmode));
18744 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18745 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18747 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18748 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18750 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18751 emit_move_insn (dest,
18752 gen_rtx_REG (Pmode, LR_REGNO));
18753 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18759 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18760 lab = gen_label_rtx ();
18761 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18762 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18763 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18765 emit_insn (gen_addsi3 (dest, temp0, dest));
18767 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18769 /* This is for AIX code running in non-PIC ELF32. */
18772 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18773 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18775 emit_insn (gen_elf_high (dest, realsym));
18776 emit_insn (gen_elf_low (dest, dest, realsym));
18780 gcc_assert (DEFAULT_ABI == ABI_AIX);
18783 emit_insn (gen_load_toc_aix_si (dest));
18785 emit_insn (gen_load_toc_aix_di (dest));
18789 /* Emit instructions to restore the link register after determining where
18790 its value has been stored. */
18793 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18795 rs6000_stack_t *info = rs6000_stack_info ();
18798 operands[0] = source;
18799 operands[1] = scratch;
18801 if (info->lr_save_p)
18803 rtx frame_rtx = stack_pointer_rtx;
18804 HOST_WIDE_INT sp_offset = 0;
18807 if (frame_pointer_needed
18808 || cfun->calls_alloca
18809 || info->total_size > 32767)
18811 tmp = gen_frame_mem (Pmode, frame_rtx);
18812 emit_move_insn (operands[1], tmp);
18813 frame_rtx = operands[1];
18815 else if (info->push_p)
18816 sp_offset = info->total_size;
18818 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18819 tmp = gen_frame_mem (Pmode, tmp);
18820 emit_move_insn (tmp, operands[0]);
18823 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18825 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18826 state of lr_save_p so any change from here on would be a bug. In
18827 particular, stop rs6000_ra_ever_killed from considering the SET
18828 of lr we may have added just above. */
18829 cfun->machine->lr_save_state = info->lr_save_p + 1;
18832 static GTY(()) alias_set_type set = -1;
18835 get_TOC_alias_set (void)
18838 set = new_alias_set ();
18842 /* This returns nonzero if the current function uses the TOC. This is
18843 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18844 is generated by the ABI_V4 load_toc_* patterns. */
18851 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18854 rtx pat = PATTERN (insn);
18857 if (GET_CODE (pat) == PARALLEL)
18858 for (i = 0; i < XVECLEN (pat, 0); i++)
18860 rtx sub = XVECEXP (pat, 0, i);
18861 if (GET_CODE (sub) == USE)
18863 sub = XEXP (sub, 0);
18864 if (GET_CODE (sub) == UNSPEC
18865 && XINT (sub, 1) == UNSPEC_TOC)
18875 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18877 rtx tocrel, tocreg;
18879 if (TARGET_DEBUG_ADDR)
18881 if (GET_CODE (symbol) == SYMBOL_REF)
18882 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18886 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18887 GET_RTX_NAME (GET_CODE (symbol)));
18888 debug_rtx (symbol);
18892 if (!can_create_pseudo_p ())
18893 df_set_regs_ever_live (TOC_REGISTER, true);
18895 tocrel = gen_rtx_CONST (Pmode,
18896 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18898 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18899 if (TARGET_CMODEL != CMODEL_SMALL)
18901 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18902 if (largetoc_reg != NULL)
18904 emit_move_insn (largetoc_reg, hi);
18907 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18910 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18913 /* Issue assembly directives that create a reference to the given DWARF
18914 FRAME_TABLE_LABEL from the current function section. */
18916 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18918 fprintf (asm_out_file, "\t.ref %s\n",
18919 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18922 /* If _Unwind_* has been called from within the same module,
18923 toc register is not guaranteed to be saved to 40(1) on function
18924 entry. Save it there in that case. */
18927 rs6000_aix_emit_builtin_unwind_init (void)
18930 rtx stack_top = gen_reg_rtx (Pmode);
18931 rtx opcode_addr = gen_reg_rtx (Pmode);
18932 rtx opcode = gen_reg_rtx (SImode);
18933 rtx tocompare = gen_reg_rtx (SImode);
18934 rtx no_toc_save_needed = gen_label_rtx ();
18936 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18937 emit_move_insn (stack_top, mem);
18939 mem = gen_frame_mem (Pmode,
18940 gen_rtx_PLUS (Pmode, stack_top,
18941 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18942 emit_move_insn (opcode_addr, mem);
18943 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18944 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18945 : 0xE8410028, SImode));
18947 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18948 SImode, NULL_RTX, NULL_RTX,
18949 no_toc_save_needed, -1);
18951 mem = gen_frame_mem (Pmode,
18952 gen_rtx_PLUS (Pmode, stack_top,
18953 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18954 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18955 emit_label (no_toc_save_needed);
18958 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18959 and the change to the stack pointer. */
18962 rs6000_emit_stack_tie (void)
18964 rtx mem = gen_frame_mem (BLKmode,
18965 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18967 emit_insn (gen_stack_tie (mem));
18970 /* Emit the correct code for allocating stack space, as insns.
18971 If COPY_REG, make sure a copy of the old frame is left there.
18972 The generated code may use hard register 0 as a temporary. */
18975 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18978 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18979 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18980 rtx todec = gen_int_mode (-size, Pmode);
18983 if (INTVAL (todec) != -size)
18985 warning (0, "stack frame too large");
18986 emit_insn (gen_trap ());
18990 if (crtl->limit_stack)
18992 if (REG_P (stack_limit_rtx)
18993 && REGNO (stack_limit_rtx) > 1
18994 && REGNO (stack_limit_rtx) <= 31)
18996 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18997 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19000 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19002 && DEFAULT_ABI == ABI_V4)
19004 rtx toload = gen_rtx_CONST (VOIDmode,
19005 gen_rtx_PLUS (Pmode,
19009 emit_insn (gen_elf_high (tmp_reg, toload));
19010 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19011 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19015 warning (0, "stack limit expression is not supported");
19019 emit_move_insn (copy_reg, stack_reg);
19023 /* Need a note here so that try_split doesn't get confused. */
19024 if (get_last_insn () == NULL_RTX)
19025 emit_note (NOTE_INSN_DELETED);
19026 insn = emit_move_insn (tmp_reg, todec);
19027 try_split (PATTERN (insn), insn, 0);
19031 insn = emit_insn (TARGET_32BIT
19032 ? gen_movsi_update_stack (stack_reg, stack_reg,
19034 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19035 todec, stack_reg));
19036 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19037 it now and set the alias set/attributes. The above gen_*_update
19038 calls will generate a PARALLEL with the MEM set being the first
19040 par = PATTERN (insn);
19041 gcc_assert (GET_CODE (par) == PARALLEL);
19042 set = XVECEXP (par, 0, 0);
19043 gcc_assert (GET_CODE (set) == SET);
19044 mem = SET_DEST (set);
19045 gcc_assert (MEM_P (mem));
19046 MEM_NOTRAP_P (mem) = 1;
19047 set_mem_alias_set (mem, get_frame_alias_set ());
19049 RTX_FRAME_RELATED_P (insn) = 1;
19050 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19051 gen_rtx_SET (VOIDmode, stack_reg,
19052 gen_rtx_PLUS (Pmode, stack_reg,
19053 GEN_INT (-size))));
19056 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19058 #if PROBE_INTERVAL > 32768
19059 #error Cannot use indexed addressing mode for stack probing
19062 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19063 inclusive. These are offsets from the current stack pointer. */
19066 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19068 /* See if we have a constant small number of probes to generate. If so,
19069 that's the easy case. */
19070 if (first + size <= 32768)
19074 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19075 it exceeds SIZE. If only one probe is needed, this will not
19076 generate any code. Then probe at FIRST + SIZE. */
19077 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19078 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19080 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19083 /* Otherwise, do the same as above, but in a loop. Note that we must be
19084 extra careful with variables wrapping around because we might be at
19085 the very top (or the very bottom) of the address space and we have
19086 to be able to handle this case properly; in particular, we use an
19087 equality test for the loop condition. */
19090 HOST_WIDE_INT rounded_size;
19091 rtx r12 = gen_rtx_REG (Pmode, 12);
19092 rtx r0 = gen_rtx_REG (Pmode, 0);
19094 /* Sanity check for the addressing mode we're going to use. */
19095 gcc_assert (first <= 32768);
19097 /* Step 1: round SIZE to the previous multiple of the interval. */
19099 rounded_size = size & -PROBE_INTERVAL;
19102 /* Step 2: compute initial and final value of the loop counter. */
19104 /* TEST_ADDR = SP + FIRST. */
19105 emit_insn (gen_rtx_SET (VOIDmode, r12,
19106 plus_constant (stack_pointer_rtx, -first)));
19108 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19109 if (rounded_size > 32768)
19111 emit_move_insn (r0, GEN_INT (-rounded_size));
19112 emit_insn (gen_rtx_SET (VOIDmode, r0,
19113 gen_rtx_PLUS (Pmode, r12, r0)));
19116 emit_insn (gen_rtx_SET (VOIDmode, r0,
19117 plus_constant (r12, -rounded_size)));
19120 /* Step 3: the loop
19122 while (TEST_ADDR != LAST_ADDR)
19124 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19128 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19129 until it is equal to ROUNDED_SIZE. */
19132 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19134 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19137 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19138 that SIZE is equal to ROUNDED_SIZE. */
19140 if (size != rounded_size)
19141 emit_stack_probe (plus_constant (r12, rounded_size - size));
19145 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19146 absolute addresses. */
19149 output_probe_stack_range (rtx reg1, rtx reg2)
19151 static int labelno = 0;
19152 char loop_lab[32], end_lab[32];
19155 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19156 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19158 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19160 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19164 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19166 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19168 fputs ("\tbeq 0,", asm_out_file);
19169 assemble_name_raw (asm_out_file, end_lab);
19170 fputc ('\n', asm_out_file);
19172 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19173 xops[1] = GEN_INT (-PROBE_INTERVAL);
19174 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19176 /* Probe at TEST_ADDR and branch. */
19177 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19178 fprintf (asm_out_file, "\tb ");
19179 assemble_name_raw (asm_out_file, loop_lab);
19180 fputc ('\n', asm_out_file);
19182 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19187 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19188 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19189 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19190 deduce these equivalences by itself so it wasn't necessary to hold
19191 its hand so much. */
19194 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19195 rtx reg2, rtx rreg)
19199 /* copy_rtx will not make unique copies of registers, so we need to
19200 ensure we don't have unwanted sharing here. */
19202 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19205 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19207 real = copy_rtx (PATTERN (insn));
19209 if (reg2 != NULL_RTX)
19210 real = replace_rtx (real, reg2, rreg);
19212 real = replace_rtx (real, reg,
19213 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19214 STACK_POINTER_REGNUM),
19217 /* We expect that 'real' is either a SET or a PARALLEL containing
19218 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19219 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19221 if (GET_CODE (real) == SET)
19225 temp = simplify_rtx (SET_SRC (set));
19227 SET_SRC (set) = temp;
19228 temp = simplify_rtx (SET_DEST (set));
19230 SET_DEST (set) = temp;
19231 if (GET_CODE (SET_DEST (set)) == MEM)
19233 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19235 XEXP (SET_DEST (set), 0) = temp;
19242 gcc_assert (GET_CODE (real) == PARALLEL);
19243 for (i = 0; i < XVECLEN (real, 0); i++)
19244 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19246 rtx set = XVECEXP (real, 0, i);
19248 temp = simplify_rtx (SET_SRC (set));
19250 SET_SRC (set) = temp;
19251 temp = simplify_rtx (SET_DEST (set));
19253 SET_DEST (set) = temp;
19254 if (GET_CODE (SET_DEST (set)) == MEM)
19256 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19258 XEXP (SET_DEST (set), 0) = temp;
19260 RTX_FRAME_RELATED_P (set) = 1;
19264 RTX_FRAME_RELATED_P (insn) = 1;
19265 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19268 /* Returns an insn that has a vrsave set operation with the
19269 appropriate CLOBBERs. */
19272 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19275 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19276 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19279 = gen_rtx_SET (VOIDmode,
19281 gen_rtx_UNSPEC_VOLATILE (SImode,
19282 gen_rtvec (2, reg, vrsave),
19283 UNSPECV_SET_VRSAVE));
19287 /* We need to clobber the registers in the mask so the scheduler
19288 does not move sets to VRSAVE before sets of AltiVec registers.
19290 However, if the function receives nonlocal gotos, reload will set
19291 all call saved registers live. We will end up with:
19293 (set (reg 999) (mem))
19294 (parallel [ (set (reg vrsave) (unspec blah))
19295 (clobber (reg 999))])
19297 The clobber will cause the store into reg 999 to be dead, and
19298 flow will attempt to delete an epilogue insn. In this case, we
19299 need an unspec use/set of the register. */
19301 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19302 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19304 if (!epiloguep || call_used_regs [i])
19305 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19306 gen_rtx_REG (V4SImode, i));
19309 rtx reg = gen_rtx_REG (V4SImode, i);
19312 = gen_rtx_SET (VOIDmode,
19314 gen_rtx_UNSPEC (V4SImode,
19315 gen_rtvec (1, reg), 27));
19319 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19321 for (i = 0; i < nclobs; ++i)
19322 XVECEXP (insn, 0, i) = clobs[i];
19327 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19328 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19331 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19332 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19334 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19335 rtx replacea, replaceb;
19337 int_rtx = GEN_INT (offset);
19339 /* Some cases that need register indexed addressing. */
19340 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19341 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19342 || (TARGET_E500_DOUBLE && mode == DFmode)
19344 && SPE_VECTOR_MODE (mode)
19345 && !SPE_CONST_OFFSET_OK (offset)))
19347 /* Whomever calls us must make sure r11 is available in the
19348 flow path of instructions in the prologue. */
19349 offset_rtx = gen_rtx_REG (Pmode, 11);
19350 emit_move_insn (offset_rtx, int_rtx);
19352 replacea = offset_rtx;
19353 replaceb = int_rtx;
19357 offset_rtx = int_rtx;
19358 replacea = NULL_RTX;
19359 replaceb = NULL_RTX;
19362 reg = gen_rtx_REG (mode, regno);
19363 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19364 mem = gen_frame_mem (mode, addr);
19366 insn = emit_move_insn (mem, reg);
19368 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19371 /* Emit an offset memory reference suitable for a frame store, while
19372 converting to a valid addressing mode. */
19375 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19377 rtx int_rtx, offset_rtx;
19379 int_rtx = GEN_INT (offset);
19381 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19382 || (TARGET_E500_DOUBLE && mode == DFmode))
19384 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19385 emit_move_insn (offset_rtx, int_rtx);
19388 offset_rtx = int_rtx;
19390 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19393 /* Look for user-defined global regs. We should not save and restore these,
19394 and cannot use stmw/lmw if there are any in its range. */
19397 no_global_regs_above (int first, bool gpr)
19400 int last = gpr ? 32 : 64;
19401 for (i = first; i < last; i++)
19402 if (global_regs[i])
19407 #ifndef TARGET_FIX_AND_CONTINUE
19408 #define TARGET_FIX_AND_CONTINUE 0
19411 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19412 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19413 #define LAST_SAVRES_REGISTER 31
19414 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19416 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19418 /* Temporary holding space for an out-of-line register save/restore
19420 static char savres_routine_name[30];
19422 /* Return the name for an out-of-line register save/restore routine.
19423 We are saving/restoring GPRs if GPR is true. */
19426 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19427 bool savep, bool gpr, bool lr)
19429 const char *prefix = "";
19430 const char *suffix = "";
19432 /* Different targets are supposed to define
19433 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19434 routine name could be defined with:
19436 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19438 This is a nice idea in practice, but in reality, things are
19439 complicated in several ways:
19441 - ELF targets have save/restore routines for GPRs.
19443 - SPE targets use different prefixes for 32/64-bit registers, and
19444 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19446 - PPC64 ELF targets have routines for save/restore of GPRs that
19447 differ in what they do with the link register, so having a set
19448 prefix doesn't work. (We only use one of the save routines at
19449 the moment, though.)
19451 - PPC32 elf targets have "exit" versions of the restore routines
19452 that restore the link register and can save some extra space.
19453 These require an extra suffix. (There are also "tail" versions
19454 of the restore routines and "GOT" versions of the save routines,
19455 but we don't generate those at present. Same problems apply,
19458 We deal with all this by synthesizing our own prefix/suffix and
19459 using that for the simple sprintf call shown above. */
19462 /* No floating point saves on the SPE. */
19466 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19468 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19473 else if (DEFAULT_ABI == ABI_V4)
19479 prefix = savep ? "_savegpr_" : "_restgpr_";
19481 prefix = savep ? "_savefpr_" : "_restfpr_";
19486 else if (DEFAULT_ABI == ABI_AIX)
19488 #ifndef POWERPC_LINUX
19489 /* No out-of-line save/restore routines for GPRs on AIX. */
19490 gcc_assert (!TARGET_AIX || !gpr);
19496 ? (lr ? "_savegpr0_" : "_savegpr1_")
19497 : (lr ? "_restgpr0_" : "_restgpr1_"));
19498 #ifdef POWERPC_LINUX
19500 prefix = (savep ? "_savefpr_" : "_restfpr_");
19504 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19505 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19508 else if (DEFAULT_ABI == ABI_DARWIN)
19509 sorry ("Out-of-line save/restore routines not supported on Darwin");
19511 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19513 return savres_routine_name;
19516 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19517 We are saving/restoring GPRs if GPR is true. */
19520 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19523 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19525 int select = ((savep ? 1 : 0) << 2
19527 /* On the SPE, we never have any FPRs, but we do have
19528 32/64-bit versions of the routines. */
19529 ? (info->spe_64bit_regs_used ? 1 : 0)
19530 : (gpr ? 1 : 0)) << 1)
19533 /* Don't generate bogus routine names. */
19534 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19535 && regno <= LAST_SAVRES_REGISTER);
19537 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19543 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19545 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19546 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19547 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19553 /* Emit a sequence of insns, including a stack tie if needed, for
19554 resetting the stack pointer. If SAVRES is true, then don't reset the
19555 stack pointer, but move the base of the frame into r11 for use by
19556 out-of-line register restore routines. */
19559 rs6000_emit_stack_reset (rs6000_stack_t *info,
19560 rtx sp_reg_rtx, rtx frame_reg_rtx,
19561 int sp_offset, bool savres)
19563 /* This blockage is needed so that sched doesn't decide to move
19564 the sp change before the register restores. */
19565 if (frame_reg_rtx != sp_reg_rtx
19567 && info->spe_64bit_regs_used != 0
19568 && info->first_gp_reg_save != 32))
19569 rs6000_emit_stack_tie ();
19571 if (frame_reg_rtx != sp_reg_rtx)
19573 if (sp_offset != 0)
19575 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19576 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19577 GEN_INT (sp_offset)));
19580 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19582 else if (sp_offset != 0)
19584 /* If we are restoring registers out-of-line, we will be using the
19585 "exit" variants of the restore routines, which will reset the
19586 stack for us. But we do need to point r11 into the right place
19587 for those routines. */
19588 rtx dest_reg = (savres
19589 ? gen_rtx_REG (Pmode, 11)
19592 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19593 GEN_INT (sp_offset)));
19600 /* Construct a parallel rtx describing the effect of a call to an
19601 out-of-line register save/restore routine. */
19604 rs6000_make_savres_rtx (rs6000_stack_t *info,
19605 rtx frame_reg_rtx, int save_area_offset,
19606 enum machine_mode reg_mode,
19607 bool savep, bool gpr, bool lr)
19610 int offset, start_reg, end_reg, n_regs;
19611 int reg_size = GET_MODE_SIZE (reg_mode);
19617 ? info->first_gp_reg_save
19618 : info->first_fp_reg_save);
19619 end_reg = gpr ? 32 : 64;
19620 n_regs = end_reg - start_reg;
19621 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19624 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19626 RTVEC_ELT (p, offset++)
19627 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19629 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19630 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19631 RTVEC_ELT (p, offset++)
19632 = gen_rtx_USE (VOIDmode,
19633 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19637 for (i = 0; i < end_reg - start_reg; i++)
19639 rtx addr, reg, mem;
19640 reg = gen_rtx_REG (reg_mode, start_reg + i);
19641 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19642 GEN_INT (save_area_offset + reg_size*i));
19643 mem = gen_frame_mem (reg_mode, addr);
19645 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19647 savep ? reg : mem);
19652 rtx addr, reg, mem;
19653 reg = gen_rtx_REG (Pmode, 0);
19654 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19655 GEN_INT (info->lr_save_offset));
19656 mem = gen_frame_mem (Pmode, addr);
19657 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19660 return gen_rtx_PARALLEL (VOIDmode, p);
19663 /* Determine whether the gp REG is really used. */
19666 rs6000_reg_live_or_pic_offset_p (int reg)
19668 return ((df_regs_ever_live_p (reg)
19669 && (!call_used_regs[reg]
19670 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19671 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19672 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19673 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19674 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19678 SAVRES_MULTIPLE = 0x1,
19679 SAVRES_INLINE_FPRS = 0x2,
19680 SAVRES_INLINE_GPRS = 0x4,
19681 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19682 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19683 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19686 /* Determine the strategy for savings/restoring registers. */
19689 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19690 int using_static_chain_p, int sibcall)
19692 bool using_multiple_p;
19694 bool savres_fprs_inline;
19695 bool savres_gprs_inline;
19696 bool noclobber_global_gprs
19697 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19700 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19701 && (!TARGET_SPE_ABI
19702 || info->spe_64bit_regs_used == 0)
19703 && info->first_gp_reg_save < 31
19704 && noclobber_global_gprs);
19705 /* Don't bother to try to save things out-of-line if r11 is occupied
19706 by the static chain. It would require too much fiddling and the
19707 static chain is rarely used anyway. */
19708 common = (using_static_chain_p
19710 || crtl->calls_eh_return
19711 || !info->lr_save_p
19712 || cfun->machine->ra_need_lr
19713 || info->total_size > 32767);
19714 savres_fprs_inline = (common
19715 || info->first_fp_reg_save == 64
19716 || !no_global_regs_above (info->first_fp_reg_save,
19718 /* The out-of-line FP routines use
19719 double-precision stores; we can't use those
19720 routines if we don't have such stores. */
19721 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19722 || FP_SAVE_INLINE (info->first_fp_reg_save));
19723 savres_gprs_inline = (common
19724 /* Saving CR interferes with the exit routines
19725 used on the SPE, so just punt here. */
19728 && info->spe_64bit_regs_used != 0
19729 && info->cr_save_p != 0)
19730 || info->first_gp_reg_save == 32
19731 || !noclobber_global_gprs
19732 || GP_SAVE_INLINE (info->first_gp_reg_save));
19735 /* If we are going to use store multiple, then don't even bother
19736 with the out-of-line routines, since the store-multiple instruction
19737 will always be smaller. */
19738 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19741 /* The situation is more complicated with load multiple. We'd
19742 prefer to use the out-of-line routines for restores, since the
19743 "exit" out-of-line routines can handle the restore of LR and
19744 the frame teardown. But we can only use the out-of-line
19745 routines if we know that we've used store multiple or
19746 out-of-line routines in the prologue, i.e. if we've saved all
19747 the registers from first_gp_reg_save. Otherwise, we risk
19748 loading garbage from the stack. Furthermore, we can only use
19749 the "exit" out-of-line gpr restore if we haven't saved any
19751 bool saved_all = !savres_gprs_inline || using_multiple_p;
19753 if (saved_all && info->first_fp_reg_save != 64)
19754 /* We can't use the exit routine; use load multiple if it's
19756 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19759 strategy = (using_multiple_p
19760 | (savres_fprs_inline << 1)
19761 | (savres_gprs_inline << 2));
19762 #ifdef POWERPC_LINUX
19765 if (!savres_fprs_inline)
19766 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19767 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19768 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19771 if (TARGET_AIX && !savres_fprs_inline)
19772 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19777 /* Emit function prologue as insns. */
19780 rs6000_emit_prologue (void)
19782 rs6000_stack_t *info = rs6000_stack_info ();
19783 enum machine_mode reg_mode = Pmode;
19784 int reg_size = TARGET_32BIT ? 4 : 8;
19785 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19786 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19787 rtx frame_reg_rtx = sp_reg_rtx;
19788 rtx cr_save_rtx = NULL_RTX;
19791 int saving_FPRs_inline;
19792 int saving_GPRs_inline;
19793 int using_store_multiple;
19794 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19795 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19796 && call_used_regs[STATIC_CHAIN_REGNUM]);
19797 HOST_WIDE_INT sp_offset = 0;
19799 if (flag_stack_usage)
19800 current_function_static_stack_size = info->total_size;
19802 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19803 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19805 if (TARGET_FIX_AND_CONTINUE)
19807 /* gdb on darwin arranges to forward a function from the old
19808 address by modifying the first 5 instructions of the function
19809 to branch to the overriding function. This is necessary to
19810 permit function pointers that point to the old function to
19811 actually forward to the new function. */
19812 emit_insn (gen_nop ());
19813 emit_insn (gen_nop ());
19814 emit_insn (gen_nop ());
19815 emit_insn (gen_nop ());
19816 emit_insn (gen_nop ());
19819 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19821 reg_mode = V2SImode;
19825 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19826 /*static_chain_p=*/using_static_chain_p,
19828 using_store_multiple = strategy & SAVRES_MULTIPLE;
19829 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19830 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19832 /* For V.4, update stack before we do any saving and set back pointer. */
19833 if (! WORLD_SAVE_P (info)
19835 && (DEFAULT_ABI == ABI_V4
19836 || crtl->calls_eh_return))
19838 bool need_r11 = (TARGET_SPE
19839 ? (!saving_GPRs_inline
19840 && info->spe_64bit_regs_used == 0)
19841 : (!saving_FPRs_inline || !saving_GPRs_inline));
19842 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19844 if (info->total_size < 32767)
19845 sp_offset = info->total_size;
19847 frame_reg_rtx = copy_reg;
19848 else if (info->cr_save_p
19850 || info->first_fp_reg_save < 64
19851 || info->first_gp_reg_save < 32
19852 || info->altivec_size != 0
19853 || info->vrsave_mask != 0
19854 || crtl->calls_eh_return)
19856 copy_reg = frame_ptr_rtx;
19857 frame_reg_rtx = copy_reg;
19861 /* The prologue won't be saving any regs so there is no need
19862 to set up a frame register to access any frame save area.
19863 We also won't be using sp_offset anywhere below, but set
19864 the correct value anyway to protect against future
19865 changes to this function. */
19866 sp_offset = info->total_size;
19868 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19869 if (frame_reg_rtx != sp_reg_rtx)
19870 rs6000_emit_stack_tie ();
19873 /* Handle world saves specially here. */
19874 if (WORLD_SAVE_P (info))
19881 /* save_world expects lr in r0. */
19882 reg0 = gen_rtx_REG (Pmode, 0);
19883 if (info->lr_save_p)
19885 insn = emit_move_insn (reg0,
19886 gen_rtx_REG (Pmode, LR_REGNO));
19887 RTX_FRAME_RELATED_P (insn) = 1;
19890 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19891 assumptions about the offsets of various bits of the stack
19893 gcc_assert (info->gp_save_offset == -220
19894 && info->fp_save_offset == -144
19895 && info->lr_save_offset == 8
19896 && info->cr_save_offset == 4
19899 && (!crtl->calls_eh_return
19900 || info->ehrd_offset == -432)
19901 && info->vrsave_save_offset == -224
19902 && info->altivec_save_offset == -416);
19904 treg = gen_rtx_REG (SImode, 11);
19905 emit_move_insn (treg, GEN_INT (-info->total_size));
19907 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19908 in R11. It also clobbers R12, so beware! */
19910 /* Preserve CR2 for save_world prologues */
19912 sz += 32 - info->first_gp_reg_save;
19913 sz += 64 - info->first_fp_reg_save;
19914 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19915 p = rtvec_alloc (sz);
19917 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19918 gen_rtx_REG (SImode,
19920 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19921 gen_rtx_SYMBOL_REF (Pmode,
19923 /* We do floats first so that the instruction pattern matches
19925 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19927 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19928 ? DFmode : SFmode),
19929 info->first_fp_reg_save + i);
19930 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19931 GEN_INT (info->fp_save_offset
19932 + sp_offset + 8 * i));
19933 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19934 ? DFmode : SFmode), addr);
19936 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19938 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19940 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19941 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19942 GEN_INT (info->altivec_save_offset
19943 + sp_offset + 16 * i));
19944 rtx mem = gen_frame_mem (V4SImode, addr);
19946 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19948 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19950 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19951 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19952 GEN_INT (info->gp_save_offset
19953 + sp_offset + reg_size * i));
19954 rtx mem = gen_frame_mem (reg_mode, addr);
19956 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19960 /* CR register traditionally saved as CR2. */
19961 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19962 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19963 GEN_INT (info->cr_save_offset
19965 rtx mem = gen_frame_mem (reg_mode, addr);
19967 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19969 /* Explain about use of R0. */
19970 if (info->lr_save_p)
19972 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19973 GEN_INT (info->lr_save_offset
19975 rtx mem = gen_frame_mem (reg_mode, addr);
19977 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19979 /* Explain what happens to the stack pointer. */
19981 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19982 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19985 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19986 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19987 treg, GEN_INT (-info->total_size));
19988 sp_offset = info->total_size;
19991 /* If we use the link register, get it into r0. */
19992 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19994 rtx addr, reg, mem;
19996 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19997 gen_rtx_REG (Pmode, LR_REGNO));
19998 RTX_FRAME_RELATED_P (insn) = 1;
20000 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
20001 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
20003 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20004 GEN_INT (info->lr_save_offset + sp_offset));
20005 reg = gen_rtx_REG (Pmode, 0);
20006 mem = gen_rtx_MEM (Pmode, addr);
20007 /* This should not be of rs6000_sr_alias_set, because of
20008 __builtin_return_address. */
20010 insn = emit_move_insn (mem, reg);
20011 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20012 NULL_RTX, NULL_RTX);
20016 /* If we need to save CR, put it into r12 or r11. */
20017 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20022 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20024 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20025 RTX_FRAME_RELATED_P (insn) = 1;
20026 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20027 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20028 But that's OK. All we have to do is specify that _one_ condition
20029 code register is saved in this stack slot. The thrower's epilogue
20030 will then restore all the call-saved registers.
20031 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20032 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20033 gen_rtx_REG (SImode, CR2_REGNO));
20034 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20037 /* Do any required saving of fpr's. If only one or two to save, do
20038 it ourselves. Otherwise, call function. */
20039 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20042 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20043 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20044 && ! call_used_regs[info->first_fp_reg_save+i]))
20045 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20046 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20048 info->first_fp_reg_save + i,
20049 info->fp_save_offset + sp_offset + 8 * i,
20052 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20056 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20057 info->fp_save_offset + sp_offset,
20059 /*savep=*/true, /*gpr=*/false,
20061 & SAVRES_NOINLINE_FPRS_SAVES_LR)
20063 insn = emit_insn (par);
20064 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20065 NULL_RTX, NULL_RTX);
20068 /* Save GPRs. This is done as a PARALLEL if we are using
20069 the store-multiple instructions. */
20070 if (!WORLD_SAVE_P (info)
20072 && info->spe_64bit_regs_used != 0
20073 && info->first_gp_reg_save != 32)
20076 rtx spe_save_area_ptr;
20078 /* Determine whether we can address all of the registers that need
20079 to be saved with an offset from the stack pointer that fits in
20080 the small const field for SPE memory instructions. */
20081 int spe_regs_addressable_via_sp
20082 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20083 + (32 - info->first_gp_reg_save - 1) * reg_size)
20084 && saving_GPRs_inline);
20087 if (spe_regs_addressable_via_sp)
20089 spe_save_area_ptr = frame_reg_rtx;
20090 spe_offset = info->spe_gp_save_offset + sp_offset;
20094 /* Make r11 point to the start of the SPE save area. We need
20095 to be careful here if r11 is holding the static chain. If
20096 it is, then temporarily save it in r0. We would use r0 as
20097 our base register here, but using r0 as a base register in
20098 loads and stores means something different from what we
20100 int ool_adjust = (saving_GPRs_inline
20102 : (info->first_gp_reg_save
20103 - (FIRST_SAVRES_REGISTER+1))*8);
20104 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20105 + sp_offset - ool_adjust);
20107 if (using_static_chain_p)
20109 rtx r0 = gen_rtx_REG (Pmode, 0);
20110 gcc_assert (info->first_gp_reg_save > 11);
20112 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20115 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20116 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20118 GEN_INT (offset)));
20119 /* We need to make sure the move to r11 gets noted for
20120 properly outputting unwind information. */
20121 if (!saving_GPRs_inline)
20122 rs6000_frame_related (insn, frame_reg_rtx, offset,
20123 NULL_RTX, NULL_RTX);
20127 if (saving_GPRs_inline)
20129 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20130 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20132 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20133 rtx offset, addr, mem;
20135 /* We're doing all this to ensure that the offset fits into
20136 the immediate offset of 'evstdd'. */
20137 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20139 offset = GEN_INT (reg_size * i + spe_offset);
20140 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20141 mem = gen_rtx_MEM (V2SImode, addr);
20143 insn = emit_move_insn (mem, reg);
20145 rs6000_frame_related (insn, spe_save_area_ptr,
20146 info->spe_gp_save_offset
20147 + sp_offset + reg_size * i,
20148 offset, const0_rtx);
20155 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20157 /*savep=*/true, /*gpr=*/true,
20159 insn = emit_insn (par);
20160 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20161 NULL_RTX, NULL_RTX);
20165 /* Move the static chain pointer back. */
20166 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20167 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20169 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20173 /* Need to adjust r11 (r12) if we saved any FPRs. */
20174 if (info->first_fp_reg_save != 64)
20176 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20178 rtx offset = GEN_INT (sp_offset
20179 + (-8 * (64-info->first_fp_reg_save)));
20180 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20183 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20184 info->gp_save_offset + sp_offset,
20186 /*savep=*/true, /*gpr=*/true,
20188 & SAVRES_NOINLINE_GPRS_SAVES_LR)
20190 insn = emit_insn (par);
20191 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20192 NULL_RTX, NULL_RTX);
20194 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20198 p = rtvec_alloc (32 - info->first_gp_reg_save);
20199 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20201 rtx addr, reg, mem;
20202 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20203 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20204 GEN_INT (info->gp_save_offset
20207 mem = gen_frame_mem (reg_mode, addr);
20209 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20211 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20212 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20213 NULL_RTX, NULL_RTX);
20215 else if (!WORLD_SAVE_P (info))
20218 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20219 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20221 rtx addr, reg, mem;
20222 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20224 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20225 GEN_INT (info->gp_save_offset
20228 mem = gen_frame_mem (reg_mode, addr);
20230 insn = emit_move_insn (mem, reg);
20231 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20232 NULL_RTX, NULL_RTX);
20236 /* ??? There's no need to emit actual instructions here, but it's the
20237 easiest way to get the frame unwind information emitted. */
20238 if (crtl->calls_eh_return)
20240 unsigned int i, regno;
20242 /* In AIX ABI we need to pretend we save r2 here. */
20245 rtx addr, reg, mem;
20247 reg = gen_rtx_REG (reg_mode, 2);
20248 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20249 GEN_INT (sp_offset + 5 * reg_size));
20250 mem = gen_frame_mem (reg_mode, addr);
20252 insn = emit_move_insn (mem, reg);
20253 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20254 NULL_RTX, NULL_RTX);
20255 PATTERN (insn) = gen_blockage ();
20260 regno = EH_RETURN_DATA_REGNO (i);
20261 if (regno == INVALID_REGNUM)
20264 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20265 info->ehrd_offset + sp_offset
20266 + reg_size * (int) i,
20271 /* Save CR if we use any that must be preserved. */
20272 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20274 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20275 GEN_INT (info->cr_save_offset + sp_offset));
20276 rtx mem = gen_frame_mem (SImode, addr);
20277 /* See the large comment above about why CR2_REGNO is used. */
20278 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20280 /* If r12 was used to hold the original sp, copy cr into r0 now
20282 if (REGNO (frame_reg_rtx) == 12)
20286 cr_save_rtx = gen_rtx_REG (SImode, 0);
20287 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20288 RTX_FRAME_RELATED_P (insn) = 1;
20289 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20290 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20292 insn = emit_move_insn (mem, cr_save_rtx);
20294 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20295 NULL_RTX, NULL_RTX);
20298 /* Update stack and set back pointer unless this is V.4,
20299 for which it was done previously. */
20300 if (!WORLD_SAVE_P (info) && info->push_p
20301 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20303 rtx copy_reg = NULL;
20305 if (info->total_size < 32767)
20306 sp_offset = info->total_size;
20307 else if (info->altivec_size != 0
20308 || info->vrsave_mask != 0)
20310 copy_reg = frame_ptr_rtx;
20311 frame_reg_rtx = copy_reg;
20314 sp_offset = info->total_size;
20315 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20316 if (frame_reg_rtx != sp_reg_rtx)
20317 rs6000_emit_stack_tie ();
20320 /* Set frame pointer, if needed. */
20321 if (frame_pointer_needed)
20323 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20325 RTX_FRAME_RELATED_P (insn) = 1;
20328 /* Save AltiVec registers if needed. Save here because the red zone does
20329 not include AltiVec registers. */
20330 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20334 /* There should be a non inline version of this, for when we
20335 are saving lots of vector registers. */
20336 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20337 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20339 rtx areg, savereg, mem;
20342 offset = info->altivec_save_offset + sp_offset
20343 + 16 * (i - info->first_altivec_reg_save);
20345 savereg = gen_rtx_REG (V4SImode, i);
20347 areg = gen_rtx_REG (Pmode, 0);
20348 emit_move_insn (areg, GEN_INT (offset));
20350 /* AltiVec addressing mode is [reg+reg]. */
20351 mem = gen_frame_mem (V4SImode,
20352 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20354 insn = emit_move_insn (mem, savereg);
20356 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20357 areg, GEN_INT (offset));
20361 /* VRSAVE is a bit vector representing which AltiVec registers
20362 are used. The OS uses this to determine which vector
20363 registers to save on a context switch. We need to save
20364 VRSAVE on the stack frame, add whatever AltiVec registers we
20365 used in this function, and do the corresponding magic in the
20368 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20369 && info->vrsave_mask != 0)
20371 rtx reg, mem, vrsave;
20374 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20375 as frame_reg_rtx and r11 as the static chain pointer for
20376 nested functions. */
20377 reg = gen_rtx_REG (SImode, 0);
20378 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20380 emit_insn (gen_get_vrsave_internal (reg));
20382 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20384 if (!WORLD_SAVE_P (info))
20387 offset = info->vrsave_save_offset + sp_offset;
20388 mem = gen_frame_mem (SImode,
20389 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20390 GEN_INT (offset)));
20391 insn = emit_move_insn (mem, reg);
20394 /* Include the registers in the mask. */
20395 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20397 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20400 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20401 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20402 || (DEFAULT_ABI == ABI_V4
20403 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20404 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20406 /* If emit_load_toc_table will use the link register, we need to save
20407 it. We use R12 for this purpose because emit_load_toc_table
20408 can use register 0. This allows us to use a plain 'blr' to return
20409 from the procedure more often. */
20410 int save_LR_around_toc_setup = (TARGET_ELF
20411 && DEFAULT_ABI != ABI_AIX
20413 && ! info->lr_save_p
20414 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20415 if (save_LR_around_toc_setup)
20417 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20419 insn = emit_move_insn (frame_ptr_rtx, lr);
20420 RTX_FRAME_RELATED_P (insn) = 1;
20422 rs6000_emit_load_toc_table (TRUE);
20424 insn = emit_move_insn (lr, frame_ptr_rtx);
20425 RTX_FRAME_RELATED_P (insn) = 1;
20428 rs6000_emit_load_toc_table (TRUE);
20432 if (DEFAULT_ABI == ABI_DARWIN
20433 && flag_pic && crtl->uses_pic_offset_table)
20435 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20436 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20438 /* Save and restore LR locally around this call (in R0). */
20439 if (!info->lr_save_p)
20440 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20442 emit_insn (gen_load_macho_picbase (src));
20444 emit_move_insn (gen_rtx_REG (Pmode,
20445 RS6000_PIC_OFFSET_TABLE_REGNUM),
20448 if (!info->lr_save_p)
20449 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20454 /* Write function prologue. */
20457 rs6000_output_function_prologue (FILE *file,
20458 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20460 rs6000_stack_t *info = rs6000_stack_info ();
20462 if (TARGET_DEBUG_STACK)
20463 debug_stack_info (info);
20465 /* Write .extern for any function we will call to save and restore
20467 if (info->first_fp_reg_save < 64
20468 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20471 int regno = info->first_fp_reg_save - 32;
20473 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20474 /*gpr=*/false, /*lr=*/false);
20475 fprintf (file, "\t.extern %s\n", name);
20477 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20478 /*gpr=*/false, /*lr=*/true);
20479 fprintf (file, "\t.extern %s\n", name);
20482 /* Write .extern for AIX common mode routines, if needed. */
20483 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20485 fputs ("\t.extern __mulh\n", file);
20486 fputs ("\t.extern __mull\n", file);
20487 fputs ("\t.extern __divss\n", file);
20488 fputs ("\t.extern __divus\n", file);
20489 fputs ("\t.extern __quoss\n", file);
20490 fputs ("\t.extern __quous\n", file);
20491 common_mode_defined = 1;
20494 if (! HAVE_prologue)
20500 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20501 the "toplevel" insn chain. */
20502 emit_note (NOTE_INSN_DELETED);
20503 rs6000_emit_prologue ();
20504 emit_note (NOTE_INSN_DELETED);
20506 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20510 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20512 INSN_ADDRESSES_NEW (insn, addr);
20517 prologue = get_insns ();
20520 if (TARGET_DEBUG_STACK)
20521 debug_rtx_list (prologue, 100);
20523 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20527 rs6000_pic_labelno++;
20530 /* Non-zero if vmx regs are restored before the frame pop, zero if
20531 we restore after the pop when possible. */
20532 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20534 /* Reload CR from REG. */
20537 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20542 if (using_mfcr_multiple)
20544 for (i = 0; i < 8; i++)
20545 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20547 gcc_assert (count);
20550 if (using_mfcr_multiple && count > 1)
20555 p = rtvec_alloc (count);
20558 for (i = 0; i < 8; i++)
20559 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20561 rtvec r = rtvec_alloc (2);
20562 RTVEC_ELT (r, 0) = reg;
20563 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20564 RTVEC_ELT (p, ndx) =
20565 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20566 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20569 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20570 gcc_assert (ndx == count);
20573 for (i = 0; i < 8; i++)
20574 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20576 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20582 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20583 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20584 below stack pointer not cloberred by signals. */
20587 offset_below_red_zone_p (HOST_WIDE_INT offset)
20589 return offset < (DEFAULT_ABI == ABI_V4
20591 : TARGET_32BIT ? -220 : -288);
20594 /* Emit function epilogue as insns. */
20597 rs6000_emit_epilogue (int sibcall)
20599 rs6000_stack_t *info;
20600 int restoring_GPRs_inline;
20601 int restoring_FPRs_inline;
20602 int using_load_multiple;
20603 int using_mtcr_multiple;
20604 int use_backchain_to_restore_sp;
20608 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20609 rtx frame_reg_rtx = sp_reg_rtx;
20610 rtx cfa_restores = NULL_RTX;
20612 rtx cr_save_reg = NULL_RTX;
20613 enum machine_mode reg_mode = Pmode;
20614 int reg_size = TARGET_32BIT ? 4 : 8;
20617 info = rs6000_stack_info ();
20619 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20621 reg_mode = V2SImode;
20625 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20626 /*static_chain_p=*/0, sibcall);
20627 using_load_multiple = strategy & SAVRES_MULTIPLE;
20628 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20629 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20630 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20631 || rs6000_cpu == PROCESSOR_PPC603
20632 || rs6000_cpu == PROCESSOR_PPC750
20634 /* Restore via the backchain when we have a large frame, since this
20635 is more efficient than an addis, addi pair. The second condition
20636 here will not trigger at the moment; We don't actually need a
20637 frame pointer for alloca, but the generic parts of the compiler
20638 give us one anyway. */
20639 use_backchain_to_restore_sp = (info->total_size > 32767
20640 || info->total_size
20641 + (info->lr_save_p ? info->lr_save_offset : 0)
20643 || (cfun->calls_alloca
20644 && !frame_pointer_needed));
20645 restore_lr = (info->lr_save_p
20646 && (restoring_FPRs_inline
20647 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20648 && (restoring_GPRs_inline
20649 || info->first_fp_reg_save < 64));
20651 if (WORLD_SAVE_P (info))
20655 const char *alloc_rname;
20658 /* eh_rest_world_r10 will return to the location saved in the LR
20659 stack slot (which is not likely to be our caller.)
20660 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20661 rest_world is similar, except any R10 parameter is ignored.
20662 The exception-handling stuff that was here in 2.95 is no
20663 longer necessary. */
20667 + 32 - info->first_gp_reg_save
20668 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20669 + 63 + 1 - info->first_fp_reg_save);
20671 strcpy (rname, ((crtl->calls_eh_return) ?
20672 "*eh_rest_world_r10" : "*rest_world"));
20673 alloc_rname = ggc_strdup (rname);
20676 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20677 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20678 gen_rtx_REG (Pmode,
20681 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20682 /* The instruction pattern requires a clobber here;
20683 it is shared with the restVEC helper. */
20685 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20688 /* CR register traditionally saved as CR2. */
20689 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20690 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20691 GEN_INT (info->cr_save_offset));
20692 rtx mem = gen_frame_mem (reg_mode, addr);
20694 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20697 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20699 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20700 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20701 GEN_INT (info->gp_save_offset
20703 rtx mem = gen_frame_mem (reg_mode, addr);
20705 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20707 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20709 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20710 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20711 GEN_INT (info->altivec_save_offset
20713 rtx mem = gen_frame_mem (V4SImode, addr);
20715 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20717 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20719 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20720 ? DFmode : SFmode),
20721 info->first_fp_reg_save + i);
20722 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20723 GEN_INT (info->fp_save_offset
20725 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20726 ? DFmode : SFmode), addr);
20728 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20731 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20733 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20735 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20737 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20739 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20740 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20745 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20747 sp_offset = info->total_size;
20749 /* Restore AltiVec registers if we must do so before adjusting the
20751 if (TARGET_ALTIVEC_ABI
20752 && info->altivec_size != 0
20753 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20754 || (DEFAULT_ABI != ABI_V4
20755 && offset_below_red_zone_p (info->altivec_save_offset))))
20759 if (use_backchain_to_restore_sp)
20761 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20762 emit_move_insn (frame_reg_rtx,
20763 gen_rtx_MEM (Pmode, sp_reg_rtx));
20766 else if (frame_pointer_needed)
20767 frame_reg_rtx = hard_frame_pointer_rtx;
20769 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20770 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20772 rtx addr, areg, mem, reg;
20774 areg = gen_rtx_REG (Pmode, 0);
20776 (areg, GEN_INT (info->altivec_save_offset
20778 + 16 * (i - info->first_altivec_reg_save)));
20780 /* AltiVec addressing mode is [reg+reg]. */
20781 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20782 mem = gen_frame_mem (V4SImode, addr);
20784 reg = gen_rtx_REG (V4SImode, i);
20785 emit_move_insn (reg, mem);
20786 if (offset_below_red_zone_p (info->altivec_save_offset
20787 + (i - info->first_altivec_reg_save)
20789 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20794 /* Restore VRSAVE if we must do so before adjusting the stack. */
20796 && TARGET_ALTIVEC_VRSAVE
20797 && info->vrsave_mask != 0
20798 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20799 || (DEFAULT_ABI != ABI_V4
20800 && offset_below_red_zone_p (info->vrsave_save_offset))))
20802 rtx addr, mem, reg;
20804 if (frame_reg_rtx == sp_reg_rtx)
20806 if (use_backchain_to_restore_sp)
20808 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20809 emit_move_insn (frame_reg_rtx,
20810 gen_rtx_MEM (Pmode, sp_reg_rtx));
20813 else if (frame_pointer_needed)
20814 frame_reg_rtx = hard_frame_pointer_rtx;
20817 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20818 GEN_INT (info->vrsave_save_offset + sp_offset));
20819 mem = gen_frame_mem (SImode, addr);
20820 reg = gen_rtx_REG (SImode, 12);
20821 emit_move_insn (reg, mem);
20823 emit_insn (generate_set_vrsave (reg, info, 1));
20827 /* If we have a large stack frame, restore the old stack pointer
20828 using the backchain. */
20829 if (use_backchain_to_restore_sp)
20831 if (frame_reg_rtx == sp_reg_rtx)
20833 /* Under V.4, don't reset the stack pointer until after we're done
20834 loading the saved registers. */
20835 if (DEFAULT_ABI == ABI_V4)
20836 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20838 insn = emit_move_insn (frame_reg_rtx,
20839 gen_rtx_MEM (Pmode, sp_reg_rtx));
20842 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20843 && DEFAULT_ABI == ABI_V4)
20844 /* frame_reg_rtx has been set up by the altivec restore. */
20848 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20849 frame_reg_rtx = sp_reg_rtx;
20852 /* If we have a frame pointer, we can restore the old stack pointer
20854 else if (frame_pointer_needed)
20856 frame_reg_rtx = sp_reg_rtx;
20857 if (DEFAULT_ABI == ABI_V4)
20858 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20859 /* Prevent reordering memory accesses against stack pointer restore. */
20860 else if (cfun->calls_alloca
20861 || offset_below_red_zone_p (-info->total_size))
20863 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20864 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20865 MEM_NOTRAP_P (mem1) = 1;
20866 MEM_NOTRAP_P (mem2) = 1;
20867 emit_insn (gen_frame_tie (mem1, mem2));
20870 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20871 GEN_INT (info->total_size)));
20874 else if (info->push_p
20875 && DEFAULT_ABI != ABI_V4
20876 && !crtl->calls_eh_return)
20878 /* Prevent reordering memory accesses against stack pointer restore. */
20879 if (cfun->calls_alloca
20880 || offset_below_red_zone_p (-info->total_size))
20882 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20883 MEM_NOTRAP_P (mem) = 1;
20884 emit_insn (gen_stack_tie (mem));
20886 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20887 GEN_INT (info->total_size)));
20890 if (insn && frame_reg_rtx == sp_reg_rtx)
20894 REG_NOTES (insn) = cfa_restores;
20895 cfa_restores = NULL_RTX;
20897 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20898 RTX_FRAME_RELATED_P (insn) = 1;
20901 /* Restore AltiVec registers if we have not done so already. */
20902 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20903 && TARGET_ALTIVEC_ABI
20904 && info->altivec_size != 0
20905 && (DEFAULT_ABI == ABI_V4
20906 || !offset_below_red_zone_p (info->altivec_save_offset)))
20910 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20911 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20913 rtx addr, areg, mem, reg;
20915 areg = gen_rtx_REG (Pmode, 0);
20917 (areg, GEN_INT (info->altivec_save_offset
20919 + 16 * (i - info->first_altivec_reg_save)));
20921 /* AltiVec addressing mode is [reg+reg]. */
20922 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20923 mem = gen_frame_mem (V4SImode, addr);
20925 reg = gen_rtx_REG (V4SImode, i);
20926 emit_move_insn (reg, mem);
20927 if (DEFAULT_ABI == ABI_V4)
20928 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20933 /* Restore VRSAVE if we have not done so already. */
20934 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20936 && TARGET_ALTIVEC_VRSAVE
20937 && info->vrsave_mask != 0
20938 && (DEFAULT_ABI == ABI_V4
20939 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20941 rtx addr, mem, reg;
20943 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20944 GEN_INT (info->vrsave_save_offset + sp_offset));
20945 mem = gen_frame_mem (SImode, addr);
20946 reg = gen_rtx_REG (SImode, 12);
20947 emit_move_insn (reg, mem);
20949 emit_insn (generate_set_vrsave (reg, info, 1));
20952 /* Get the old lr if we saved it. If we are restoring registers
20953 out-of-line, then the out-of-line routines can do this for us. */
20954 if (restore_lr && restoring_GPRs_inline)
20956 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20957 info->lr_save_offset + sp_offset);
20959 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20962 /* Get the old cr if we saved it. */
20963 if (info->cr_save_p)
20965 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20966 GEN_INT (info->cr_save_offset + sp_offset));
20967 rtx mem = gen_frame_mem (SImode, addr);
20969 cr_save_reg = gen_rtx_REG (SImode,
20970 DEFAULT_ABI == ABI_AIX
20971 && !restoring_GPRs_inline
20972 && info->first_fp_reg_save < 64
20974 emit_move_insn (cr_save_reg, mem);
20977 /* Set LR here to try to overlap restores below. LR is always saved
20978 above incoming stack, so it never needs REG_CFA_RESTORE. */
20979 if (restore_lr && restoring_GPRs_inline)
20980 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20981 gen_rtx_REG (Pmode, 0));
20983 /* Load exception handler data registers, if needed. */
20984 if (crtl->calls_eh_return)
20986 unsigned int i, regno;
20990 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20991 GEN_INT (sp_offset + 5 * reg_size));
20992 rtx mem = gen_frame_mem (reg_mode, addr);
20994 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21001 regno = EH_RETURN_DATA_REGNO (i);
21002 if (regno == INVALID_REGNUM)
21005 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21006 info->ehrd_offset + sp_offset
21007 + reg_size * (int) i);
21009 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21013 /* Restore GPRs. This is done as a PARALLEL if we are using
21014 the load-multiple instructions. */
21016 && info->spe_64bit_regs_used != 0
21017 && info->first_gp_reg_save != 32)
21019 /* Determine whether we can address all of the registers that need
21020 to be saved with an offset from the stack pointer that fits in
21021 the small const field for SPE memory instructions. */
21022 int spe_regs_addressable_via_sp
21023 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21024 + (32 - info->first_gp_reg_save - 1) * reg_size)
21025 && restoring_GPRs_inline);
21028 if (spe_regs_addressable_via_sp)
21029 spe_offset = info->spe_gp_save_offset + sp_offset;
21032 rtx old_frame_reg_rtx = frame_reg_rtx;
21033 /* Make r11 point to the start of the SPE save area. We worried about
21034 not clobbering it when we were saving registers in the prologue.
21035 There's no need to worry here because the static chain is passed
21036 anew to every function. */
21037 int ool_adjust = (restoring_GPRs_inline
21039 : (info->first_gp_reg_save
21040 - (FIRST_SAVRES_REGISTER+1))*8);
21042 if (frame_reg_rtx == sp_reg_rtx)
21043 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21044 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21045 GEN_INT (info->spe_gp_save_offset
21048 /* Keep the invariant that frame_reg_rtx + sp_offset points
21049 at the top of the stack frame. */
21050 sp_offset = -info->spe_gp_save_offset;
21055 if (restoring_GPRs_inline)
21057 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21058 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21060 rtx offset, addr, mem, reg;
21062 /* We're doing all this to ensure that the immediate offset
21063 fits into the immediate field of 'evldd'. */
21064 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21066 offset = GEN_INT (spe_offset + reg_size * i);
21067 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21068 mem = gen_rtx_MEM (V2SImode, addr);
21069 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21071 insn = emit_move_insn (reg, mem);
21072 if (DEFAULT_ABI == ABI_V4)
21074 if (frame_pointer_needed
21075 && info->first_gp_reg_save + i
21076 == HARD_FRAME_POINTER_REGNUM)
21078 add_reg_note (insn, REG_CFA_DEF_CFA,
21079 plus_constant (frame_reg_rtx,
21081 RTX_FRAME_RELATED_P (insn) = 1;
21084 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21093 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21095 /*savep=*/false, /*gpr=*/true,
21097 emit_jump_insn (par);
21098 /* We don't want anybody else emitting things after we jumped
21103 else if (!restoring_GPRs_inline)
21105 /* We are jumping to an out-of-line function. */
21106 bool can_use_exit = info->first_fp_reg_save == 64;
21109 /* Emit stack reset code if we need it. */
21111 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21112 sp_offset, can_use_exit);
21115 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21118 GEN_INT (sp_offset - info->fp_size)));
21119 if (REGNO (frame_reg_rtx) == 11)
21120 sp_offset += info->fp_size;
21123 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21124 info->gp_save_offset, reg_mode,
21125 /*savep=*/false, /*gpr=*/true,
21126 /*lr=*/can_use_exit);
21130 if (info->cr_save_p)
21132 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21133 if (DEFAULT_ABI == ABI_V4)
21135 = alloc_reg_note (REG_CFA_RESTORE,
21136 gen_rtx_REG (SImode, CR2_REGNO),
21140 emit_jump_insn (par);
21142 /* We don't want anybody else emitting things after we jumped
21147 insn = emit_insn (par);
21148 if (DEFAULT_ABI == ABI_V4)
21150 if (frame_pointer_needed)
21152 add_reg_note (insn, REG_CFA_DEF_CFA,
21153 plus_constant (frame_reg_rtx, sp_offset));
21154 RTX_FRAME_RELATED_P (insn) = 1;
21157 for (i = info->first_gp_reg_save; i < 32; i++)
21159 = alloc_reg_note (REG_CFA_RESTORE,
21160 gen_rtx_REG (reg_mode, i), cfa_restores);
21163 else if (using_load_multiple)
21166 p = rtvec_alloc (32 - info->first_gp_reg_save);
21167 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21169 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21170 GEN_INT (info->gp_save_offset
21173 rtx mem = gen_frame_mem (reg_mode, addr);
21174 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21176 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21177 if (DEFAULT_ABI == ABI_V4)
21178 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21181 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21182 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21184 add_reg_note (insn, REG_CFA_DEF_CFA,
21185 plus_constant (frame_reg_rtx, sp_offset));
21186 RTX_FRAME_RELATED_P (insn) = 1;
21191 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21192 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21194 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21195 GEN_INT (info->gp_save_offset
21198 rtx mem = gen_frame_mem (reg_mode, addr);
21199 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21201 insn = emit_move_insn (reg, mem);
21202 if (DEFAULT_ABI == ABI_V4)
21204 if (frame_pointer_needed
21205 && info->first_gp_reg_save + i
21206 == HARD_FRAME_POINTER_REGNUM)
21208 add_reg_note (insn, REG_CFA_DEF_CFA,
21209 plus_constant (frame_reg_rtx, sp_offset));
21210 RTX_FRAME_RELATED_P (insn) = 1;
21213 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21219 if (restore_lr && !restoring_GPRs_inline)
21221 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21222 info->lr_save_offset + sp_offset);
21224 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21225 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21226 gen_rtx_REG (Pmode, 0));
21229 /* Restore fpr's if we need to do it without calling a function. */
21230 if (restoring_FPRs_inline)
21231 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21232 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21233 && ! call_used_regs[info->first_fp_reg_save+i]))
21235 rtx addr, mem, reg;
21236 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21237 GEN_INT (info->fp_save_offset
21240 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21241 ? DFmode : SFmode), addr);
21242 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21243 ? DFmode : SFmode),
21244 info->first_fp_reg_save + i);
21246 emit_move_insn (reg, mem);
21247 if (DEFAULT_ABI == ABI_V4)
21248 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21252 /* If we saved cr, restore it here. Just those that were used. */
21253 if (info->cr_save_p)
21255 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21256 if (DEFAULT_ABI == ABI_V4)
21258 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21262 /* If this is V.4, unwind the stack pointer after all of the loads
21264 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21265 sp_offset, !restoring_FPRs_inline);
21270 REG_NOTES (insn) = cfa_restores;
21271 cfa_restores = NULL_RTX;
21273 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21274 RTX_FRAME_RELATED_P (insn) = 1;
21277 if (crtl->calls_eh_return)
21279 rtx sa = EH_RETURN_STACKADJ_RTX;
21280 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21286 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21287 if (! restoring_FPRs_inline)
21288 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21290 p = rtvec_alloc (2);
21292 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21293 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21294 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21295 : gen_rtx_CLOBBER (VOIDmode,
21296 gen_rtx_REG (Pmode, 65)));
21298 /* If we have to restore more than two FP registers, branch to the
21299 restore function. It will return to our caller. */
21300 if (! restoring_FPRs_inline)
21305 sym = rs6000_savres_routine_sym (info,
21309 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21310 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21311 gen_rtx_REG (Pmode,
21312 DEFAULT_ABI == ABI_AIX
21314 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21317 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21318 GEN_INT (info->fp_save_offset + 8*i));
21319 mem = gen_frame_mem (DFmode, addr);
21321 RTVEC_ELT (p, i+4) =
21322 gen_rtx_SET (VOIDmode,
21323 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21328 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21332 /* Write function epilogue. */
21335 rs6000_output_function_epilogue (FILE *file,
21336 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21338 if (! HAVE_epilogue)
21340 rtx insn = get_last_insn ();
21341 /* If the last insn was a BARRIER, we don't have to write anything except
21342 the trace table. */
21343 if (GET_CODE (insn) == NOTE)
21344 insn = prev_nonnote_insn (insn);
21345 if (insn == 0 || GET_CODE (insn) != BARRIER)
21347 /* This is slightly ugly, but at least we don't have two
21348 copies of the epilogue-emitting code. */
21351 /* A NOTE_INSN_DELETED is supposed to be at the start
21352 and end of the "toplevel" insn chain. */
21353 emit_note (NOTE_INSN_DELETED);
21354 rs6000_emit_epilogue (FALSE);
21355 emit_note (NOTE_INSN_DELETED);
21357 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21361 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21363 INSN_ADDRESSES_NEW (insn, addr);
21368 if (TARGET_DEBUG_STACK)
21369 debug_rtx_list (get_insns (), 100);
21370 final (get_insns (), file, FALSE);
21376 macho_branch_islands ();
21377 /* Mach-O doesn't support labels at the end of objects, so if
21378 it looks like we might want one, insert a NOP. */
21380 rtx insn = get_last_insn ();
21383 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21384 insn = PREV_INSN (insn);
21388 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21389 fputs ("\tnop\n", file);
21393 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21396 We don't output a traceback table if -finhibit-size-directive was
21397 used. The documentation for -finhibit-size-directive reads
21398 ``don't output a @code{.size} assembler directive, or anything
21399 else that would cause trouble if the function is split in the
21400 middle, and the two halves are placed at locations far apart in
21401 memory.'' The traceback table has this property, since it
21402 includes the offset from the start of the function to the
21403 traceback table itself.
21405 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21406 different traceback table. */
21407 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21408 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21410 const char *fname = NULL;
21411 const char *language_string = lang_hooks.name;
21412 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21414 int optional_tbtab;
21415 rs6000_stack_t *info = rs6000_stack_info ();
21417 if (rs6000_traceback == traceback_full)
21418 optional_tbtab = 1;
21419 else if (rs6000_traceback == traceback_part)
21420 optional_tbtab = 0;
21422 optional_tbtab = !optimize_size && !TARGET_ELF;
21424 if (optional_tbtab)
21426 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21427 while (*fname == '.') /* V.4 encodes . in the name */
21430 /* Need label immediately before tbtab, so we can compute
21431 its offset from the function start. */
21432 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21433 ASM_OUTPUT_LABEL (file, fname);
21436 /* The .tbtab pseudo-op can only be used for the first eight
21437 expressions, since it can't handle the possibly variable
21438 length fields that follow. However, if you omit the optional
21439 fields, the assembler outputs zeros for all optional fields
21440 anyways, giving each variable length field is minimum length
21441 (as defined in sys/debug.h). Thus we can not use the .tbtab
21442 pseudo-op at all. */
21444 /* An all-zero word flags the start of the tbtab, for debuggers
21445 that have to find it by searching forward from the entry
21446 point or from the current pc. */
21447 fputs ("\t.long 0\n", file);
21449 /* Tbtab format type. Use format type 0. */
21450 fputs ("\t.byte 0,", file);
21452 /* Language type. Unfortunately, there does not seem to be any
21453 official way to discover the language being compiled, so we
21454 use language_string.
21455 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21456 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21457 a number, so for now use 9. LTO isn't assigned a number either,
21458 so for now use 0. */
21459 if (! strcmp (language_string, "GNU C")
21460 || ! strcmp (language_string, "GNU GIMPLE"))
21462 else if (! strcmp (language_string, "GNU F77")
21463 || ! strcmp (language_string, "GNU Fortran"))
21465 else if (! strcmp (language_string, "GNU Pascal"))
21467 else if (! strcmp (language_string, "GNU Ada"))
21469 else if (! strcmp (language_string, "GNU C++")
21470 || ! strcmp (language_string, "GNU Objective-C++"))
21472 else if (! strcmp (language_string, "GNU Java"))
21474 else if (! strcmp (language_string, "GNU Objective-C"))
21477 gcc_unreachable ();
21478 fprintf (file, "%d,", i);
21480 /* 8 single bit fields: global linkage (not set for C extern linkage,
21481 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21482 from start of procedure stored in tbtab, internal function, function
21483 has controlled storage, function has no toc, function uses fp,
21484 function logs/aborts fp operations. */
21485 /* Assume that fp operations are used if any fp reg must be saved. */
21486 fprintf (file, "%d,",
21487 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21489 /* 6 bitfields: function is interrupt handler, name present in
21490 proc table, function calls alloca, on condition directives
21491 (controls stack walks, 3 bits), saves condition reg, saves
21493 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21494 set up as a frame pointer, even when there is no alloca call. */
21495 fprintf (file, "%d,",
21496 ((optional_tbtab << 6)
21497 | ((optional_tbtab & frame_pointer_needed) << 5)
21498 | (info->cr_save_p << 1)
21499 | (info->lr_save_p)));
21501 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21503 fprintf (file, "%d,",
21504 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21506 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21507 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21509 if (optional_tbtab)
21511 /* Compute the parameter info from the function decl argument
21514 int next_parm_info_bit = 31;
21516 for (decl = DECL_ARGUMENTS (current_function_decl);
21517 decl; decl = DECL_CHAIN (decl))
21519 rtx parameter = DECL_INCOMING_RTL (decl);
21520 enum machine_mode mode = GET_MODE (parameter);
21522 if (GET_CODE (parameter) == REG)
21524 if (SCALAR_FLOAT_MODE_P (mode))
21545 gcc_unreachable ();
21548 /* If only one bit will fit, don't or in this entry. */
21549 if (next_parm_info_bit > 0)
21550 parm_info |= (bits << (next_parm_info_bit - 1));
21551 next_parm_info_bit -= 2;
21555 fixed_parms += ((GET_MODE_SIZE (mode)
21556 + (UNITS_PER_WORD - 1))
21558 next_parm_info_bit -= 1;
21564 /* Number of fixed point parameters. */
21565 /* This is actually the number of words of fixed point parameters; thus
21566 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21567 fprintf (file, "%d,", fixed_parms);
21569 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21571 /* This is actually the number of fp registers that hold parameters;
21572 and thus the maximum value is 13. */
21573 /* Set parameters on stack bit if parameters are not in their original
21574 registers, regardless of whether they are on the stack? Xlc
21575 seems to set the bit when not optimizing. */
21576 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21578 if (! optional_tbtab)
21581 /* Optional fields follow. Some are variable length. */
21583 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21584 11 double float. */
21585 /* There is an entry for each parameter in a register, in the order that
21586 they occur in the parameter list. Any intervening arguments on the
21587 stack are ignored. If the list overflows a long (max possible length
21588 34 bits) then completely leave off all elements that don't fit. */
21589 /* Only emit this long if there was at least one parameter. */
21590 if (fixed_parms || float_parms)
21591 fprintf (file, "\t.long %d\n", parm_info);
21593 /* Offset from start of code to tb table. */
21594 fputs ("\t.long ", file);
21595 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21596 RS6000_OUTPUT_BASENAME (file, fname);
21598 rs6000_output_function_entry (file, fname);
21601 /* Interrupt handler mask. */
21602 /* Omit this long, since we never set the interrupt handler bit
21605 /* Number of CTL (controlled storage) anchors. */
21606 /* Omit this long, since the has_ctl bit is never set above. */
21608 /* Displacement into stack of each CTL anchor. */
21609 /* Omit this list of longs, because there are no CTL anchors. */
21611 /* Length of function name. */
21614 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21616 /* Function name. */
21617 assemble_string (fname, strlen (fname));
21619 /* Register for alloca automatic storage; this is always reg 31.
21620 Only emit this if the alloca bit was set above. */
21621 if (frame_pointer_needed)
21622 fputs ("\t.byte 31\n", file);
21624 fputs ("\t.align 2\n", file);
21628 /* A C compound statement that outputs the assembler code for a thunk
21629 function, used to implement C++ virtual function calls with
21630 multiple inheritance. The thunk acts as a wrapper around a virtual
21631 function, adjusting the implicit object parameter before handing
21632 control off to the real function.
21634 First, emit code to add the integer DELTA to the location that
21635 contains the incoming first argument. Assume that this argument
21636 contains a pointer, and is the one used to pass the `this' pointer
21637 in C++. This is the incoming argument *before* the function
21638 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21639 values of all other incoming arguments.
21641 After the addition, emit code to jump to FUNCTION, which is a
21642 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21643 not touch the return address. Hence returning from FUNCTION will
21644 return to whoever called the current `thunk'.
21646 The effect must be as if FUNCTION had been called directly with the
21647 adjusted first argument. This macro is responsible for emitting
21648 all of the code for a thunk function; output_function_prologue()
21649 and output_function_epilogue() are not invoked.
21651 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21652 been extracted from it.) It might possibly be useful on some
21653 targets, but probably not.
21655 If you do not define this macro, the target-independent code in the
21656 C++ frontend will generate a less efficient heavyweight thunk that
21657 calls FUNCTION instead of jumping to it. The generic approach does
21658 not support varargs. */
21661 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21662 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21665 rtx this_rtx, insn, funexp;
21667 reload_completed = 1;
21668 epilogue_completed = 1;
21670 /* Mark the end of the (empty) prologue. */
21671 emit_note (NOTE_INSN_PROLOGUE_END);
21673 /* Find the "this" pointer. If the function returns a structure,
21674 the structure return pointer is in r3. */
21675 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21676 this_rtx = gen_rtx_REG (Pmode, 4);
21678 this_rtx = gen_rtx_REG (Pmode, 3);
21680 /* Apply the constant offset, if required. */
21682 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21684 /* Apply the offset from the vtable, if required. */
21687 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21688 rtx tmp = gen_rtx_REG (Pmode, 12);
21690 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21691 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21693 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21694 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21698 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21700 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21702 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21705 /* Generate a tail call to the target function. */
21706 if (!TREE_USED (function))
21708 assemble_external (function);
21709 TREE_USED (function) = 1;
21711 funexp = XEXP (DECL_RTL (function), 0);
21712 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21715 if (MACHOPIC_INDIRECT)
21716 funexp = machopic_indirect_call_target (funexp);
21719 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21720 generate sibcall RTL explicitly. */
21721 insn = emit_call_insn (
21722 gen_rtx_PARALLEL (VOIDmode,
21724 gen_rtx_CALL (VOIDmode,
21725 funexp, const0_rtx),
21726 gen_rtx_USE (VOIDmode, const0_rtx),
21727 gen_rtx_USE (VOIDmode,
21728 gen_rtx_REG (SImode,
21730 gen_rtx_RETURN (VOIDmode))));
21731 SIBLING_CALL_P (insn) = 1;
21734 /* Run just enough of rest_of_compilation to get the insns emitted.
21735 There's not really enough bulk here to make other passes such as
21736 instruction scheduling worth while. Note that use_thunk calls
21737 assemble_start_function and assemble_end_function. */
21738 insn = get_insns ();
21739 insn_locators_alloc ();
21740 shorten_branches (insn);
21741 final_start_function (insn, file, 1);
21742 final (insn, file, 1);
21743 final_end_function ();
21745 reload_completed = 0;
21746 epilogue_completed = 0;
21749 /* A quick summary of the various types of 'constant-pool tables'
21752 Target Flags Name One table per
21753 AIX (none) AIX TOC object file
21754 AIX -mfull-toc AIX TOC object file
21755 AIX -mminimal-toc AIX minimal TOC translation unit
21756 SVR4/EABI (none) SVR4 SDATA object file
21757 SVR4/EABI -fpic SVR4 pic object file
21758 SVR4/EABI -fPIC SVR4 PIC translation unit
21759 SVR4/EABI -mrelocatable EABI TOC function
21760 SVR4/EABI -maix AIX TOC object file
21761 SVR4/EABI -maix -mminimal-toc
21762 AIX minimal TOC translation unit
21764 Name Reg. Set by entries contains:
21765 made by addrs? fp? sum?
21767 AIX TOC 2 crt0 as Y option option
21768 AIX minimal TOC 30 prolog gcc Y Y option
21769 SVR4 SDATA 13 crt0 gcc N Y N
21770 SVR4 pic 30 prolog ld Y not yet N
21771 SVR4 PIC 30 prolog gcc Y option option
21772 EABI TOC 30 prolog gcc Y option option
21776 /* Hash functions for the hash table. */
21779 rs6000_hash_constant (rtx k)
21781 enum rtx_code code = GET_CODE (k);
21782 enum machine_mode mode = GET_MODE (k);
21783 unsigned result = (code << 3) ^ mode;
21784 const char *format;
21787 format = GET_RTX_FORMAT (code);
21788 flen = strlen (format);
21794 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21797 if (mode != VOIDmode)
21798 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21810 for (; fidx < flen; fidx++)
21811 switch (format[fidx])
21816 const char *str = XSTR (k, fidx);
21817 len = strlen (str);
21818 result = result * 613 + len;
21819 for (i = 0; i < len; i++)
21820 result = result * 613 + (unsigned) str[i];
21825 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21829 result = result * 613 + (unsigned) XINT (k, fidx);
21832 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21833 result = result * 613 + (unsigned) XWINT (k, fidx);
21837 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21838 result = result * 613 + (unsigned) (XWINT (k, fidx)
21845 gcc_unreachable ();
21852 toc_hash_function (const void *hash_entry)
21854 const struct toc_hash_struct *thc =
21855 (const struct toc_hash_struct *) hash_entry;
21856 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21859 /* Compare H1 and H2 for equivalence. */
21862 toc_hash_eq (const void *h1, const void *h2)
21864 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21865 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21867 if (((const struct toc_hash_struct *) h1)->key_mode
21868 != ((const struct toc_hash_struct *) h2)->key_mode)
21871 return rtx_equal_p (r1, r2);
21874 /* These are the names given by the C++ front-end to vtables, and
21875 vtable-like objects. Ideally, this logic should not be here;
21876 instead, there should be some programmatic way of inquiring as
21877 to whether or not an object is a vtable. */
21879 #define VTABLE_NAME_P(NAME) \
21880 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21881 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21882 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21883 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21884 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21886 #ifdef NO_DOLLAR_IN_LABEL
21887 /* Return a GGC-allocated character string translating dollar signs in
21888 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21891 rs6000_xcoff_strip_dollar (const char *name)
21896 p = strchr (name, '$');
21898 if (p == 0 || p == name)
21901 len = strlen (name);
21902 strip = (char *) alloca (len + 1);
21903 strcpy (strip, name);
21904 p = strchr (strip, '$');
21908 p = strchr (p + 1, '$');
21911 return ggc_alloc_string (strip, len);
21916 rs6000_output_symbol_ref (FILE *file, rtx x)
21918 /* Currently C++ toc references to vtables can be emitted before it
21919 is decided whether the vtable is public or private. If this is
21920 the case, then the linker will eventually complain that there is
21921 a reference to an unknown section. Thus, for vtables only,
21922 we emit the TOC reference to reference the symbol and not the
21924 const char *name = XSTR (x, 0);
21926 if (VTABLE_NAME_P (name))
21928 RS6000_OUTPUT_BASENAME (file, name);
21931 assemble_name (file, name);
21934 /* Output a TOC entry. We derive the entry name from what is being
21938 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21941 const char *name = buf;
21943 HOST_WIDE_INT offset = 0;
21945 gcc_assert (!TARGET_NO_TOC);
21947 /* When the linker won't eliminate them, don't output duplicate
21948 TOC entries (this happens on AIX if there is any kind of TOC,
21949 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21951 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21953 struct toc_hash_struct *h;
21956 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21957 time because GGC is not initialized at that point. */
21958 if (toc_hash_table == NULL)
21959 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21960 toc_hash_eq, NULL);
21962 h = ggc_alloc_toc_hash_struct ();
21964 h->key_mode = mode;
21965 h->labelno = labelno;
21967 found = htab_find_slot (toc_hash_table, h, INSERT);
21968 if (*found == NULL)
21970 else /* This is indeed a duplicate.
21971 Set this label equal to that label. */
21973 fputs ("\t.set ", file);
21974 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21975 fprintf (file, "%d,", labelno);
21976 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21977 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21983 /* If we're going to put a double constant in the TOC, make sure it's
21984 aligned properly when strict alignment is on. */
21985 if (GET_CODE (x) == CONST_DOUBLE
21986 && STRICT_ALIGNMENT
21987 && GET_MODE_BITSIZE (mode) >= 64
21988 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21989 ASM_OUTPUT_ALIGN (file, 3);
21992 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21994 /* Handle FP constants specially. Note that if we have a minimal
21995 TOC, things we put here aren't actually in the TOC, so we can allow
21997 if (GET_CODE (x) == CONST_DOUBLE &&
21998 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22000 REAL_VALUE_TYPE rv;
22003 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22004 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22005 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22007 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22011 if (TARGET_MINIMAL_TOC)
22012 fputs (DOUBLE_INT_ASM_OP, file);
22014 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22015 k[0] & 0xffffffff, k[1] & 0xffffffff,
22016 k[2] & 0xffffffff, k[3] & 0xffffffff);
22017 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22018 k[0] & 0xffffffff, k[1] & 0xffffffff,
22019 k[2] & 0xffffffff, k[3] & 0xffffffff);
22024 if (TARGET_MINIMAL_TOC)
22025 fputs ("\t.long ", file);
22027 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22028 k[0] & 0xffffffff, k[1] & 0xffffffff,
22029 k[2] & 0xffffffff, k[3] & 0xffffffff);
22030 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22031 k[0] & 0xffffffff, k[1] & 0xffffffff,
22032 k[2] & 0xffffffff, k[3] & 0xffffffff);
22036 else if (GET_CODE (x) == CONST_DOUBLE &&
22037 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22039 REAL_VALUE_TYPE rv;
22042 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22044 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22045 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22047 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22051 if (TARGET_MINIMAL_TOC)
22052 fputs (DOUBLE_INT_ASM_OP, file);
22054 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22055 k[0] & 0xffffffff, k[1] & 0xffffffff);
22056 fprintf (file, "0x%lx%08lx\n",
22057 k[0] & 0xffffffff, k[1] & 0xffffffff);
22062 if (TARGET_MINIMAL_TOC)
22063 fputs ("\t.long ", file);
22065 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22066 k[0] & 0xffffffff, k[1] & 0xffffffff);
22067 fprintf (file, "0x%lx,0x%lx\n",
22068 k[0] & 0xffffffff, k[1] & 0xffffffff);
22072 else if (GET_CODE (x) == CONST_DOUBLE &&
22073 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22075 REAL_VALUE_TYPE rv;
22078 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22079 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22080 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22082 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22086 if (TARGET_MINIMAL_TOC)
22087 fputs (DOUBLE_INT_ASM_OP, file);
22089 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22090 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22095 if (TARGET_MINIMAL_TOC)
22096 fputs ("\t.long ", file);
22098 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22099 fprintf (file, "0x%lx\n", l & 0xffffffff);
22103 else if (GET_MODE (x) == VOIDmode
22104 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22106 unsigned HOST_WIDE_INT low;
22107 HOST_WIDE_INT high;
22109 if (GET_CODE (x) == CONST_DOUBLE)
22111 low = CONST_DOUBLE_LOW (x);
22112 high = CONST_DOUBLE_HIGH (x);
22115 #if HOST_BITS_PER_WIDE_INT == 32
22118 high = (low & 0x80000000) ? ~0 : 0;
22122 low = INTVAL (x) & 0xffffffff;
22123 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22127 /* TOC entries are always Pmode-sized, but since this
22128 is a bigendian machine then if we're putting smaller
22129 integer constants in the TOC we have to pad them.
22130 (This is still a win over putting the constants in
22131 a separate constant pool, because then we'd have
22132 to have both a TOC entry _and_ the actual constant.)
22134 For a 32-bit target, CONST_INT values are loaded and shifted
22135 entirely within `low' and can be stored in one TOC entry. */
22137 /* It would be easy to make this work, but it doesn't now. */
22138 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22140 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22142 #if HOST_BITS_PER_WIDE_INT == 32
22143 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22144 POINTER_SIZE, &low, &high, 0);
22147 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22148 high = (HOST_WIDE_INT) low >> 32;
22155 if (TARGET_MINIMAL_TOC)
22156 fputs (DOUBLE_INT_ASM_OP, file);
22158 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22159 (long) high & 0xffffffff, (long) low & 0xffffffff);
22160 fprintf (file, "0x%lx%08lx\n",
22161 (long) high & 0xffffffff, (long) low & 0xffffffff);
22166 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22168 if (TARGET_MINIMAL_TOC)
22169 fputs ("\t.long ", file);
22171 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22172 (long) high & 0xffffffff, (long) low & 0xffffffff);
22173 fprintf (file, "0x%lx,0x%lx\n",
22174 (long) high & 0xffffffff, (long) low & 0xffffffff);
22178 if (TARGET_MINIMAL_TOC)
22179 fputs ("\t.long ", file);
22181 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22182 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22188 if (GET_CODE (x) == CONST)
22190 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22191 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22193 base = XEXP (XEXP (x, 0), 0);
22194 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22197 switch (GET_CODE (base))
22200 name = XSTR (base, 0);
22204 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22205 CODE_LABEL_NUMBER (XEXP (base, 0)));
22209 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22213 gcc_unreachable ();
22216 if (TARGET_MINIMAL_TOC)
22217 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22220 fputs ("\t.tc ", file);
22221 RS6000_OUTPUT_BASENAME (file, name);
22224 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22226 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22228 fputs ("[TC],", file);
22231 /* Currently C++ toc references to vtables can be emitted before it
22232 is decided whether the vtable is public or private. If this is
22233 the case, then the linker will eventually complain that there is
22234 a TOC reference to an unknown section. Thus, for vtables only,
22235 we emit the TOC reference to reference the symbol and not the
22237 if (VTABLE_NAME_P (name))
22239 RS6000_OUTPUT_BASENAME (file, name);
22241 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22242 else if (offset > 0)
22243 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22246 output_addr_const (file, x);
22250 /* Output an assembler pseudo-op to write an ASCII string of N characters
22251 starting at P to FILE.
22253 On the RS/6000, we have to do this using the .byte operation and
22254 write out special characters outside the quoted string.
22255 Also, the assembler is broken; very long strings are truncated,
22256 so we must artificially break them up early. */
22259 output_ascii (FILE *file, const char *p, int n)
22262 int i, count_string;
22263 const char *for_string = "\t.byte \"";
22264 const char *for_decimal = "\t.byte ";
22265 const char *to_close = NULL;
22268 for (i = 0; i < n; i++)
22271 if (c >= ' ' && c < 0177)
22274 fputs (for_string, file);
22277 /* Write two quotes to get one. */
22285 for_decimal = "\"\n\t.byte ";
22289 if (count_string >= 512)
22291 fputs (to_close, file);
22293 for_string = "\t.byte \"";
22294 for_decimal = "\t.byte ";
22302 fputs (for_decimal, file);
22303 fprintf (file, "%d", c);
22305 for_string = "\n\t.byte \"";
22306 for_decimal = ", ";
22312 /* Now close the string if we have written one. Then end the line. */
22314 fputs (to_close, file);
22317 /* Generate a unique section name for FILENAME for a section type
22318 represented by SECTION_DESC. Output goes into BUF.
22320 SECTION_DESC can be any string, as long as it is different for each
22321 possible section type.
22323 We name the section in the same manner as xlc. The name begins with an
22324 underscore followed by the filename (after stripping any leading directory
22325 names) with the last period replaced by the string SECTION_DESC. If
22326 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22330 rs6000_gen_section_name (char **buf, const char *filename,
22331 const char *section_desc)
22333 const char *q, *after_last_slash, *last_period = 0;
22337 after_last_slash = filename;
22338 for (q = filename; *q; q++)
22341 after_last_slash = q + 1;
22342 else if (*q == '.')
22346 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22347 *buf = (char *) xmalloc (len);
22352 for (q = after_last_slash; *q; q++)
22354 if (q == last_period)
22356 strcpy (p, section_desc);
22357 p += strlen (section_desc);
22361 else if (ISALNUM (*q))
22365 if (last_period == 0)
22366 strcpy (p, section_desc);
22371 /* Emit profile function. */
22374 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22376 /* Non-standard profiling for kernels, which just saves LR then calls
22377 _mcount without worrying about arg saves. The idea is to change
22378 the function prologue as little as possible as it isn't easy to
22379 account for arg save/restore code added just for _mcount. */
22380 if (TARGET_PROFILE_KERNEL)
22383 if (DEFAULT_ABI == ABI_AIX)
22385 #ifndef NO_PROFILE_COUNTERS
22386 # define NO_PROFILE_COUNTERS 0
22388 if (NO_PROFILE_COUNTERS)
22389 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22390 LCT_NORMAL, VOIDmode, 0);
22394 const char *label_name;
22397 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22398 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22399 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22401 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22402 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22405 else if (DEFAULT_ABI == ABI_DARWIN)
22407 const char *mcount_name = RS6000_MCOUNT;
22408 int caller_addr_regno = LR_REGNO;
22410 /* Be conservative and always set this, at least for now. */
22411 crtl->uses_pic_offset_table = 1;
22414 /* For PIC code, set up a stub and collect the caller's address
22415 from r0, which is where the prologue puts it. */
22416 if (MACHOPIC_INDIRECT
22417 && crtl->uses_pic_offset_table)
22418 caller_addr_regno = 0;
22420 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22421 LCT_NORMAL, VOIDmode, 1,
22422 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22426 /* Write function profiler code. */
22429 output_function_profiler (FILE *file, int labelno)
22433 switch (DEFAULT_ABI)
22436 gcc_unreachable ();
22441 warning (0, "no profiling of 64-bit code for this ABI");
22444 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22445 fprintf (file, "\tmflr %s\n", reg_names[0]);
22446 if (NO_PROFILE_COUNTERS)
22448 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22449 reg_names[0], reg_names[1]);
22451 else if (TARGET_SECURE_PLT && flag_pic)
22453 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22454 reg_names[0], reg_names[1]);
22455 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22456 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22457 reg_names[12], reg_names[12]);
22458 assemble_name (file, buf);
22459 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22460 assemble_name (file, buf);
22461 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22463 else if (flag_pic == 1)
22465 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22466 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22467 reg_names[0], reg_names[1]);
22468 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22469 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22470 assemble_name (file, buf);
22471 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22473 else if (flag_pic > 1)
22475 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22476 reg_names[0], reg_names[1]);
22477 /* Now, we need to get the address of the label. */
22478 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22479 assemble_name (file, buf);
22480 fputs ("-.\n1:", file);
22481 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22482 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22483 reg_names[0], reg_names[11]);
22484 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22485 reg_names[0], reg_names[0], reg_names[11]);
22489 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22490 assemble_name (file, buf);
22491 fputs ("@ha\n", file);
22492 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22493 reg_names[0], reg_names[1]);
22494 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22495 assemble_name (file, buf);
22496 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22499 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22500 fprintf (file, "\tbl %s%s\n",
22501 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22506 if (!TARGET_PROFILE_KERNEL)
22508 /* Don't do anything, done in output_profile_hook (). */
22512 gcc_assert (!TARGET_32BIT);
22514 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22515 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22517 if (cfun->static_chain_decl != NULL)
22519 asm_fprintf (file, "\tstd %s,24(%s)\n",
22520 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22521 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22522 asm_fprintf (file, "\tld %s,24(%s)\n",
22523 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22526 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22534 /* The following variable value is the last issued insn. */
22536 static rtx last_scheduled_insn;
22538 /* The following variable helps to balance issuing of load and
22539 store instructions */
22541 static int load_store_pendulum;
22543 /* Power4 load update and store update instructions are cracked into a
22544 load or store and an integer insn which are executed in the same cycle.
22545 Branches have their own dispatch slot which does not count against the
22546 GCC issue rate, but it changes the program flow so there are no other
22547 instructions to issue in this cycle. */
22550 rs6000_variable_issue_1 (rtx insn, int more)
22552 last_scheduled_insn = insn;
22553 if (GET_CODE (PATTERN (insn)) == USE
22554 || GET_CODE (PATTERN (insn)) == CLOBBER)
22556 cached_can_issue_more = more;
22557 return cached_can_issue_more;
22560 if (insn_terminates_group_p (insn, current_group))
22562 cached_can_issue_more = 0;
22563 return cached_can_issue_more;
22566 /* If no reservation, but reach here */
22567 if (recog_memoized (insn) < 0)
22570 if (rs6000_sched_groups)
22572 if (is_microcoded_insn (insn))
22573 cached_can_issue_more = 0;
22574 else if (is_cracked_insn (insn))
22575 cached_can_issue_more = more > 2 ? more - 2 : 0;
22577 cached_can_issue_more = more - 1;
22579 return cached_can_issue_more;
22582 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22585 cached_can_issue_more = more - 1;
22586 return cached_can_issue_more;
22590 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22592 int r = rs6000_variable_issue_1 (insn, more);
22594 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22598 /* Adjust the cost of a scheduling dependency. Return the new cost of
22599 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22602 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22604 enum attr_type attr_type;
22606 if (! recog_memoized (insn))
22609 switch (REG_NOTE_KIND (link))
22613 /* Data dependency; DEP_INSN writes a register that INSN reads
22614 some cycles later. */
22616 /* Separate a load from a narrower, dependent store. */
22617 if (rs6000_sched_groups
22618 && GET_CODE (PATTERN (insn)) == SET
22619 && GET_CODE (PATTERN (dep_insn)) == SET
22620 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22621 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22622 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22623 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22626 attr_type = get_attr_type (insn);
22631 /* Tell the first scheduling pass about the latency between
22632 a mtctr and bctr (and mtlr and br/blr). The first
22633 scheduling pass will not know about this latency since
22634 the mtctr instruction, which has the latency associated
22635 to it, will be generated by reload. */
22636 return TARGET_POWER ? 5 : 4;
22638 /* Leave some extra cycles between a compare and its
22639 dependent branch, to inhibit expensive mispredicts. */
22640 if ((rs6000_cpu_attr == CPU_PPC603
22641 || rs6000_cpu_attr == CPU_PPC604
22642 || rs6000_cpu_attr == CPU_PPC604E
22643 || rs6000_cpu_attr == CPU_PPC620
22644 || rs6000_cpu_attr == CPU_PPC630
22645 || rs6000_cpu_attr == CPU_PPC750
22646 || rs6000_cpu_attr == CPU_PPC7400
22647 || rs6000_cpu_attr == CPU_PPC7450
22648 || rs6000_cpu_attr == CPU_POWER4
22649 || rs6000_cpu_attr == CPU_POWER5
22650 || rs6000_cpu_attr == CPU_POWER7
22651 || rs6000_cpu_attr == CPU_CELL)
22652 && recog_memoized (dep_insn)
22653 && (INSN_CODE (dep_insn) >= 0))
22655 switch (get_attr_type (dep_insn))
22659 case TYPE_DELAYED_COMPARE:
22660 case TYPE_IMUL_COMPARE:
22661 case TYPE_LMUL_COMPARE:
22662 case TYPE_FPCOMPARE:
22663 case TYPE_CR_LOGICAL:
22664 case TYPE_DELAYED_CR:
22673 case TYPE_STORE_UX:
22675 case TYPE_FPSTORE_U:
22676 case TYPE_FPSTORE_UX:
22677 if ((rs6000_cpu == PROCESSOR_POWER6)
22678 && recog_memoized (dep_insn)
22679 && (INSN_CODE (dep_insn) >= 0))
22682 if (GET_CODE (PATTERN (insn)) != SET)
22683 /* If this happens, we have to extend this to schedule
22684 optimally. Return default for now. */
22687 /* Adjust the cost for the case where the value written
22688 by a fixed point operation is used as the address
22689 gen value on a store. */
22690 switch (get_attr_type (dep_insn))
22697 if (! store_data_bypass_p (dep_insn, insn))
22701 case TYPE_LOAD_EXT:
22702 case TYPE_LOAD_EXT_U:
22703 case TYPE_LOAD_EXT_UX:
22704 case TYPE_VAR_SHIFT_ROTATE:
22705 case TYPE_VAR_DELAYED_COMPARE:
22707 if (! store_data_bypass_p (dep_insn, insn))
22713 case TYPE_FAST_COMPARE:
22716 case TYPE_INSERT_WORD:
22717 case TYPE_INSERT_DWORD:
22718 case TYPE_FPLOAD_U:
22719 case TYPE_FPLOAD_UX:
22721 case TYPE_STORE_UX:
22722 case TYPE_FPSTORE_U:
22723 case TYPE_FPSTORE_UX:
22725 if (! store_data_bypass_p (dep_insn, insn))
22733 case TYPE_IMUL_COMPARE:
22734 case TYPE_LMUL_COMPARE:
22736 if (! store_data_bypass_p (dep_insn, insn))
22742 if (! store_data_bypass_p (dep_insn, insn))
22748 if (! store_data_bypass_p (dep_insn, insn))
22761 case TYPE_LOAD_EXT:
22762 case TYPE_LOAD_EXT_U:
22763 case TYPE_LOAD_EXT_UX:
22764 if ((rs6000_cpu == PROCESSOR_POWER6)
22765 && recog_memoized (dep_insn)
22766 && (INSN_CODE (dep_insn) >= 0))
22769 /* Adjust the cost for the case where the value written
22770 by a fixed point instruction is used within the address
22771 gen portion of a subsequent load(u)(x) */
22772 switch (get_attr_type (dep_insn))
22779 if (set_to_load_agen (dep_insn, insn))
22783 case TYPE_LOAD_EXT:
22784 case TYPE_LOAD_EXT_U:
22785 case TYPE_LOAD_EXT_UX:
22786 case TYPE_VAR_SHIFT_ROTATE:
22787 case TYPE_VAR_DELAYED_COMPARE:
22789 if (set_to_load_agen (dep_insn, insn))
22795 case TYPE_FAST_COMPARE:
22798 case TYPE_INSERT_WORD:
22799 case TYPE_INSERT_DWORD:
22800 case TYPE_FPLOAD_U:
22801 case TYPE_FPLOAD_UX:
22803 case TYPE_STORE_UX:
22804 case TYPE_FPSTORE_U:
22805 case TYPE_FPSTORE_UX:
22807 if (set_to_load_agen (dep_insn, insn))
22815 case TYPE_IMUL_COMPARE:
22816 case TYPE_LMUL_COMPARE:
22818 if (set_to_load_agen (dep_insn, insn))
22824 if (set_to_load_agen (dep_insn, insn))
22830 if (set_to_load_agen (dep_insn, insn))
22841 if ((rs6000_cpu == PROCESSOR_POWER6)
22842 && recog_memoized (dep_insn)
22843 && (INSN_CODE (dep_insn) >= 0)
22844 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22851 /* Fall out to return default cost. */
22855 case REG_DEP_OUTPUT:
22856 /* Output dependency; DEP_INSN writes a register that INSN writes some
22858 if ((rs6000_cpu == PROCESSOR_POWER6)
22859 && recog_memoized (dep_insn)
22860 && (INSN_CODE (dep_insn) >= 0))
22862 attr_type = get_attr_type (insn);
22867 if (get_attr_type (dep_insn) == TYPE_FP)
22871 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22879 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22884 gcc_unreachable ();
22890 /* Debug version of rs6000_adjust_cost. */
22893 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22895 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22901 switch (REG_NOTE_KIND (link))
22903 default: dep = "unknown depencency"; break;
22904 case REG_DEP_TRUE: dep = "data dependency"; break;
22905 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22906 case REG_DEP_ANTI: dep = "anti depencency"; break;
22910 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22911 "%s, insn:\n", ret, cost, dep);
22919 /* The function returns a true if INSN is microcoded.
22920 Return false otherwise. */
22923 is_microcoded_insn (rtx insn)
22925 if (!insn || !NONDEBUG_INSN_P (insn)
22926 || GET_CODE (PATTERN (insn)) == USE
22927 || GET_CODE (PATTERN (insn)) == CLOBBER)
22930 if (rs6000_cpu_attr == CPU_CELL)
22931 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22933 if (rs6000_sched_groups)
22935 enum attr_type type = get_attr_type (insn);
22936 if (type == TYPE_LOAD_EXT_U
22937 || type == TYPE_LOAD_EXT_UX
22938 || type == TYPE_LOAD_UX
22939 || type == TYPE_STORE_UX
22940 || type == TYPE_MFCR)
22947 /* The function returns true if INSN is cracked into 2 instructions
22948 by the processor (and therefore occupies 2 issue slots). */
22951 is_cracked_insn (rtx insn)
22953 if (!insn || !NONDEBUG_INSN_P (insn)
22954 || GET_CODE (PATTERN (insn)) == USE
22955 || GET_CODE (PATTERN (insn)) == CLOBBER)
22958 if (rs6000_sched_groups)
22960 enum attr_type type = get_attr_type (insn);
22961 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22962 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22963 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22964 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22965 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22966 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22967 || type == TYPE_IDIV || type == TYPE_LDIV
22968 || type == TYPE_INSERT_WORD)
22975 /* The function returns true if INSN can be issued only from
22976 the branch slot. */
22979 is_branch_slot_insn (rtx insn)
22981 if (!insn || !NONDEBUG_INSN_P (insn)
22982 || GET_CODE (PATTERN (insn)) == USE
22983 || GET_CODE (PATTERN (insn)) == CLOBBER)
22986 if (rs6000_sched_groups)
22988 enum attr_type type = get_attr_type (insn);
22989 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22997 /* The function returns true if out_inst sets a value that is
22998 used in the address generation computation of in_insn */
23000 set_to_load_agen (rtx out_insn, rtx in_insn)
23002 rtx out_set, in_set;
23004 /* For performance reasons, only handle the simple case where
23005 both loads are a single_set. */
23006 out_set = single_set (out_insn);
23009 in_set = single_set (in_insn);
23011 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23017 /* The function returns true if the target storage location of
23018 out_insn is adjacent to the target storage location of in_insn */
23019 /* Return 1 if memory locations are adjacent. */
23022 adjacent_mem_locations (rtx insn1, rtx insn2)
23025 rtx a = get_store_dest (PATTERN (insn1));
23026 rtx b = get_store_dest (PATTERN (insn2));
23028 if ((GET_CODE (XEXP (a, 0)) == REG
23029 || (GET_CODE (XEXP (a, 0)) == PLUS
23030 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23031 && (GET_CODE (XEXP (b, 0)) == REG
23032 || (GET_CODE (XEXP (b, 0)) == PLUS
23033 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23035 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23038 if (GET_CODE (XEXP (a, 0)) == PLUS)
23040 reg0 = XEXP (XEXP (a, 0), 0);
23041 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23044 reg0 = XEXP (a, 0);
23046 if (GET_CODE (XEXP (b, 0)) == PLUS)
23048 reg1 = XEXP (XEXP (b, 0), 0);
23049 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23052 reg1 = XEXP (b, 0);
23054 val_diff = val1 - val0;
23056 return ((REGNO (reg0) == REGNO (reg1))
23057 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23058 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23064 /* A C statement (sans semicolon) to update the integer scheduling
23065 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23066 INSN earlier, reduce the priority to execute INSN later. Do not
23067 define this macro if you do not need to adjust the scheduling
23068 priorities of insns. */
23071 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23073 /* On machines (like the 750) which have asymmetric integer units,
23074 where one integer unit can do multiply and divides and the other
23075 can't, reduce the priority of multiply/divide so it is scheduled
23076 before other integer operations. */
23079 if (! INSN_P (insn))
23082 if (GET_CODE (PATTERN (insn)) == USE)
23085 switch (rs6000_cpu_attr) {
23087 switch (get_attr_type (insn))
23094 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23095 priority, priority);
23096 if (priority >= 0 && priority < 0x01000000)
23103 if (insn_must_be_first_in_group (insn)
23104 && reload_completed
23105 && current_sched_info->sched_max_insns_priority
23106 && rs6000_sched_restricted_insns_priority)
23109 /* Prioritize insns that can be dispatched only in the first
23111 if (rs6000_sched_restricted_insns_priority == 1)
23112 /* Attach highest priority to insn. This means that in
23113 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23114 precede 'priority' (critical path) considerations. */
23115 return current_sched_info->sched_max_insns_priority;
23116 else if (rs6000_sched_restricted_insns_priority == 2)
23117 /* Increase priority of insn by a minimal amount. This means that in
23118 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23119 considerations precede dispatch-slot restriction considerations. */
23120 return (priority + 1);
23123 if (rs6000_cpu == PROCESSOR_POWER6
23124 && ((load_store_pendulum == -2 && is_load_insn (insn))
23125 || (load_store_pendulum == 2 && is_store_insn (insn))))
23126 /* Attach highest priority to insn if the scheduler has just issued two
23127 stores and this instruction is a load, or two loads and this instruction
23128 is a store. Power6 wants loads and stores scheduled alternately
23130 return current_sched_info->sched_max_insns_priority;
23135 /* Return true if the instruction is nonpipelined on the Cell. */
23137 is_nonpipeline_insn (rtx insn)
23139 enum attr_type type;
23140 if (!insn || !NONDEBUG_INSN_P (insn)
23141 || GET_CODE (PATTERN (insn)) == USE
23142 || GET_CODE (PATTERN (insn)) == CLOBBER)
23145 type = get_attr_type (insn);
23146 if (type == TYPE_IMUL
23147 || type == TYPE_IMUL2
23148 || type == TYPE_IMUL3
23149 || type == TYPE_LMUL
23150 || type == TYPE_IDIV
23151 || type == TYPE_LDIV
23152 || type == TYPE_SDIV
23153 || type == TYPE_DDIV
23154 || type == TYPE_SSQRT
23155 || type == TYPE_DSQRT
23156 || type == TYPE_MFCR
23157 || type == TYPE_MFCRF
23158 || type == TYPE_MFJMPR)
23166 /* Return how many instructions the machine can issue per cycle. */
23169 rs6000_issue_rate (void)
23171 /* Unless scheduling for register pressure, use issue rate of 1 for
23172 first scheduling pass to decrease degradation. */
23173 if (!reload_completed && !flag_sched_pressure)
23176 switch (rs6000_cpu_attr) {
23177 case CPU_RIOS1: /* ? */
23179 case CPU_PPC601: /* ? */
23188 case CPU_PPCE300C2:
23189 case CPU_PPCE300C3:
23190 case CPU_PPCE500MC:
23191 case CPU_PPCE500MC64:
23211 /* Return how many instructions to look ahead for better insn
23215 rs6000_use_sched_lookahead (void)
23217 if (rs6000_cpu_attr == CPU_PPC8540)
23219 if (rs6000_cpu_attr == CPU_CELL)
23220 return (reload_completed ? 8 : 0);
23224 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23226 rs6000_use_sched_lookahead_guard (rtx insn)
23228 if (rs6000_cpu_attr != CPU_CELL)
23231 if (insn == NULL_RTX || !INSN_P (insn))
23234 if (!reload_completed
23235 || is_nonpipeline_insn (insn)
23236 || is_microcoded_insn (insn))
23242 /* Determine is PAT refers to memory. */
23245 is_mem_ref (rtx pat)
23251 /* stack_tie does not produce any real memory traffic. */
23252 if (GET_CODE (pat) == UNSPEC
23253 && XINT (pat, 1) == UNSPEC_TIE)
23256 if (GET_CODE (pat) == MEM)
23259 /* Recursively process the pattern. */
23260 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23262 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23265 ret |= is_mem_ref (XEXP (pat, i));
23266 else if (fmt[i] == 'E')
23267 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23268 ret |= is_mem_ref (XVECEXP (pat, i, j));
23274 /* Determine if PAT is a PATTERN of a load insn. */
23277 is_load_insn1 (rtx pat)
23279 if (!pat || pat == NULL_RTX)
23282 if (GET_CODE (pat) == SET)
23283 return is_mem_ref (SET_SRC (pat));
23285 if (GET_CODE (pat) == PARALLEL)
23289 for (i = 0; i < XVECLEN (pat, 0); i++)
23290 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23297 /* Determine if INSN loads from memory. */
23300 is_load_insn (rtx insn)
23302 if (!insn || !INSN_P (insn))
23305 if (GET_CODE (insn) == CALL_INSN)
23308 return is_load_insn1 (PATTERN (insn));
23311 /* Determine if PAT is a PATTERN of a store insn. */
23314 is_store_insn1 (rtx pat)
23316 if (!pat || pat == NULL_RTX)
23319 if (GET_CODE (pat) == SET)
23320 return is_mem_ref (SET_DEST (pat));
23322 if (GET_CODE (pat) == PARALLEL)
23326 for (i = 0; i < XVECLEN (pat, 0); i++)
23327 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23334 /* Determine if INSN stores to memory. */
23337 is_store_insn (rtx insn)
23339 if (!insn || !INSN_P (insn))
23342 return is_store_insn1 (PATTERN (insn));
23345 /* Return the dest of a store insn. */
23348 get_store_dest (rtx pat)
23350 gcc_assert (is_store_insn1 (pat));
23352 if (GET_CODE (pat) == SET)
23353 return SET_DEST (pat);
23354 else if (GET_CODE (pat) == PARALLEL)
23358 for (i = 0; i < XVECLEN (pat, 0); i++)
23360 rtx inner_pat = XVECEXP (pat, 0, i);
23361 if (GET_CODE (inner_pat) == SET
23362 && is_mem_ref (SET_DEST (inner_pat)))
23366 /* We shouldn't get here, because we should have either a simple
23367 store insn or a store with update which are covered above. */
23371 /* Returns whether the dependence between INSN and NEXT is considered
23372 costly by the given target. */
23375 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23380 /* If the flag is not enabled - no dependence is considered costly;
23381 allow all dependent insns in the same group.
23382 This is the most aggressive option. */
23383 if (rs6000_sched_costly_dep == no_dep_costly)
23386 /* If the flag is set to 1 - a dependence is always considered costly;
23387 do not allow dependent instructions in the same group.
23388 This is the most conservative option. */
23389 if (rs6000_sched_costly_dep == all_deps_costly)
23392 insn = DEP_PRO (dep);
23393 next = DEP_CON (dep);
23395 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23396 && is_load_insn (next)
23397 && is_store_insn (insn))
23398 /* Prevent load after store in the same group. */
23401 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23402 && is_load_insn (next)
23403 && is_store_insn (insn)
23404 && DEP_TYPE (dep) == REG_DEP_TRUE)
23405 /* Prevent load after store in the same group if it is a true
23409 /* The flag is set to X; dependences with latency >= X are considered costly,
23410 and will not be scheduled in the same group. */
23411 if (rs6000_sched_costly_dep <= max_dep_latency
23412 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23418 /* Return the next insn after INSN that is found before TAIL is reached,
23419 skipping any "non-active" insns - insns that will not actually occupy
23420 an issue slot. Return NULL_RTX if such an insn is not found. */
23423 get_next_active_insn (rtx insn, rtx tail)
23425 if (insn == NULL_RTX || insn == tail)
23430 insn = NEXT_INSN (insn);
23431 if (insn == NULL_RTX || insn == tail)
23436 || (NONJUMP_INSN_P (insn)
23437 && GET_CODE (PATTERN (insn)) != USE
23438 && GET_CODE (PATTERN (insn)) != CLOBBER
23439 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23445 /* We are about to begin issuing insns for this clock cycle. */
23448 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23449 rtx *ready ATTRIBUTE_UNUSED,
23450 int *pn_ready ATTRIBUTE_UNUSED,
23451 int clock_var ATTRIBUTE_UNUSED)
23453 int n_ready = *pn_ready;
23456 fprintf (dump, "// rs6000_sched_reorder :\n");
23458 /* Reorder the ready list, if the second to last ready insn
23459 is a nonepipeline insn. */
23460 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23462 if (is_nonpipeline_insn (ready[n_ready - 1])
23463 && (recog_memoized (ready[n_ready - 2]) > 0))
23464 /* Simply swap first two insns. */
23466 rtx tmp = ready[n_ready - 1];
23467 ready[n_ready - 1] = ready[n_ready - 2];
23468 ready[n_ready - 2] = tmp;
23472 if (rs6000_cpu == PROCESSOR_POWER6)
23473 load_store_pendulum = 0;
23475 return rs6000_issue_rate ();
23478 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23481 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23482 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23485 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23487 /* For Power6, we need to handle some special cases to try and keep the
23488 store queue from overflowing and triggering expensive flushes.
23490 This code monitors how load and store instructions are being issued
23491 and skews the ready list one way or the other to increase the likelihood
23492 that a desired instruction is issued at the proper time.
23494 A couple of things are done. First, we maintain a "load_store_pendulum"
23495 to track the current state of load/store issue.
23497 - If the pendulum is at zero, then no loads or stores have been
23498 issued in the current cycle so we do nothing.
23500 - If the pendulum is 1, then a single load has been issued in this
23501 cycle and we attempt to locate another load in the ready list to
23504 - If the pendulum is -2, then two stores have already been
23505 issued in this cycle, so we increase the priority of the first load
23506 in the ready list to increase it's likelihood of being chosen first
23509 - If the pendulum is -1, then a single store has been issued in this
23510 cycle and we attempt to locate another store in the ready list to
23511 issue with it, preferring a store to an adjacent memory location to
23512 facilitate store pairing in the store queue.
23514 - If the pendulum is 2, then two loads have already been
23515 issued in this cycle, so we increase the priority of the first store
23516 in the ready list to increase it's likelihood of being chosen first
23519 - If the pendulum < -2 or > 2, then do nothing.
23521 Note: This code covers the most common scenarios. There exist non
23522 load/store instructions which make use of the LSU and which
23523 would need to be accounted for to strictly model the behavior
23524 of the machine. Those instructions are currently unaccounted
23525 for to help minimize compile time overhead of this code.
23527 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23533 if (is_store_insn (last_scheduled_insn))
23534 /* Issuing a store, swing the load_store_pendulum to the left */
23535 load_store_pendulum--;
23536 else if (is_load_insn (last_scheduled_insn))
23537 /* Issuing a load, swing the load_store_pendulum to the right */
23538 load_store_pendulum++;
23540 return cached_can_issue_more;
23542 /* If the pendulum is balanced, or there is only one instruction on
23543 the ready list, then all is well, so return. */
23544 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23545 return cached_can_issue_more;
23547 if (load_store_pendulum == 1)
23549 /* A load has been issued in this cycle. Scan the ready list
23550 for another load to issue with it */
23555 if (is_load_insn (ready[pos]))
23557 /* Found a load. Move it to the head of the ready list,
23558 and adjust it's priority so that it is more likely to
23561 for (i=pos; i<*pn_ready-1; i++)
23562 ready[i] = ready[i + 1];
23563 ready[*pn_ready-1] = tmp;
23565 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23566 INSN_PRIORITY (tmp)++;
23572 else if (load_store_pendulum == -2)
23574 /* Two stores have been issued in this cycle. Increase the
23575 priority of the first load in the ready list to favor it for
23576 issuing in the next cycle. */
23581 if (is_load_insn (ready[pos])
23583 && INSN_PRIORITY_KNOWN (ready[pos]))
23585 INSN_PRIORITY (ready[pos])++;
23587 /* Adjust the pendulum to account for the fact that a load
23588 was found and increased in priority. This is to prevent
23589 increasing the priority of multiple loads */
23590 load_store_pendulum--;
23597 else if (load_store_pendulum == -1)
23599 /* A store has been issued in this cycle. Scan the ready list for
23600 another store to issue with it, preferring a store to an adjacent
23602 int first_store_pos = -1;
23608 if (is_store_insn (ready[pos]))
23610 /* Maintain the index of the first store found on the
23612 if (first_store_pos == -1)
23613 first_store_pos = pos;
23615 if (is_store_insn (last_scheduled_insn)
23616 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23618 /* Found an adjacent store. Move it to the head of the
23619 ready list, and adjust it's priority so that it is
23620 more likely to stay there */
23622 for (i=pos; i<*pn_ready-1; i++)
23623 ready[i] = ready[i + 1];
23624 ready[*pn_ready-1] = tmp;
23626 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23627 INSN_PRIORITY (tmp)++;
23629 first_store_pos = -1;
23637 if (first_store_pos >= 0)
23639 /* An adjacent store wasn't found, but a non-adjacent store was,
23640 so move the non-adjacent store to the front of the ready
23641 list, and adjust its priority so that it is more likely to
23643 tmp = ready[first_store_pos];
23644 for (i=first_store_pos; i<*pn_ready-1; i++)
23645 ready[i] = ready[i + 1];
23646 ready[*pn_ready-1] = tmp;
23647 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23648 INSN_PRIORITY (tmp)++;
23651 else if (load_store_pendulum == 2)
23653 /* Two loads have been issued in this cycle. Increase the priority
23654 of the first store in the ready list to favor it for issuing in
23660 if (is_store_insn (ready[pos])
23662 && INSN_PRIORITY_KNOWN (ready[pos]))
23664 INSN_PRIORITY (ready[pos])++;
23666 /* Adjust the pendulum to account for the fact that a store
23667 was found and increased in priority. This is to prevent
23668 increasing the priority of multiple stores */
23669 load_store_pendulum++;
23678 return cached_can_issue_more;
23681 /* Return whether the presence of INSN causes a dispatch group termination
23682 of group WHICH_GROUP.
23684 If WHICH_GROUP == current_group, this function will return true if INSN
23685 causes the termination of the current group (i.e, the dispatch group to
23686 which INSN belongs). This means that INSN will be the last insn in the
23687 group it belongs to.
23689 If WHICH_GROUP == previous_group, this function will return true if INSN
23690 causes the termination of the previous group (i.e, the dispatch group that
23691 precedes the group to which INSN belongs). This means that INSN will be
23692 the first insn in the group it belongs to). */
23695 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23702 first = insn_must_be_first_in_group (insn);
23703 last = insn_must_be_last_in_group (insn);
23708 if (which_group == current_group)
23710 else if (which_group == previous_group)
23718 insn_must_be_first_in_group (rtx insn)
23720 enum attr_type type;
23723 || GET_CODE (insn) == NOTE
23724 || DEBUG_INSN_P (insn)
23725 || GET_CODE (PATTERN (insn)) == USE
23726 || GET_CODE (PATTERN (insn)) == CLOBBER)
23729 switch (rs6000_cpu)
23731 case PROCESSOR_POWER5:
23732 if (is_cracked_insn (insn))
23734 case PROCESSOR_POWER4:
23735 if (is_microcoded_insn (insn))
23738 if (!rs6000_sched_groups)
23741 type = get_attr_type (insn);
23748 case TYPE_DELAYED_CR:
23749 case TYPE_CR_LOGICAL:
23763 case PROCESSOR_POWER6:
23764 type = get_attr_type (insn);
23768 case TYPE_INSERT_DWORD:
23772 case TYPE_VAR_SHIFT_ROTATE:
23779 case TYPE_INSERT_WORD:
23780 case TYPE_DELAYED_COMPARE:
23781 case TYPE_IMUL_COMPARE:
23782 case TYPE_LMUL_COMPARE:
23783 case TYPE_FPCOMPARE:
23794 case TYPE_LOAD_EXT_UX:
23796 case TYPE_STORE_UX:
23797 case TYPE_FPLOAD_U:
23798 case TYPE_FPLOAD_UX:
23799 case TYPE_FPSTORE_U:
23800 case TYPE_FPSTORE_UX:
23806 case PROCESSOR_POWER7:
23807 type = get_attr_type (insn);
23811 case TYPE_CR_LOGICAL:
23818 case TYPE_DELAYED_COMPARE:
23819 case TYPE_VAR_DELAYED_COMPARE:
23825 case TYPE_LOAD_EXT:
23826 case TYPE_LOAD_EXT_U:
23827 case TYPE_LOAD_EXT_UX:
23829 case TYPE_STORE_UX:
23830 case TYPE_FPLOAD_U:
23831 case TYPE_FPLOAD_UX:
23832 case TYPE_FPSTORE_U:
23833 case TYPE_FPSTORE_UX:
23849 insn_must_be_last_in_group (rtx insn)
23851 enum attr_type type;
23854 || GET_CODE (insn) == NOTE
23855 || DEBUG_INSN_P (insn)
23856 || GET_CODE (PATTERN (insn)) == USE
23857 || GET_CODE (PATTERN (insn)) == CLOBBER)
23860 switch (rs6000_cpu) {
23861 case PROCESSOR_POWER4:
23862 case PROCESSOR_POWER5:
23863 if (is_microcoded_insn (insn))
23866 if (is_branch_slot_insn (insn))
23870 case PROCESSOR_POWER6:
23871 type = get_attr_type (insn);
23878 case TYPE_VAR_SHIFT_ROTATE:
23885 case TYPE_DELAYED_COMPARE:
23886 case TYPE_IMUL_COMPARE:
23887 case TYPE_LMUL_COMPARE:
23888 case TYPE_FPCOMPARE:
23902 case PROCESSOR_POWER7:
23903 type = get_attr_type (insn);
23911 case TYPE_LOAD_EXT_U:
23912 case TYPE_LOAD_EXT_UX:
23913 case TYPE_STORE_UX:
23926 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23927 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23930 is_costly_group (rtx *group_insns, rtx next_insn)
23933 int issue_rate = rs6000_issue_rate ();
23935 for (i = 0; i < issue_rate; i++)
23937 sd_iterator_def sd_it;
23939 rtx insn = group_insns[i];
23944 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23946 rtx next = DEP_CON (dep);
23948 if (next == next_insn
23949 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23957 /* Utility of the function redefine_groups.
23958 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23959 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23960 to keep it "far" (in a separate group) from GROUP_INSNS, following
23961 one of the following schemes, depending on the value of the flag
23962 -minsert_sched_nops = X:
23963 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23964 in order to force NEXT_INSN into a separate group.
23965 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23966 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23967 insertion (has a group just ended, how many vacant issue slots remain in the
23968 last group, and how many dispatch groups were encountered so far). */
23971 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23972 rtx next_insn, bool *group_end, int can_issue_more,
23977 int issue_rate = rs6000_issue_rate ();
23978 bool end = *group_end;
23981 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23982 return can_issue_more;
23984 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23985 return can_issue_more;
23987 force = is_costly_group (group_insns, next_insn);
23989 return can_issue_more;
23991 if (sched_verbose > 6)
23992 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23993 *group_count ,can_issue_more);
23995 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23998 can_issue_more = 0;
24000 /* Since only a branch can be issued in the last issue_slot, it is
24001 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24002 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24003 in this case the last nop will start a new group and the branch
24004 will be forced to the new group. */
24005 if (can_issue_more && !is_branch_slot_insn (next_insn))
24008 while (can_issue_more > 0)
24011 emit_insn_before (nop, next_insn);
24019 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24021 int n_nops = rs6000_sched_insert_nops;
24023 /* Nops can't be issued from the branch slot, so the effective
24024 issue_rate for nops is 'issue_rate - 1'. */
24025 if (can_issue_more == 0)
24026 can_issue_more = issue_rate;
24028 if (can_issue_more == 0)
24030 can_issue_more = issue_rate - 1;
24033 for (i = 0; i < issue_rate; i++)
24035 group_insns[i] = 0;
24042 emit_insn_before (nop, next_insn);
24043 if (can_issue_more == issue_rate - 1) /* new group begins */
24046 if (can_issue_more == 0)
24048 can_issue_more = issue_rate - 1;
24051 for (i = 0; i < issue_rate; i++)
24053 group_insns[i] = 0;
24059 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24062 /* Is next_insn going to start a new group? */
24065 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24066 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24067 || (can_issue_more < issue_rate &&
24068 insn_terminates_group_p (next_insn, previous_group)));
24069 if (*group_end && end)
24072 if (sched_verbose > 6)
24073 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24074 *group_count, can_issue_more);
24075 return can_issue_more;
24078 return can_issue_more;
24081 /* This function tries to synch the dispatch groups that the compiler "sees"
24082 with the dispatch groups that the processor dispatcher is expected to
24083 form in practice. It tries to achieve this synchronization by forcing the
24084 estimated processor grouping on the compiler (as opposed to the function
24085 'pad_goups' which tries to force the scheduler's grouping on the processor).
24087 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24088 examines the (estimated) dispatch groups that will be formed by the processor
24089 dispatcher. It marks these group boundaries to reflect the estimated
24090 processor grouping, overriding the grouping that the scheduler had marked.
24091 Depending on the value of the flag '-minsert-sched-nops' this function can
24092 force certain insns into separate groups or force a certain distance between
24093 them by inserting nops, for example, if there exists a "costly dependence"
24096 The function estimates the group boundaries that the processor will form as
24097 follows: It keeps track of how many vacant issue slots are available after
24098 each insn. A subsequent insn will start a new group if one of the following
24100 - no more vacant issue slots remain in the current dispatch group.
24101 - only the last issue slot, which is the branch slot, is vacant, but the next
24102 insn is not a branch.
24103 - only the last 2 or less issue slots, including the branch slot, are vacant,
24104 which means that a cracked insn (which occupies two issue slots) can't be
24105 issued in this group.
24106 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24107 start a new group. */
24110 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24112 rtx insn, next_insn;
24114 int can_issue_more;
24117 int group_count = 0;
24121 issue_rate = rs6000_issue_rate ();
24122 group_insns = XALLOCAVEC (rtx, issue_rate);
24123 for (i = 0; i < issue_rate; i++)
24125 group_insns[i] = 0;
24127 can_issue_more = issue_rate;
24129 insn = get_next_active_insn (prev_head_insn, tail);
24132 while (insn != NULL_RTX)
24134 slot = (issue_rate - can_issue_more);
24135 group_insns[slot] = insn;
24137 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24138 if (insn_terminates_group_p (insn, current_group))
24139 can_issue_more = 0;
24141 next_insn = get_next_active_insn (insn, tail);
24142 if (next_insn == NULL_RTX)
24143 return group_count + 1;
24145 /* Is next_insn going to start a new group? */
24147 = (can_issue_more == 0
24148 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24149 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24150 || (can_issue_more < issue_rate &&
24151 insn_terminates_group_p (next_insn, previous_group)));
24153 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24154 next_insn, &group_end, can_issue_more,
24160 can_issue_more = 0;
24161 for (i = 0; i < issue_rate; i++)
24163 group_insns[i] = 0;
24167 if (GET_MODE (next_insn) == TImode && can_issue_more)
24168 PUT_MODE (next_insn, VOIDmode);
24169 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24170 PUT_MODE (next_insn, TImode);
24173 if (can_issue_more == 0)
24174 can_issue_more = issue_rate;
24177 return group_count;
24180 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24181 dispatch group boundaries that the scheduler had marked. Pad with nops
24182 any dispatch groups which have vacant issue slots, in order to force the
24183 scheduler's grouping on the processor dispatcher. The function
24184 returns the number of dispatch groups found. */
24187 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24189 rtx insn, next_insn;
24192 int can_issue_more;
24194 int group_count = 0;
24196 /* Initialize issue_rate. */
24197 issue_rate = rs6000_issue_rate ();
24198 can_issue_more = issue_rate;
24200 insn = get_next_active_insn (prev_head_insn, tail);
24201 next_insn = get_next_active_insn (insn, tail);
24203 while (insn != NULL_RTX)
24206 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24208 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24210 if (next_insn == NULL_RTX)
24215 /* If the scheduler had marked group termination at this location
24216 (between insn and next_insn), and neither insn nor next_insn will
24217 force group termination, pad the group with nops to force group
24220 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24221 && !insn_terminates_group_p (insn, current_group)
24222 && !insn_terminates_group_p (next_insn, previous_group))
24224 if (!is_branch_slot_insn (next_insn))
24227 while (can_issue_more)
24230 emit_insn_before (nop, next_insn);
24235 can_issue_more = issue_rate;
24240 next_insn = get_next_active_insn (insn, tail);
24243 return group_count;
24246 /* We're beginning a new block. Initialize data structures as necessary. */
24249 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24250 int sched_verbose ATTRIBUTE_UNUSED,
24251 int max_ready ATTRIBUTE_UNUSED)
24253 last_scheduled_insn = NULL_RTX;
24254 load_store_pendulum = 0;
24257 /* The following function is called at the end of scheduling BB.
24258 After reload, it inserts nops at insn group bundling. */
24261 rs6000_sched_finish (FILE *dump, int sched_verbose)
24266 fprintf (dump, "=== Finishing schedule.\n");
24268 if (reload_completed && rs6000_sched_groups)
24270 /* Do not run sched_finish hook when selective scheduling enabled. */
24271 if (sel_sched_p ())
24274 if (rs6000_sched_insert_nops == sched_finish_none)
24277 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24278 n_groups = pad_groups (dump, sched_verbose,
24279 current_sched_info->prev_head,
24280 current_sched_info->next_tail);
24282 n_groups = redefine_groups (dump, sched_verbose,
24283 current_sched_info->prev_head,
24284 current_sched_info->next_tail);
24286 if (sched_verbose >= 6)
24288 fprintf (dump, "ngroups = %d\n", n_groups);
24289 print_rtl (dump, current_sched_info->prev_head);
24290 fprintf (dump, "Done finish_sched\n");
24295 struct _rs6000_sched_context
24297 short cached_can_issue_more;
24298 rtx last_scheduled_insn;
24299 int load_store_pendulum;
24302 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24303 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24305 /* Allocate store for new scheduling context. */
24307 rs6000_alloc_sched_context (void)
24309 return xmalloc (sizeof (rs6000_sched_context_def));
24312 /* If CLEAN_P is true then initializes _SC with clean data,
24313 and from the global context otherwise. */
24315 rs6000_init_sched_context (void *_sc, bool clean_p)
24317 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24321 sc->cached_can_issue_more = 0;
24322 sc->last_scheduled_insn = NULL_RTX;
24323 sc->load_store_pendulum = 0;
24327 sc->cached_can_issue_more = cached_can_issue_more;
24328 sc->last_scheduled_insn = last_scheduled_insn;
24329 sc->load_store_pendulum = load_store_pendulum;
24333 /* Sets the global scheduling context to the one pointed to by _SC. */
24335 rs6000_set_sched_context (void *_sc)
24337 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24339 gcc_assert (sc != NULL);
24341 cached_can_issue_more = sc->cached_can_issue_more;
24342 last_scheduled_insn = sc->last_scheduled_insn;
24343 load_store_pendulum = sc->load_store_pendulum;
24348 rs6000_free_sched_context (void *_sc)
24350 gcc_assert (_sc != NULL);
24356 /* Length in units of the trampoline for entering a nested function. */
24359 rs6000_trampoline_size (void)
24363 switch (DEFAULT_ABI)
24366 gcc_unreachable ();
24369 ret = (TARGET_32BIT) ? 12 : 24;
24374 ret = (TARGET_32BIT) ? 40 : 48;
24381 /* Emit RTL insns to initialize the variable parts of a trampoline.
24382 FNADDR is an RTX for the address of the function's pure code.
24383 CXT is an RTX for the static chain value for the function. */
24386 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24388 int regsize = (TARGET_32BIT) ? 4 : 8;
24389 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24390 rtx ctx_reg = force_reg (Pmode, cxt);
24391 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24393 switch (DEFAULT_ABI)
24396 gcc_unreachable ();
24398 /* Under AIX, just build the 3 word function descriptor */
24401 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24402 rtx fn_reg = gen_reg_rtx (Pmode);
24403 rtx toc_reg = gen_reg_rtx (Pmode);
24405 /* Macro to shorten the code expansions below. */
24406 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24408 m_tramp = replace_equiv_address (m_tramp, addr);
24410 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24411 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24412 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24413 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24414 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24420 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24423 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24424 LCT_NORMAL, VOIDmode, 4,
24426 GEN_INT (rs6000_trampoline_size ()), SImode,
24434 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24435 identifier as an argument, so the front end shouldn't look it up. */
24438 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24440 return is_attribute_p ("altivec", attr_id);
24443 /* Handle the "altivec" attribute. The attribute may have
24444 arguments as follows:
24446 __attribute__((altivec(vector__)))
24447 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24448 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24450 and may appear more than once (e.g., 'vector bool char') in a
24451 given declaration. */
24454 rs6000_handle_altivec_attribute (tree *node,
24455 tree name ATTRIBUTE_UNUSED,
24457 int flags ATTRIBUTE_UNUSED,
24458 bool *no_add_attrs)
24460 tree type = *node, result = NULL_TREE;
24461 enum machine_mode mode;
24464 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24465 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24466 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24469 while (POINTER_TYPE_P (type)
24470 || TREE_CODE (type) == FUNCTION_TYPE
24471 || TREE_CODE (type) == METHOD_TYPE
24472 || TREE_CODE (type) == ARRAY_TYPE)
24473 type = TREE_TYPE (type);
24475 mode = TYPE_MODE (type);
24477 /* Check for invalid AltiVec type qualifiers. */
24478 if (type == long_double_type_node)
24479 error ("use of %<long double%> in AltiVec types is invalid");
24480 else if (type == boolean_type_node)
24481 error ("use of boolean types in AltiVec types is invalid");
24482 else if (TREE_CODE (type) == COMPLEX_TYPE)
24483 error ("use of %<complex%> in AltiVec types is invalid");
24484 else if (DECIMAL_FLOAT_MODE_P (mode))
24485 error ("use of decimal floating point types in AltiVec types is invalid");
24486 else if (!TARGET_VSX)
24488 if (type == long_unsigned_type_node || type == long_integer_type_node)
24491 error ("use of %<long%> in AltiVec types is invalid for "
24492 "64-bit code without -mvsx");
24493 else if (rs6000_warn_altivec_long)
24494 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24497 else if (type == long_long_unsigned_type_node
24498 || type == long_long_integer_type_node)
24499 error ("use of %<long long%> in AltiVec types is invalid without "
24501 else if (type == double_type_node)
24502 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24505 switch (altivec_type)
24508 unsigned_p = TYPE_UNSIGNED (type);
24512 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24515 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24518 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24521 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24523 case SFmode: result = V4SF_type_node; break;
24524 case DFmode: result = V2DF_type_node; break;
24525 /* If the user says 'vector int bool', we may be handed the 'bool'
24526 attribute _before_ the 'vector' attribute, and so select the
24527 proper type in the 'b' case below. */
24528 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24529 case V2DImode: case V2DFmode:
24537 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24538 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24539 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24540 case QImode: case V16QImode: result = bool_V16QI_type_node;
24547 case V8HImode: result = pixel_V8HI_type_node;
24553 /* Propagate qualifiers attached to the element type
24554 onto the vector type. */
24555 if (result && result != type && TYPE_QUALS (type))
24556 result = build_qualified_type (result, TYPE_QUALS (type));
24558 *no_add_attrs = true; /* No need to hang on to the attribute. */
24561 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24566 /* AltiVec defines four built-in scalar types that serve as vector
24567 elements; we must teach the compiler how to mangle them. */
24569 static const char *
24570 rs6000_mangle_type (const_tree type)
24572 type = TYPE_MAIN_VARIANT (type);
24574 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24575 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24578 if (type == bool_char_type_node) return "U6__boolc";
24579 if (type == bool_short_type_node) return "U6__bools";
24580 if (type == pixel_type_node) return "u7__pixel";
24581 if (type == bool_int_type_node) return "U6__booli";
24582 if (type == bool_long_type_node) return "U6__booll";
24584 /* Mangle IBM extended float long double as `g' (__float128) on
24585 powerpc*-linux where long-double-64 previously was the default. */
24586 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24588 && TARGET_LONG_DOUBLE_128
24589 && !TARGET_IEEEQUAD)
24592 /* For all other types, use normal C++ mangling. */
24596 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24597 struct attribute_spec.handler. */
24600 rs6000_handle_longcall_attribute (tree *node, tree name,
24601 tree args ATTRIBUTE_UNUSED,
24602 int flags ATTRIBUTE_UNUSED,
24603 bool *no_add_attrs)
24605 if (TREE_CODE (*node) != FUNCTION_TYPE
24606 && TREE_CODE (*node) != FIELD_DECL
24607 && TREE_CODE (*node) != TYPE_DECL)
24609 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24611 *no_add_attrs = true;
24617 /* Set longcall attributes on all functions declared when
24618 rs6000_default_long_calls is true. */
24620 rs6000_set_default_type_attributes (tree type)
24622 if (rs6000_default_long_calls
24623 && (TREE_CODE (type) == FUNCTION_TYPE
24624 || TREE_CODE (type) == METHOD_TYPE))
24625 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24627 TYPE_ATTRIBUTES (type));
24630 darwin_set_default_type_attributes (type);
24634 /* Return a reference suitable for calling a function with the
24635 longcall attribute. */
24638 rs6000_longcall_ref (rtx call_ref)
24640 const char *call_name;
24643 if (GET_CODE (call_ref) != SYMBOL_REF)
24646 /* System V adds '.' to the internal name, so skip them. */
24647 call_name = XSTR (call_ref, 0);
24648 if (*call_name == '.')
24650 while (*call_name == '.')
24653 node = get_identifier (call_name);
24654 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24657 return force_reg (Pmode, call_ref);
24660 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24661 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24664 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24665 struct attribute_spec.handler. */
24667 rs6000_handle_struct_attribute (tree *node, tree name,
24668 tree args ATTRIBUTE_UNUSED,
24669 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24672 if (DECL_P (*node))
24674 if (TREE_CODE (*node) == TYPE_DECL)
24675 type = &TREE_TYPE (*node);
24680 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24681 || TREE_CODE (*type) == UNION_TYPE)))
24683 warning (OPT_Wattributes, "%qE attribute ignored", name);
24684 *no_add_attrs = true;
24687 else if ((is_attribute_p ("ms_struct", name)
24688 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24689 || ((is_attribute_p ("gcc_struct", name)
24690 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24692 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24694 *no_add_attrs = true;
24701 rs6000_ms_bitfield_layout_p (const_tree record_type)
24703 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24704 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24705 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24708 #ifdef USING_ELFOS_H
24710 /* A get_unnamed_section callback, used for switching to toc_section. */
24713 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24715 if (DEFAULT_ABI == ABI_AIX
24716 && TARGET_MINIMAL_TOC
24717 && !TARGET_RELOCATABLE)
24719 if (!toc_initialized)
24721 toc_initialized = 1;
24722 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24723 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24724 fprintf (asm_out_file, "\t.tc ");
24725 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24726 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24727 fprintf (asm_out_file, "\n");
24729 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24730 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24731 fprintf (asm_out_file, " = .+32768\n");
24734 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24736 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24737 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24740 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24741 if (!toc_initialized)
24743 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24744 fprintf (asm_out_file, " = .+32768\n");
24745 toc_initialized = 1;
24750 /* Implement TARGET_ASM_INIT_SECTIONS. */
24753 rs6000_elf_asm_init_sections (void)
24756 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24759 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24760 SDATA2_SECTION_ASM_OP);
24763 /* Implement TARGET_SELECT_RTX_SECTION. */
24766 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24767 unsigned HOST_WIDE_INT align)
24769 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24770 return toc_section;
24772 return default_elf_select_rtx_section (mode, x, align);
24775 /* For a SYMBOL_REF, set generic flags and then perform some
24776 target-specific processing.
24778 When the AIX ABI is requested on a non-AIX system, replace the
24779 function name with the real name (with a leading .) rather than the
24780 function descriptor name. This saves a lot of overriding code to
24781 read the prefixes. */
24784 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24786 default_encode_section_info (decl, rtl, first);
24789 && TREE_CODE (decl) == FUNCTION_DECL
24791 && DEFAULT_ABI == ABI_AIX)
24793 rtx sym_ref = XEXP (rtl, 0);
24794 size_t len = strlen (XSTR (sym_ref, 0));
24795 char *str = XALLOCAVEC (char, len + 2);
24797 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24798 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24803 compare_section_name (const char *section, const char *templ)
24807 len = strlen (templ);
24808 return (strncmp (section, templ, len) == 0
24809 && (section[len] == 0 || section[len] == '.'));
24813 rs6000_elf_in_small_data_p (const_tree decl)
24815 if (rs6000_sdata == SDATA_NONE)
24818 /* We want to merge strings, so we never consider them small data. */
24819 if (TREE_CODE (decl) == STRING_CST)
24822 /* Functions are never in the small data area. */
24823 if (TREE_CODE (decl) == FUNCTION_DECL)
24826 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24828 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24829 if (compare_section_name (section, ".sdata")
24830 || compare_section_name (section, ".sdata2")
24831 || compare_section_name (section, ".gnu.linkonce.s")
24832 || compare_section_name (section, ".sbss")
24833 || compare_section_name (section, ".sbss2")
24834 || compare_section_name (section, ".gnu.linkonce.sb")
24835 || strcmp (section, ".PPC.EMB.sdata0") == 0
24836 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24841 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24844 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24845 /* If it's not public, and we're not going to reference it there,
24846 there's no need to put it in the small data section. */
24847 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24854 #endif /* USING_ELFOS_H */
24856 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24859 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24861 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24864 /* Return a REG that occurs in ADDR with coefficient 1.
24865 ADDR can be effectively incremented by incrementing REG.
24867 r0 is special and we must not select it as an address
24868 register by this routine since our caller will try to
24869 increment the returned register via an "la" instruction. */
24872 find_addr_reg (rtx addr)
24874 while (GET_CODE (addr) == PLUS)
24876 if (GET_CODE (XEXP (addr, 0)) == REG
24877 && REGNO (XEXP (addr, 0)) != 0)
24878 addr = XEXP (addr, 0);
24879 else if (GET_CODE (XEXP (addr, 1)) == REG
24880 && REGNO (XEXP (addr, 1)) != 0)
24881 addr = XEXP (addr, 1);
24882 else if (CONSTANT_P (XEXP (addr, 0)))
24883 addr = XEXP (addr, 1);
24884 else if (CONSTANT_P (XEXP (addr, 1)))
24885 addr = XEXP (addr, 0);
24887 gcc_unreachable ();
24889 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24894 rs6000_fatal_bad_address (rtx op)
24896 fatal_insn ("bad address", op);
24901 typedef struct branch_island_d {
24902 tree function_name;
24907 DEF_VEC_O(branch_island);
24908 DEF_VEC_ALLOC_O(branch_island,gc);
24910 static VEC(branch_island,gc) *branch_islands;
24912 /* Remember to generate a branch island for far calls to the given
24916 add_compiler_branch_island (tree label_name, tree function_name,
24919 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24921 bi->function_name = function_name;
24922 bi->label_name = label_name;
24923 bi->line_number = line_number;
24926 /* Generate far-jump branch islands for everything recorded in
24927 branch_islands. Invoked immediately after the last instruction of
24928 the epilogue has been emitted; the branch islands must be appended
24929 to, and contiguous with, the function body. Mach-O stubs are
24930 generated in machopic_output_stub(). */
24933 macho_branch_islands (void)
24937 while (!VEC_empty (branch_island, branch_islands))
24939 branch_island *bi = VEC_last (branch_island, branch_islands);
24940 const char *label = IDENTIFIER_POINTER (bi->label_name);
24941 const char *name = IDENTIFIER_POINTER (bi->function_name);
24942 char name_buf[512];
24943 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24944 if (name[0] == '*' || name[0] == '&')
24945 strcpy (name_buf, name+1);
24949 strcpy (name_buf+1, name);
24951 strcpy (tmp_buf, "\n");
24952 strcat (tmp_buf, label);
24953 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24954 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24955 dbxout_stabd (N_SLINE, bi->line_number);
24956 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24959 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24960 strcat (tmp_buf, label);
24961 strcat (tmp_buf, "_pic\n");
24962 strcat (tmp_buf, label);
24963 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24965 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24966 strcat (tmp_buf, name_buf);
24967 strcat (tmp_buf, " - ");
24968 strcat (tmp_buf, label);
24969 strcat (tmp_buf, "_pic)\n");
24971 strcat (tmp_buf, "\tmtlr r0\n");
24973 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24974 strcat (tmp_buf, name_buf);
24975 strcat (tmp_buf, " - ");
24976 strcat (tmp_buf, label);
24977 strcat (tmp_buf, "_pic)\n");
24979 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24983 strcat (tmp_buf, ":\nlis r12,hi16(");
24984 strcat (tmp_buf, name_buf);
24985 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24986 strcat (tmp_buf, name_buf);
24987 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24989 output_asm_insn (tmp_buf, 0);
24990 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24991 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24992 dbxout_stabd (N_SLINE, bi->line_number);
24993 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24994 VEC_pop (branch_island, branch_islands);
24998 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24999 already there or not. */
25002 no_previous_def (tree function_name)
25007 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25008 if (function_name == bi->function_name)
25013 /* GET_PREV_LABEL gets the label name from the previous definition of
25017 get_prev_label (tree function_name)
25022 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25023 if (function_name == bi->function_name)
25024 return bi->label_name;
25028 /* INSN is either a function call or a millicode call. It may have an
25029 unconditional jump in its delay slot.
25031 CALL_DEST is the routine we are calling. */
25034 output_call (rtx insn, rtx *operands, int dest_operand_number,
25035 int cookie_operand_number)
25037 static char buf[256];
25038 if (darwin_emit_branch_islands
25039 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25040 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25043 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25045 if (no_previous_def (funname))
25047 rtx label_rtx = gen_label_rtx ();
25048 char *label_buf, temp_buf[256];
25049 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25050 CODE_LABEL_NUMBER (label_rtx));
25051 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25052 labelname = get_identifier (label_buf);
25053 add_compiler_branch_island (labelname, funname, insn_line (insn));
25056 labelname = get_prev_label (funname);
25058 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25059 instruction will reach 'foo', otherwise link as 'bl L42'".
25060 "L42" should be a 'branch island', that will do a far jump to
25061 'foo'. Branch islands are generated in
25062 macho_branch_islands(). */
25063 sprintf (buf, "jbsr %%z%d,%.246s",
25064 dest_operand_number, IDENTIFIER_POINTER (labelname));
25067 sprintf (buf, "bl %%z%d", dest_operand_number);
25071 /* Generate PIC and indirect symbol stubs. */
25074 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25076 unsigned int length;
25077 char *symbol_name, *lazy_ptr_name;
25078 char *local_label_0;
25079 static int label = 0;
25081 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25082 symb = (*targetm.strip_name_encoding) (symb);
25085 length = strlen (symb);
25086 symbol_name = XALLOCAVEC (char, length + 32);
25087 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25089 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25090 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25093 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25095 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25099 fprintf (file, "\t.align 5\n");
25101 fprintf (file, "%s:\n", stub);
25102 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25105 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25106 sprintf (local_label_0, "\"L%011d$spb\"", label);
25108 fprintf (file, "\tmflr r0\n");
25109 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25110 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25111 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25112 lazy_ptr_name, local_label_0);
25113 fprintf (file, "\tmtlr r0\n");
25114 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25115 (TARGET_64BIT ? "ldu" : "lwzu"),
25116 lazy_ptr_name, local_label_0);
25117 fprintf (file, "\tmtctr r12\n");
25118 fprintf (file, "\tbctr\n");
25122 fprintf (file, "\t.align 4\n");
25124 fprintf (file, "%s:\n", stub);
25125 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25127 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25128 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25129 (TARGET_64BIT ? "ldu" : "lwzu"),
25131 fprintf (file, "\tmtctr r12\n");
25132 fprintf (file, "\tbctr\n");
25135 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25136 fprintf (file, "%s:\n", lazy_ptr_name);
25137 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25138 fprintf (file, "%sdyld_stub_binding_helper\n",
25139 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25142 /* Legitimize PIC addresses. If the address is already
25143 position-independent, we return ORIG. Newly generated
25144 position-independent addresses go into a reg. This is REG if non
25145 zero, otherwise we allocate register(s) as necessary. */
25147 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25150 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25155 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25156 reg = gen_reg_rtx (Pmode);
25158 if (GET_CODE (orig) == CONST)
25162 if (GET_CODE (XEXP (orig, 0)) == PLUS
25163 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25166 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25168 /* Use a different reg for the intermediate value, as
25169 it will be marked UNCHANGING. */
25170 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25171 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25174 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25177 if (GET_CODE (offset) == CONST_INT)
25179 if (SMALL_INT (offset))
25180 return plus_constant (base, INTVAL (offset));
25181 else if (! reload_in_progress && ! reload_completed)
25182 offset = force_reg (Pmode, offset);
25185 rtx mem = force_const_mem (Pmode, orig);
25186 return machopic_legitimize_pic_address (mem, Pmode, reg);
25189 return gen_rtx_PLUS (Pmode, base, offset);
25192 /* Fall back on generic machopic code. */
25193 return machopic_legitimize_pic_address (orig, mode, reg);
25196 /* Output a .machine directive for the Darwin assembler, and call
25197 the generic start_file routine. */
25200 rs6000_darwin_file_start (void)
25202 static const struct
25208 { "ppc64", "ppc64", MASK_64BIT },
25209 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25210 { "power4", "ppc970", 0 },
25211 { "G5", "ppc970", 0 },
25212 { "7450", "ppc7450", 0 },
25213 { "7400", "ppc7400", MASK_ALTIVEC },
25214 { "G4", "ppc7400", 0 },
25215 { "750", "ppc750", 0 },
25216 { "740", "ppc750", 0 },
25217 { "G3", "ppc750", 0 },
25218 { "604e", "ppc604e", 0 },
25219 { "604", "ppc604", 0 },
25220 { "603e", "ppc603", 0 },
25221 { "603", "ppc603", 0 },
25222 { "601", "ppc601", 0 },
25223 { NULL, "ppc", 0 } };
25224 const char *cpu_id = "";
25227 rs6000_file_start ();
25228 darwin_file_start ();
25230 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25231 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25232 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25233 && rs6000_select[i].string[0] != '\0')
25234 cpu_id = rs6000_select[i].string;
25236 /* Look through the mapping array. Pick the first name that either
25237 matches the argument, has a bit set in IF_SET that is also set
25238 in the target flags, or has a NULL name. */
25241 while (mapping[i].arg != NULL
25242 && strcmp (mapping[i].arg, cpu_id) != 0
25243 && (mapping[i].if_set & target_flags) == 0)
25246 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25249 #endif /* TARGET_MACHO */
25253 rs6000_elf_reloc_rw_mask (void)
25257 else if (DEFAULT_ABI == ABI_AIX)
25263 /* Record an element in the table of global constructors. SYMBOL is
25264 a SYMBOL_REF of the function to be called; PRIORITY is a number
25265 between 0 and MAX_INIT_PRIORITY.
25267 This differs from default_named_section_asm_out_constructor in
25268 that we have special handling for -mrelocatable. */
25271 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25273 const char *section = ".ctors";
25276 if (priority != DEFAULT_INIT_PRIORITY)
25278 sprintf (buf, ".ctors.%.5u",
25279 /* Invert the numbering so the linker puts us in the proper
25280 order; constructors are run from right to left, and the
25281 linker sorts in increasing order. */
25282 MAX_INIT_PRIORITY - priority);
25286 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25287 assemble_align (POINTER_SIZE);
25289 if (TARGET_RELOCATABLE)
25291 fputs ("\t.long (", asm_out_file);
25292 output_addr_const (asm_out_file, symbol);
25293 fputs (")@fixup\n", asm_out_file);
25296 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25300 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25302 const char *section = ".dtors";
25305 if (priority != DEFAULT_INIT_PRIORITY)
25307 sprintf (buf, ".dtors.%.5u",
25308 /* Invert the numbering so the linker puts us in the proper
25309 order; constructors are run from right to left, and the
25310 linker sorts in increasing order. */
25311 MAX_INIT_PRIORITY - priority);
25315 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25316 assemble_align (POINTER_SIZE);
25318 if (TARGET_RELOCATABLE)
25320 fputs ("\t.long (", asm_out_file);
25321 output_addr_const (asm_out_file, symbol);
25322 fputs (")@fixup\n", asm_out_file);
25325 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25329 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25333 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25334 ASM_OUTPUT_LABEL (file, name);
25335 fputs (DOUBLE_INT_ASM_OP, file);
25336 rs6000_output_function_entry (file, name);
25337 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25340 fputs ("\t.size\t", file);
25341 assemble_name (file, name);
25342 fputs (",24\n\t.type\t.", file);
25343 assemble_name (file, name);
25344 fputs (",@function\n", file);
25345 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25347 fputs ("\t.globl\t.", file);
25348 assemble_name (file, name);
25353 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25354 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25355 rs6000_output_function_entry (file, name);
25356 fputs (":\n", file);
25360 if (TARGET_RELOCATABLE
25361 && !TARGET_SECURE_PLT
25362 && (get_pool_size () != 0 || crtl->profile)
25367 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25369 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25370 fprintf (file, "\t.long ");
25371 assemble_name (file, buf);
25373 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25374 assemble_name (file, buf);
25378 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25379 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25381 if (DEFAULT_ABI == ABI_AIX)
25383 const char *desc_name, *orig_name;
25385 orig_name = (*targetm.strip_name_encoding) (name);
25386 desc_name = orig_name;
25387 while (*desc_name == '.')
25390 if (TREE_PUBLIC (decl))
25391 fprintf (file, "\t.globl %s\n", desc_name);
25393 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25394 fprintf (file, "%s:\n", desc_name);
25395 fprintf (file, "\t.long %s\n", orig_name);
25396 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25397 if (DEFAULT_ABI == ABI_AIX)
25398 fputs ("\t.long 0\n", file);
25399 fprintf (file, "\t.previous\n");
25401 ASM_OUTPUT_LABEL (file, name);
25405 rs6000_elf_end_indicate_exec_stack (void)
25408 file_end_indicate_exec_stack ();
25414 rs6000_xcoff_asm_output_anchor (rtx symbol)
25418 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25419 SYMBOL_REF_BLOCK_OFFSET (symbol));
25420 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25424 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25426 fputs (GLOBAL_ASM_OP, stream);
25427 RS6000_OUTPUT_BASENAME (stream, name);
25428 putc ('\n', stream);
25431 /* A get_unnamed_decl callback, used for read-only sections. PTR
25432 points to the section string variable. */
25435 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25437 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25438 *(const char *const *) directive,
25439 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25442 /* Likewise for read-write sections. */
25445 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25447 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25448 *(const char *const *) directive,
25449 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25452 /* A get_unnamed_section callback, used for switching to toc_section. */
25455 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25457 if (TARGET_MINIMAL_TOC)
25459 /* toc_section is always selected at least once from
25460 rs6000_xcoff_file_start, so this is guaranteed to
25461 always be defined once and only once in each file. */
25462 if (!toc_initialized)
25464 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25465 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25466 toc_initialized = 1;
25468 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25469 (TARGET_32BIT ? "" : ",3"));
25472 fputs ("\t.toc\n", asm_out_file);
25475 /* Implement TARGET_ASM_INIT_SECTIONS. */
25478 rs6000_xcoff_asm_init_sections (void)
25480 read_only_data_section
25481 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25482 &xcoff_read_only_section_name);
25484 private_data_section
25485 = get_unnamed_section (SECTION_WRITE,
25486 rs6000_xcoff_output_readwrite_section_asm_op,
25487 &xcoff_private_data_section_name);
25489 read_only_private_data_section
25490 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25491 &xcoff_private_data_section_name);
25494 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25496 readonly_data_section = read_only_data_section;
25497 exception_section = data_section;
25501 rs6000_xcoff_reloc_rw_mask (void)
25507 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25508 tree decl ATTRIBUTE_UNUSED)
25511 static const char * const suffix[3] = { "PR", "RO", "RW" };
25513 if (flags & SECTION_CODE)
25515 else if (flags & SECTION_WRITE)
25520 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25521 (flags & SECTION_CODE) ? "." : "",
25522 name, suffix[smclass], flags & SECTION_ENTSIZE);
25526 rs6000_xcoff_select_section (tree decl, int reloc,
25527 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25529 if (decl_readonly_section (decl, reloc))
25531 if (TREE_PUBLIC (decl))
25532 return read_only_data_section;
25534 return read_only_private_data_section;
25538 if (TREE_PUBLIC (decl))
25539 return data_section;
25541 return private_data_section;
25546 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25550 /* Use select_section for private and uninitialized data. */
25551 if (!TREE_PUBLIC (decl)
25552 || DECL_COMMON (decl)
25553 || DECL_INITIAL (decl) == NULL_TREE
25554 || DECL_INITIAL (decl) == error_mark_node
25555 || (flag_zero_initialized_in_bss
25556 && initializer_zerop (DECL_INITIAL (decl))))
25559 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25560 name = (*targetm.strip_name_encoding) (name);
25561 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25564 /* Select section for constant in constant pool.
25566 On RS/6000, all constants are in the private read-only data area.
25567 However, if this is being placed in the TOC it must be output as a
25571 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25572 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25574 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25575 return toc_section;
25577 return read_only_private_data_section;
25580 /* Remove any trailing [DS] or the like from the symbol name. */
25582 static const char *
25583 rs6000_xcoff_strip_name_encoding (const char *name)
25588 len = strlen (name);
25589 if (name[len - 1] == ']')
25590 return ggc_alloc_string (name, len - 4);
25595 /* Section attributes. AIX is always PIC. */
25597 static unsigned int
25598 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25600 unsigned int align;
25601 unsigned int flags = default_section_type_flags (decl, name, reloc);
25603 /* Align to at least UNIT size. */
25604 if (flags & SECTION_CODE)
25605 align = MIN_UNITS_PER_WORD;
25607 /* Increase alignment of large objects if not already stricter. */
25608 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25609 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25610 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25612 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25615 /* Output at beginning of assembler file.
25617 Initialize the section names for the RS/6000 at this point.
25619 Specify filename, including full path, to assembler.
25621 We want to go into the TOC section so at least one .toc will be emitted.
25622 Also, in order to output proper .bs/.es pairs, we need at least one static
25623 [RW] section emitted.
25625 Finally, declare mcount when profiling to make the assembler happy. */
25628 rs6000_xcoff_file_start (void)
25630 rs6000_gen_section_name (&xcoff_bss_section_name,
25631 main_input_filename, ".bss_");
25632 rs6000_gen_section_name (&xcoff_private_data_section_name,
25633 main_input_filename, ".rw_");
25634 rs6000_gen_section_name (&xcoff_read_only_section_name,
25635 main_input_filename, ".ro_");
25637 fputs ("\t.file\t", asm_out_file);
25638 output_quoted_string (asm_out_file, main_input_filename);
25639 fputc ('\n', asm_out_file);
25640 if (write_symbols != NO_DEBUG)
25641 switch_to_section (private_data_section);
25642 switch_to_section (text_section);
25644 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25645 rs6000_file_start ();
25648 /* Output at end of assembler file.
25649 On the RS/6000, referencing data should automatically pull in text. */
25652 rs6000_xcoff_file_end (void)
25654 switch_to_section (text_section);
25655 fputs ("_section_.text:\n", asm_out_file);
25656 switch_to_section (data_section);
25657 fputs (TARGET_32BIT
25658 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25661 #endif /* TARGET_XCOFF */
25663 /* Compute a (partial) cost for rtx X. Return true if the complete
25664 cost has been computed, and false if subexpressions should be
25665 scanned. In either case, *TOTAL contains the cost result. */
25668 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25671 enum machine_mode mode = GET_MODE (x);
25675 /* On the RS/6000, if it is valid in the insn, it is free. */
25677 if (((outer_code == SET
25678 || outer_code == PLUS
25679 || outer_code == MINUS)
25680 && (satisfies_constraint_I (x)
25681 || satisfies_constraint_L (x)))
25682 || (outer_code == AND
25683 && (satisfies_constraint_K (x)
25685 ? satisfies_constraint_L (x)
25686 : satisfies_constraint_J (x))
25687 || mask_operand (x, mode)
25689 && mask64_operand (x, DImode))))
25690 || ((outer_code == IOR || outer_code == XOR)
25691 && (satisfies_constraint_K (x)
25693 ? satisfies_constraint_L (x)
25694 : satisfies_constraint_J (x))))
25695 || outer_code == ASHIFT
25696 || outer_code == ASHIFTRT
25697 || outer_code == LSHIFTRT
25698 || outer_code == ROTATE
25699 || outer_code == ROTATERT
25700 || outer_code == ZERO_EXTRACT
25701 || (outer_code == MULT
25702 && satisfies_constraint_I (x))
25703 || ((outer_code == DIV || outer_code == UDIV
25704 || outer_code == MOD || outer_code == UMOD)
25705 && exact_log2 (INTVAL (x)) >= 0)
25706 || (outer_code == COMPARE
25707 && (satisfies_constraint_I (x)
25708 || satisfies_constraint_K (x)))
25709 || (outer_code == EQ
25710 && (satisfies_constraint_I (x)
25711 || satisfies_constraint_K (x)
25713 ? satisfies_constraint_L (x)
25714 : satisfies_constraint_J (x))))
25715 || (outer_code == GTU
25716 && satisfies_constraint_I (x))
25717 || (outer_code == LTU
25718 && satisfies_constraint_P (x)))
25723 else if ((outer_code == PLUS
25724 && reg_or_add_cint_operand (x, VOIDmode))
25725 || (outer_code == MINUS
25726 && reg_or_sub_cint_operand (x, VOIDmode))
25727 || ((outer_code == SET
25728 || outer_code == IOR
25729 || outer_code == XOR)
25731 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25733 *total = COSTS_N_INSNS (1);
25739 if (mode == DImode && code == CONST_DOUBLE)
25741 if ((outer_code == IOR || outer_code == XOR)
25742 && CONST_DOUBLE_HIGH (x) == 0
25743 && (CONST_DOUBLE_LOW (x)
25744 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25749 else if ((outer_code == AND && and64_2_operand (x, DImode))
25750 || ((outer_code == SET
25751 || outer_code == IOR
25752 || outer_code == XOR)
25753 && CONST_DOUBLE_HIGH (x) == 0))
25755 *total = COSTS_N_INSNS (1);
25765 /* When optimizing for size, MEM should be slightly more expensive
25766 than generating address, e.g., (plus (reg) (const)).
25767 L1 cache latency is about two instructions. */
25768 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25776 if (mode == DFmode)
25778 if (GET_CODE (XEXP (x, 0)) == MULT)
25780 /* FNMA accounted in outer NEG. */
25781 if (outer_code == NEG)
25782 *total = rs6000_cost->dmul - rs6000_cost->fp;
25784 *total = rs6000_cost->dmul;
25787 *total = rs6000_cost->fp;
25789 else if (mode == SFmode)
25791 /* FNMA accounted in outer NEG. */
25792 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25795 *total = rs6000_cost->fp;
25798 *total = COSTS_N_INSNS (1);
25802 if (mode == DFmode)
25804 if (GET_CODE (XEXP (x, 0)) == MULT
25805 || GET_CODE (XEXP (x, 1)) == MULT)
25807 /* FNMA accounted in outer NEG. */
25808 if (outer_code == NEG)
25809 *total = rs6000_cost->dmul - rs6000_cost->fp;
25811 *total = rs6000_cost->dmul;
25814 *total = rs6000_cost->fp;
25816 else if (mode == SFmode)
25818 /* FNMA accounted in outer NEG. */
25819 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25822 *total = rs6000_cost->fp;
25825 *total = COSTS_N_INSNS (1);
25829 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25830 && satisfies_constraint_I (XEXP (x, 1)))
25832 if (INTVAL (XEXP (x, 1)) >= -256
25833 && INTVAL (XEXP (x, 1)) <= 255)
25834 *total = rs6000_cost->mulsi_const9;
25836 *total = rs6000_cost->mulsi_const;
25838 /* FMA accounted in outer PLUS/MINUS. */
25839 else if ((mode == DFmode || mode == SFmode)
25840 && (outer_code == PLUS || outer_code == MINUS))
25842 else if (mode == DFmode)
25843 *total = rs6000_cost->dmul;
25844 else if (mode == SFmode)
25845 *total = rs6000_cost->fp;
25846 else if (mode == DImode)
25847 *total = rs6000_cost->muldi;
25849 *total = rs6000_cost->mulsi;
25854 if (FLOAT_MODE_P (mode))
25856 *total = mode == DFmode ? rs6000_cost->ddiv
25857 : rs6000_cost->sdiv;
25864 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25865 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25867 if (code == DIV || code == MOD)
25869 *total = COSTS_N_INSNS (2);
25872 *total = COSTS_N_INSNS (1);
25876 if (GET_MODE (XEXP (x, 1)) == DImode)
25877 *total = rs6000_cost->divdi;
25879 *total = rs6000_cost->divsi;
25881 /* Add in shift and subtract for MOD. */
25882 if (code == MOD || code == UMOD)
25883 *total += COSTS_N_INSNS (2);
25888 *total = COSTS_N_INSNS (4);
25892 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25896 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25900 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25912 *total = COSTS_N_INSNS (1);
25920 /* Handle mul_highpart. */
25921 if (outer_code == TRUNCATE
25922 && GET_CODE (XEXP (x, 0)) == MULT)
25924 if (mode == DImode)
25925 *total = rs6000_cost->muldi;
25927 *total = rs6000_cost->mulsi;
25930 else if (outer_code == AND)
25933 *total = COSTS_N_INSNS (1);
25938 if (GET_CODE (XEXP (x, 0)) == MEM)
25941 *total = COSTS_N_INSNS (1);
25947 if (!FLOAT_MODE_P (mode))
25949 *total = COSTS_N_INSNS (1);
25955 case UNSIGNED_FLOAT:
25958 case FLOAT_TRUNCATE:
25959 *total = rs6000_cost->fp;
25963 if (mode == DFmode)
25966 *total = rs6000_cost->fp;
25970 switch (XINT (x, 1))
25973 *total = rs6000_cost->fp;
25985 *total = COSTS_N_INSNS (1);
25988 else if (FLOAT_MODE_P (mode)
25989 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25991 *total = rs6000_cost->fp;
25999 /* Carry bit requires mode == Pmode.
26000 NEG or PLUS already counted so only add one. */
26002 && (outer_code == NEG || outer_code == PLUS))
26004 *total = COSTS_N_INSNS (1);
26007 if (outer_code == SET)
26009 if (XEXP (x, 1) == const0_rtx)
26011 if (TARGET_ISEL && !TARGET_MFCRF)
26012 *total = COSTS_N_INSNS (8);
26014 *total = COSTS_N_INSNS (2);
26017 else if (mode == Pmode)
26019 *total = COSTS_N_INSNS (3);
26028 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26030 if (TARGET_ISEL && !TARGET_MFCRF)
26031 *total = COSTS_N_INSNS (8);
26033 *total = COSTS_N_INSNS (2);
26037 if (outer_code == COMPARE)
26051 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26054 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26057 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26060 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26061 "total = %d, speed = %s, x:\n",
26062 ret ? "complete" : "scan inner",
26063 GET_RTX_NAME (code),
26064 GET_RTX_NAME (outer_code),
26066 speed ? "true" : "false");
26073 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26076 rs6000_debug_address_cost (rtx x, bool speed)
26078 int ret = TARGET_ADDRESS_COST (x, speed);
26080 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26081 ret, speed ? "true" : "false");
26088 /* A C expression returning the cost of moving data from a register of class
26089 CLASS1 to one of CLASS2. */
26092 rs6000_register_move_cost (enum machine_mode mode,
26093 reg_class_t from, reg_class_t to)
26097 /* Moves from/to GENERAL_REGS. */
26098 if (reg_classes_intersect_p (to, GENERAL_REGS)
26099 || reg_classes_intersect_p (from, GENERAL_REGS))
26101 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26104 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26105 ret = (rs6000_memory_move_cost (mode, from, false)
26106 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26108 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26110 else if (from == CR_REGS)
26113 /* Power6 has slower LR/CTR moves so make them more expensive than
26114 memory in order to bias spills to memory .*/
26115 else if (rs6000_cpu == PROCESSOR_POWER6
26116 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26117 ret = 6 * hard_regno_nregs[0][mode];
26120 /* A move will cost one instruction per GPR moved. */
26121 ret = 2 * hard_regno_nregs[0][mode];
26124 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26125 else if (VECTOR_UNIT_VSX_P (mode)
26126 && reg_classes_intersect_p (to, VSX_REGS)
26127 && reg_classes_intersect_p (from, VSX_REGS))
26128 ret = 2 * hard_regno_nregs[32][mode];
26130 /* Moving between two similar registers is just one instruction. */
26131 else if (reg_classes_intersect_p (to, from))
26132 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26134 /* Everything else has to go through GENERAL_REGS. */
26136 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26137 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26139 if (TARGET_DEBUG_COST)
26141 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26142 ret, GET_MODE_NAME (mode), reg_class_names[from],
26143 reg_class_names[to]);
26148 /* A C expressions returning the cost of moving data of MODE from a register to
26152 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26153 bool in ATTRIBUTE_UNUSED)
26157 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26158 ret = 4 * hard_regno_nregs[0][mode];
26159 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26160 ret = 4 * hard_regno_nregs[32][mode];
26161 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26162 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26164 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26166 if (TARGET_DEBUG_COST)
26168 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26169 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26174 /* Returns a code for a target-specific builtin that implements
26175 reciprocal of the function, or NULL_TREE if not available. */
26178 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26179 bool sqrt ATTRIBUTE_UNUSED)
26181 if (optimize_insn_for_size_p ())
26187 case VSX_BUILTIN_XVSQRTDP:
26188 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26191 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26193 case VSX_BUILTIN_XVSQRTSP:
26194 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26197 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26206 case BUILT_IN_SQRT:
26207 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26210 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26212 case BUILT_IN_SQRTF:
26213 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26216 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26223 /* Load up a constant. If the mode is a vector mode, splat the value across
26224 all of the vector elements. */
26227 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26231 if (mode == SFmode || mode == DFmode)
26233 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26234 reg = force_reg (mode, d);
26236 else if (mode == V4SFmode)
26238 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26239 rtvec v = gen_rtvec (4, d, d, d, d);
26240 reg = gen_reg_rtx (mode);
26241 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26243 else if (mode == V2DFmode)
26245 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26246 rtvec v = gen_rtvec (2, d, d);
26247 reg = gen_reg_rtx (mode);
26248 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26251 gcc_unreachable ();
26256 /* Generate a FMADD instruction:
26257 dst = (m1 * m2) + a
26259 generating different RTL based on the fused multiply/add switch. */
26262 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26264 enum machine_mode mode = GET_MODE (dst);
26266 if (!TARGET_FUSED_MADD)
26268 /* For the simple ops, use the generator function, rather than assuming
26269 that the RTL is standard. */
26270 enum insn_code mcode = optab_handler (smul_optab, mode);
26271 enum insn_code acode = optab_handler (add_optab, mode);
26272 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26273 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26274 rtx mreg = gen_reg_rtx (mode);
26276 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26277 emit_insn (gen_mul (mreg, m1, m2));
26278 emit_insn (gen_add (dst, mreg, a));
26282 emit_insn (gen_rtx_SET (VOIDmode, dst,
26283 gen_rtx_PLUS (mode,
26284 gen_rtx_MULT (mode, m1, m2),
26288 /* Generate a FMSUB instruction:
26289 dst = (m1 * m2) - a
26291 generating different RTL based on the fused multiply/add switch. */
26294 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26296 enum machine_mode mode = GET_MODE (dst);
26298 if (!TARGET_FUSED_MADD
26299 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26301 /* For the simple ops, use the generator function, rather than assuming
26302 that the RTL is standard. */
26303 enum insn_code mcode = optab_handler (smul_optab, mode);
26304 enum insn_code scode = optab_handler (add_optab, mode);
26305 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26306 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26307 rtx mreg = gen_reg_rtx (mode);
26309 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26310 emit_insn (gen_mul (mreg, m1, m2));
26311 emit_insn (gen_sub (dst, mreg, a));
26315 emit_insn (gen_rtx_SET (VOIDmode, dst,
26316 gen_rtx_MINUS (mode,
26317 gen_rtx_MULT (mode, m1, m2),
26321 /* Generate a FNMSUB instruction:
26322 dst = - ((m1 * m2) - a)
26324 Which is equivalent to (except in the prescence of -0.0):
26325 dst = a - (m1 * m2)
26327 generating different RTL based on the fast-math and fused multiply/add
26331 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26333 enum machine_mode mode = GET_MODE (dst);
26335 if (!TARGET_FUSED_MADD)
26337 /* For the simple ops, use the generator function, rather than assuming
26338 that the RTL is standard. */
26339 enum insn_code mcode = optab_handler (smul_optab, mode);
26340 enum insn_code scode = optab_handler (sub_optab, mode);
26341 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26342 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26343 rtx mreg = gen_reg_rtx (mode);
26345 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26346 emit_insn (gen_mul (mreg, m1, m2));
26347 emit_insn (gen_sub (dst, a, mreg));
26352 rtx m = gen_rtx_MULT (mode, m1, m2);
26354 if (!HONOR_SIGNED_ZEROS (mode))
26355 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26358 emit_insn (gen_rtx_SET (VOIDmode, dst,
26360 gen_rtx_MINUS (mode, m, a))));
26364 /* Newton-Raphson approximation of floating point divide with just 2 passes
26365 (either single precision floating point, or newer machines with higher
26366 accuracy estimates). Support both scalar and vector divide. Assumes no
26367 trapping math and finite arguments. */
26370 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26372 enum machine_mode mode = GET_MODE (dst);
26373 rtx x0, e0, e1, y1, u0, v0;
26374 enum insn_code code = optab_handler (smul_optab, mode);
26375 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26376 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26378 gcc_assert (code != CODE_FOR_nothing);
26380 /* x0 = 1./d estimate */
26381 x0 = gen_reg_rtx (mode);
26382 emit_insn (gen_rtx_SET (VOIDmode, x0,
26383 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26386 e0 = gen_reg_rtx (mode);
26387 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26389 e1 = gen_reg_rtx (mode);
26390 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26392 y1 = gen_reg_rtx (mode);
26393 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26395 u0 = gen_reg_rtx (mode);
26396 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26398 v0 = gen_reg_rtx (mode);
26399 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26401 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26404 /* Newton-Raphson approximation of floating point divide that has a low
26405 precision estimate. Assumes no trapping math and finite arguments. */
26408 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26410 enum machine_mode mode = GET_MODE (dst);
26411 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26412 enum insn_code code = optab_handler (smul_optab, mode);
26413 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26415 gcc_assert (code != CODE_FOR_nothing);
26417 one = rs6000_load_constant_and_splat (mode, dconst1);
26419 /* x0 = 1./d estimate */
26420 x0 = gen_reg_rtx (mode);
26421 emit_insn (gen_rtx_SET (VOIDmode, x0,
26422 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26425 e0 = gen_reg_rtx (mode);
26426 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26428 y1 = gen_reg_rtx (mode);
26429 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26431 e1 = gen_reg_rtx (mode);
26432 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26434 y2 = gen_reg_rtx (mode);
26435 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26437 e2 = gen_reg_rtx (mode);
26438 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26440 y3 = gen_reg_rtx (mode);
26441 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26443 u0 = gen_reg_rtx (mode);
26444 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26446 v0 = gen_reg_rtx (mode);
26447 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26449 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26452 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26453 add a reg_note saying that this was a division. Support both scalar and
26454 vector divide. Assumes no trapping math and finite arguments. */
26457 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26459 enum machine_mode mode = GET_MODE (dst);
26461 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26462 rs6000_emit_swdiv_high_precision (dst, n, d);
26464 rs6000_emit_swdiv_low_precision (dst, n, d);
26467 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26470 /* Newton-Raphson approximation of single/double-precision floating point
26471 rsqrt. Assumes no trapping math and finite arguments. */
26474 rs6000_emit_swrsqrt (rtx dst, rtx src)
26476 enum machine_mode mode = GET_MODE (src);
26477 rtx x0 = gen_reg_rtx (mode);
26478 rtx y = gen_reg_rtx (mode);
26479 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26480 REAL_VALUE_TYPE dconst3_2;
26483 enum insn_code code = optab_handler (smul_optab, mode);
26484 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26486 gcc_assert (code != CODE_FOR_nothing);
26488 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26489 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26490 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26492 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26494 /* x0 = rsqrt estimate */
26495 emit_insn (gen_rtx_SET (VOIDmode, x0,
26496 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26499 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26500 rs6000_emit_msub (y, src, halfthree, src);
26502 for (i = 0; i < passes; i++)
26504 rtx x1 = gen_reg_rtx (mode);
26505 rtx u = gen_reg_rtx (mode);
26506 rtx v = gen_reg_rtx (mode);
26508 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26509 emit_insn (gen_mul (u, x0, x0));
26510 rs6000_emit_nmsub (v, y, u, halfthree);
26511 emit_insn (gen_mul (x1, x0, v));
26515 emit_move_insn (dst, x0);
26519 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26520 (Power7) targets. DST is the target, and SRC is the argument operand. */
26523 rs6000_emit_popcount (rtx dst, rtx src)
26525 enum machine_mode mode = GET_MODE (dst);
26528 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26529 if (TARGET_POPCNTD)
26531 if (mode == SImode)
26532 emit_insn (gen_popcntdsi2 (dst, src));
26534 emit_insn (gen_popcntddi2 (dst, src));
26538 tmp1 = gen_reg_rtx (mode);
26540 if (mode == SImode)
26542 emit_insn (gen_popcntbsi2 (tmp1, src));
26543 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26545 tmp2 = force_reg (SImode, tmp2);
26546 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26550 emit_insn (gen_popcntbdi2 (tmp1, src));
26551 tmp2 = expand_mult (DImode, tmp1,
26552 GEN_INT ((HOST_WIDE_INT)
26553 0x01010101 << 32 | 0x01010101),
26555 tmp2 = force_reg (DImode, tmp2);
26556 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26561 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26562 target, and SRC is the argument operand. */
26565 rs6000_emit_parity (rtx dst, rtx src)
26567 enum machine_mode mode = GET_MODE (dst);
26570 tmp = gen_reg_rtx (mode);
26572 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26575 if (mode == SImode)
26577 emit_insn (gen_popcntbsi2 (tmp, src));
26578 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26582 emit_insn (gen_popcntbdi2 (tmp, src));
26583 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26588 if (mode == SImode)
26590 /* Is mult+shift >= shift+xor+shift+xor? */
26591 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26593 rtx tmp1, tmp2, tmp3, tmp4;
26595 tmp1 = gen_reg_rtx (SImode);
26596 emit_insn (gen_popcntbsi2 (tmp1, src));
26598 tmp2 = gen_reg_rtx (SImode);
26599 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26600 tmp3 = gen_reg_rtx (SImode);
26601 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26603 tmp4 = gen_reg_rtx (SImode);
26604 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26605 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26608 rs6000_emit_popcount (tmp, src);
26609 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26613 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26614 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26616 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26618 tmp1 = gen_reg_rtx (DImode);
26619 emit_insn (gen_popcntbdi2 (tmp1, src));
26621 tmp2 = gen_reg_rtx (DImode);
26622 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26623 tmp3 = gen_reg_rtx (DImode);
26624 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26626 tmp4 = gen_reg_rtx (DImode);
26627 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26628 tmp5 = gen_reg_rtx (DImode);
26629 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26631 tmp6 = gen_reg_rtx (DImode);
26632 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26633 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26636 rs6000_emit_popcount (tmp, src);
26637 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26641 /* Return an RTX representing where to find the function value of a
26642 function returning MODE. */
26644 rs6000_complex_function_value (enum machine_mode mode)
26646 unsigned int regno;
26648 enum machine_mode inner = GET_MODE_INNER (mode);
26649 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26651 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26652 regno = FP_ARG_RETURN;
26655 regno = GP_ARG_RETURN;
26657 /* 32-bit is OK since it'll go in r3/r4. */
26658 if (TARGET_32BIT && inner_bytes >= 4)
26659 return gen_rtx_REG (mode, regno);
26662 if (inner_bytes >= 8)
26663 return gen_rtx_REG (mode, regno);
26665 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26667 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26668 GEN_INT (inner_bytes));
26669 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26672 /* Target hook for TARGET_FUNCTION_VALUE.
26674 On the SPE, both FPs and vectors are returned in r3.
26676 On RS/6000 an integer value is in r3 and a floating-point value is in
26677 fp1, unless -msoft-float. */
26680 rs6000_function_value (const_tree valtype,
26681 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26682 bool outgoing ATTRIBUTE_UNUSED)
26684 enum machine_mode mode;
26685 unsigned int regno;
26687 /* Special handling for structs in darwin64. */
26689 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26691 CUMULATIVE_ARGS valcum;
26695 valcum.fregno = FP_ARG_MIN_REG;
26696 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26697 /* Do a trial code generation as if this were going to be passed as
26698 an argument; if any part goes in memory, we return NULL. */
26699 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26702 /* Otherwise fall through to standard ABI rules. */
26705 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26707 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26708 return gen_rtx_PARALLEL (DImode,
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),
26718 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26720 return gen_rtx_PARALLEL (DCmode,
26722 gen_rtx_EXPR_LIST (VOIDmode,
26723 gen_rtx_REG (SImode, GP_ARG_RETURN),
26725 gen_rtx_EXPR_LIST (VOIDmode,
26726 gen_rtx_REG (SImode,
26727 GP_ARG_RETURN + 1),
26729 gen_rtx_EXPR_LIST (VOIDmode,
26730 gen_rtx_REG (SImode,
26731 GP_ARG_RETURN + 2),
26733 gen_rtx_EXPR_LIST (VOIDmode,
26734 gen_rtx_REG (SImode,
26735 GP_ARG_RETURN + 3),
26739 mode = TYPE_MODE (valtype);
26740 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26741 || POINTER_TYPE_P (valtype))
26742 mode = TARGET_32BIT ? SImode : DImode;
26744 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26745 /* _Decimal128 must use an even/odd register pair. */
26746 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26747 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26748 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26749 regno = FP_ARG_RETURN;
26750 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26751 && targetm.calls.split_complex_arg)
26752 return rs6000_complex_function_value (mode);
26753 else if (TREE_CODE (valtype) == VECTOR_TYPE
26754 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26755 && ALTIVEC_VECTOR_MODE (mode))
26756 regno = ALTIVEC_ARG_RETURN;
26757 else if (TREE_CODE (valtype) == VECTOR_TYPE
26758 && TARGET_VSX && TARGET_ALTIVEC_ABI
26759 && VSX_VECTOR_MODE (mode))
26760 regno = ALTIVEC_ARG_RETURN;
26761 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26762 && (mode == DFmode || mode == DCmode
26763 || mode == TFmode || mode == TCmode))
26764 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26766 regno = GP_ARG_RETURN;
26768 return gen_rtx_REG (mode, regno);
26771 /* Define how to find the value returned by a library function
26772 assuming the value has mode MODE. */
26774 rs6000_libcall_value (enum machine_mode mode)
26776 unsigned int regno;
26778 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26780 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26781 return gen_rtx_PARALLEL (DImode,
26783 gen_rtx_EXPR_LIST (VOIDmode,
26784 gen_rtx_REG (SImode, GP_ARG_RETURN),
26786 gen_rtx_EXPR_LIST (VOIDmode,
26787 gen_rtx_REG (SImode,
26788 GP_ARG_RETURN + 1),
26792 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26793 /* _Decimal128 must use an even/odd register pair. */
26794 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26795 else if (SCALAR_FLOAT_MODE_P (mode)
26796 && TARGET_HARD_FLOAT && TARGET_FPRS
26797 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26798 regno = FP_ARG_RETURN;
26799 else if (ALTIVEC_VECTOR_MODE (mode)
26800 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26801 regno = ALTIVEC_ARG_RETURN;
26802 else if (VSX_VECTOR_MODE (mode)
26803 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26804 regno = ALTIVEC_ARG_RETURN;
26805 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26806 return rs6000_complex_function_value (mode);
26807 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26808 && (mode == DFmode || mode == DCmode
26809 || mode == TFmode || mode == TCmode))
26810 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26812 regno = GP_ARG_RETURN;
26814 return gen_rtx_REG (mode, regno);
26818 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26819 Frame pointer elimination is automatically handled.
26821 For the RS/6000, if frame pointer elimination is being done, we would like
26822 to convert ap into fp, not sp.
26824 We need r30 if -mminimal-toc was specified, and there are constant pool
26828 rs6000_can_eliminate (const int from, const int to)
26830 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26831 ? ! frame_pointer_needed
26832 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26833 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26837 /* Define the offset between two registers, FROM to be eliminated and its
26838 replacement TO, at the start of a routine. */
26840 rs6000_initial_elimination_offset (int from, int to)
26842 rs6000_stack_t *info = rs6000_stack_info ();
26843 HOST_WIDE_INT offset;
26845 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26846 offset = info->push_p ? 0 : -info->total_size;
26847 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26849 offset = info->push_p ? 0 : -info->total_size;
26850 if (FRAME_GROWS_DOWNWARD)
26851 offset += info->fixed_size + info->vars_size + info->parm_size;
26853 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26854 offset = FRAME_GROWS_DOWNWARD
26855 ? info->fixed_size + info->vars_size + info->parm_size
26857 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26858 offset = info->total_size;
26859 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26860 offset = info->push_p ? info->total_size : 0;
26861 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26864 gcc_unreachable ();
26870 rs6000_dwarf_register_span (rtx reg)
26874 unsigned regno = REGNO (reg);
26875 enum machine_mode mode = GET_MODE (reg);
26879 && (SPE_VECTOR_MODE (GET_MODE (reg))
26880 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26881 && mode != SFmode && mode != SDmode && mode != SCmode)))
26886 regno = REGNO (reg);
26888 /* The duality of the SPE register size wreaks all kinds of havoc.
26889 This is a way of distinguishing r0 in 32-bits from r0 in
26891 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26892 gcc_assert (words <= 4);
26893 for (i = 0; i < words; i++, regno++)
26895 if (BYTES_BIG_ENDIAN)
26897 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26898 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26902 parts[2 * i] = gen_rtx_REG (SImode, regno);
26903 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26907 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26910 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26913 rs6000_init_dwarf_reg_sizes_extra (tree address)
26918 enum machine_mode mode = TYPE_MODE (char_type_node);
26919 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26920 rtx mem = gen_rtx_MEM (BLKmode, addr);
26921 rtx value = gen_int_mode (4, mode);
26923 for (i = 1201; i < 1232; i++)
26925 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26926 HOST_WIDE_INT offset
26927 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26929 emit_move_insn (adjust_address (mem, mode, offset), value);
26934 /* Map internal gcc register numbers to DWARF2 register numbers. */
26937 rs6000_dbx_register_number (unsigned int regno)
26939 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26941 if (regno == MQ_REGNO)
26943 if (regno == LR_REGNO)
26945 if (regno == CTR_REGNO)
26947 if (CR_REGNO_P (regno))
26948 return regno - CR0_REGNO + 86;
26949 if (regno == CA_REGNO)
26950 return 101; /* XER */
26951 if (ALTIVEC_REGNO_P (regno))
26952 return regno - FIRST_ALTIVEC_REGNO + 1124;
26953 if (regno == VRSAVE_REGNO)
26955 if (regno == VSCR_REGNO)
26957 if (regno == SPE_ACC_REGNO)
26959 if (regno == SPEFSCR_REGNO)
26961 /* SPE high reg number. We get these values of regno from
26962 rs6000_dwarf_register_span. */
26963 gcc_assert (regno >= 1200 && regno < 1232);
26967 /* target hook eh_return_filter_mode */
26968 static enum machine_mode
26969 rs6000_eh_return_filter_mode (void)
26971 return TARGET_32BIT ? SImode : word_mode;
26974 /* Target hook for scalar_mode_supported_p. */
26976 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26978 if (DECIMAL_FLOAT_MODE_P (mode))
26979 return default_decimal_float_supported_p ();
26981 return default_scalar_mode_supported_p (mode);
26984 /* Target hook for vector_mode_supported_p. */
26986 rs6000_vector_mode_supported_p (enum machine_mode mode)
26989 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26992 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26995 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27002 /* Target hook for invalid_arg_for_unprototyped_fn. */
27003 static const char *
27004 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27006 return (!rs6000_darwin64_abi
27008 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27009 && (funcdecl == NULL_TREE
27010 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27011 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27012 ? N_("AltiVec argument passed to unprototyped function")
27016 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27017 setup by using __stack_chk_fail_local hidden function instead of
27018 calling __stack_chk_fail directly. Otherwise it is better to call
27019 __stack_chk_fail directly. */
27022 rs6000_stack_protect_fail (void)
27024 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27025 ? default_hidden_stack_protect_fail ()
27026 : default_external_stack_protect_fail ();
27030 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27031 int num_operands ATTRIBUTE_UNUSED)
27033 if (rs6000_warn_cell_microcode)
27036 int insn_code_number = recog_memoized (insn);
27037 location_t location = locator_location (INSN_LOCATOR (insn));
27039 /* Punt on insns we cannot recognize. */
27040 if (insn_code_number < 0)
27043 temp = get_insn_template (insn_code_number, insn);
27045 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27046 warning_at (location, OPT_mwarn_cell_microcode,
27047 "emitting microcode insn %s\t[%s] #%d",
27048 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27049 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27050 warning_at (location, OPT_mwarn_cell_microcode,
27051 "emitting conditional microcode insn %s\t[%s] #%d",
27052 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27057 /* Allocate a stack temp and fixup the address so it meets the particular
27058 memory requirements (either offetable or REG+REG addressing). */
27061 rs6000_allocate_stack_temp (enum machine_mode mode,
27062 bool offsettable_p,
27065 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27066 rtx addr = XEXP (stack, 0);
27067 int strict_p = (reload_in_progress || reload_completed);
27069 if (!legitimate_indirect_address_p (addr, strict_p))
27072 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27073 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27075 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27076 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27082 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27083 to such a form to deal with memory reference instructions like STFIWX that
27084 only take reg+reg addressing. */
27087 rs6000_address_for_fpconvert (rtx x)
27089 int strict_p = (reload_in_progress || reload_completed);
27092 gcc_assert (MEM_P (x));
27093 addr = XEXP (x, 0);
27094 if (! legitimate_indirect_address_p (addr, strict_p)
27095 && ! legitimate_indexed_address_p (addr, strict_p))
27096 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27101 /* Expand 32-bit int -> floating point conversions. Return true if
27105 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27107 enum machine_mode dmode = GET_MODE (dest);
27108 rtx (*func_si) (rtx, rtx, rtx, rtx);
27109 rtx (*func_si_mem) (rtx, rtx);
27110 rtx (*func_di) (rtx, rtx);
27113 gcc_assert (GET_MODE (src) == SImode);
27115 if (dmode == SFmode)
27119 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27120 func_si = gen_floatunssisf2_lfiwzx;
27121 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27122 func_di = gen_floatunsdisf2;
27126 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27127 func_si = gen_floatsisf2_lfiwax;
27128 func_si_mem = gen_floatsisf2_lfiwax_mem;
27129 func_di = gen_floatdisf2;
27133 else if (dmode == DFmode)
27137 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27138 func_si = gen_floatunssidf2_lfiwzx;
27139 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27140 func_di = gen_floatunsdidf2;
27144 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27145 func_si = gen_floatsidf2_lfiwax;
27146 func_si_mem = gen_floatsidf2_lfiwax_mem;
27147 func_di = gen_floatdidf2;
27152 gcc_unreachable ();
27156 src = rs6000_address_for_fpconvert (src);
27157 emit_insn (func_si_mem (dest, src));
27159 else if (!TARGET_MFPGPR)
27161 reg = gen_reg_rtx (DImode);
27162 stack = rs6000_allocate_stack_temp (SImode, false, true);
27163 emit_insn (func_si (dest, src, stack, reg));
27168 src = force_reg (SImode, src);
27169 reg = convert_to_mode (DImode, src, unsigned_p);
27170 emit_insn (func_di (dest, reg));
27174 #include "gt-rs6000.h"