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 /* Implement targetm.vectorize.units_per_simd_word. */
3576 rs6000_units_per_simd_word (enum machine_mode mode ATTRIBUTE_UNUSED)
3578 return (TARGET_VSX ? UNITS_PER_VSX_WORD
3579 : (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD
3580 : (TARGET_SPE ? UNITS_PER_SPE_WORD
3581 : (TARGET_PAIRED_FLOAT ? UNITS_PER_PAIRED_WORD
3582 : UNITS_PER_WORD))));
3585 /* Handle generic options of the form -mfoo=yes/no.
3586 NAME is the option name.
3587 VALUE is the option value.
3588 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3589 whether the option value is 'yes' or 'no' respectively. */
3591 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3595 else if (!strcmp (value, "yes"))
3597 else if (!strcmp (value, "no"))
3600 error ("unknown -m%s= option specified: '%s'", name, value);
3603 /* Validate and record the size specified with the -mtls-size option. */
3606 rs6000_parse_tls_size_option (void)
3608 if (rs6000_tls_size_string == 0)
3610 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3611 rs6000_tls_size = 16;
3612 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3613 rs6000_tls_size = 32;
3614 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3615 rs6000_tls_size = 64;
3617 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3621 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3623 if (DEFAULT_ABI == ABI_DARWIN)
3624 /* The Darwin libraries never set errno, so we might as well
3625 avoid calling them when that's the only reason we would. */
3626 flag_errno_math = 0;
3628 /* Double growth factor to counter reduced min jump length. */
3629 set_param_value ("max-grow-copy-bb-insns", 16);
3631 /* Enable section anchors by default.
3632 Skip section anchors for Objective C and Objective C++
3633 until front-ends fixed. */
3634 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3635 flag_section_anchors = 2;
3638 static enum fpu_type_t
3639 rs6000_parse_fpu_option (const char *option)
3641 if (!strcmp("none", option)) return FPU_NONE;
3642 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3643 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3644 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3645 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3646 error("unknown value %s for -mfpu", option);
3651 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3652 library with vectorized intrinsics. */
3655 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3658 const char *suffix = NULL;
3659 tree fntype, new_fndecl, bdecl = NULL_TREE;
3662 enum machine_mode el_mode, in_mode;
3665 /* Libmass is suitable for unsafe math only as it does not correctly support
3666 parts of IEEE with the required precision such as denormals. Only support
3667 it if we have VSX to use the simd d2 or f4 functions.
3668 XXX: Add variable length support. */
3669 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3672 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3673 n = TYPE_VECTOR_SUBPARTS (type_out);
3674 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3675 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3676 if (el_mode != in_mode
3680 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3682 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3685 case BUILT_IN_ATAN2:
3686 case BUILT_IN_HYPOT:
3692 case BUILT_IN_ACOSH:
3694 case BUILT_IN_ASINH:
3696 case BUILT_IN_ATANH:
3704 case BUILT_IN_EXPM1:
3705 case BUILT_IN_LGAMMA:
3706 case BUILT_IN_LOG10:
3707 case BUILT_IN_LOG1P:
3715 bdecl = implicit_built_in_decls[fn];
3716 suffix = "d2"; /* pow -> powd2 */
3717 if (el_mode != DFmode
3722 case BUILT_IN_ATAN2F:
3723 case BUILT_IN_HYPOTF:
3728 case BUILT_IN_ACOSF:
3729 case BUILT_IN_ACOSHF:
3730 case BUILT_IN_ASINF:
3731 case BUILT_IN_ASINHF:
3732 case BUILT_IN_ATANF:
3733 case BUILT_IN_ATANHF:
3734 case BUILT_IN_CBRTF:
3736 case BUILT_IN_COSHF:
3738 case BUILT_IN_ERFCF:
3739 case BUILT_IN_EXP2F:
3741 case BUILT_IN_EXPM1F:
3742 case BUILT_IN_LGAMMAF:
3743 case BUILT_IN_LOG10F:
3744 case BUILT_IN_LOG1PF:
3745 case BUILT_IN_LOG2F:
3748 case BUILT_IN_SINHF:
3749 case BUILT_IN_SQRTF:
3751 case BUILT_IN_TANHF:
3752 bdecl = implicit_built_in_decls[fn];
3753 suffix = "4"; /* powf -> powf4 */
3754 if (el_mode != SFmode
3766 gcc_assert (suffix != NULL);
3767 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3768 strcpy (name, bname + sizeof ("__builtin_") - 1);
3769 strcat (name, suffix);
3772 fntype = build_function_type_list (type_out, type_in, NULL);
3773 else if (n_args == 2)
3774 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3778 /* Build a function declaration for the vectorized function. */
3779 new_fndecl = build_decl (BUILTINS_LOCATION,
3780 FUNCTION_DECL, get_identifier (name), fntype);
3781 TREE_PUBLIC (new_fndecl) = 1;
3782 DECL_EXTERNAL (new_fndecl) = 1;
3783 DECL_IS_NOVOPS (new_fndecl) = 1;
3784 TREE_READONLY (new_fndecl) = 1;
3789 /* Returns a function decl for a vectorized version of the builtin function
3790 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3791 if it is not available. */
3794 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3797 enum machine_mode in_mode, out_mode;
3800 if (TREE_CODE (type_out) != VECTOR_TYPE
3801 || TREE_CODE (type_in) != VECTOR_TYPE
3802 || !TARGET_VECTORIZE_BUILTINS)
3805 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3806 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3807 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3808 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3810 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3812 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3815 case BUILT_IN_COPYSIGN:
3816 if (VECTOR_UNIT_VSX_P (V2DFmode)
3817 && out_mode == DFmode && out_n == 2
3818 && in_mode == DFmode && in_n == 2)
3819 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3821 case BUILT_IN_COPYSIGNF:
3822 if (out_mode != SFmode || out_n != 4
3823 || in_mode != SFmode || in_n != 4)
3825 if (VECTOR_UNIT_VSX_P (V4SFmode))
3826 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3827 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3828 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
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_XVSQRTDP];
3836 case BUILT_IN_SQRTF:
3837 if (VECTOR_UNIT_VSX_P (V4SFmode)
3838 && out_mode == SFmode && out_n == 4
3839 && in_mode == SFmode && in_n == 4)
3840 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3843 if (VECTOR_UNIT_VSX_P (V2DFmode)
3844 && out_mode == DFmode && out_n == 2
3845 && in_mode == DFmode && in_n == 2)
3846 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3848 case BUILT_IN_CEILF:
3849 if (out_mode != SFmode || out_n != 4
3850 || in_mode != SFmode || in_n != 4)
3852 if (VECTOR_UNIT_VSX_P (V4SFmode))
3853 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3854 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3855 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3857 case BUILT_IN_FLOOR:
3858 if (VECTOR_UNIT_VSX_P (V2DFmode)
3859 && out_mode == DFmode && out_n == 2
3860 && in_mode == DFmode && in_n == 2)
3861 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3863 case BUILT_IN_FLOORF:
3864 if (out_mode != SFmode || out_n != 4
3865 || in_mode != SFmode || in_n != 4)
3867 if (VECTOR_UNIT_VSX_P (V4SFmode))
3868 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3869 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3870 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3872 case BUILT_IN_TRUNC:
3873 if (VECTOR_UNIT_VSX_P (V2DFmode)
3874 && out_mode == DFmode && out_n == 2
3875 && in_mode == DFmode && in_n == 2)
3876 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3878 case BUILT_IN_TRUNCF:
3879 if (out_mode != SFmode || out_n != 4
3880 || in_mode != SFmode || in_n != 4)
3882 if (VECTOR_UNIT_VSX_P (V4SFmode))
3883 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3884 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3885 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3887 case BUILT_IN_NEARBYINT:
3888 if (VECTOR_UNIT_VSX_P (V2DFmode)
3889 && flag_unsafe_math_optimizations
3890 && out_mode == DFmode && out_n == 2
3891 && in_mode == DFmode && in_n == 2)
3892 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3894 case BUILT_IN_NEARBYINTF:
3895 if (VECTOR_UNIT_VSX_P (V4SFmode)
3896 && flag_unsafe_math_optimizations
3897 && out_mode == SFmode && out_n == 4
3898 && in_mode == SFmode && in_n == 4)
3899 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3902 if (VECTOR_UNIT_VSX_P (V2DFmode)
3903 && !flag_trapping_math
3904 && out_mode == DFmode && out_n == 2
3905 && in_mode == DFmode && in_n == 2)
3906 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3908 case BUILT_IN_RINTF:
3909 if (VECTOR_UNIT_VSX_P (V4SFmode)
3910 && !flag_trapping_math
3911 && out_mode == SFmode && out_n == 4
3912 && in_mode == SFmode && in_n == 4)
3913 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3920 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3922 enum rs6000_builtins fn
3923 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3926 case RS6000_BUILTIN_RSQRTF:
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_VRSQRTFP];
3932 case RS6000_BUILTIN_RSQRT:
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_VEC_RSQRT_V2DF];
3938 case RS6000_BUILTIN_RECIPF:
3939 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3940 && out_mode == SFmode && out_n == 4
3941 && in_mode == SFmode && in_n == 4)
3942 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3944 case RS6000_BUILTIN_RECIP:
3945 if (VECTOR_UNIT_VSX_P (V2DFmode)
3946 && out_mode == DFmode && out_n == 2
3947 && in_mode == DFmode && in_n == 2)
3948 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3955 /* Generate calls to libmass if appropriate. */
3956 if (rs6000_veclib_handler)
3957 return rs6000_veclib_handler (fndecl, type_out, type_in);
3963 /* Implement TARGET_HANDLE_OPTION. */
3966 rs6000_handle_option (size_t code, const char *arg, int value)
3968 enum fpu_type_t fpu_type = FPU_NONE;
3974 g_switch_value = value;
3975 g_switch_set = true;
3979 target_flags &= ~(MASK_POWER | MASK_POWER2
3980 | MASK_MULTIPLE | MASK_STRING);
3981 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3982 | MASK_MULTIPLE | MASK_STRING);
3984 case OPT_mno_powerpc:
3985 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3986 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3987 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3988 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3991 target_flags &= ~MASK_MINIMAL_TOC;
3992 TARGET_NO_FP_IN_TOC = 0;
3993 TARGET_NO_SUM_IN_TOC = 0;
3994 target_flags_explicit |= MASK_MINIMAL_TOC;
3995 #ifdef TARGET_USES_SYSV4_OPT
3996 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3997 just the same as -mminimal-toc. */
3998 target_flags |= MASK_MINIMAL_TOC;
3999 target_flags_explicit |= MASK_MINIMAL_TOC;
4003 #ifdef TARGET_USES_SYSV4_OPT
4005 /* Make -mtoc behave like -mminimal-toc. */
4006 target_flags |= MASK_MINIMAL_TOC;
4007 target_flags_explicit |= MASK_MINIMAL_TOC;
4011 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4013 if (strcmp (arg, "small") == 0)
4014 cmodel = CMODEL_SMALL;
4015 else if (strcmp (arg, "medium") == 0)
4016 cmodel = CMODEL_MEDIUM;
4017 else if (strcmp (arg, "large") == 0)
4018 cmodel = CMODEL_LARGE;
4021 error ("invalid option for -mcmodel: '%s'", arg);
4024 rs6000_explicit_options.cmodel = true;
4027 #ifdef TARGET_USES_AIX64_OPT
4032 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4033 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4034 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4037 #ifdef TARGET_USES_AIX64_OPT
4042 target_flags &= ~MASK_POWERPC64;
4043 target_flags_explicit |= MASK_POWERPC64;
4046 case OPT_minsert_sched_nops_:
4047 rs6000_sched_insert_nops_str = arg;
4050 case OPT_mminimal_toc:
4053 TARGET_NO_FP_IN_TOC = 0;
4054 TARGET_NO_SUM_IN_TOC = 0;
4061 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4062 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4069 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4070 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4074 case OPT_mpowerpc_gpopt:
4075 case OPT_mpowerpc_gfxopt:
4078 target_flags |= MASK_POWERPC;
4079 target_flags_explicit |= MASK_POWERPC;
4083 case OPT_maix_struct_return:
4084 case OPT_msvr4_struct_return:
4085 rs6000_explicit_options.aix_struct_ret = true;
4089 rs6000_explicit_options.vrsave = true;
4090 TARGET_ALTIVEC_VRSAVE = value;
4094 rs6000_explicit_options.vrsave = true;
4095 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4099 target_flags_explicit |= MASK_ISEL;
4101 rs6000_parse_yes_no_option ("isel", arg, &isel);
4103 target_flags |= MASK_ISEL;
4105 target_flags &= ~MASK_ISEL;
4109 rs6000_explicit_options.spe = true;
4114 rs6000_explicit_options.spe = true;
4115 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4119 rs6000_debug_name = arg;
4122 #ifdef TARGET_USES_SYSV4_OPT
4124 rs6000_abi_name = arg;
4128 rs6000_sdata_name = arg;
4131 case OPT_mtls_size_:
4132 rs6000_tls_size_string = arg;
4135 case OPT_mrelocatable:
4138 target_flags |= MASK_MINIMAL_TOC;
4139 target_flags_explicit |= MASK_MINIMAL_TOC;
4140 TARGET_NO_FP_IN_TOC = 1;
4144 case OPT_mrelocatable_lib:
4147 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4148 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4149 TARGET_NO_FP_IN_TOC = 1;
4153 target_flags &= ~MASK_RELOCATABLE;
4154 target_flags_explicit |= MASK_RELOCATABLE;
4160 if (!strcmp (arg, "altivec"))
4162 rs6000_explicit_options.altivec_abi = true;
4163 rs6000_altivec_abi = 1;
4165 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4168 else if (! strcmp (arg, "no-altivec"))
4170 rs6000_explicit_options.altivec_abi = true;
4171 rs6000_altivec_abi = 0;
4173 else if (! strcmp (arg, "spe"))
4175 rs6000_explicit_options.spe_abi = true;
4177 rs6000_altivec_abi = 0;
4178 if (!TARGET_SPE_ABI)
4179 error ("not configured for ABI: '%s'", arg);
4181 else if (! strcmp (arg, "no-spe"))
4183 rs6000_explicit_options.spe_abi = true;
4187 /* These are here for testing during development only, do not
4188 document in the manual please. */
4189 else if (! strcmp (arg, "d64"))
4191 rs6000_darwin64_abi = 1;
4192 warning (0, "Using darwin64 ABI");
4194 else if (! strcmp (arg, "d32"))
4196 rs6000_darwin64_abi = 0;
4197 warning (0, "Using old darwin ABI");
4200 else if (! strcmp (arg, "ibmlongdouble"))
4202 rs6000_explicit_options.ieee = true;
4203 rs6000_ieeequad = 0;
4204 warning (0, "Using IBM extended precision long double");
4206 else if (! strcmp (arg, "ieeelongdouble"))
4208 rs6000_explicit_options.ieee = true;
4209 rs6000_ieeequad = 1;
4210 warning (0, "Using IEEE extended precision long double");
4215 error ("unknown ABI specified: '%s'", arg);
4221 rs6000_select[1].string = arg;
4225 rs6000_select[2].string = arg;
4228 case OPT_mtraceback_:
4229 rs6000_traceback_name = arg;
4232 case OPT_mfloat_gprs_:
4233 rs6000_explicit_options.float_gprs = true;
4234 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4235 rs6000_float_gprs = 1;
4236 else if (! strcmp (arg, "double"))
4237 rs6000_float_gprs = 2;
4238 else if (! strcmp (arg, "no"))
4239 rs6000_float_gprs = 0;
4242 error ("invalid option for -mfloat-gprs: '%s'", arg);
4247 case OPT_mlong_double_:
4248 rs6000_explicit_options.long_double = true;
4249 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4250 if (value != 64 && value != 128)
4252 error ("Unknown switch -mlong-double-%s", arg);
4253 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4257 rs6000_long_double_type_size = value;
4260 case OPT_msched_costly_dep_:
4261 rs6000_sched_costly_dep_str = arg;
4265 rs6000_explicit_options.alignment = true;
4266 if (! strcmp (arg, "power"))
4268 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4269 some C library functions, so warn about it. The flag may be
4270 useful for performance studies from time to time though, so
4271 don't disable it entirely. */
4272 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4273 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4274 " it is incompatible with the installed C and C++ libraries");
4275 rs6000_alignment_flags = MASK_ALIGN_POWER;
4277 else if (! strcmp (arg, "natural"))
4278 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4281 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4286 case OPT_msingle_float:
4287 if (!TARGET_SINGLE_FPU)
4288 warning (0, "-msingle-float option equivalent to -mhard-float");
4289 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4290 rs6000_double_float = 0;
4291 target_flags &= ~MASK_SOFT_FLOAT;
4292 target_flags_explicit |= MASK_SOFT_FLOAT;
4295 case OPT_mdouble_float:
4296 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4297 rs6000_single_float = 1;
4298 target_flags &= ~MASK_SOFT_FLOAT;
4299 target_flags_explicit |= MASK_SOFT_FLOAT;
4302 case OPT_msimple_fpu:
4303 if (!TARGET_SINGLE_FPU)
4304 warning (0, "-msimple-fpu option ignored");
4307 case OPT_mhard_float:
4308 /* -mhard_float implies -msingle-float and -mdouble-float. */
4309 rs6000_single_float = rs6000_double_float = 1;
4312 case OPT_msoft_float:
4313 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4314 rs6000_single_float = rs6000_double_float = 0;
4318 fpu_type = rs6000_parse_fpu_option(arg);
4319 if (fpu_type != FPU_NONE)
4320 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4322 target_flags &= ~MASK_SOFT_FLOAT;
4323 target_flags_explicit |= MASK_SOFT_FLOAT;
4324 rs6000_xilinx_fpu = 1;
4325 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4326 rs6000_single_float = 1;
4327 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4328 rs6000_single_float = rs6000_double_float = 1;
4329 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4330 rs6000_simple_fpu = 1;
4334 /* -mfpu=none is equivalent to -msoft-float */
4335 target_flags |= MASK_SOFT_FLOAT;
4336 target_flags_explicit |= MASK_SOFT_FLOAT;
4337 rs6000_single_float = rs6000_double_float = 0;
4341 rs6000_recip_name = (value) ? "default" : "none";
4345 rs6000_recip_name = arg;
4351 /* Do anything needed at the start of the asm file. */
4354 rs6000_file_start (void)
4358 const char *start = buffer;
4359 struct rs6000_cpu_select *ptr;
4360 const char *default_cpu = TARGET_CPU_DEFAULT;
4361 FILE *file = asm_out_file;
4363 default_file_start ();
4365 #ifdef TARGET_BI_ARCH
4366 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4370 if (flag_verbose_asm)
4372 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4373 rs6000_select[0].string = default_cpu;
4375 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4377 ptr = &rs6000_select[i];
4378 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4380 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4385 if (PPC405_ERRATUM77)
4387 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4391 #ifdef USING_ELFOS_H
4392 switch (rs6000_sdata)
4394 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4395 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4396 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4397 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4400 if (rs6000_sdata && g_switch_value)
4402 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4412 #ifdef HAVE_AS_GNU_ATTRIBUTE
4413 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4415 fprintf (file, "\t.gnu_attribute 4, %d\n",
4416 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4417 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4419 fprintf (file, "\t.gnu_attribute 8, %d\n",
4420 (TARGET_ALTIVEC_ABI ? 2
4421 : TARGET_SPE_ABI ? 3
4423 fprintf (file, "\t.gnu_attribute 12, %d\n",
4424 aix_struct_return ? 2 : 1);
4429 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4431 switch_to_section (toc_section);
4432 switch_to_section (text_section);
4437 /* Return nonzero if this function is known to have a null epilogue. */
4440 direct_return (void)
4442 if (reload_completed)
4444 rs6000_stack_t *info = rs6000_stack_info ();
4446 if (info->first_gp_reg_save == 32
4447 && info->first_fp_reg_save == 64
4448 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4449 && ! info->lr_save_p
4450 && ! info->cr_save_p
4451 && info->vrsave_mask == 0
4459 /* Return the number of instructions it takes to form a constant in an
4460 integer register. */
4463 num_insns_constant_wide (HOST_WIDE_INT value)
4465 /* signed constant loadable with {cal|addi} */
4466 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4469 /* constant loadable with {cau|addis} */
4470 else if ((value & 0xffff) == 0
4471 && (value >> 31 == -1 || value >> 31 == 0))
4474 #if HOST_BITS_PER_WIDE_INT == 64
4475 else if (TARGET_POWERPC64)
4477 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4478 HOST_WIDE_INT high = value >> 31;
4480 if (high == 0 || high == -1)
4486 return num_insns_constant_wide (high) + 1;
4488 return num_insns_constant_wide (low) + 1;
4490 return (num_insns_constant_wide (high)
4491 + num_insns_constant_wide (low) + 1);
4500 num_insns_constant (rtx op, enum machine_mode mode)
4502 HOST_WIDE_INT low, high;
4504 switch (GET_CODE (op))
4507 #if HOST_BITS_PER_WIDE_INT == 64
4508 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4509 && mask64_operand (op, mode))
4513 return num_insns_constant_wide (INTVAL (op));
4516 if (mode == SFmode || mode == SDmode)
4521 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4522 if (DECIMAL_FLOAT_MODE_P (mode))
4523 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4525 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4526 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4529 if (mode == VOIDmode || mode == DImode)
4531 high = CONST_DOUBLE_HIGH (op);
4532 low = CONST_DOUBLE_LOW (op);
4539 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4540 if (DECIMAL_FLOAT_MODE_P (mode))
4541 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4543 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4544 high = l[WORDS_BIG_ENDIAN == 0];
4545 low = l[WORDS_BIG_ENDIAN != 0];
4549 return (num_insns_constant_wide (low)
4550 + num_insns_constant_wide (high));
4553 if ((high == 0 && low >= 0)
4554 || (high == -1 && low < 0))
4555 return num_insns_constant_wide (low);
4557 else if (mask64_operand (op, mode))
4561 return num_insns_constant_wide (high) + 1;
4564 return (num_insns_constant_wide (high)
4565 + num_insns_constant_wide (low) + 1);
4573 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4574 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4575 corresponding element of the vector, but for V4SFmode and V2SFmode,
4576 the corresponding "float" is interpreted as an SImode integer. */
4579 const_vector_elt_as_int (rtx op, unsigned int elt)
4581 rtx tmp = CONST_VECTOR_ELT (op, elt);
4582 if (GET_MODE (op) == V4SFmode
4583 || GET_MODE (op) == V2SFmode)
4584 tmp = gen_lowpart (SImode, tmp);
4585 return INTVAL (tmp);
4588 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4589 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4590 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4591 all items are set to the same value and contain COPIES replicas of the
4592 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4593 operand and the others are set to the value of the operand's msb. */
4596 vspltis_constant (rtx op, unsigned step, unsigned copies)
4598 enum machine_mode mode = GET_MODE (op);
4599 enum machine_mode inner = GET_MODE_INNER (mode);
4602 unsigned nunits = GET_MODE_NUNITS (mode);
4603 unsigned bitsize = GET_MODE_BITSIZE (inner);
4604 unsigned mask = GET_MODE_MASK (inner);
4606 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4607 HOST_WIDE_INT splat_val = val;
4608 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4610 /* Construct the value to be splatted, if possible. If not, return 0. */
4611 for (i = 2; i <= copies; i *= 2)
4613 HOST_WIDE_INT small_val;
4615 small_val = splat_val >> bitsize;
4617 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4619 splat_val = small_val;
4622 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4623 if (EASY_VECTOR_15 (splat_val))
4626 /* Also check if we can splat, and then add the result to itself. Do so if
4627 the value is positive, of if the splat instruction is using OP's mode;
4628 for splat_val < 0, the splat and the add should use the same mode. */
4629 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4630 && (splat_val >= 0 || (step == 1 && copies == 1)))
4633 /* Also check if are loading up the most significant bit which can be done by
4634 loading up -1 and shifting the value left by -1. */
4635 else if (EASY_VECTOR_MSB (splat_val, inner))
4641 /* Check if VAL is present in every STEP-th element, and the
4642 other elements are filled with its most significant bit. */
4643 for (i = 0; i < nunits - 1; ++i)
4645 HOST_WIDE_INT desired_val;
4646 if (((i + 1) & (step - 1)) == 0)
4649 desired_val = msb_val;
4651 if (desired_val != const_vector_elt_as_int (op, i))
4659 /* Return true if OP is of the given MODE and can be synthesized
4660 with a vspltisb, vspltish or vspltisw. */
4663 easy_altivec_constant (rtx op, enum machine_mode mode)
4665 unsigned step, copies;
4667 if (mode == VOIDmode)
4668 mode = GET_MODE (op);
4669 else if (mode != GET_MODE (op))
4672 /* Start with a vspltisw. */
4673 step = GET_MODE_NUNITS (mode) / 4;
4676 if (vspltis_constant (op, step, copies))
4679 /* Then try with a vspltish. */
4685 if (vspltis_constant (op, step, copies))
4688 /* And finally a vspltisb. */
4694 if (vspltis_constant (op, step, copies))
4700 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4701 result is OP. Abort if it is not possible. */
4704 gen_easy_altivec_constant (rtx op)
4706 enum machine_mode mode = GET_MODE (op);
4707 int nunits = GET_MODE_NUNITS (mode);
4708 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4709 unsigned step = nunits / 4;
4710 unsigned copies = 1;
4712 /* Start with a vspltisw. */
4713 if (vspltis_constant (op, step, copies))
4714 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4716 /* Then try with a vspltish. */
4722 if (vspltis_constant (op, step, copies))
4723 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4725 /* And finally a vspltisb. */
4731 if (vspltis_constant (op, step, copies))
4732 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4738 output_vec_const_move (rtx *operands)
4741 enum machine_mode mode;
4746 mode = GET_MODE (dest);
4748 if (TARGET_VSX && zero_constant (vec, mode))
4749 return "xxlxor %x0,%x0,%x0";
4754 if (zero_constant (vec, mode))
4755 return "vxor %0,%0,%0";
4757 splat_vec = gen_easy_altivec_constant (vec);
4758 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4759 operands[1] = XEXP (splat_vec, 0);
4760 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4763 switch (GET_MODE (splat_vec))
4766 return "vspltisw %0,%1";
4769 return "vspltish %0,%1";
4772 return "vspltisb %0,%1";
4779 gcc_assert (TARGET_SPE);
4781 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4782 pattern of V1DI, V4HI, and V2SF.
4784 FIXME: We should probably return # and add post reload
4785 splitters for these, but this way is so easy ;-). */
4786 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4787 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4788 operands[1] = CONST_VECTOR_ELT (vec, 0);
4789 operands[2] = CONST_VECTOR_ELT (vec, 1);
4791 return "li %0,%1\n\tevmergelo %0,%0,%0";
4793 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4796 /* Initialize TARGET of vector PAIRED to VALS. */
4799 paired_expand_vector_init (rtx target, rtx vals)
4801 enum machine_mode mode = GET_MODE (target);
4802 int n_elts = GET_MODE_NUNITS (mode);
4804 rtx x, new_rtx, tmp, constant_op, op1, op2;
4807 for (i = 0; i < n_elts; ++i)
4809 x = XVECEXP (vals, 0, i);
4810 if (!CONSTANT_P (x))
4815 /* Load from constant pool. */
4816 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4822 /* The vector is initialized only with non-constants. */
4823 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4824 XVECEXP (vals, 0, 1));
4826 emit_move_insn (target, new_rtx);
4830 /* One field is non-constant and the other one is a constant. Load the
4831 constant from the constant pool and use ps_merge instruction to
4832 construct the whole vector. */
4833 op1 = XVECEXP (vals, 0, 0);
4834 op2 = XVECEXP (vals, 0, 1);
4836 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4838 tmp = gen_reg_rtx (GET_MODE (constant_op));
4839 emit_move_insn (tmp, constant_op);
4841 if (CONSTANT_P (op1))
4842 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4844 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4846 emit_move_insn (target, new_rtx);
4850 paired_expand_vector_move (rtx operands[])
4852 rtx op0 = operands[0], op1 = operands[1];
4854 emit_move_insn (op0, op1);
4857 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4858 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4859 operands for the relation operation COND. This is a recursive
4863 paired_emit_vector_compare (enum rtx_code rcode,
4864 rtx dest, rtx op0, rtx op1,
4865 rtx cc_op0, rtx cc_op1)
4867 rtx tmp = gen_reg_rtx (V2SFmode);
4870 gcc_assert (TARGET_PAIRED_FLOAT);
4871 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4877 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4881 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4882 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4886 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4889 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4892 tmp1 = gen_reg_rtx (V2SFmode);
4893 max = gen_reg_rtx (V2SFmode);
4894 min = gen_reg_rtx (V2SFmode);
4895 gen_reg_rtx (V2SFmode);
4897 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4898 emit_insn (gen_selv2sf4
4899 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4900 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4901 emit_insn (gen_selv2sf4
4902 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4903 emit_insn (gen_subv2sf3 (tmp1, min, max));
4904 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4907 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4910 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4913 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4916 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4919 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4928 /* Emit vector conditional expression.
4929 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4930 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4933 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4934 rtx cond, rtx cc_op0, rtx cc_op1)
4936 enum rtx_code rcode = GET_CODE (cond);
4938 if (!TARGET_PAIRED_FLOAT)
4941 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4946 /* Initialize vector TARGET to VALS. */
4949 rs6000_expand_vector_init (rtx target, rtx vals)
4951 enum machine_mode mode = GET_MODE (target);
4952 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4953 int n_elts = GET_MODE_NUNITS (mode);
4954 int n_var = 0, one_var = -1;
4955 bool all_same = true, all_const_zero = true;
4959 for (i = 0; i < n_elts; ++i)
4961 x = XVECEXP (vals, 0, i);
4962 if (!CONSTANT_P (x))
4963 ++n_var, one_var = i;
4964 else if (x != CONST0_RTX (inner_mode))
4965 all_const_zero = false;
4967 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4973 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4974 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4975 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4977 /* Zero register. */
4978 emit_insn (gen_rtx_SET (VOIDmode, target,
4979 gen_rtx_XOR (mode, target, target)));
4982 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4984 /* Splat immediate. */
4985 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4990 /* Load from constant pool. */
4991 emit_move_insn (target, const_vec);
4996 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4997 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5001 rtx element = XVECEXP (vals, 0, 0);
5002 if (mode == V2DFmode)
5003 emit_insn (gen_vsx_splat_v2df (target, element));
5005 emit_insn (gen_vsx_splat_v2di (target, element));
5009 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5010 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5011 if (mode == V2DFmode)
5012 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5014 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5019 /* With single precision floating point on VSX, know that internally single
5020 precision is actually represented as a double, and either make 2 V2DF
5021 vectors, and convert these vectors to single precision, or do one
5022 conversion, and splat the result to the other elements. */
5023 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5027 rtx freg = gen_reg_rtx (V4SFmode);
5028 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5030 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5031 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5035 rtx dbl_even = gen_reg_rtx (V2DFmode);
5036 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5037 rtx flt_even = gen_reg_rtx (V4SFmode);
5038 rtx flt_odd = gen_reg_rtx (V4SFmode);
5040 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5041 copy_to_reg (XVECEXP (vals, 0, 0)),
5042 copy_to_reg (XVECEXP (vals, 0, 1))));
5043 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5044 copy_to_reg (XVECEXP (vals, 0, 2)),
5045 copy_to_reg (XVECEXP (vals, 0, 3))));
5046 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5047 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5048 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5053 /* Store value to stack temp. Load vector element. Splat. However, splat
5054 of 64-bit items is not supported on Altivec. */
5055 if (all_same && GET_MODE_SIZE (mode) <= 4)
5057 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5058 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5059 XVECEXP (vals, 0, 0));
5060 x = gen_rtx_UNSPEC (VOIDmode,
5061 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5062 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5064 gen_rtx_SET (VOIDmode,
5067 x = gen_rtx_VEC_SELECT (inner_mode, target,
5068 gen_rtx_PARALLEL (VOIDmode,
5069 gen_rtvec (1, const0_rtx)));
5070 emit_insn (gen_rtx_SET (VOIDmode, target,
5071 gen_rtx_VEC_DUPLICATE (mode, x)));
5075 /* One field is non-constant. Load constant then overwrite
5079 rtx copy = copy_rtx (vals);
5081 /* Load constant part of vector, substitute neighboring value for
5083 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5084 rs6000_expand_vector_init (target, copy);
5086 /* Insert variable. */
5087 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5091 /* Construct the vector in memory one field at a time
5092 and load the whole vector. */
5093 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5094 for (i = 0; i < n_elts; i++)
5095 emit_move_insn (adjust_address_nv (mem, inner_mode,
5096 i * GET_MODE_SIZE (inner_mode)),
5097 XVECEXP (vals, 0, i));
5098 emit_move_insn (target, mem);
5101 /* Set field ELT of TARGET to VAL. */
5104 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5106 enum machine_mode mode = GET_MODE (target);
5107 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5108 rtx reg = gen_reg_rtx (mode);
5110 int width = GET_MODE_SIZE (inner_mode);
5113 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5115 rtx (*set_func) (rtx, rtx, rtx, rtx)
5116 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5117 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5121 /* Load single variable value. */
5122 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5123 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5124 x = gen_rtx_UNSPEC (VOIDmode,
5125 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5126 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5128 gen_rtx_SET (VOIDmode,
5132 /* Linear sequence. */
5133 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5134 for (i = 0; i < 16; ++i)
5135 XVECEXP (mask, 0, i) = GEN_INT (i);
5137 /* Set permute mask to insert element into target. */
5138 for (i = 0; i < width; ++i)
5139 XVECEXP (mask, 0, elt*width + i)
5140 = GEN_INT (i + 0x10);
5141 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5142 x = gen_rtx_UNSPEC (mode,
5143 gen_rtvec (3, target, reg,
5144 force_reg (V16QImode, x)),
5146 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5149 /* Extract field ELT from VEC into TARGET. */
5152 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5154 enum machine_mode mode = GET_MODE (vec);
5155 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5158 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5160 rtx (*extract_func) (rtx, rtx, rtx)
5161 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5162 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5166 /* Allocate mode-sized buffer. */
5167 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5169 /* Add offset to field within buffer matching vector element. */
5170 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5172 /* Store single field into mode-sized buffer. */
5173 x = gen_rtx_UNSPEC (VOIDmode,
5174 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5175 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5177 gen_rtx_SET (VOIDmode,
5180 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5183 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5184 implement ANDing by the mask IN. */
5186 build_mask64_2_operands (rtx in, rtx *out)
5188 #if HOST_BITS_PER_WIDE_INT >= 64
5189 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5192 gcc_assert (GET_CODE (in) == CONST_INT);
5197 /* Assume c initially something like 0x00fff000000fffff. The idea
5198 is to rotate the word so that the middle ^^^^^^ group of zeros
5199 is at the MS end and can be cleared with an rldicl mask. We then
5200 rotate back and clear off the MS ^^ group of zeros with a
5202 c = ~c; /* c == 0xff000ffffff00000 */
5203 lsb = c & -c; /* lsb == 0x0000000000100000 */
5204 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5205 c = ~c; /* c == 0x00fff000000fffff */
5206 c &= -lsb; /* c == 0x00fff00000000000 */
5207 lsb = c & -c; /* lsb == 0x0000100000000000 */
5208 c = ~c; /* c == 0xff000fffffffffff */
5209 c &= -lsb; /* c == 0xff00000000000000 */
5211 while ((lsb >>= 1) != 0)
5212 shift++; /* shift == 44 on exit from loop */
5213 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5214 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5215 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5219 /* Assume c initially something like 0xff000f0000000000. The idea
5220 is to rotate the word so that the ^^^ middle group of zeros
5221 is at the LS end and can be cleared with an rldicr mask. We then
5222 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5224 lsb = c & -c; /* lsb == 0x0000010000000000 */
5225 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5226 c = ~c; /* c == 0x00fff0ffffffffff */
5227 c &= -lsb; /* c == 0x00fff00000000000 */
5228 lsb = c & -c; /* lsb == 0x0000100000000000 */
5229 c = ~c; /* c == 0xff000fffffffffff */
5230 c &= -lsb; /* c == 0xff00000000000000 */
5232 while ((lsb >>= 1) != 0)
5233 shift++; /* shift == 44 on exit from loop */
5234 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5235 m1 >>= shift; /* m1 == 0x0000000000000fff */
5236 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5239 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5240 masks will be all 1's. We are guaranteed more than one transition. */
5241 out[0] = GEN_INT (64 - shift);
5242 out[1] = GEN_INT (m1);
5243 out[2] = GEN_INT (shift);
5244 out[3] = GEN_INT (m2);
5252 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5255 invalid_e500_subreg (rtx op, enum machine_mode mode)
5257 if (TARGET_E500_DOUBLE)
5259 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5260 subreg:TI and reg:TF. Decimal float modes are like integer
5261 modes (only low part of each register used) for this
5263 if (GET_CODE (op) == SUBREG
5264 && (mode == SImode || mode == DImode || mode == TImode
5265 || mode == DDmode || mode == TDmode)
5266 && REG_P (SUBREG_REG (op))
5267 && (GET_MODE (SUBREG_REG (op)) == DFmode
5268 || GET_MODE (SUBREG_REG (op)) == TFmode))
5271 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5273 if (GET_CODE (op) == SUBREG
5274 && (mode == DFmode || mode == TFmode)
5275 && REG_P (SUBREG_REG (op))
5276 && (GET_MODE (SUBREG_REG (op)) == DImode
5277 || GET_MODE (SUBREG_REG (op)) == TImode
5278 || GET_MODE (SUBREG_REG (op)) == DDmode
5279 || GET_MODE (SUBREG_REG (op)) == TDmode))
5284 && GET_CODE (op) == SUBREG
5286 && REG_P (SUBREG_REG (op))
5287 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5293 /* AIX increases natural record alignment to doubleword if the first
5294 field is an FP double while the FP fields remain word aligned. */
5297 rs6000_special_round_type_align (tree type, unsigned int computed,
5298 unsigned int specified)
5300 unsigned int align = MAX (computed, specified);
5301 tree field = TYPE_FIELDS (type);
5303 /* Skip all non field decls */
5304 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5305 field = DECL_CHAIN (field);
5307 if (field != NULL && field != type)
5309 type = TREE_TYPE (field);
5310 while (TREE_CODE (type) == ARRAY_TYPE)
5311 type = TREE_TYPE (type);
5313 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5314 align = MAX (align, 64);
5320 /* Darwin increases record alignment to the natural alignment of
5324 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5325 unsigned int specified)
5327 unsigned int align = MAX (computed, specified);
5329 if (TYPE_PACKED (type))
5332 /* Find the first field, looking down into aggregates. */
5334 tree field = TYPE_FIELDS (type);
5335 /* Skip all non field decls */
5336 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5337 field = DECL_CHAIN (field);
5340 /* A packed field does not contribute any extra alignment. */
5341 if (DECL_PACKED (field))
5343 type = TREE_TYPE (field);
5344 while (TREE_CODE (type) == ARRAY_TYPE)
5345 type = TREE_TYPE (type);
5346 } while (AGGREGATE_TYPE_P (type));
5348 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5349 align = MAX (align, TYPE_ALIGN (type));
5354 /* Return 1 for an operand in small memory on V.4/eabi. */
5357 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5358 enum machine_mode mode ATTRIBUTE_UNUSED)
5363 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5366 if (DEFAULT_ABI != ABI_V4)
5369 /* Vector and float memory instructions have a limited offset on the
5370 SPE, so using a vector or float variable directly as an operand is
5373 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5376 if (GET_CODE (op) == SYMBOL_REF)
5379 else if (GET_CODE (op) != CONST
5380 || GET_CODE (XEXP (op, 0)) != PLUS
5381 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5382 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5387 rtx sum = XEXP (op, 0);
5388 HOST_WIDE_INT summand;
5390 /* We have to be careful here, because it is the referenced address
5391 that must be 32k from _SDA_BASE_, not just the symbol. */
5392 summand = INTVAL (XEXP (sum, 1));
5393 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5396 sym_ref = XEXP (sum, 0);
5399 return SYMBOL_REF_SMALL_P (sym_ref);
5405 /* Return true if either operand is a general purpose register. */
5408 gpr_or_gpr_p (rtx op0, rtx op1)
5410 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5411 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5415 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5418 reg_offset_addressing_ok_p (enum machine_mode mode)
5428 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5429 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5437 /* Paired vector modes. Only reg+reg addressing is valid. */
5438 if (TARGET_PAIRED_FLOAT)
5450 virtual_stack_registers_memory_p (rtx op)
5454 if (GET_CODE (op) == REG)
5455 regnum = REGNO (op);
5457 else if (GET_CODE (op) == PLUS
5458 && GET_CODE (XEXP (op, 0)) == REG
5459 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5460 regnum = REGNO (XEXP (op, 0));
5465 return (regnum >= FIRST_VIRTUAL_REGISTER
5466 && regnum <= LAST_VIRTUAL_REGISTER);
5470 constant_pool_expr_p (rtx op)
5474 split_const (op, &base, &offset);
5475 return (GET_CODE (base) == SYMBOL_REF
5476 && CONSTANT_POOL_ADDRESS_P (base)
5477 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5480 static rtx tocrel_base, tocrel_offset;
5483 toc_relative_expr_p (rtx op)
5485 if (GET_CODE (op) != CONST)
5488 split_const (op, &tocrel_base, &tocrel_offset);
5489 return (GET_CODE (tocrel_base) == UNSPEC
5490 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5494 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5497 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5498 && GET_CODE (XEXP (x, 0)) == REG
5499 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5500 || ((TARGET_MINIMAL_TOC
5501 || TARGET_CMODEL != CMODEL_SMALL)
5502 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5503 && toc_relative_expr_p (XEXP (x, 1)));
5507 legitimate_small_data_p (enum machine_mode mode, rtx x)
5509 return (DEFAULT_ABI == ABI_V4
5510 && !flag_pic && !TARGET_TOC
5511 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5512 && small_data_operand (x, mode));
5515 /* SPE offset addressing is limited to 5-bits worth of double words. */
5516 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5519 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5521 unsigned HOST_WIDE_INT offset, extra;
5523 if (GET_CODE (x) != PLUS)
5525 if (GET_CODE (XEXP (x, 0)) != REG)
5527 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5529 if (!reg_offset_addressing_ok_p (mode))
5530 return virtual_stack_registers_memory_p (x);
5531 if (legitimate_constant_pool_address_p (x, strict))
5533 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5536 offset = INTVAL (XEXP (x, 1));
5544 /* SPE vector modes. */
5545 return SPE_CONST_OFFSET_OK (offset);
5548 if (TARGET_E500_DOUBLE)
5549 return SPE_CONST_OFFSET_OK (offset);
5551 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5553 if (VECTOR_MEM_VSX_P (DFmode))
5558 /* On e500v2, we may have:
5560 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5562 Which gets addressed with evldd instructions. */
5563 if (TARGET_E500_DOUBLE)
5564 return SPE_CONST_OFFSET_OK (offset);
5566 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5568 else if (offset & 3)
5573 if (TARGET_E500_DOUBLE)
5574 return (SPE_CONST_OFFSET_OK (offset)
5575 && SPE_CONST_OFFSET_OK (offset + 8));
5579 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5581 else if (offset & 3)
5592 return (offset < 0x10000) && (offset + extra < 0x10000);
5596 legitimate_indexed_address_p (rtx x, int strict)
5600 if (GET_CODE (x) != PLUS)
5606 /* Recognize the rtl generated by reload which we know will later be
5607 replaced with proper base and index regs. */
5609 && reload_in_progress
5610 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5614 return (REG_P (op0) && REG_P (op1)
5615 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5616 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5617 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5618 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5622 avoiding_indexed_address_p (enum machine_mode mode)
5624 /* Avoid indexed addressing for modes that have non-indexed
5625 load/store instruction forms. */
5626 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5630 legitimate_indirect_address_p (rtx x, int strict)
5632 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5636 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5638 if (!TARGET_MACHO || !flag_pic
5639 || mode != SImode || GET_CODE (x) != MEM)
5643 if (GET_CODE (x) != LO_SUM)
5645 if (GET_CODE (XEXP (x, 0)) != REG)
5647 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5651 return CONSTANT_P (x);
5655 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5657 if (GET_CODE (x) != LO_SUM)
5659 if (GET_CODE (XEXP (x, 0)) != REG)
5661 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5663 /* Restrict addressing for DI because of our SUBREG hackery. */
5664 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5665 || mode == DDmode || mode == TDmode
5670 if (TARGET_ELF || TARGET_MACHO)
5672 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5676 if (GET_MODE_NUNITS (mode) != 1)
5678 if (GET_MODE_BITSIZE (mode) > 64
5679 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5680 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5681 && (mode == DFmode || mode == DDmode))))
5684 return CONSTANT_P (x);
5691 /* Try machine-dependent ways of modifying an illegitimate address
5692 to be legitimate. If we find one, return the new, valid address.
5693 This is used from only one place: `memory_address' in explow.c.
5695 OLDX is the address as it was before break_out_memory_refs was
5696 called. In some cases it is useful to look at this to decide what
5699 It is always safe for this function to do nothing. It exists to
5700 recognize opportunities to optimize the output.
5702 On RS/6000, first check for the sum of a register with a constant
5703 integer that is out of range. If so, generate code to add the
5704 constant with the low-order 16 bits masked to the register and force
5705 this result into another register (this can be done with `cau').
5706 Then generate an address of REG+(CONST&0xffff), allowing for the
5707 possibility of bit 16 being a one.
5709 Then check for the sum of a register and something not constant, try to
5710 load the other things into a register and return the sum. */
5713 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5714 enum machine_mode mode)
5716 unsigned int extra = 0;
5718 if (!reg_offset_addressing_ok_p (mode))
5720 if (virtual_stack_registers_memory_p (x))
5723 /* In theory we should not be seeing addresses of the form reg+0,
5724 but just in case it is generated, optimize it away. */
5725 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5726 return force_reg (Pmode, XEXP (x, 0));
5728 /* Make sure both operands are registers. */
5729 else if (GET_CODE (x) == PLUS)
5730 return gen_rtx_PLUS (Pmode,
5731 force_reg (Pmode, XEXP (x, 0)),
5732 force_reg (Pmode, XEXP (x, 1)));
5734 return force_reg (Pmode, x);
5736 if (GET_CODE (x) == SYMBOL_REF)
5738 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5740 return rs6000_legitimize_tls_address (x, model);
5750 if (!TARGET_POWERPC64)
5758 extra = TARGET_POWERPC64 ? 8 : 12;
5764 if (GET_CODE (x) == PLUS
5765 && GET_CODE (XEXP (x, 0)) == REG
5766 && GET_CODE (XEXP (x, 1)) == CONST_INT
5767 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5769 && !((TARGET_POWERPC64
5770 && (mode == DImode || mode == TImode)
5771 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5772 || SPE_VECTOR_MODE (mode)
5773 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5774 || mode == DImode || mode == DDmode
5775 || mode == TDmode))))
5777 HOST_WIDE_INT high_int, low_int;
5779 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5780 if (low_int >= 0x8000 - extra)
5782 high_int = INTVAL (XEXP (x, 1)) - low_int;
5783 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5784 GEN_INT (high_int)), 0);
5785 return plus_constant (sum, low_int);
5787 else if (GET_CODE (x) == PLUS
5788 && GET_CODE (XEXP (x, 0)) == REG
5789 && GET_CODE (XEXP (x, 1)) != CONST_INT
5790 && GET_MODE_NUNITS (mode) == 1
5791 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5793 || ((mode != DImode && mode != DFmode && mode != DDmode)
5794 || (TARGET_E500_DOUBLE && mode != DDmode)))
5795 && (TARGET_POWERPC64 || mode != DImode)
5796 && !avoiding_indexed_address_p (mode)
5801 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5802 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5804 else if (SPE_VECTOR_MODE (mode)
5805 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5806 || mode == DDmode || mode == TDmode
5807 || mode == DImode)))
5811 /* We accept [reg + reg] and [reg + OFFSET]. */
5813 if (GET_CODE (x) == PLUS)
5815 rtx op1 = XEXP (x, 0);
5816 rtx op2 = XEXP (x, 1);
5819 op1 = force_reg (Pmode, op1);
5821 if (GET_CODE (op2) != REG
5822 && (GET_CODE (op2) != CONST_INT
5823 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5824 || (GET_MODE_SIZE (mode) > 8
5825 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5826 op2 = force_reg (Pmode, op2);
5828 /* We can't always do [reg + reg] for these, because [reg +
5829 reg + offset] is not a legitimate addressing mode. */
5830 y = gen_rtx_PLUS (Pmode, op1, op2);
5832 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5833 return force_reg (Pmode, y);
5838 return force_reg (Pmode, x);
5844 && GET_CODE (x) != CONST_INT
5845 && GET_CODE (x) != CONST_DOUBLE
5847 && GET_MODE_NUNITS (mode) == 1
5848 && (GET_MODE_BITSIZE (mode) <= 32
5849 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5850 && (mode == DFmode || mode == DDmode))))
5852 rtx reg = gen_reg_rtx (Pmode);
5853 emit_insn (gen_elf_high (reg, x));
5854 return gen_rtx_LO_SUM (Pmode, reg, x);
5856 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5859 && ! MACHO_DYNAMIC_NO_PIC_P
5861 && GET_CODE (x) != CONST_INT
5862 && GET_CODE (x) != CONST_DOUBLE
5864 && GET_MODE_NUNITS (mode) == 1
5865 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5866 || (mode != DFmode && mode != DDmode))
5870 rtx reg = gen_reg_rtx (Pmode);
5871 emit_insn (gen_macho_high (reg, x));
5872 return gen_rtx_LO_SUM (Pmode, reg, x);
5875 && GET_CODE (x) == SYMBOL_REF
5876 && constant_pool_expr_p (x)
5877 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5879 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5880 return create_TOC_reference (x, reg);
5886 /* Debug version of rs6000_legitimize_address. */
5888 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5894 ret = rs6000_legitimize_address (x, oldx, mode);
5895 insns = get_insns ();
5901 "\nrs6000_legitimize_address: mode %s, old code %s, "
5902 "new code %s, modified\n",
5903 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5904 GET_RTX_NAME (GET_CODE (ret)));
5906 fprintf (stderr, "Original address:\n");
5909 fprintf (stderr, "oldx:\n");
5912 fprintf (stderr, "New address:\n");
5917 fprintf (stderr, "Insns added:\n");
5918 debug_rtx_list (insns, 20);
5924 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5925 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5936 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5937 We need to emit DTP-relative relocations. */
5940 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5945 fputs ("\t.long\t", file);
5948 fputs (DOUBLE_INT_ASM_OP, file);
5953 output_addr_const (file, x);
5954 fputs ("@dtprel+0x8000", file);
5957 /* In the name of slightly smaller debug output, and to cater to
5958 general assembler lossage, recognize various UNSPEC sequences
5959 and turn them back into a direct symbol reference. */
5962 rs6000_delegitimize_address (rtx orig_x)
5966 orig_x = delegitimize_mem_from_attrs (orig_x);
5971 if ((GET_CODE (x) == PLUS
5972 || GET_CODE (x) == LO_SUM)
5973 && GET_CODE (XEXP (x, 0)) == REG
5974 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5975 || TARGET_MINIMAL_TOC
5976 || TARGET_CMODEL != CMODEL_SMALL)
5977 && GET_CODE (XEXP (x, 1)) == CONST)
5979 y = XEXP (XEXP (x, 1), 0);
5980 if (GET_CODE (y) == UNSPEC
5981 && XINT (y, 1) == UNSPEC_TOCREL)
5983 y = XVECEXP (y, 0, 0);
5984 if (!MEM_P (orig_x))
5987 return replace_equiv_address_nv (orig_x, y);
5992 && GET_CODE (orig_x) == LO_SUM
5993 && GET_CODE (XEXP (x, 1)) == CONST)
5995 y = XEXP (XEXP (x, 1), 0);
5996 if (GET_CODE (y) == UNSPEC
5997 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5998 return XVECEXP (y, 0, 0);
6004 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6006 static GTY(()) rtx rs6000_tls_symbol;
6008 rs6000_tls_get_addr (void)
6010 if (!rs6000_tls_symbol)
6011 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6013 return rs6000_tls_symbol;
6016 /* Construct the SYMBOL_REF for TLS GOT references. */
6018 static GTY(()) rtx rs6000_got_symbol;
6020 rs6000_got_sym (void)
6022 if (!rs6000_got_symbol)
6024 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6025 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6026 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6029 return rs6000_got_symbol;
6032 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6033 this (thread-local) address. */
6036 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6040 dest = gen_reg_rtx (Pmode);
6041 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6047 tlsreg = gen_rtx_REG (Pmode, 13);
6048 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6052 tlsreg = gen_rtx_REG (Pmode, 2);
6053 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6057 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6061 tmp = gen_reg_rtx (Pmode);
6064 tlsreg = gen_rtx_REG (Pmode, 13);
6065 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6069 tlsreg = gen_rtx_REG (Pmode, 2);
6070 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6074 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6076 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6081 rtx r3, got, tga, tmp1, tmp2, call_insn;
6083 /* We currently use relocations like @got@tlsgd for tls, which
6084 means the linker will handle allocation of tls entries, placing
6085 them in the .got section. So use a pointer to the .got section,
6086 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6087 or to secondary GOT sections used by 32-bit -fPIC. */
6089 got = gen_rtx_REG (Pmode, 2);
6093 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6096 rtx gsym = rs6000_got_sym ();
6097 got = gen_reg_rtx (Pmode);
6099 rs6000_emit_move (got, gsym, Pmode);
6104 tmp1 = gen_reg_rtx (Pmode);
6105 tmp2 = gen_reg_rtx (Pmode);
6106 mem = gen_const_mem (Pmode, tmp1);
6107 lab = gen_label_rtx ();
6108 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6109 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6110 emit_move_insn (tmp2, mem);
6111 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6112 set_unique_reg_note (last, REG_EQUAL, gsym);
6117 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6119 r3 = gen_rtx_REG (Pmode, 3);
6120 tga = rs6000_tls_get_addr ();
6121 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6123 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6124 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6125 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6126 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6127 else if (DEFAULT_ABI == ABI_V4)
6128 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6131 call_insn = last_call_insn ();
6132 PATTERN (call_insn) = insn;
6133 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6134 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6135 pic_offset_table_rtx);
6137 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6139 r3 = gen_rtx_REG (Pmode, 3);
6140 tga = rs6000_tls_get_addr ();
6141 tmp1 = gen_reg_rtx (Pmode);
6142 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6144 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6145 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6146 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6147 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6148 else if (DEFAULT_ABI == ABI_V4)
6149 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6152 call_insn = last_call_insn ();
6153 PATTERN (call_insn) = insn;
6154 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6155 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6156 pic_offset_table_rtx);
6158 if (rs6000_tls_size == 16)
6161 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6163 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6165 else if (rs6000_tls_size == 32)
6167 tmp2 = gen_reg_rtx (Pmode);
6169 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6171 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6174 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6176 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6180 tmp2 = gen_reg_rtx (Pmode);
6182 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6184 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6186 insn = gen_rtx_SET (Pmode, dest,
6187 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6193 /* IE, or 64-bit offset LE. */
6194 tmp2 = gen_reg_rtx (Pmode);
6196 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6198 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6201 insn = gen_tls_tls_64 (dest, tmp2, addr);
6203 insn = gen_tls_tls_32 (dest, tmp2, addr);
6211 /* Return 1 if X contains a thread-local symbol. */
6214 rs6000_tls_referenced_p (rtx x)
6216 if (! TARGET_HAVE_TLS)
6219 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6222 /* Return 1 if *X is a thread-local symbol. This is the same as
6223 rs6000_tls_symbol_ref except for the type of the unused argument. */
6226 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6228 return RS6000_SYMBOL_REF_TLS_P (*x);
6231 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6232 replace the input X, or the original X if no replacement is called for.
6233 The output parameter *WIN is 1 if the calling macro should goto WIN,
6236 For RS/6000, we wish to handle large displacements off a base
6237 register by splitting the addend across an addiu/addis and the mem insn.
6238 This cuts number of extra insns needed from 3 to 1.
6240 On Darwin, we use this to generate code for floating point constants.
6241 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6242 The Darwin code is inside #if TARGET_MACHO because only then are the
6243 machopic_* functions defined. */
6245 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6246 int opnum, int type,
6247 int ind_levels ATTRIBUTE_UNUSED, int *win)
6249 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6251 /* We must recognize output that we have already generated ourselves. */
6252 if (GET_CODE (x) == PLUS
6253 && GET_CODE (XEXP (x, 0)) == PLUS
6254 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6255 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6256 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6258 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6259 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6260 opnum, (enum reload_type)type);
6265 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6266 if (GET_CODE (x) == LO_SUM
6267 && GET_CODE (XEXP (x, 0)) == HIGH)
6269 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6270 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6271 opnum, (enum reload_type)type);
6277 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6278 && GET_CODE (x) == LO_SUM
6279 && GET_CODE (XEXP (x, 0)) == PLUS
6280 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6281 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6282 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6283 && machopic_operand_p (XEXP (x, 1)))
6285 /* Result of previous invocation of this function on Darwin
6286 floating point constant. */
6287 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6288 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6289 opnum, (enum reload_type)type);
6295 if (TARGET_CMODEL != CMODEL_SMALL
6296 && GET_CODE (x) == LO_SUM
6297 && GET_CODE (XEXP (x, 0)) == PLUS
6298 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6299 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6300 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6301 && GET_CODE (XEXP (x, 1)) == CONST
6302 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6303 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6304 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6306 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6307 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6308 opnum, (enum reload_type) type);
6313 /* Force ld/std non-word aligned offset into base register by wrapping
6315 if (GET_CODE (x) == PLUS
6316 && GET_CODE (XEXP (x, 0)) == REG
6317 && REGNO (XEXP (x, 0)) < 32
6318 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6319 && GET_CODE (XEXP (x, 1)) == CONST_INT
6321 && (INTVAL (XEXP (x, 1)) & 3) != 0
6322 && VECTOR_MEM_NONE_P (mode)
6323 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6324 && TARGET_POWERPC64)
6326 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6327 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6328 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6329 opnum, (enum reload_type) type);
6334 if (GET_CODE (x) == PLUS
6335 && GET_CODE (XEXP (x, 0)) == REG
6336 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6337 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6338 && GET_CODE (XEXP (x, 1)) == CONST_INT
6340 && !SPE_VECTOR_MODE (mode)
6341 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6342 || mode == DDmode || mode == TDmode
6344 && VECTOR_MEM_NONE_P (mode))
6346 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6347 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6349 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6351 /* Check for 32-bit overflow. */
6352 if (high + low != val)
6358 /* Reload the high part into a base reg; leave the low part
6359 in the mem directly. */
6361 x = gen_rtx_PLUS (GET_MODE (x),
6362 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6366 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6367 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6368 opnum, (enum reload_type)type);
6373 if (GET_CODE (x) == SYMBOL_REF
6375 && VECTOR_MEM_NONE_P (mode)
6376 && !SPE_VECTOR_MODE (mode)
6378 && DEFAULT_ABI == ABI_DARWIN
6379 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6381 && DEFAULT_ABI == ABI_V4
6384 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6385 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6389 && (mode != DImode || TARGET_POWERPC64)
6390 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6391 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6396 rtx offset = machopic_gen_offset (x);
6397 x = gen_rtx_LO_SUM (GET_MODE (x),
6398 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6399 gen_rtx_HIGH (Pmode, offset)), offset);
6403 x = gen_rtx_LO_SUM (GET_MODE (x),
6404 gen_rtx_HIGH (Pmode, x), x);
6406 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6407 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6408 opnum, (enum reload_type)type);
6413 /* Reload an offset address wrapped by an AND that represents the
6414 masking of the lower bits. Strip the outer AND and let reload
6415 convert the offset address into an indirect address. For VSX,
6416 force reload to create the address with an AND in a separate
6417 register, because we can't guarantee an altivec register will
6419 if (VECTOR_MEM_ALTIVEC_P (mode)
6420 && GET_CODE (x) == AND
6421 && GET_CODE (XEXP (x, 0)) == PLUS
6422 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6423 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6424 && GET_CODE (XEXP (x, 1)) == CONST_INT
6425 && INTVAL (XEXP (x, 1)) == -16)
6434 && GET_CODE (x) == SYMBOL_REF
6435 && constant_pool_expr_p (x)
6436 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6438 x = create_TOC_reference (x, NULL_RTX);
6439 if (TARGET_CMODEL != CMODEL_SMALL)
6440 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6441 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6442 opnum, (enum reload_type) type);
6450 /* Debug version of rs6000_legitimize_reload_address. */
6452 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6453 int opnum, int type,
6454 int ind_levels, int *win)
6456 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6459 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6460 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6461 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6465 fprintf (stderr, "Same address returned\n");
6467 fprintf (stderr, "NULL returned\n");
6470 fprintf (stderr, "New address:\n");
6477 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6478 that is a valid memory address for an instruction.
6479 The MODE argument is the machine mode for the MEM expression
6480 that wants to use this address.
6482 On the RS/6000, there are four valid address: a SYMBOL_REF that
6483 refers to a constant pool entry of an address (or the sum of it
6484 plus a constant), a short (16-bit signed) constant plus a register,
6485 the sum of two registers, or a register indirect, possibly with an
6486 auto-increment. For DFmode, DDmode and DImode with a constant plus
6487 register, we must ensure that both words are addressable or PowerPC64
6488 with offset word aligned.
6490 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6491 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6492 because adjacent memory cells are accessed by adding word-sized offsets
6493 during assembly output. */
6495 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6497 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6499 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6500 if (VECTOR_MEM_ALTIVEC_P (mode)
6501 && GET_CODE (x) == AND
6502 && GET_CODE (XEXP (x, 1)) == CONST_INT
6503 && INTVAL (XEXP (x, 1)) == -16)
6506 if (RS6000_SYMBOL_REF_TLS_P (x))
6508 if (legitimate_indirect_address_p (x, reg_ok_strict))
6510 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6511 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6512 && !SPE_VECTOR_MODE (mode)
6515 /* Restrict addressing for DI because of our SUBREG hackery. */
6516 && !(TARGET_E500_DOUBLE
6517 && (mode == DFmode || mode == DDmode || mode == DImode))
6519 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6521 if (virtual_stack_registers_memory_p (x))
6523 if (reg_offset_p && legitimate_small_data_p (mode, x))
6525 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6527 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6530 && GET_CODE (x) == PLUS
6531 && GET_CODE (XEXP (x, 0)) == REG
6532 && (XEXP (x, 0) == virtual_stack_vars_rtx
6533 || XEXP (x, 0) == arg_pointer_rtx)
6534 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6536 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6541 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6543 || (mode != DFmode && mode != DDmode)
6544 || (TARGET_E500_DOUBLE && mode != DDmode))
6545 && (TARGET_POWERPC64 || mode != DImode)
6546 && !avoiding_indexed_address_p (mode)
6547 && legitimate_indexed_address_p (x, reg_ok_strict))
6549 if (GET_CODE (x) == PRE_MODIFY
6553 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6555 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6556 && (TARGET_POWERPC64 || mode != DImode)
6557 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6558 && !SPE_VECTOR_MODE (mode)
6559 /* Restrict addressing for DI because of our SUBREG hackery. */
6560 && !(TARGET_E500_DOUBLE
6561 && (mode == DFmode || mode == DDmode || mode == DImode))
6563 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6564 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6565 || (!avoiding_indexed_address_p (mode)
6566 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6567 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6569 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6574 /* Debug version of rs6000_legitimate_address_p. */
6576 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6579 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6581 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6582 "strict = %d, code = %s\n",
6583 ret ? "true" : "false",
6584 GET_MODE_NAME (mode),
6586 GET_RTX_NAME (GET_CODE (x)));
6592 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6595 rs6000_mode_dependent_address_p (const_rtx addr)
6597 return rs6000_mode_dependent_address_ptr (addr);
6600 /* Go to LABEL if ADDR (a legitimate address expression)
6601 has an effect that depends on the machine mode it is used for.
6603 On the RS/6000 this is true of all integral offsets (since AltiVec
6604 and VSX modes don't allow them) or is a pre-increment or decrement.
6606 ??? Except that due to conceptual problems in offsettable_address_p
6607 we can't really report the problems of integral offsets. So leave
6608 this assuming that the adjustable offset must be valid for the
6609 sub-words of a TFmode operand, which is what we had before. */
6612 rs6000_mode_dependent_address (const_rtx addr)
6614 switch (GET_CODE (addr))
6617 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6618 is considered a legitimate address before reload, so there
6619 are no offset restrictions in that case. Note that this
6620 condition is safe in strict mode because any address involving
6621 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6622 been rejected as illegitimate. */
6623 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6624 && XEXP (addr, 0) != arg_pointer_rtx
6625 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6627 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6628 return val + 12 + 0x8000 >= 0x10000;
6633 /* Anything in the constant pool is sufficiently aligned that
6634 all bytes have the same high part address. */
6635 return !legitimate_constant_pool_address_p (addr, false);
6637 /* Auto-increment cases are now treated generically in recog.c. */
6639 return TARGET_UPDATE;
6641 /* AND is only allowed in Altivec loads. */
6652 /* Debug version of rs6000_mode_dependent_address. */
6654 rs6000_debug_mode_dependent_address (const_rtx addr)
6656 bool ret = rs6000_mode_dependent_address (addr);
6658 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6659 ret ? "true" : "false");
6665 /* Implement FIND_BASE_TERM. */
6668 rs6000_find_base_term (rtx op)
6672 split_const (op, &base, &offset);
6673 if (GET_CODE (base) == UNSPEC)
6674 switch (XINT (base, 1))
6677 case UNSPEC_MACHOPIC_OFFSET:
6678 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6679 for aliasing purposes. */
6680 return XVECEXP (base, 0, 0);
6686 /* More elaborate version of recog's offsettable_memref_p predicate
6687 that works around the ??? note of rs6000_mode_dependent_address.
6688 In particular it accepts
6690 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6692 in 32-bit mode, that the recog predicate rejects. */
6695 rs6000_offsettable_memref_p (rtx op)
6700 /* First mimic offsettable_memref_p. */
6701 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6704 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6705 the latter predicate knows nothing about the mode of the memory
6706 reference and, therefore, assumes that it is the largest supported
6707 mode (TFmode). As a consequence, legitimate offsettable memory
6708 references are rejected. rs6000_legitimate_offset_address_p contains
6709 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6710 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6713 /* Change register usage conditional on target flags. */
6715 rs6000_conditional_register_usage (void)
6719 /* Set MQ register fixed (already call_used) if not POWER
6720 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6725 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6727 fixed_regs[13] = call_used_regs[13]
6728 = call_really_used_regs[13] = 1;
6730 /* Conditionally disable FPRs. */
6731 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6732 for (i = 32; i < 64; i++)
6733 fixed_regs[i] = call_used_regs[i]
6734 = call_really_used_regs[i] = 1;
6736 /* The TOC register is not killed across calls in a way that is
6737 visible to the compiler. */
6738 if (DEFAULT_ABI == ABI_AIX)
6739 call_really_used_regs[2] = 0;
6741 if (DEFAULT_ABI == ABI_V4
6742 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6744 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6746 if (DEFAULT_ABI == ABI_V4
6747 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6749 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6750 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6751 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6753 if (DEFAULT_ABI == ABI_DARWIN
6754 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6755 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6756 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6757 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6759 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6760 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6761 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6765 global_regs[SPEFSCR_REGNO] = 1;
6766 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6767 registers in prologues and epilogues. We no longer use r14
6768 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6769 pool for link-compatibility with older versions of GCC. Once
6770 "old" code has died out, we can return r14 to the allocation
6773 = call_used_regs[14]
6774 = call_really_used_regs[14] = 1;
6777 if (!TARGET_ALTIVEC && !TARGET_VSX)
6779 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6780 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6781 call_really_used_regs[VRSAVE_REGNO] = 1;
6784 if (TARGET_ALTIVEC || TARGET_VSX)
6785 global_regs[VSCR_REGNO] = 1;
6787 if (TARGET_ALTIVEC_ABI)
6789 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6790 call_used_regs[i] = call_really_used_regs[i] = 1;
6792 /* AIX reserves VR20:31 in non-extended ABI mode. */
6794 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6795 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6799 /* Try to output insns to set TARGET equal to the constant C if it can
6800 be done in less than N insns. Do all computations in MODE.
6801 Returns the place where the output has been placed if it can be
6802 done and the insns have been emitted. If it would take more than N
6803 insns, zero is returned and no insns and emitted. */
6806 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6807 rtx source, int n ATTRIBUTE_UNUSED)
6809 rtx result, insn, set;
6810 HOST_WIDE_INT c0, c1;
6817 dest = gen_reg_rtx (mode);
6818 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6822 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6824 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6825 GEN_INT (INTVAL (source)
6826 & (~ (HOST_WIDE_INT) 0xffff))));
6827 emit_insn (gen_rtx_SET (VOIDmode, dest,
6828 gen_rtx_IOR (SImode, copy_rtx (result),
6829 GEN_INT (INTVAL (source) & 0xffff))));
6834 switch (GET_CODE (source))
6837 c0 = INTVAL (source);
6842 #if HOST_BITS_PER_WIDE_INT >= 64
6843 c0 = CONST_DOUBLE_LOW (source);
6846 c0 = CONST_DOUBLE_LOW (source);
6847 c1 = CONST_DOUBLE_HIGH (source);
6855 result = rs6000_emit_set_long_const (dest, c0, c1);
6862 insn = get_last_insn ();
6863 set = single_set (insn);
6864 if (! CONSTANT_P (SET_SRC (set)))
6865 set_unique_reg_note (insn, REG_EQUAL, source);
6870 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6871 fall back to a straight forward decomposition. We do this to avoid
6872 exponential run times encountered when looking for longer sequences
6873 with rs6000_emit_set_const. */
6875 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6877 if (!TARGET_POWERPC64)
6879 rtx operand1, operand2;
6881 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6883 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6885 emit_move_insn (operand1, GEN_INT (c1));
6886 emit_move_insn (operand2, GEN_INT (c2));
6890 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6893 ud2 = (c1 & 0xffff0000) >> 16;
6894 #if HOST_BITS_PER_WIDE_INT >= 64
6898 ud4 = (c2 & 0xffff0000) >> 16;
6900 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6901 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6904 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6906 emit_move_insn (dest, GEN_INT (ud1));
6909 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6910 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6913 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6916 emit_move_insn (dest, GEN_INT (ud2 << 16));
6918 emit_move_insn (copy_rtx (dest),
6919 gen_rtx_IOR (DImode, copy_rtx (dest),
6922 else if (ud3 == 0 && ud4 == 0)
6924 gcc_assert (ud2 & 0x8000);
6925 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6928 emit_move_insn (copy_rtx (dest),
6929 gen_rtx_IOR (DImode, copy_rtx (dest),
6931 emit_move_insn (copy_rtx (dest),
6932 gen_rtx_ZERO_EXTEND (DImode,
6933 gen_lowpart (SImode,
6936 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6937 || (ud4 == 0 && ! (ud3 & 0x8000)))
6940 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6943 emit_move_insn (dest, GEN_INT (ud3 << 16));
6946 emit_move_insn (copy_rtx (dest),
6947 gen_rtx_IOR (DImode, copy_rtx (dest),
6949 emit_move_insn (copy_rtx (dest),
6950 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6953 emit_move_insn (copy_rtx (dest),
6954 gen_rtx_IOR (DImode, copy_rtx (dest),
6960 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6963 emit_move_insn (dest, GEN_INT (ud4 << 16));
6966 emit_move_insn (copy_rtx (dest),
6967 gen_rtx_IOR (DImode, copy_rtx (dest),
6970 emit_move_insn (copy_rtx (dest),
6971 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6974 emit_move_insn (copy_rtx (dest),
6975 gen_rtx_IOR (DImode, copy_rtx (dest),
6976 GEN_INT (ud2 << 16)));
6978 emit_move_insn (copy_rtx (dest),
6979 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6985 /* Helper for the following. Get rid of [r+r] memory refs
6986 in cases where it won't work (TImode, TFmode, TDmode). */
6989 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6991 if (reload_in_progress)
6994 if (GET_CODE (operands[0]) == MEM
6995 && GET_CODE (XEXP (operands[0], 0)) != REG
6996 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6998 = replace_equiv_address (operands[0],
6999 copy_addr_to_reg (XEXP (operands[0], 0)));
7001 if (GET_CODE (operands[1]) == MEM
7002 && GET_CODE (XEXP (operands[1], 0)) != REG
7003 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7005 = replace_equiv_address (operands[1],
7006 copy_addr_to_reg (XEXP (operands[1], 0)));
7009 /* Return true if OP, a SYMBOL_REF, should be considered local when
7010 generating -mcmodel=medium code. */
7013 toc_relative_ok (rtx op)
7017 if (!SYMBOL_REF_LOCAL_P (op))
7020 /* This is a bit hard to explain. When building shared libraries,
7021 you are supposed to pass -fpic or -fPIC to the compiler.
7022 -fpic/-fPIC not only generate position independent code but also
7023 generate code that supports ELF shared library global function
7024 or variable overriding. ppc64 is always PIC and at least some of
7025 the ELF shared libaray semantics of global variables happen to be
7026 supported without -fpic/-fPIC. So people may not be careful
7027 about using -fPIC for shared libs.
7028 With -mcmodel=medium this situation changes. A shared library
7029 built without -fpic/-fPIC requires text relocs for global var
7030 access (and would fail to load since glibc ld.so doesn't support
7031 the required dynamic relocs). So avoid this potential
7032 problem by using -mcmodel=large access for global vars, unless
7033 we know we are compiling for an executable. */
7037 decl = SYMBOL_REF_DECL (op);
7038 if (!decl || !DECL_P (decl))
7040 if (!TREE_PUBLIC (decl))
7042 if (DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)
7045 /* If we get here we must have a global var. See binds_local_p. */
7046 return flag_whole_program;
7049 /* Return true if memory accesses to DECL are known to never straddle
7053 offsettable_ok_by_alignment (tree decl)
7055 unsigned HOST_WIDE_INT dsize, dalign;
7057 /* Presume any compiler generated symbol_ref is suitably aligned. */
7061 if (TREE_CODE (decl) != VAR_DECL
7062 && TREE_CODE (decl) != PARM_DECL
7063 && TREE_CODE (decl) != RESULT_DECL
7064 && TREE_CODE (decl) != FIELD_DECL)
7067 if (!DECL_SIZE_UNIT (decl))
7070 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7073 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7079 dalign = DECL_ALIGN_UNIT (decl);
7080 return dalign >= dsize;
7083 /* Emit a move from SOURCE to DEST in mode MODE. */
7085 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7089 operands[1] = source;
7091 if (TARGET_DEBUG_ADDR)
7094 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7095 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7096 GET_MODE_NAME (mode),
7099 can_create_pseudo_p ());
7101 fprintf (stderr, "source:\n");
7105 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7106 if (GET_CODE (operands[1]) == CONST_DOUBLE
7107 && ! FLOAT_MODE_P (mode)
7108 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7110 /* FIXME. This should never happen. */
7111 /* Since it seems that it does, do the safe thing and convert
7113 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7115 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7116 || FLOAT_MODE_P (mode)
7117 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7118 || CONST_DOUBLE_LOW (operands[1]) < 0)
7119 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7120 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7122 /* Check if GCC is setting up a block move that will end up using FP
7123 registers as temporaries. We must make sure this is acceptable. */
7124 if (GET_CODE (operands[0]) == MEM
7125 && GET_CODE (operands[1]) == MEM
7127 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7128 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7129 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7130 ? 32 : MEM_ALIGN (operands[0])))
7131 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7133 : MEM_ALIGN (operands[1]))))
7134 && ! MEM_VOLATILE_P (operands [0])
7135 && ! MEM_VOLATILE_P (operands [1]))
7137 emit_move_insn (adjust_address (operands[0], SImode, 0),
7138 adjust_address (operands[1], SImode, 0));
7139 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7140 adjust_address (copy_rtx (operands[1]), SImode, 4));
7144 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7145 && !gpc_reg_operand (operands[1], mode))
7146 operands[1] = force_reg (mode, operands[1]);
7148 if (mode == SFmode && ! TARGET_POWERPC
7149 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7150 && GET_CODE (operands[0]) == MEM)
7154 if (reload_in_progress || reload_completed)
7155 regnum = true_regnum (operands[1]);
7156 else if (GET_CODE (operands[1]) == REG)
7157 regnum = REGNO (operands[1]);
7161 /* If operands[1] is a register, on POWER it may have
7162 double-precision data in it, so truncate it to single
7164 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7167 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7168 : gen_reg_rtx (mode));
7169 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7170 operands[1] = newreg;
7174 /* Recognize the case where operand[1] is a reference to thread-local
7175 data and load its address to a register. */
7176 if (rs6000_tls_referenced_p (operands[1]))
7178 enum tls_model model;
7179 rtx tmp = operands[1];
7182 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7184 addend = XEXP (XEXP (tmp, 0), 1);
7185 tmp = XEXP (XEXP (tmp, 0), 0);
7188 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7189 model = SYMBOL_REF_TLS_MODEL (tmp);
7190 gcc_assert (model != 0);
7192 tmp = rs6000_legitimize_tls_address (tmp, model);
7195 tmp = gen_rtx_PLUS (mode, tmp, addend);
7196 tmp = force_operand (tmp, operands[0]);
7201 /* Handle the case where reload calls us with an invalid address. */
7202 if (reload_in_progress && mode == Pmode
7203 && (! general_operand (operands[1], mode)
7204 || ! nonimmediate_operand (operands[0], mode)))
7207 /* 128-bit constant floating-point values on Darwin should really be
7208 loaded as two parts. */
7209 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7210 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7212 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7213 know how to get a DFmode SUBREG of a TFmode. */
7214 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7215 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7216 simplify_gen_subreg (imode, operands[1], mode, 0),
7218 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7219 GET_MODE_SIZE (imode)),
7220 simplify_gen_subreg (imode, operands[1], mode,
7221 GET_MODE_SIZE (imode)),
7226 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7227 cfun->machine->sdmode_stack_slot =
7228 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7230 if (reload_in_progress
7232 && MEM_P (operands[0])
7233 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7234 && REG_P (operands[1]))
7236 if (FP_REGNO_P (REGNO (operands[1])))
7238 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7239 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7240 emit_insn (gen_movsd_store (mem, operands[1]));
7242 else if (INT_REGNO_P (REGNO (operands[1])))
7244 rtx mem = adjust_address_nv (operands[0], mode, 4);
7245 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7246 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7252 if (reload_in_progress
7254 && REG_P (operands[0])
7255 && MEM_P (operands[1])
7256 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7258 if (FP_REGNO_P (REGNO (operands[0])))
7260 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7261 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7262 emit_insn (gen_movsd_load (operands[0], mem));
7264 else if (INT_REGNO_P (REGNO (operands[0])))
7266 rtx mem = adjust_address_nv (operands[1], mode, 4);
7267 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7268 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7275 /* FIXME: In the long term, this switch statement should go away
7276 and be replaced by a sequence of tests based on things like
7282 if (CONSTANT_P (operands[1])
7283 && GET_CODE (operands[1]) != CONST_INT)
7284 operands[1] = force_const_mem (mode, operands[1]);
7289 rs6000_eliminate_indexed_memrefs (operands);
7296 if (CONSTANT_P (operands[1])
7297 && ! easy_fp_constant (operands[1], mode))
7298 operands[1] = force_const_mem (mode, operands[1]);
7311 if (CONSTANT_P (operands[1])
7312 && !easy_vector_constant (operands[1], mode))
7313 operands[1] = force_const_mem (mode, operands[1]);
7318 /* Use default pattern for address of ELF small data */
7321 && DEFAULT_ABI == ABI_V4
7322 && (GET_CODE (operands[1]) == SYMBOL_REF
7323 || GET_CODE (operands[1]) == CONST)
7324 && small_data_operand (operands[1], mode))
7326 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7330 if (DEFAULT_ABI == ABI_V4
7331 && mode == Pmode && mode == SImode
7332 && flag_pic == 1 && got_operand (operands[1], mode))
7334 emit_insn (gen_movsi_got (operands[0], operands[1]));
7338 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7342 && CONSTANT_P (operands[1])
7343 && GET_CODE (operands[1]) != HIGH
7344 && GET_CODE (operands[1]) != CONST_INT)
7346 rtx target = (!can_create_pseudo_p ()
7348 : gen_reg_rtx (mode));
7350 /* If this is a function address on -mcall-aixdesc,
7351 convert it to the address of the descriptor. */
7352 if (DEFAULT_ABI == ABI_AIX
7353 && GET_CODE (operands[1]) == SYMBOL_REF
7354 && XSTR (operands[1], 0)[0] == '.')
7356 const char *name = XSTR (operands[1], 0);
7358 while (*name == '.')
7360 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7361 CONSTANT_POOL_ADDRESS_P (new_ref)
7362 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7363 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7364 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7365 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7366 operands[1] = new_ref;
7369 if (DEFAULT_ABI == ABI_DARWIN)
7372 if (MACHO_DYNAMIC_NO_PIC_P)
7374 /* Take care of any required data indirection. */
7375 operands[1] = rs6000_machopic_legitimize_pic_address (
7376 operands[1], mode, operands[0]);
7377 if (operands[0] != operands[1])
7378 emit_insn (gen_rtx_SET (VOIDmode,
7379 operands[0], operands[1]));
7383 emit_insn (gen_macho_high (target, operands[1]));
7384 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7388 emit_insn (gen_elf_high (target, operands[1]));
7389 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7393 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7394 and we have put it in the TOC, we just need to make a TOC-relative
7397 && GET_CODE (operands[1]) == SYMBOL_REF
7398 && constant_pool_expr_p (operands[1])
7399 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7400 get_pool_mode (operands[1])))
7401 || (TARGET_CMODEL == CMODEL_MEDIUM
7402 && GET_CODE (operands[1]) == SYMBOL_REF
7403 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7404 && toc_relative_ok (operands[1])
7405 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7408 if (TARGET_CMODEL != CMODEL_SMALL)
7410 if (can_create_pseudo_p ())
7411 reg = gen_reg_rtx (Pmode);
7415 operands[1] = create_TOC_reference (operands[1], reg);
7417 else if (mode == Pmode
7418 && CONSTANT_P (operands[1])
7419 && ((GET_CODE (operands[1]) != CONST_INT
7420 && ! easy_fp_constant (operands[1], mode))
7421 || (GET_CODE (operands[1]) == CONST_INT
7422 && (num_insns_constant (operands[1], mode)
7423 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7424 || (GET_CODE (operands[0]) == REG
7425 && FP_REGNO_P (REGNO (operands[0]))))
7426 && GET_CODE (operands[1]) != HIGH
7427 && ! legitimate_constant_pool_address_p (operands[1], false)
7428 && ! toc_relative_expr_p (operands[1])
7429 && (TARGET_CMODEL == CMODEL_SMALL
7430 || can_create_pseudo_p ()
7431 || (REG_P (operands[0])
7432 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7436 /* Darwin uses a special PIC legitimizer. */
7437 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7440 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7442 if (operands[0] != operands[1])
7443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7448 /* If we are to limit the number of things we put in the TOC and
7449 this is a symbol plus a constant we can add in one insn,
7450 just put the symbol in the TOC and add the constant. Don't do
7451 this if reload is in progress. */
7452 if (GET_CODE (operands[1]) == CONST
7453 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7454 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7455 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7456 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7457 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7458 && ! side_effects_p (operands[0]))
7461 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7462 rtx other = XEXP (XEXP (operands[1], 0), 1);
7464 sym = force_reg (mode, sym);
7465 emit_insn (gen_add3_insn (operands[0], sym, other));
7469 operands[1] = force_const_mem (mode, operands[1]);
7472 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7473 && constant_pool_expr_p (XEXP (operands[1], 0))
7474 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7475 get_pool_constant (XEXP (operands[1], 0)),
7476 get_pool_mode (XEXP (operands[1], 0))))
7480 if (TARGET_CMODEL != CMODEL_SMALL)
7482 if (can_create_pseudo_p ())
7483 reg = gen_reg_rtx (Pmode);
7487 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7488 operands[1] = gen_const_mem (mode, tocref);
7489 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7495 rs6000_eliminate_indexed_memrefs (operands);
7499 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7501 gen_rtx_SET (VOIDmode,
7502 operands[0], operands[1]),
7503 gen_rtx_CLOBBER (VOIDmode,
7504 gen_rtx_SCRATCH (SImode)))));
7510 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7513 /* Above, we may have called force_const_mem which may have returned
7514 an invalid address. If we can, fix this up; otherwise, reload will
7515 have to deal with it. */
7516 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7517 operands[1] = validize_mem (operands[1]);
7520 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7523 /* Nonzero if we can use a floating-point register to pass this arg. */
7524 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7525 (SCALAR_FLOAT_MODE_P (MODE) \
7526 && (CUM)->fregno <= FP_ARG_MAX_REG \
7527 && TARGET_HARD_FLOAT && TARGET_FPRS)
7529 /* Nonzero if we can use an AltiVec register to pass this arg. */
7530 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7531 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7532 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7533 && TARGET_ALTIVEC_ABI \
7536 /* Return a nonzero value to say to return the function value in
7537 memory, just as large structures are always returned. TYPE will be
7538 the data type of the value, and FNTYPE will be the type of the
7539 function doing the returning, or @code{NULL} for libcalls.
7541 The AIX ABI for the RS/6000 specifies that all structures are
7542 returned in memory. The Darwin ABI does the same.
7544 For the Darwin 64 Bit ABI, a function result can be returned in
7545 registers or in memory, depending on the size of the return data
7546 type. If it is returned in registers, the value occupies the same
7547 registers as it would if it were the first and only function
7548 argument. Otherwise, the function places its result in memory at
7549 the location pointed to by GPR3.
7551 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7552 but a draft put them in memory, and GCC used to implement the draft
7553 instead of the final standard. Therefore, aix_struct_return
7554 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7555 compatibility can change DRAFT_V4_STRUCT_RET to override the
7556 default, and -m switches get the final word. See
7557 rs6000_override_options for more details.
7559 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7560 long double support is enabled. These values are returned in memory.
7562 int_size_in_bytes returns -1 for variable size objects, which go in
7563 memory always. The cast to unsigned makes -1 > 8. */
7566 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7568 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7570 && rs6000_darwin64_abi
7571 && TREE_CODE (type) == RECORD_TYPE
7572 && int_size_in_bytes (type) > 0)
7574 CUMULATIVE_ARGS valcum;
7578 valcum.fregno = FP_ARG_MIN_REG;
7579 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7580 /* Do a trial code generation as if this were going to be passed
7581 as an argument; if any part goes in memory, we return NULL. */
7582 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7585 /* Otherwise fall through to more conventional ABI rules. */
7588 if (AGGREGATE_TYPE_P (type)
7589 && (aix_struct_return
7590 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7593 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7594 modes only exist for GCC vector types if -maltivec. */
7595 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7596 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7599 /* Return synthetic vectors in memory. */
7600 if (TREE_CODE (type) == VECTOR_TYPE
7601 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7603 static bool warned_for_return_big_vectors = false;
7604 if (!warned_for_return_big_vectors)
7606 warning (0, "GCC vector returned by reference: "
7607 "non-standard ABI extension with no compatibility guarantee");
7608 warned_for_return_big_vectors = true;
7613 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7619 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7620 for a call to a function whose data type is FNTYPE.
7621 For a library call, FNTYPE is 0.
7623 For incoming args we set the number of arguments in the prototype large
7624 so we never return a PARALLEL. */
7627 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7628 rtx libname ATTRIBUTE_UNUSED, int incoming,
7629 int libcall, int n_named_args)
7631 static CUMULATIVE_ARGS zero_cumulative;
7633 *cum = zero_cumulative;
7635 cum->fregno = FP_ARG_MIN_REG;
7636 cum->vregno = ALTIVEC_ARG_MIN_REG;
7637 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7638 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7639 ? CALL_LIBCALL : CALL_NORMAL);
7640 cum->sysv_gregno = GP_ARG_MIN_REG;
7641 cum->stdarg = stdarg_p (fntype);
7643 cum->nargs_prototype = 0;
7644 if (incoming || cum->prototype)
7645 cum->nargs_prototype = n_named_args;
7647 /* Check for a longcall attribute. */
7648 if ((!fntype && rs6000_default_long_calls)
7650 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7651 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7652 cum->call_cookie |= CALL_LONG;
7654 if (TARGET_DEBUG_ARG)
7656 fprintf (stderr, "\ninit_cumulative_args:");
7659 tree ret_type = TREE_TYPE (fntype);
7660 fprintf (stderr, " ret code = %s,",
7661 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7664 if (cum->call_cookie & CALL_LONG)
7665 fprintf (stderr, " longcall,");
7667 fprintf (stderr, " proto = %d, nargs = %d\n",
7668 cum->prototype, cum->nargs_prototype);
7673 && TARGET_ALTIVEC_ABI
7674 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7676 error ("cannot return value in vector register because"
7677 " altivec instructions are disabled, use -maltivec"
7682 /* Return true if TYPE must be passed on the stack and not in registers. */
7685 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7687 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7688 return must_pass_in_stack_var_size (mode, type);
7690 return must_pass_in_stack_var_size_or_pad (mode, type);
7693 /* If defined, a C expression which determines whether, and in which
7694 direction, to pad out an argument with extra space. The value
7695 should be of type `enum direction': either `upward' to pad above
7696 the argument, `downward' to pad below, or `none' to inhibit
7699 For the AIX ABI structs are always stored left shifted in their
7703 function_arg_padding (enum machine_mode mode, const_tree type)
7705 #ifndef AGGREGATE_PADDING_FIXED
7706 #define AGGREGATE_PADDING_FIXED 0
7708 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7709 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7712 if (!AGGREGATE_PADDING_FIXED)
7714 /* GCC used to pass structures of the same size as integer types as
7715 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7716 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7717 passed padded downward, except that -mstrict-align further
7718 muddied the water in that multi-component structures of 2 and 4
7719 bytes in size were passed padded upward.
7721 The following arranges for best compatibility with previous
7722 versions of gcc, but removes the -mstrict-align dependency. */
7723 if (BYTES_BIG_ENDIAN)
7725 HOST_WIDE_INT size = 0;
7727 if (mode == BLKmode)
7729 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7730 size = int_size_in_bytes (type);
7733 size = GET_MODE_SIZE (mode);
7735 if (size == 1 || size == 2 || size == 4)
7741 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7743 if (type != 0 && AGGREGATE_TYPE_P (type))
7747 /* Fall back to the default. */
7748 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7751 /* If defined, a C expression that gives the alignment boundary, in bits,
7752 of an argument with the specified mode and type. If it is not defined,
7753 PARM_BOUNDARY is used for all arguments.
7755 V.4 wants long longs and doubles to be double word aligned. Just
7756 testing the mode size is a boneheaded way to do this as it means
7757 that other types such as complex int are also double word aligned.
7758 However, we're stuck with this because changing the ABI might break
7759 existing library interfaces.
7761 Doubleword align SPE vectors.
7762 Quadword align Altivec vectors.
7763 Quadword align large synthetic vector types. */
7766 function_arg_boundary (enum machine_mode mode, const_tree type)
7768 if (DEFAULT_ABI == ABI_V4
7769 && (GET_MODE_SIZE (mode) == 8
7770 || (TARGET_HARD_FLOAT
7772 && (mode == TFmode || mode == TDmode))))
7774 else if (SPE_VECTOR_MODE (mode)
7775 || (type && TREE_CODE (type) == VECTOR_TYPE
7776 && int_size_in_bytes (type) >= 8
7777 && int_size_in_bytes (type) < 16))
7779 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7780 || (type && TREE_CODE (type) == VECTOR_TYPE
7781 && int_size_in_bytes (type) >= 16))
7783 else if (TARGET_MACHO
7784 && rs6000_darwin64_abi
7786 && type && TYPE_ALIGN (type) > 64)
7789 return PARM_BOUNDARY;
7792 /* For a function parm of MODE and TYPE, return the starting word in
7793 the parameter area. NWORDS of the parameter area are already used. */
7796 rs6000_parm_start (enum machine_mode mode, const_tree type,
7797 unsigned int nwords)
7800 unsigned int parm_offset;
7802 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7803 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7804 return nwords + (-(parm_offset + nwords) & align);
7807 /* Compute the size (in words) of a function argument. */
7809 static unsigned long
7810 rs6000_arg_size (enum machine_mode mode, const_tree type)
7814 if (mode != BLKmode)
7815 size = GET_MODE_SIZE (mode);
7817 size = int_size_in_bytes (type);
7820 return (size + 3) >> 2;
7822 return (size + 7) >> 3;
7825 /* Use this to flush pending int fields. */
7828 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7829 HOST_WIDE_INT bitpos, int final)
7831 unsigned int startbit, endbit;
7832 int intregs, intoffset;
7833 enum machine_mode mode;
7835 /* Handle the situations where a float is taking up the first half
7836 of the GPR, and the other half is empty (typically due to
7837 alignment restrictions). We can detect this by a 8-byte-aligned
7838 int field, or by seeing that this is the final flush for this
7839 argument. Count the word and continue on. */
7840 if (cum->floats_in_gpr == 1
7841 && (cum->intoffset % 64 == 0
7842 || (cum->intoffset == -1 && final)))
7845 cum->floats_in_gpr = 0;
7848 if (cum->intoffset == -1)
7851 intoffset = cum->intoffset;
7852 cum->intoffset = -1;
7853 cum->floats_in_gpr = 0;
7855 if (intoffset % BITS_PER_WORD != 0)
7857 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7859 if (mode == BLKmode)
7861 /* We couldn't find an appropriate mode, which happens,
7862 e.g., in packed structs when there are 3 bytes to load.
7863 Back intoffset back to the beginning of the word in this
7865 intoffset = intoffset & -BITS_PER_WORD;
7869 startbit = intoffset & -BITS_PER_WORD;
7870 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7871 intregs = (endbit - startbit) / BITS_PER_WORD;
7872 cum->words += intregs;
7873 /* words should be unsigned. */
7874 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7876 int pad = (endbit/BITS_PER_WORD) - cum->words;
7881 /* The darwin64 ABI calls for us to recurse down through structs,
7882 looking for elements passed in registers. Unfortunately, we have
7883 to track int register count here also because of misalignments
7884 in powerpc alignment mode. */
7887 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7889 HOST_WIDE_INT startbitpos)
7893 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7894 if (TREE_CODE (f) == FIELD_DECL)
7896 HOST_WIDE_INT bitpos = startbitpos;
7897 tree ftype = TREE_TYPE (f);
7898 enum machine_mode mode;
7899 if (ftype == error_mark_node)
7901 mode = TYPE_MODE (ftype);
7903 if (DECL_SIZE (f) != 0
7904 && host_integerp (bit_position (f), 1))
7905 bitpos += int_bit_position (f);
7907 /* ??? FIXME: else assume zero offset. */
7909 if (TREE_CODE (ftype) == RECORD_TYPE)
7910 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7911 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7913 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7914 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7915 /* Single-precision floats present a special problem for
7916 us, because they are smaller than an 8-byte GPR, and so
7917 the structure-packing rules combined with the standard
7918 varargs behavior mean that we want to pack float/float
7919 and float/int combinations into a single register's
7920 space. This is complicated by the arg advance flushing,
7921 which works on arbitrarily large groups of int-type
7925 if (cum->floats_in_gpr == 1)
7927 /* Two floats in a word; count the word and reset
7930 cum->floats_in_gpr = 0;
7932 else if (bitpos % 64 == 0)
7934 /* A float at the beginning of an 8-byte word;
7935 count it and put off adjusting cum->words until
7936 we see if a arg advance flush is going to do it
7938 cum->floats_in_gpr++;
7942 /* The float is at the end of a word, preceded
7943 by integer fields, so the arg advance flush
7944 just above has already set cum->words and
7945 everything is taken care of. */
7949 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7951 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7953 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7957 else if (cum->intoffset == -1)
7958 cum->intoffset = bitpos;
7962 /* Check for an item that needs to be considered specially under the darwin 64
7963 bit ABI. These are record types where the mode is BLK or the structure is
7966 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7968 return rs6000_darwin64_abi
7969 && ((mode == BLKmode
7970 && TREE_CODE (type) == RECORD_TYPE
7971 && int_size_in_bytes (type) > 0)
7972 || (type && TREE_CODE (type) == RECORD_TYPE
7973 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7976 /* Update the data in CUM to advance over an argument
7977 of mode MODE and data type TYPE.
7978 (TYPE is null for libcalls where that information may not be available.)
7980 Note that for args passed by reference, function_arg will be called
7981 with MODE and TYPE set to that of the pointer to the arg, not the arg
7985 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7986 const_tree type, bool named, int depth)
7989 /* Only tick off an argument if we're not recursing. */
7991 cum->nargs_prototype--;
7993 if (TARGET_ALTIVEC_ABI
7994 && (ALTIVEC_VECTOR_MODE (mode)
7995 || VSX_VECTOR_MODE (mode)
7996 || (type && TREE_CODE (type) == VECTOR_TYPE
7997 && int_size_in_bytes (type) == 16)))
8001 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8004 if (!TARGET_ALTIVEC)
8005 error ("cannot pass argument in vector register because"
8006 " altivec instructions are disabled, use -maltivec"
8009 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8010 even if it is going to be passed in a vector register.
8011 Darwin does the same for variable-argument functions. */
8012 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8013 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8023 /* Vector parameters must be 16-byte aligned. This places
8024 them at 2 mod 4 in terms of words in 32-bit mode, since
8025 the parameter save area starts at offset 24 from the
8026 stack. In 64-bit mode, they just have to start on an
8027 even word, since the parameter save area is 16-byte
8028 aligned. Space for GPRs is reserved even if the argument
8029 will be passed in memory. */
8031 align = (2 - cum->words) & 3;
8033 align = cum->words & 1;
8034 cum->words += align + rs6000_arg_size (mode, type);
8036 if (TARGET_DEBUG_ARG)
8038 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8040 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8041 cum->nargs_prototype, cum->prototype,
8042 GET_MODE_NAME (mode));
8046 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8048 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8051 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8053 int size = int_size_in_bytes (type);
8054 /* Variable sized types have size == -1 and are
8055 treated as if consisting entirely of ints.
8056 Pad to 16 byte boundary if needed. */
8057 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8058 && (cum->words % 2) != 0)
8060 /* For varargs, we can just go up by the size of the struct. */
8062 cum->words += (size + 7) / 8;
8065 /* It is tempting to say int register count just goes up by
8066 sizeof(type)/8, but this is wrong in a case such as
8067 { int; double; int; } [powerpc alignment]. We have to
8068 grovel through the fields for these too. */
8070 cum->floats_in_gpr = 0;
8071 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8072 rs6000_darwin64_record_arg_advance_flush (cum,
8073 size * BITS_PER_UNIT, 1);
8075 if (TARGET_DEBUG_ARG)
8077 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8078 cum->words, TYPE_ALIGN (type), size);
8080 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8081 cum->nargs_prototype, cum->prototype,
8082 GET_MODE_NAME (mode));
8085 else if (DEFAULT_ABI == ABI_V4)
8087 if (TARGET_HARD_FLOAT && TARGET_FPRS
8088 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8089 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8090 || (mode == TFmode && !TARGET_IEEEQUAD)
8091 || mode == SDmode || mode == DDmode || mode == TDmode))
8093 /* _Decimal128 must use an even/odd register pair. This assumes
8094 that the register number is odd when fregno is odd. */
8095 if (mode == TDmode && (cum->fregno % 2) == 1)
8098 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8099 <= FP_ARG_V4_MAX_REG)
8100 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8103 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8104 if (mode == DFmode || mode == TFmode
8105 || mode == DDmode || mode == TDmode)
8106 cum->words += cum->words & 1;
8107 cum->words += rs6000_arg_size (mode, type);
8112 int n_words = rs6000_arg_size (mode, type);
8113 int gregno = cum->sysv_gregno;
8115 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8116 (r7,r8) or (r9,r10). As does any other 2 word item such
8117 as complex int due to a historical mistake. */
8119 gregno += (1 - gregno) & 1;
8121 /* Multi-reg args are not split between registers and stack. */
8122 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8124 /* Long long and SPE vectors are aligned on the stack.
8125 So are other 2 word items such as complex int due to
8126 a historical mistake. */
8128 cum->words += cum->words & 1;
8129 cum->words += n_words;
8132 /* Note: continuing to accumulate gregno past when we've started
8133 spilling to the stack indicates the fact that we've started
8134 spilling to the stack to expand_builtin_saveregs. */
8135 cum->sysv_gregno = gregno + n_words;
8138 if (TARGET_DEBUG_ARG)
8140 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8141 cum->words, cum->fregno);
8142 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8143 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8144 fprintf (stderr, "mode = %4s, named = %d\n",
8145 GET_MODE_NAME (mode), named);
8150 int n_words = rs6000_arg_size (mode, type);
8151 int start_words = cum->words;
8152 int align_words = rs6000_parm_start (mode, type, start_words);
8154 cum->words = align_words + n_words;
8156 if (SCALAR_FLOAT_MODE_P (mode)
8157 && TARGET_HARD_FLOAT && TARGET_FPRS)
8159 /* _Decimal128 must be passed in an even/odd float register pair.
8160 This assumes that the register number is odd when fregno is
8162 if (mode == TDmode && (cum->fregno % 2) == 1)
8164 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8167 if (TARGET_DEBUG_ARG)
8169 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8170 cum->words, cum->fregno);
8171 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8172 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8173 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8174 named, align_words - start_words, depth);
8180 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8181 const_tree type, bool named)
8183 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8187 spe_build_register_parallel (enum machine_mode mode, int gregno)
8194 r1 = gen_rtx_REG (DImode, gregno);
8195 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8196 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8200 r1 = gen_rtx_REG (DImode, gregno);
8201 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8202 r3 = gen_rtx_REG (DImode, gregno + 2);
8203 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8204 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8207 r1 = gen_rtx_REG (DImode, gregno);
8208 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8209 r3 = gen_rtx_REG (DImode, gregno + 2);
8210 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8211 r5 = gen_rtx_REG (DImode, gregno + 4);
8212 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8213 r7 = gen_rtx_REG (DImode, gregno + 6);
8214 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8215 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8222 /* Determine where to put a SIMD argument on the SPE. */
8224 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8227 int gregno = cum->sysv_gregno;
8229 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8230 are passed and returned in a pair of GPRs for ABI compatibility. */
8231 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8232 || mode == DCmode || mode == TCmode))
8234 int n_words = rs6000_arg_size (mode, type);
8236 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8238 gregno += (1 - gregno) & 1;
8240 /* Multi-reg args are not split between registers and stack. */
8241 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8244 return spe_build_register_parallel (mode, gregno);
8248 int n_words = rs6000_arg_size (mode, type);
8250 /* SPE vectors are put in odd registers. */
8251 if (n_words == 2 && (gregno & 1) == 0)
8254 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8257 enum machine_mode m = SImode;
8259 r1 = gen_rtx_REG (m, gregno);
8260 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8261 r2 = gen_rtx_REG (m, gregno + 1);
8262 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8263 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8270 if (gregno <= GP_ARG_MAX_REG)
8271 return gen_rtx_REG (mode, gregno);
8277 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8278 structure between cum->intoffset and bitpos to integer registers. */
8281 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8282 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8284 enum machine_mode mode;
8286 unsigned int startbit, endbit;
8287 int this_regno, intregs, intoffset;
8290 if (cum->intoffset == -1)
8293 intoffset = cum->intoffset;
8294 cum->intoffset = -1;
8296 /* If this is the trailing part of a word, try to only load that
8297 much into the register. Otherwise load the whole register. Note
8298 that in the latter case we may pick up unwanted bits. It's not a
8299 problem at the moment but may wish to revisit. */
8301 if (intoffset % BITS_PER_WORD != 0)
8303 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8305 if (mode == BLKmode)
8307 /* We couldn't find an appropriate mode, which happens,
8308 e.g., in packed structs when there are 3 bytes to load.
8309 Back intoffset back to the beginning of the word in this
8311 intoffset = intoffset & -BITS_PER_WORD;
8318 startbit = intoffset & -BITS_PER_WORD;
8319 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8320 intregs = (endbit - startbit) / BITS_PER_WORD;
8321 this_regno = cum->words + intoffset / BITS_PER_WORD;
8323 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8326 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8330 intoffset /= BITS_PER_UNIT;
8333 regno = GP_ARG_MIN_REG + this_regno;
8334 reg = gen_rtx_REG (mode, regno);
8336 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8339 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8343 while (intregs > 0);
8346 /* Recursive workhorse for the following. */
8349 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8350 HOST_WIDE_INT startbitpos, rtx rvec[],
8355 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8356 if (TREE_CODE (f) == FIELD_DECL)
8358 HOST_WIDE_INT bitpos = startbitpos;
8359 tree ftype = TREE_TYPE (f);
8360 enum machine_mode mode;
8361 if (ftype == error_mark_node)
8363 mode = TYPE_MODE (ftype);
8365 if (DECL_SIZE (f) != 0
8366 && host_integerp (bit_position (f), 1))
8367 bitpos += int_bit_position (f);
8369 /* ??? FIXME: else assume zero offset. */
8371 if (TREE_CODE (ftype) == RECORD_TYPE)
8372 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8373 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8378 case SCmode: mode = SFmode; break;
8379 case DCmode: mode = DFmode; break;
8380 case TCmode: mode = TFmode; break;
8384 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8386 = gen_rtx_EXPR_LIST (VOIDmode,
8387 gen_rtx_REG (mode, cum->fregno++),
8388 GEN_INT (bitpos / BITS_PER_UNIT));
8389 if (mode == TFmode || mode == TDmode)
8392 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8394 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8396 = gen_rtx_EXPR_LIST (VOIDmode,
8397 gen_rtx_REG (mode, cum->vregno++),
8398 GEN_INT (bitpos / BITS_PER_UNIT));
8400 else if (cum->intoffset == -1)
8401 cum->intoffset = bitpos;
8405 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8406 the register(s) to be used for each field and subfield of a struct
8407 being passed by value, along with the offset of where the
8408 register's value may be found in the block. FP fields go in FP
8409 register, vector fields go in vector registers, and everything
8410 else goes in int registers, packed as in memory.
8412 This code is also used for function return values. RETVAL indicates
8413 whether this is the case.
8415 Much of this is taken from the SPARC V9 port, which has a similar
8416 calling convention. */
8419 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8420 bool named, bool retval)
8422 rtx rvec[FIRST_PSEUDO_REGISTER];
8423 int k = 1, kbase = 1;
8424 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8425 /* This is a copy; modifications are not visible to our caller. */
8426 CUMULATIVE_ARGS copy_cum = *orig_cum;
8427 CUMULATIVE_ARGS *cum = ©_cum;
8429 /* Pad to 16 byte boundary if needed. */
8430 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8431 && (cum->words % 2) != 0)
8438 /* Put entries into rvec[] for individual FP and vector fields, and
8439 for the chunks of memory that go in int regs. Note we start at
8440 element 1; 0 is reserved for an indication of using memory, and
8441 may or may not be filled in below. */
8442 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8443 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8445 /* If any part of the struct went on the stack put all of it there.
8446 This hack is because the generic code for
8447 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8448 parts of the struct are not at the beginning. */
8452 return NULL_RTX; /* doesn't go in registers at all */
8454 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8456 if (k > 1 || cum->use_stack)
8457 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8462 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8465 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8470 rtx rvec[GP_ARG_NUM_REG + 1];
8472 if (align_words >= GP_ARG_NUM_REG)
8475 n_units = rs6000_arg_size (mode, type);
8477 /* Optimize the simple case where the arg fits in one gpr, except in
8478 the case of BLKmode due to assign_parms assuming that registers are
8479 BITS_PER_WORD wide. */
8481 || (n_units == 1 && mode != BLKmode))
8482 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8485 if (align_words + n_units > GP_ARG_NUM_REG)
8486 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8487 using a magic NULL_RTX component.
8488 This is not strictly correct. Only some of the arg belongs in
8489 memory, not all of it. However, the normal scheme using
8490 function_arg_partial_nregs can result in unusual subregs, eg.
8491 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8492 store the whole arg to memory is often more efficient than code
8493 to store pieces, and we know that space is available in the right
8494 place for the whole arg. */
8495 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8500 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8501 rtx off = GEN_INT (i++ * 4);
8502 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8504 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8506 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8509 /* Determine where to put an argument to a function.
8510 Value is zero to push the argument on the stack,
8511 or a hard register in which to store the argument.
8513 MODE is the argument's machine mode.
8514 TYPE is the data type of the argument (as a tree).
8515 This is null for libcalls where that information may
8517 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8518 the preceding args and about the function being called. It is
8519 not modified in this routine.
8520 NAMED is nonzero if this argument is a named parameter
8521 (otherwise it is an extra parameter matching an ellipsis).
8523 On RS/6000 the first eight words of non-FP are normally in registers
8524 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8525 Under V.4, the first 8 FP args are in registers.
8527 If this is floating-point and no prototype is specified, we use
8528 both an FP and integer register (or possibly FP reg and stack). Library
8529 functions (when CALL_LIBCALL is set) always have the proper types for args,
8530 so we can pass the FP value just in one register. emit_library_function
8531 doesn't support PARALLEL anyway.
8533 Note that for args passed by reference, function_arg will be called
8534 with MODE and TYPE set to that of the pointer to the arg, not the arg
8538 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8539 const_tree type, bool named)
8541 enum rs6000_abi abi = DEFAULT_ABI;
8543 /* Return a marker to indicate whether CR1 needs to set or clear the
8544 bit that V.4 uses to say fp args were passed in registers.
8545 Assume that we don't need the marker for software floating point,
8546 or compiler generated library calls. */
8547 if (mode == VOIDmode)
8550 && (cum->call_cookie & CALL_LIBCALL) == 0
8552 || (cum->nargs_prototype < 0
8553 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8555 /* For the SPE, we need to crxor CR6 always. */
8557 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8558 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8559 return GEN_INT (cum->call_cookie
8560 | ((cum->fregno == FP_ARG_MIN_REG)
8561 ? CALL_V4_SET_FP_ARGS
8562 : CALL_V4_CLEAR_FP_ARGS));
8565 return GEN_INT (cum->call_cookie);
8568 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8570 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8571 if (rslt != NULL_RTX)
8573 /* Else fall through to usual handling. */
8576 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8577 if (TARGET_64BIT && ! cum->prototype)
8579 /* Vector parameters get passed in vector register
8580 and also in GPRs or memory, in absence of prototype. */
8583 align_words = (cum->words + 1) & ~1;
8585 if (align_words >= GP_ARG_NUM_REG)
8591 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8593 return gen_rtx_PARALLEL (mode,
8595 gen_rtx_EXPR_LIST (VOIDmode,
8597 gen_rtx_EXPR_LIST (VOIDmode,
8598 gen_rtx_REG (mode, cum->vregno),
8602 return gen_rtx_REG (mode, cum->vregno);
8603 else if (TARGET_ALTIVEC_ABI
8604 && (ALTIVEC_VECTOR_MODE (mode)
8605 || VSX_VECTOR_MODE (mode)
8606 || (type && TREE_CODE (type) == VECTOR_TYPE
8607 && int_size_in_bytes (type) == 16)))
8609 if (named || abi == ABI_V4)
8613 /* Vector parameters to varargs functions under AIX or Darwin
8614 get passed in memory and possibly also in GPRs. */
8615 int align, align_words, n_words;
8616 enum machine_mode part_mode;
8618 /* Vector parameters must be 16-byte aligned. This places them at
8619 2 mod 4 in terms of words in 32-bit mode, since the parameter
8620 save area starts at offset 24 from the stack. In 64-bit mode,
8621 they just have to start on an even word, since the parameter
8622 save area is 16-byte aligned. */
8624 align = (2 - cum->words) & 3;
8626 align = cum->words & 1;
8627 align_words = cum->words + align;
8629 /* Out of registers? Memory, then. */
8630 if (align_words >= GP_ARG_NUM_REG)
8633 if (TARGET_32BIT && TARGET_POWERPC64)
8634 return rs6000_mixed_function_arg (mode, type, align_words);
8636 /* The vector value goes in GPRs. Only the part of the
8637 value in GPRs is reported here. */
8639 n_words = rs6000_arg_size (mode, type);
8640 if (align_words + n_words > GP_ARG_NUM_REG)
8641 /* Fortunately, there are only two possibilities, the value
8642 is either wholly in GPRs or half in GPRs and half not. */
8645 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8648 else if (TARGET_SPE_ABI && TARGET_SPE
8649 && (SPE_VECTOR_MODE (mode)
8650 || (TARGET_E500_DOUBLE && (mode == DFmode
8653 || mode == TCmode))))
8654 return rs6000_spe_function_arg (cum, mode, type);
8656 else if (abi == ABI_V4)
8658 if (TARGET_HARD_FLOAT && TARGET_FPRS
8659 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8660 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8661 || (mode == TFmode && !TARGET_IEEEQUAD)
8662 || mode == SDmode || mode == DDmode || mode == TDmode))
8664 /* _Decimal128 must use an even/odd register pair. This assumes
8665 that the register number is odd when fregno is odd. */
8666 if (mode == TDmode && (cum->fregno % 2) == 1)
8669 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8670 <= FP_ARG_V4_MAX_REG)
8671 return gen_rtx_REG (mode, cum->fregno);
8677 int n_words = rs6000_arg_size (mode, type);
8678 int gregno = cum->sysv_gregno;
8680 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8681 (r7,r8) or (r9,r10). As does any other 2 word item such
8682 as complex int due to a historical mistake. */
8684 gregno += (1 - gregno) & 1;
8686 /* Multi-reg args are not split between registers and stack. */
8687 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8690 if (TARGET_32BIT && TARGET_POWERPC64)
8691 return rs6000_mixed_function_arg (mode, type,
8692 gregno - GP_ARG_MIN_REG);
8693 return gen_rtx_REG (mode, gregno);
8698 int align_words = rs6000_parm_start (mode, type, cum->words);
8700 /* _Decimal128 must be passed in an even/odd float register pair.
8701 This assumes that the register number is odd when fregno is odd. */
8702 if (mode == TDmode && (cum->fregno % 2) == 1)
8705 if (USE_FP_FOR_ARG_P (cum, mode, type))
8707 rtx rvec[GP_ARG_NUM_REG + 1];
8711 enum machine_mode fmode = mode;
8712 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8714 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8716 /* Currently, we only ever need one reg here because complex
8717 doubles are split. */
8718 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8719 && (fmode == TFmode || fmode == TDmode));
8721 /* Long double or _Decimal128 split over regs and memory. */
8722 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8725 /* Do we also need to pass this arg in the parameter save
8728 && (cum->nargs_prototype <= 0
8729 || (DEFAULT_ABI == ABI_AIX
8731 && align_words >= GP_ARG_NUM_REG)));
8733 if (!needs_psave && mode == fmode)
8734 return gen_rtx_REG (fmode, cum->fregno);
8739 /* Describe the part that goes in gprs or the stack.
8740 This piece must come first, before the fprs. */
8741 if (align_words < GP_ARG_NUM_REG)
8743 unsigned long n_words = rs6000_arg_size (mode, type);
8745 if (align_words + n_words > GP_ARG_NUM_REG
8746 || (TARGET_32BIT && TARGET_POWERPC64))
8748 /* If this is partially on the stack, then we only
8749 include the portion actually in registers here. */
8750 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8753 if (align_words + n_words > GP_ARG_NUM_REG)
8754 /* Not all of the arg fits in gprs. Say that it
8755 goes in memory too, using a magic NULL_RTX
8756 component. Also see comment in
8757 rs6000_mixed_function_arg for why the normal
8758 function_arg_partial_nregs scheme doesn't work
8760 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8764 r = gen_rtx_REG (rmode,
8765 GP_ARG_MIN_REG + align_words);
8766 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8767 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8769 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8773 /* The whole arg fits in gprs. */
8774 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8775 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8779 /* It's entirely in memory. */
8780 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8783 /* Describe where this piece goes in the fprs. */
8784 r = gen_rtx_REG (fmode, cum->fregno);
8785 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8787 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8789 else if (align_words < GP_ARG_NUM_REG)
8791 if (TARGET_32BIT && TARGET_POWERPC64)
8792 return rs6000_mixed_function_arg (mode, type, align_words);
8794 if (mode == BLKmode)
8797 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8804 /* For an arg passed partly in registers and partly in memory, this is
8805 the number of bytes passed in registers. For args passed entirely in
8806 registers or entirely in memory, zero. When an arg is described by a
8807 PARALLEL, perhaps using more than one register type, this function
8808 returns the number of bytes used by the first element of the PARALLEL. */
8811 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8812 tree type, bool named)
8817 if (DEFAULT_ABI == ABI_V4)
8820 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8821 && cum->nargs_prototype >= 0)
8824 /* In this complicated case we just disable the partial_nregs code. */
8825 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8828 align_words = rs6000_parm_start (mode, type, cum->words);
8830 if (USE_FP_FOR_ARG_P (cum, mode, type))
8832 /* If we are passing this arg in the fixed parameter save area
8833 (gprs or memory) as well as fprs, then this function should
8834 return the number of partial bytes passed in the parameter
8835 save area rather than partial bytes passed in fprs. */
8837 && (cum->nargs_prototype <= 0
8838 || (DEFAULT_ABI == ABI_AIX
8840 && align_words >= GP_ARG_NUM_REG)))
8842 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8843 > FP_ARG_MAX_REG + 1)
8844 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8845 else if (cum->nargs_prototype >= 0)
8849 if (align_words < GP_ARG_NUM_REG
8850 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8851 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8853 if (ret != 0 && TARGET_DEBUG_ARG)
8854 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8859 /* A C expression that indicates when an argument must be passed by
8860 reference. If nonzero for an argument, a copy of that argument is
8861 made in memory and a pointer to the argument is passed instead of
8862 the argument itself. The pointer is passed in whatever way is
8863 appropriate for passing a pointer to that type.
8865 Under V.4, aggregates and long double are passed by reference.
8867 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8868 reference unless the AltiVec vector extension ABI is in force.
8870 As an extension to all ABIs, variable sized types are passed by
8874 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8875 enum machine_mode mode, const_tree type,
8876 bool named ATTRIBUTE_UNUSED)
8878 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8880 if (TARGET_DEBUG_ARG)
8881 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8888 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8890 if (TARGET_DEBUG_ARG)
8891 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8895 if (int_size_in_bytes (type) < 0)
8897 if (TARGET_DEBUG_ARG)
8898 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8902 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8903 modes only exist for GCC vector types if -maltivec. */
8904 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8906 if (TARGET_DEBUG_ARG)
8907 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8911 /* Pass synthetic vectors in memory. */
8912 if (TREE_CODE (type) == VECTOR_TYPE
8913 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8915 static bool warned_for_pass_big_vectors = false;
8916 if (TARGET_DEBUG_ARG)
8917 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8918 if (!warned_for_pass_big_vectors)
8920 warning (0, "GCC vector passed by reference: "
8921 "non-standard ABI extension with no compatibility guarantee");
8922 warned_for_pass_big_vectors = true;
8931 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8934 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8939 for (i = 0; i < nregs; i++)
8941 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8942 if (reload_completed)
8944 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8947 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8948 i * GET_MODE_SIZE (reg_mode));
8951 tem = replace_equiv_address (tem, XEXP (tem, 0));
8955 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8959 /* Perform any needed actions needed for a function that is receiving a
8960 variable number of arguments.
8964 MODE and TYPE are the mode and type of the current parameter.
8966 PRETEND_SIZE is a variable that should be set to the amount of stack
8967 that must be pushed by the prolog to pretend that our caller pushed
8970 Normally, this macro will push all remaining incoming registers on the
8971 stack and set PRETEND_SIZE to the length of the registers pushed. */
8974 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8975 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8978 CUMULATIVE_ARGS next_cum;
8979 int reg_size = TARGET_32BIT ? 4 : 8;
8980 rtx save_area = NULL_RTX, mem;
8981 int first_reg_offset;
8984 /* Skip the last named argument. */
8986 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
8988 if (DEFAULT_ABI == ABI_V4)
8990 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8994 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8995 HOST_WIDE_INT offset = 0;
8997 /* Try to optimize the size of the varargs save area.
8998 The ABI requires that ap.reg_save_area is doubleword
8999 aligned, but we don't need to allocate space for all
9000 the bytes, only those to which we actually will save
9002 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9003 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9004 if (TARGET_HARD_FLOAT && TARGET_FPRS
9005 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9006 && cfun->va_list_fpr_size)
9009 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9010 * UNITS_PER_FP_WORD;
9011 if (cfun->va_list_fpr_size
9012 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9013 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9015 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9016 * UNITS_PER_FP_WORD;
9020 offset = -((first_reg_offset * reg_size) & ~7);
9021 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9023 gpr_reg_num = cfun->va_list_gpr_size;
9024 if (reg_size == 4 && (first_reg_offset & 1))
9027 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9030 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9032 - (int) (GP_ARG_NUM_REG * reg_size);
9034 if (gpr_size + fpr_size)
9037 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9038 gcc_assert (GET_CODE (reg_save_area) == MEM);
9039 reg_save_area = XEXP (reg_save_area, 0);
9040 if (GET_CODE (reg_save_area) == PLUS)
9042 gcc_assert (XEXP (reg_save_area, 0)
9043 == virtual_stack_vars_rtx);
9044 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9045 offset += INTVAL (XEXP (reg_save_area, 1));
9048 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9051 cfun->machine->varargs_save_offset = offset;
9052 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9057 first_reg_offset = next_cum.words;
9058 save_area = virtual_incoming_args_rtx;
9060 if (targetm.calls.must_pass_in_stack (mode, type))
9061 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9064 set = get_varargs_alias_set ();
9065 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9066 && cfun->va_list_gpr_size)
9068 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9070 if (va_list_gpr_counter_field)
9072 /* V4 va_list_gpr_size counts number of registers needed. */
9073 if (nregs > cfun->va_list_gpr_size)
9074 nregs = cfun->va_list_gpr_size;
9078 /* char * va_list instead counts number of bytes needed. */
9079 if (nregs > cfun->va_list_gpr_size / reg_size)
9080 nregs = cfun->va_list_gpr_size / reg_size;
9083 mem = gen_rtx_MEM (BLKmode,
9084 plus_constant (save_area,
9085 first_reg_offset * reg_size));
9086 MEM_NOTRAP_P (mem) = 1;
9087 set_mem_alias_set (mem, set);
9088 set_mem_align (mem, BITS_PER_WORD);
9090 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9094 /* Save FP registers if needed. */
9095 if (DEFAULT_ABI == ABI_V4
9096 && TARGET_HARD_FLOAT && TARGET_FPRS
9098 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9099 && cfun->va_list_fpr_size)
9101 int fregno = next_cum.fregno, nregs;
9102 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9103 rtx lab = gen_label_rtx ();
9104 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9105 * UNITS_PER_FP_WORD);
9108 (gen_rtx_SET (VOIDmode,
9110 gen_rtx_IF_THEN_ELSE (VOIDmode,
9111 gen_rtx_NE (VOIDmode, cr1,
9113 gen_rtx_LABEL_REF (VOIDmode, lab),
9117 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9118 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9120 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9122 plus_constant (save_area, off));
9123 MEM_NOTRAP_P (mem) = 1;
9124 set_mem_alias_set (mem, set);
9125 set_mem_align (mem, GET_MODE_ALIGNMENT (
9126 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9127 ? DFmode : SFmode));
9128 emit_move_insn (mem, gen_rtx_REG (
9129 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9130 ? DFmode : SFmode, fregno));
9137 /* Create the va_list data type. */
9140 rs6000_build_builtin_va_list (void)
9142 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9144 /* For AIX, prefer 'char *' because that's what the system
9145 header files like. */
9146 if (DEFAULT_ABI != ABI_V4)
9147 return build_pointer_type (char_type_node);
9149 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9150 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9151 get_identifier ("__va_list_tag"), record);
9153 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9154 unsigned_char_type_node);
9155 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9156 unsigned_char_type_node);
9157 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9159 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9160 get_identifier ("reserved"), short_unsigned_type_node);
9161 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9162 get_identifier ("overflow_arg_area"),
9164 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9165 get_identifier ("reg_save_area"),
9168 va_list_gpr_counter_field = f_gpr;
9169 va_list_fpr_counter_field = f_fpr;
9171 DECL_FIELD_CONTEXT (f_gpr) = record;
9172 DECL_FIELD_CONTEXT (f_fpr) = record;
9173 DECL_FIELD_CONTEXT (f_res) = record;
9174 DECL_FIELD_CONTEXT (f_ovf) = record;
9175 DECL_FIELD_CONTEXT (f_sav) = record;
9177 TREE_CHAIN (record) = type_decl;
9178 TYPE_NAME (record) = type_decl;
9179 TYPE_FIELDS (record) = f_gpr;
9180 DECL_CHAIN (f_gpr) = f_fpr;
9181 DECL_CHAIN (f_fpr) = f_res;
9182 DECL_CHAIN (f_res) = f_ovf;
9183 DECL_CHAIN (f_ovf) = f_sav;
9185 layout_type (record);
9187 /* The correct type is an array type of one element. */
9188 return build_array_type (record, build_index_type (size_zero_node));
9191 /* Implement va_start. */
9194 rs6000_va_start (tree valist, rtx nextarg)
9196 HOST_WIDE_INT words, n_gpr, n_fpr;
9197 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9198 tree gpr, fpr, ovf, sav, t;
9200 /* Only SVR4 needs something special. */
9201 if (DEFAULT_ABI != ABI_V4)
9203 std_expand_builtin_va_start (valist, nextarg);
9207 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9208 f_fpr = DECL_CHAIN (f_gpr);
9209 f_res = DECL_CHAIN (f_fpr);
9210 f_ovf = DECL_CHAIN (f_res);
9211 f_sav = DECL_CHAIN (f_ovf);
9213 valist = build_va_arg_indirect_ref (valist);
9214 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9215 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9217 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9219 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9222 /* Count number of gp and fp argument registers used. */
9223 words = crtl->args.info.words;
9224 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9226 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9229 if (TARGET_DEBUG_ARG)
9230 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9231 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9232 words, n_gpr, n_fpr);
9234 if (cfun->va_list_gpr_size)
9236 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9237 build_int_cst (NULL_TREE, n_gpr));
9238 TREE_SIDE_EFFECTS (t) = 1;
9239 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9242 if (cfun->va_list_fpr_size)
9244 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9245 build_int_cst (NULL_TREE, n_fpr));
9246 TREE_SIDE_EFFECTS (t) = 1;
9247 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9250 /* Find the overflow area. */
9251 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9253 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9254 size_int (words * UNITS_PER_WORD));
9255 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9256 TREE_SIDE_EFFECTS (t) = 1;
9257 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9259 /* If there were no va_arg invocations, don't set up the register
9261 if (!cfun->va_list_gpr_size
9262 && !cfun->va_list_fpr_size
9263 && n_gpr < GP_ARG_NUM_REG
9264 && n_fpr < FP_ARG_V4_MAX_REG)
9267 /* Find the register save area. */
9268 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9269 if (cfun->machine->varargs_save_offset)
9270 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9271 size_int (cfun->machine->varargs_save_offset));
9272 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9273 TREE_SIDE_EFFECTS (t) = 1;
9274 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9277 /* Implement va_arg. */
9280 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9283 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9284 tree gpr, fpr, ovf, sav, reg, t, u;
9285 int size, rsize, n_reg, sav_ofs, sav_scale;
9286 tree lab_false, lab_over, addr;
9288 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9292 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9294 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9295 return build_va_arg_indirect_ref (t);
9298 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9299 earlier version of gcc, with the property that it always applied alignment
9300 adjustments to the va-args (even for zero-sized types). The cheapest way
9301 to deal with this is to replicate the effect of the part of
9302 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9304 We don't need to check for pass-by-reference because of the test above.
9305 We can return a simplifed answer, since we know there's no offset to add. */
9308 && rs6000_darwin64_abi
9309 && integer_zerop (TYPE_SIZE (type)))
9311 unsigned HOST_WIDE_INT align, boundary;
9312 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9313 align = PARM_BOUNDARY / BITS_PER_UNIT;
9314 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9315 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9316 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9317 boundary /= BITS_PER_UNIT;
9318 if (boundary > align)
9321 /* This updates arg ptr by the amount that would be necessary
9322 to align the zero-sized (but not zero-alignment) item. */
9323 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9324 fold_build2 (POINTER_PLUS_EXPR,
9326 valist_tmp, size_int (boundary - 1)));
9327 gimplify_and_add (t, pre_p);
9329 t = fold_convert (sizetype, valist_tmp);
9330 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9331 fold_convert (TREE_TYPE (valist),
9332 fold_build2 (BIT_AND_EXPR, sizetype, t,
9333 size_int (-boundary))));
9334 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9335 gimplify_and_add (t, pre_p);
9337 /* Since it is zero-sized there's no increment for the item itself. */
9338 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9339 return build_va_arg_indirect_ref (valist_tmp);
9342 if (DEFAULT_ABI != ABI_V4)
9344 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9346 tree elem_type = TREE_TYPE (type);
9347 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9348 int elem_size = GET_MODE_SIZE (elem_mode);
9350 if (elem_size < UNITS_PER_WORD)
9352 tree real_part, imag_part;
9353 gimple_seq post = NULL;
9355 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9357 /* Copy the value into a temporary, lest the formal temporary
9358 be reused out from under us. */
9359 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9360 gimple_seq_add_seq (pre_p, post);
9362 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9365 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9369 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9372 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9373 f_fpr = DECL_CHAIN (f_gpr);
9374 f_res = DECL_CHAIN (f_fpr);
9375 f_ovf = DECL_CHAIN (f_res);
9376 f_sav = DECL_CHAIN (f_ovf);
9378 valist = build_va_arg_indirect_ref (valist);
9379 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9380 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9382 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9384 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9387 size = int_size_in_bytes (type);
9388 rsize = (size + 3) / 4;
9391 if (TARGET_HARD_FLOAT && TARGET_FPRS
9392 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9393 || (TARGET_DOUBLE_FLOAT
9394 && (TYPE_MODE (type) == DFmode
9395 || TYPE_MODE (type) == TFmode
9396 || TYPE_MODE (type) == SDmode
9397 || TYPE_MODE (type) == DDmode
9398 || TYPE_MODE (type) == TDmode))))
9400 /* FP args go in FP registers, if present. */
9402 n_reg = (size + 7) / 8;
9403 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9404 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9405 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9410 /* Otherwise into GP registers. */
9419 /* Pull the value out of the saved registers.... */
9422 addr = create_tmp_var (ptr_type_node, "addr");
9424 /* AltiVec vectors never go in registers when -mabi=altivec. */
9425 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9429 lab_false = create_artificial_label (input_location);
9430 lab_over = create_artificial_label (input_location);
9432 /* Long long and SPE vectors are aligned in the registers.
9433 As are any other 2 gpr item such as complex int due to a
9434 historical mistake. */
9436 if (n_reg == 2 && reg == gpr)
9439 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9440 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9441 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9442 unshare_expr (reg), u);
9444 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9445 reg number is 0 for f1, so we want to make it odd. */
9446 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9448 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9449 build_int_cst (TREE_TYPE (reg), 1));
9450 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9453 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9454 t = build2 (GE_EXPR, boolean_type_node, u, t);
9455 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9456 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9457 gimplify_and_add (t, pre_p);
9461 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9463 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9464 build_int_cst (TREE_TYPE (reg), n_reg));
9465 u = fold_convert (sizetype, u);
9466 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9467 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9469 /* _Decimal32 varargs are located in the second word of the 64-bit
9470 FP register for 32-bit binaries. */
9471 if (!TARGET_POWERPC64
9472 && TARGET_HARD_FLOAT && TARGET_FPRS
9473 && TYPE_MODE (type) == SDmode)
9474 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9476 gimplify_assign (addr, t, pre_p);
9478 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9480 stmt = gimple_build_label (lab_false);
9481 gimple_seq_add_stmt (pre_p, stmt);
9483 if ((n_reg == 2 && !regalign) || n_reg > 2)
9485 /* Ensure that we don't find any more args in regs.
9486 Alignment has taken care of for special cases. */
9487 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9491 /* ... otherwise out of the overflow area. */
9493 /* Care for on-stack alignment if needed. */
9497 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9498 t = fold_convert (sizetype, t);
9499 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9501 t = fold_convert (TREE_TYPE (ovf), t);
9503 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9505 gimplify_assign (unshare_expr (addr), t, pre_p);
9507 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9508 gimplify_assign (unshare_expr (ovf), t, pre_p);
9512 stmt = gimple_build_label (lab_over);
9513 gimple_seq_add_stmt (pre_p, stmt);
9516 if (STRICT_ALIGNMENT
9517 && (TYPE_ALIGN (type)
9518 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9520 /* The value (of type complex double, for example) may not be
9521 aligned in memory in the saved registers, so copy via a
9522 temporary. (This is the same code as used for SPARC.) */
9523 tree tmp = create_tmp_var (type, "va_arg_tmp");
9524 tree dest_addr = build_fold_addr_expr (tmp);
9526 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9527 3, dest_addr, addr, size_int (rsize * 4));
9529 gimplify_and_add (copy, pre_p);
9533 addr = fold_convert (ptrtype, addr);
9534 return build_va_arg_indirect_ref (addr);
9540 def_builtin (int mask, const char *name, tree type, int code)
9542 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9545 if (rs6000_builtin_decls[code])
9546 fatal_error ("internal error: builtin function to %s already processed.",
9549 rs6000_builtin_decls[code] = t =
9550 add_builtin_function (name, type, code, BUILT_IN_MD,
9553 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9554 switch (builtin_classify[code])
9559 /* assume builtin can do anything. */
9560 case RS6000_BTC_MISC:
9563 /* const function, function only depends on the inputs. */
9564 case RS6000_BTC_CONST:
9565 TREE_READONLY (t) = 1;
9566 TREE_NOTHROW (t) = 1;
9569 /* pure function, function can read global memory. */
9570 case RS6000_BTC_PURE:
9571 DECL_PURE_P (t) = 1;
9572 TREE_NOTHROW (t) = 1;
9575 /* Function is a math function. If rounding mode is on, then treat
9576 the function as not reading global memory, but it can have
9577 arbitrary side effects. If it is off, then assume the function is
9578 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9579 attribute in builtin-attribute.def that is used for the math
9581 case RS6000_BTC_FP_PURE:
9582 TREE_NOTHROW (t) = 1;
9583 if (flag_rounding_math)
9585 DECL_PURE_P (t) = 1;
9586 DECL_IS_NOVOPS (t) = 1;
9589 TREE_READONLY (t) = 1;
9595 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9597 static const struct builtin_description bdesc_3arg[] =
9599 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9600 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9601 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9602 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9603 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9604 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9605 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9606 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9607 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9608 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9609 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9610 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9611 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9612 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9613 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9614 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9615 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9620 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9621 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9622 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9623 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9624 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9625 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9626 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9627 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9628 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9629 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9633 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9635 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9636 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9637 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9638 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9639 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9640 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9641 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9642 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9643 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9644 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9645 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9646 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9647 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9648 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9649 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9651 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9652 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9653 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9654 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9656 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9657 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9658 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9659 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9664 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9665 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9666 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9667 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9668 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9669 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9670 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9671 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9672 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9673 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9675 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9676 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9677 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9678 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9679 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9680 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9681 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9682 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9683 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9684 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9686 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9687 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9688 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9689 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9690 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9691 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9692 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9693 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9694 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9696 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9697 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9698 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9699 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9700 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9701 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9702 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9704 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9705 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9706 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9707 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9708 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9709 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9710 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9711 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9712 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9715 /* DST operations: void foo (void *, const int, const char). */
9717 static const struct builtin_description bdesc_dst[] =
9719 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9720 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9721 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9722 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9730 /* Simple binary operations: VECc = foo (VECa, VECb). */
9732 static struct builtin_description bdesc_2arg[] =
9734 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9735 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9736 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9737 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9738 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9739 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9740 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9741 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9742 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9743 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9744 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9745 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9746 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9747 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9748 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9749 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9750 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9751 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9752 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9753 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9754 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9755 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9756 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9757 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9758 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9759 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9760 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9761 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9762 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9763 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9764 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9765 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9766 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9767 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9769 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9770 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9771 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9772 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9773 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9774 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9775 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9776 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9777 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9782 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9783 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9784 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9785 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9786 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9787 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9788 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9789 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9790 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9791 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9792 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9793 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9794 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9795 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9796 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9797 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9798 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9799 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9800 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9801 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9802 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9803 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9804 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9805 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9806 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9807 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9808 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9809 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9810 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9811 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9812 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9813 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9814 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9815 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9816 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9817 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9818 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9819 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9820 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9821 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9822 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9823 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9824 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9825 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9826 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9827 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9828 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9829 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9830 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9831 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9832 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9833 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9834 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9835 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9836 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9837 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9838 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9839 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9840 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9841 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9842 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9843 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9844 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9845 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9846 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9847 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9848 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9849 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9850 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9852 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9853 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9854 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9855 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9856 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9857 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9858 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9859 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9860 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9861 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9862 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9863 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9865 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9866 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9867 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9868 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9869 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9870 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9871 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9872 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9873 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9874 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9875 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9876 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9878 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9879 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9880 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9881 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9882 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9883 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9885 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9886 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9887 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9888 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9889 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9890 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9891 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9892 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9893 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9894 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9895 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9896 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9898 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9899 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9907 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9911 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9912 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9938 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9939 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9954 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9955 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9972 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9973 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10007 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10008 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10026 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10028 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10029 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10031 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10032 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10033 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10034 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10035 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10036 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10037 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10038 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10039 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10040 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10042 /* Place holder, leave as first spe builtin. */
10043 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10044 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10045 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10046 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10047 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10048 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10049 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10050 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10051 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10052 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10053 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10054 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10055 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10056 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10057 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10058 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10059 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10060 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10061 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10062 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10063 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10064 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10065 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10066 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10067 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10068 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10069 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10070 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10071 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10072 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10073 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10074 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10075 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10076 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10077 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10078 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10079 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10080 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10081 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10082 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10083 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10084 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10085 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10086 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10087 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10088 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10089 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10090 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10091 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10092 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10093 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10094 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10095 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10096 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10097 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10098 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10099 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10100 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10101 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10102 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10103 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10104 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10105 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10106 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10107 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10108 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10109 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10110 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10111 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10112 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10113 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10114 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10115 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10116 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10117 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10118 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10119 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10120 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10121 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10122 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10123 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10124 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10125 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10126 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10127 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10128 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10129 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10130 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10131 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10132 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10133 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10134 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10135 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10136 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10137 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10138 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10139 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10140 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10141 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10142 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10143 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10144 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10145 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10146 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10147 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10148 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10149 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10150 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10151 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10153 /* SPE binary operations expecting a 5-bit unsigned literal. */
10154 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10156 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10157 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10158 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10159 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10160 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10161 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10162 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10163 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10164 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10165 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10166 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10167 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10168 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10169 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10170 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10171 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10172 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10173 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10174 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10175 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10176 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10177 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10178 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10179 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10180 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10181 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10183 /* Place-holder. Leave as last binary SPE builtin. */
10184 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10187 /* AltiVec predicates. */
10189 struct builtin_description_predicates
10191 const unsigned int mask;
10192 const enum insn_code icode;
10193 const char *const name;
10194 const enum rs6000_builtins code;
10197 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10199 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10200 ALTIVEC_BUILTIN_VCMPBFP_P },
10201 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10202 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10203 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10204 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10205 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10206 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10207 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10208 ALTIVEC_BUILTIN_VCMPEQUW_P },
10209 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10210 ALTIVEC_BUILTIN_VCMPGTSW_P },
10211 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10212 ALTIVEC_BUILTIN_VCMPGTUW_P },
10213 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10214 ALTIVEC_BUILTIN_VCMPEQUH_P },
10215 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10216 ALTIVEC_BUILTIN_VCMPGTSH_P },
10217 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10218 ALTIVEC_BUILTIN_VCMPGTUH_P },
10219 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10220 ALTIVEC_BUILTIN_VCMPEQUB_P },
10221 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10222 ALTIVEC_BUILTIN_VCMPGTSB_P },
10223 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10224 ALTIVEC_BUILTIN_VCMPGTUB_P },
10226 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10227 VSX_BUILTIN_XVCMPEQSP_P },
10228 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10229 VSX_BUILTIN_XVCMPGESP_P },
10230 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10231 VSX_BUILTIN_XVCMPGTSP_P },
10232 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10233 VSX_BUILTIN_XVCMPEQDP_P },
10234 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10235 VSX_BUILTIN_XVCMPGEDP_P },
10236 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10237 VSX_BUILTIN_XVCMPGTDP_P },
10239 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10240 ALTIVEC_BUILTIN_VCMPEQ_P },
10241 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10242 ALTIVEC_BUILTIN_VCMPGT_P },
10243 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10244 ALTIVEC_BUILTIN_VCMPGE_P }
10247 /* SPE predicates. */
10248 static struct builtin_description bdesc_spe_predicates[] =
10250 /* Place-holder. Leave as first. */
10251 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10252 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10253 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10254 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10255 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10256 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10257 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10258 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10259 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10260 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10261 /* Place-holder. Leave as last. */
10262 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10265 /* SPE evsel predicates. */
10266 static struct builtin_description bdesc_spe_evsel[] =
10268 /* Place-holder. Leave as first. */
10269 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10270 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10271 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10272 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10273 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10274 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10275 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10276 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10277 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10278 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10279 /* Place-holder. Leave as last. */
10280 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10283 /* PAIRED predicates. */
10284 static const struct builtin_description bdesc_paired_preds[] =
10286 /* Place-holder. Leave as first. */
10287 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10288 /* Place-holder. Leave as last. */
10289 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10292 /* ABS* operations. */
10294 static const struct builtin_description bdesc_abs[] =
10296 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10297 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10298 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10299 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10300 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10301 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10302 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10303 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10304 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10305 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10306 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10309 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10312 static struct builtin_description bdesc_1arg[] =
10314 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10315 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10316 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10317 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10318 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10319 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10320 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10321 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10322 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10323 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10324 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10325 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10326 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10327 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10328 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10329 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10330 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10331 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10333 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10334 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10335 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10336 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10337 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10338 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10339 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10341 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10342 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10343 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10344 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10345 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10346 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10347 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10349 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10350 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10351 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10352 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10353 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10354 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10356 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10357 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10358 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10359 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10360 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10361 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10363 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10364 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10365 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10366 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10368 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10369 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10370 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10371 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10372 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10373 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10374 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10375 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10376 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10378 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10379 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10380 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10381 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10382 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10383 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10384 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10385 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10386 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10388 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10389 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10390 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10391 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10392 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10415 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10416 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10417 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10419 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10420 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10421 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10422 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10424 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10425 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10426 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10427 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10428 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10429 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10430 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10431 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10432 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10433 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10434 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10435 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10436 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10437 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10438 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10439 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10440 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10441 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10442 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10443 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10444 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10445 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10446 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10447 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10448 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10449 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10450 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10451 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10452 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10453 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10455 /* Place-holder. Leave as last unary SPE builtin. */
10456 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10458 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10459 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10460 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10461 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10462 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10466 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10469 tree arg0 = CALL_EXPR_ARG (exp, 0);
10470 rtx op0 = expand_normal (arg0);
10471 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10472 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10474 if (icode == CODE_FOR_nothing)
10475 /* Builtin not supported on this processor. */
10478 /* If we got invalid arguments bail out before generating bad rtl. */
10479 if (arg0 == error_mark_node)
10482 if (icode == CODE_FOR_altivec_vspltisb
10483 || icode == CODE_FOR_altivec_vspltish
10484 || icode == CODE_FOR_altivec_vspltisw
10485 || icode == CODE_FOR_spe_evsplatfi
10486 || icode == CODE_FOR_spe_evsplati)
10488 /* Only allow 5-bit *signed* literals. */
10489 if (GET_CODE (op0) != CONST_INT
10490 || INTVAL (op0) > 15
10491 || INTVAL (op0) < -16)
10493 error ("argument 1 must be a 5-bit signed literal");
10499 || GET_MODE (target) != tmode
10500 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10501 target = gen_reg_rtx (tmode);
10503 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10504 op0 = copy_to_mode_reg (mode0, op0);
10506 pat = GEN_FCN (icode) (target, op0);
10515 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10517 rtx pat, scratch1, scratch2;
10518 tree arg0 = CALL_EXPR_ARG (exp, 0);
10519 rtx op0 = expand_normal (arg0);
10520 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10521 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10523 /* If we have invalid arguments, bail out before generating bad rtl. */
10524 if (arg0 == error_mark_node)
10528 || GET_MODE (target) != tmode
10529 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10530 target = gen_reg_rtx (tmode);
10532 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10533 op0 = copy_to_mode_reg (mode0, op0);
10535 scratch1 = gen_reg_rtx (mode0);
10536 scratch2 = gen_reg_rtx (mode0);
10538 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10547 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10550 tree arg0 = CALL_EXPR_ARG (exp, 0);
10551 tree arg1 = CALL_EXPR_ARG (exp, 1);
10552 rtx op0 = expand_normal (arg0);
10553 rtx op1 = expand_normal (arg1);
10554 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10555 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10556 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10558 if (icode == CODE_FOR_nothing)
10559 /* Builtin not supported on this processor. */
10562 /* If we got invalid arguments bail out before generating bad rtl. */
10563 if (arg0 == error_mark_node || arg1 == error_mark_node)
10566 if (icode == CODE_FOR_altivec_vcfux
10567 || icode == CODE_FOR_altivec_vcfsx
10568 || icode == CODE_FOR_altivec_vctsxs
10569 || icode == CODE_FOR_altivec_vctuxs
10570 || icode == CODE_FOR_altivec_vspltb
10571 || icode == CODE_FOR_altivec_vsplth
10572 || icode == CODE_FOR_altivec_vspltw
10573 || icode == CODE_FOR_spe_evaddiw
10574 || icode == CODE_FOR_spe_evldd
10575 || icode == CODE_FOR_spe_evldh
10576 || icode == CODE_FOR_spe_evldw
10577 || icode == CODE_FOR_spe_evlhhesplat
10578 || icode == CODE_FOR_spe_evlhhossplat
10579 || icode == CODE_FOR_spe_evlhhousplat
10580 || icode == CODE_FOR_spe_evlwhe
10581 || icode == CODE_FOR_spe_evlwhos
10582 || icode == CODE_FOR_spe_evlwhou
10583 || icode == CODE_FOR_spe_evlwhsplat
10584 || icode == CODE_FOR_spe_evlwwsplat
10585 || icode == CODE_FOR_spe_evrlwi
10586 || icode == CODE_FOR_spe_evslwi
10587 || icode == CODE_FOR_spe_evsrwis
10588 || icode == CODE_FOR_spe_evsubifw
10589 || icode == CODE_FOR_spe_evsrwiu)
10591 /* Only allow 5-bit unsigned literals. */
10593 if (TREE_CODE (arg1) != INTEGER_CST
10594 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10596 error ("argument 2 must be a 5-bit unsigned literal");
10602 || GET_MODE (target) != tmode
10603 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10604 target = gen_reg_rtx (tmode);
10606 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10607 op0 = copy_to_mode_reg (mode0, op0);
10608 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10609 op1 = copy_to_mode_reg (mode1, op1);
10611 pat = GEN_FCN (icode) (target, op0, op1);
10620 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10623 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10624 tree arg0 = CALL_EXPR_ARG (exp, 1);
10625 tree arg1 = CALL_EXPR_ARG (exp, 2);
10626 rtx op0 = expand_normal (arg0);
10627 rtx op1 = expand_normal (arg1);
10628 enum machine_mode tmode = SImode;
10629 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10630 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10633 if (TREE_CODE (cr6_form) != INTEGER_CST)
10635 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10639 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10641 gcc_assert (mode0 == mode1);
10643 /* If we have invalid arguments, bail out before generating bad rtl. */
10644 if (arg0 == error_mark_node || arg1 == error_mark_node)
10648 || GET_MODE (target) != tmode
10649 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10650 target = gen_reg_rtx (tmode);
10652 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10653 op0 = copy_to_mode_reg (mode0, op0);
10654 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10655 op1 = copy_to_mode_reg (mode1, op1);
10657 scratch = gen_reg_rtx (mode0);
10659 pat = GEN_FCN (icode) (scratch, op0, op1);
10664 /* The vec_any* and vec_all* predicates use the same opcodes for two
10665 different operations, but the bits in CR6 will be different
10666 depending on what information we want. So we have to play tricks
10667 with CR6 to get the right bits out.
10669 If you think this is disgusting, look at the specs for the
10670 AltiVec predicates. */
10672 switch (cr6_form_int)
10675 emit_insn (gen_cr6_test_for_zero (target));
10678 emit_insn (gen_cr6_test_for_zero_reverse (target));
10681 emit_insn (gen_cr6_test_for_lt (target));
10684 emit_insn (gen_cr6_test_for_lt_reverse (target));
10687 error ("argument 1 of __builtin_altivec_predicate is out of range");
10695 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10698 tree arg0 = CALL_EXPR_ARG (exp, 0);
10699 tree arg1 = CALL_EXPR_ARG (exp, 1);
10700 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10701 enum machine_mode mode0 = Pmode;
10702 enum machine_mode mode1 = Pmode;
10703 rtx op0 = expand_normal (arg0);
10704 rtx op1 = expand_normal (arg1);
10706 if (icode == CODE_FOR_nothing)
10707 /* Builtin not supported on this processor. */
10710 /* If we got invalid arguments bail out before generating bad rtl. */
10711 if (arg0 == error_mark_node || arg1 == error_mark_node)
10715 || GET_MODE (target) != tmode
10716 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10717 target = gen_reg_rtx (tmode);
10719 op1 = copy_to_mode_reg (mode1, op1);
10721 if (op0 == const0_rtx)
10723 addr = gen_rtx_MEM (tmode, op1);
10727 op0 = copy_to_mode_reg (mode0, op0);
10728 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10731 pat = GEN_FCN (icode) (target, addr);
10741 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10744 tree arg0 = CALL_EXPR_ARG (exp, 0);
10745 tree arg1 = CALL_EXPR_ARG (exp, 1);
10746 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10747 enum machine_mode mode0 = Pmode;
10748 enum machine_mode mode1 = Pmode;
10749 rtx op0 = expand_normal (arg0);
10750 rtx op1 = expand_normal (arg1);
10752 if (icode == CODE_FOR_nothing)
10753 /* Builtin not supported on this processor. */
10756 /* If we got invalid arguments bail out before generating bad rtl. */
10757 if (arg0 == error_mark_node || arg1 == error_mark_node)
10761 || GET_MODE (target) != tmode
10762 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10763 target = gen_reg_rtx (tmode);
10765 op1 = copy_to_mode_reg (mode1, op1);
10767 if (op0 == const0_rtx)
10769 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10773 op0 = copy_to_mode_reg (mode0, op0);
10774 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10777 pat = GEN_FCN (icode) (target, addr);
10787 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10789 tree arg0 = CALL_EXPR_ARG (exp, 0);
10790 tree arg1 = CALL_EXPR_ARG (exp, 1);
10791 tree arg2 = CALL_EXPR_ARG (exp, 2);
10792 rtx op0 = expand_normal (arg0);
10793 rtx op1 = expand_normal (arg1);
10794 rtx op2 = expand_normal (arg2);
10796 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10797 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10798 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10800 /* Invalid arguments. Bail before doing anything stoopid! */
10801 if (arg0 == error_mark_node
10802 || arg1 == error_mark_node
10803 || arg2 == error_mark_node)
10806 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10807 op0 = copy_to_mode_reg (mode2, op0);
10808 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10809 op1 = copy_to_mode_reg (mode0, op1);
10810 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10811 op2 = copy_to_mode_reg (mode1, op2);
10813 pat = GEN_FCN (icode) (op1, op2, op0);
10820 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10822 tree arg0 = CALL_EXPR_ARG (exp, 0);
10823 tree arg1 = CALL_EXPR_ARG (exp, 1);
10824 tree arg2 = CALL_EXPR_ARG (exp, 2);
10825 rtx op0 = expand_normal (arg0);
10826 rtx op1 = expand_normal (arg1);
10827 rtx op2 = expand_normal (arg2);
10829 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10830 enum machine_mode mode1 = Pmode;
10831 enum machine_mode mode2 = Pmode;
10833 /* Invalid arguments. Bail before doing anything stoopid! */
10834 if (arg0 == error_mark_node
10835 || arg1 == error_mark_node
10836 || arg2 == error_mark_node)
10839 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10840 op0 = copy_to_mode_reg (tmode, op0);
10842 op2 = copy_to_mode_reg (mode2, op2);
10844 if (op1 == const0_rtx)
10846 addr = gen_rtx_MEM (tmode, op2);
10850 op1 = copy_to_mode_reg (mode1, op1);
10851 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10854 pat = GEN_FCN (icode) (addr, op0);
10861 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10863 tree arg0 = CALL_EXPR_ARG (exp, 0);
10864 tree arg1 = CALL_EXPR_ARG (exp, 1);
10865 tree arg2 = CALL_EXPR_ARG (exp, 2);
10866 rtx op0 = expand_normal (arg0);
10867 rtx op1 = expand_normal (arg1);
10868 rtx op2 = expand_normal (arg2);
10870 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10871 enum machine_mode mode1 = Pmode;
10872 enum machine_mode mode2 = Pmode;
10874 /* Invalid arguments. Bail before doing anything stoopid! */
10875 if (arg0 == error_mark_node
10876 || arg1 == error_mark_node
10877 || arg2 == error_mark_node)
10880 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10881 op0 = copy_to_mode_reg (tmode, op0);
10883 op2 = copy_to_mode_reg (mode2, op2);
10885 if (op1 == const0_rtx)
10887 addr = gen_rtx_MEM (tmode, op2);
10891 op1 = copy_to_mode_reg (mode1, op1);
10892 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10895 pat = GEN_FCN (icode) (addr, op0);
10902 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10905 tree arg0 = CALL_EXPR_ARG (exp, 0);
10906 tree arg1 = CALL_EXPR_ARG (exp, 1);
10907 tree arg2 = CALL_EXPR_ARG (exp, 2);
10908 rtx op0 = expand_normal (arg0);
10909 rtx op1 = expand_normal (arg1);
10910 rtx op2 = expand_normal (arg2);
10911 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10912 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10913 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10914 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10916 if (icode == CODE_FOR_nothing)
10917 /* Builtin not supported on this processor. */
10920 /* If we got invalid arguments bail out before generating bad rtl. */
10921 if (arg0 == error_mark_node
10922 || arg1 == error_mark_node
10923 || arg2 == error_mark_node)
10928 case CODE_FOR_altivec_vsldoi_v4sf:
10929 case CODE_FOR_altivec_vsldoi_v4si:
10930 case CODE_FOR_altivec_vsldoi_v8hi:
10931 case CODE_FOR_altivec_vsldoi_v16qi:
10932 /* Only allow 4-bit unsigned literals. */
10934 if (TREE_CODE (arg2) != INTEGER_CST
10935 || TREE_INT_CST_LOW (arg2) & ~0xf)
10937 error ("argument 3 must be a 4-bit unsigned literal");
10942 case CODE_FOR_vsx_xxpermdi_v2df:
10943 case CODE_FOR_vsx_xxpermdi_v2di:
10944 case CODE_FOR_vsx_xxsldwi_v16qi:
10945 case CODE_FOR_vsx_xxsldwi_v8hi:
10946 case CODE_FOR_vsx_xxsldwi_v4si:
10947 case CODE_FOR_vsx_xxsldwi_v4sf:
10948 case CODE_FOR_vsx_xxsldwi_v2di:
10949 case CODE_FOR_vsx_xxsldwi_v2df:
10950 /* Only allow 2-bit unsigned literals. */
10952 if (TREE_CODE (arg2) != INTEGER_CST
10953 || TREE_INT_CST_LOW (arg2) & ~0x3)
10955 error ("argument 3 must be a 2-bit unsigned literal");
10960 case CODE_FOR_vsx_set_v2df:
10961 case CODE_FOR_vsx_set_v2di:
10962 /* Only allow 1-bit unsigned literals. */
10964 if (TREE_CODE (arg2) != INTEGER_CST
10965 || TREE_INT_CST_LOW (arg2) & ~0x1)
10967 error ("argument 3 must be a 1-bit unsigned literal");
10977 || GET_MODE (target) != tmode
10978 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10979 target = gen_reg_rtx (tmode);
10981 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10982 op0 = copy_to_mode_reg (mode0, op0);
10983 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10984 op1 = copy_to_mode_reg (mode1, op1);
10985 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10986 op2 = copy_to_mode_reg (mode2, op2);
10988 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10989 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10991 pat = GEN_FCN (icode) (target, op0, op1, op2);
10999 /* Expand the lvx builtins. */
11001 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11003 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11004 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11006 enum machine_mode tmode, mode0;
11008 enum insn_code icode;
11012 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11013 icode = CODE_FOR_vector_load_v16qi;
11015 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11016 icode = CODE_FOR_vector_load_v8hi;
11018 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11019 icode = CODE_FOR_vector_load_v4si;
11021 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11022 icode = CODE_FOR_vector_load_v4sf;
11025 *expandedp = false;
11031 arg0 = CALL_EXPR_ARG (exp, 0);
11032 op0 = expand_normal (arg0);
11033 tmode = insn_data[icode].operand[0].mode;
11034 mode0 = insn_data[icode].operand[1].mode;
11037 || GET_MODE (target) != tmode
11038 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11039 target = gen_reg_rtx (tmode);
11041 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11042 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11044 pat = GEN_FCN (icode) (target, op0);
11051 /* Expand the stvx builtins. */
11053 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11056 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11057 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11059 enum machine_mode mode0, mode1;
11061 enum insn_code icode;
11065 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11066 icode = CODE_FOR_vector_store_v16qi;
11068 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11069 icode = CODE_FOR_vector_store_v8hi;
11071 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11072 icode = CODE_FOR_vector_store_v4si;
11074 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11075 icode = CODE_FOR_vector_store_v4sf;
11078 *expandedp = false;
11082 arg0 = CALL_EXPR_ARG (exp, 0);
11083 arg1 = CALL_EXPR_ARG (exp, 1);
11084 op0 = expand_normal (arg0);
11085 op1 = expand_normal (arg1);
11086 mode0 = insn_data[icode].operand[0].mode;
11087 mode1 = insn_data[icode].operand[1].mode;
11089 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11090 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11091 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11092 op1 = copy_to_mode_reg (mode1, op1);
11094 pat = GEN_FCN (icode) (op0, op1);
11102 /* Expand the dst builtins. */
11104 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11107 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11108 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11109 tree arg0, arg1, arg2;
11110 enum machine_mode mode0, mode1;
11111 rtx pat, op0, op1, op2;
11112 const struct builtin_description *d;
11115 *expandedp = false;
11117 /* Handle DST variants. */
11119 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11120 if (d->code == fcode)
11122 arg0 = CALL_EXPR_ARG (exp, 0);
11123 arg1 = CALL_EXPR_ARG (exp, 1);
11124 arg2 = CALL_EXPR_ARG (exp, 2);
11125 op0 = expand_normal (arg0);
11126 op1 = expand_normal (arg1);
11127 op2 = expand_normal (arg2);
11128 mode0 = insn_data[d->icode].operand[0].mode;
11129 mode1 = insn_data[d->icode].operand[1].mode;
11131 /* Invalid arguments, bail out before generating bad rtl. */
11132 if (arg0 == error_mark_node
11133 || arg1 == error_mark_node
11134 || arg2 == error_mark_node)
11139 if (TREE_CODE (arg2) != INTEGER_CST
11140 || TREE_INT_CST_LOW (arg2) & ~0x3)
11142 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11146 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11147 op0 = copy_to_mode_reg (Pmode, op0);
11148 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11149 op1 = copy_to_mode_reg (mode1, op1);
11151 pat = GEN_FCN (d->icode) (op0, op1, op2);
11161 /* Expand vec_init builtin. */
11163 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11165 enum machine_mode tmode = TYPE_MODE (type);
11166 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11167 int i, n_elt = GET_MODE_NUNITS (tmode);
11168 rtvec v = rtvec_alloc (n_elt);
11170 gcc_assert (VECTOR_MODE_P (tmode));
11171 gcc_assert (n_elt == call_expr_nargs (exp));
11173 for (i = 0; i < n_elt; ++i)
11175 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11176 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11179 if (!target || !register_operand (target, tmode))
11180 target = gen_reg_rtx (tmode);
11182 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11186 /* Return the integer constant in ARG. Constrain it to be in the range
11187 of the subparts of VEC_TYPE; issue an error if not. */
11190 get_element_number (tree vec_type, tree arg)
11192 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11194 if (!host_integerp (arg, 1)
11195 || (elt = tree_low_cst (arg, 1), elt > max))
11197 error ("selector must be an integer constant in the range 0..%wi", max);
11204 /* Expand vec_set builtin. */
11206 altivec_expand_vec_set_builtin (tree exp)
11208 enum machine_mode tmode, mode1;
11209 tree arg0, arg1, arg2;
11213 arg0 = CALL_EXPR_ARG (exp, 0);
11214 arg1 = CALL_EXPR_ARG (exp, 1);
11215 arg2 = CALL_EXPR_ARG (exp, 2);
11217 tmode = TYPE_MODE (TREE_TYPE (arg0));
11218 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11219 gcc_assert (VECTOR_MODE_P (tmode));
11221 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11222 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11223 elt = get_element_number (TREE_TYPE (arg0), arg2);
11225 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11226 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11228 op0 = force_reg (tmode, op0);
11229 op1 = force_reg (mode1, op1);
11231 rs6000_expand_vector_set (op0, op1, elt);
11236 /* Expand vec_ext builtin. */
11238 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11240 enum machine_mode tmode, mode0;
11245 arg0 = CALL_EXPR_ARG (exp, 0);
11246 arg1 = CALL_EXPR_ARG (exp, 1);
11248 op0 = expand_normal (arg0);
11249 elt = get_element_number (TREE_TYPE (arg0), arg1);
11251 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11252 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11253 gcc_assert (VECTOR_MODE_P (mode0));
11255 op0 = force_reg (mode0, op0);
11257 if (optimize || !target || !register_operand (target, tmode))
11258 target = gen_reg_rtx (tmode);
11260 rs6000_expand_vector_extract (target, op0, elt);
11265 /* Expand the builtin in EXP and store the result in TARGET. Store
11266 true in *EXPANDEDP if we found a builtin to expand. */
11268 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11270 const struct builtin_description *d;
11271 const struct builtin_description_predicates *dp;
11273 enum insn_code icode;
11274 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11277 enum machine_mode tmode, mode0;
11278 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11280 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11281 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11282 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11283 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11286 error ("unresolved overload for Altivec builtin %qF", fndecl);
11290 target = altivec_expand_ld_builtin (exp, target, expandedp);
11294 target = altivec_expand_st_builtin (exp, target, expandedp);
11298 target = altivec_expand_dst_builtin (exp, target, expandedp);
11306 case ALTIVEC_BUILTIN_STVX:
11307 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11308 case ALTIVEC_BUILTIN_STVEBX:
11309 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11310 case ALTIVEC_BUILTIN_STVEHX:
11311 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11312 case ALTIVEC_BUILTIN_STVEWX:
11313 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11314 case ALTIVEC_BUILTIN_STVXL:
11315 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11317 case ALTIVEC_BUILTIN_STVLX:
11318 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11319 case ALTIVEC_BUILTIN_STVLXL:
11320 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11321 case ALTIVEC_BUILTIN_STVRX:
11322 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11323 case ALTIVEC_BUILTIN_STVRXL:
11324 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11326 case ALTIVEC_BUILTIN_MFVSCR:
11327 icode = CODE_FOR_altivec_mfvscr;
11328 tmode = insn_data[icode].operand[0].mode;
11331 || GET_MODE (target) != tmode
11332 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11333 target = gen_reg_rtx (tmode);
11335 pat = GEN_FCN (icode) (target);
11341 case ALTIVEC_BUILTIN_MTVSCR:
11342 icode = CODE_FOR_altivec_mtvscr;
11343 arg0 = CALL_EXPR_ARG (exp, 0);
11344 op0 = expand_normal (arg0);
11345 mode0 = insn_data[icode].operand[0].mode;
11347 /* If we got invalid arguments bail out before generating bad rtl. */
11348 if (arg0 == error_mark_node)
11351 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11352 op0 = copy_to_mode_reg (mode0, op0);
11354 pat = GEN_FCN (icode) (op0);
11359 case ALTIVEC_BUILTIN_DSSALL:
11360 emit_insn (gen_altivec_dssall ());
11363 case ALTIVEC_BUILTIN_DSS:
11364 icode = CODE_FOR_altivec_dss;
11365 arg0 = CALL_EXPR_ARG (exp, 0);
11367 op0 = expand_normal (arg0);
11368 mode0 = insn_data[icode].operand[0].mode;
11370 /* If we got invalid arguments bail out before generating bad rtl. */
11371 if (arg0 == error_mark_node)
11374 if (TREE_CODE (arg0) != INTEGER_CST
11375 || TREE_INT_CST_LOW (arg0) & ~0x3)
11377 error ("argument to dss must be a 2-bit unsigned literal");
11381 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11382 op0 = copy_to_mode_reg (mode0, op0);
11384 emit_insn (gen_altivec_dss (op0));
11387 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11388 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11389 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11390 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11391 case VSX_BUILTIN_VEC_INIT_V2DF:
11392 case VSX_BUILTIN_VEC_INIT_V2DI:
11393 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11395 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11396 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11397 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11398 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11399 case VSX_BUILTIN_VEC_SET_V2DF:
11400 case VSX_BUILTIN_VEC_SET_V2DI:
11401 return altivec_expand_vec_set_builtin (exp);
11403 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11404 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11405 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11406 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11407 case VSX_BUILTIN_VEC_EXT_V2DF:
11408 case VSX_BUILTIN_VEC_EXT_V2DI:
11409 return altivec_expand_vec_ext_builtin (exp, target);
11413 /* Fall through. */
11416 /* Expand abs* operations. */
11418 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11419 if (d->code == fcode)
11420 return altivec_expand_abs_builtin (d->icode, exp, target);
11422 /* Expand the AltiVec predicates. */
11423 dp = bdesc_altivec_preds;
11424 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11425 if (dp->code == fcode)
11426 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11428 /* LV* are funky. We initialized them differently. */
11431 case ALTIVEC_BUILTIN_LVSL:
11432 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11433 exp, target, false);
11434 case ALTIVEC_BUILTIN_LVSR:
11435 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11436 exp, target, false);
11437 case ALTIVEC_BUILTIN_LVEBX:
11438 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11439 exp, target, false);
11440 case ALTIVEC_BUILTIN_LVEHX:
11441 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11442 exp, target, false);
11443 case ALTIVEC_BUILTIN_LVEWX:
11444 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11445 exp, target, false);
11446 case ALTIVEC_BUILTIN_LVXL:
11447 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11448 exp, target, false);
11449 case ALTIVEC_BUILTIN_LVX:
11450 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11451 exp, target, false);
11452 case ALTIVEC_BUILTIN_LVLX:
11453 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11454 exp, target, true);
11455 case ALTIVEC_BUILTIN_LVLXL:
11456 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11457 exp, target, true);
11458 case ALTIVEC_BUILTIN_LVRX:
11459 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11460 exp, target, true);
11461 case ALTIVEC_BUILTIN_LVRXL:
11462 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11463 exp, target, true);
11466 /* Fall through. */
11469 *expandedp = false;
11473 /* Expand the builtin in EXP and store the result in TARGET. Store
11474 true in *EXPANDEDP if we found a builtin to expand. */
11476 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11478 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11479 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11480 const struct builtin_description *d;
11487 case PAIRED_BUILTIN_STX:
11488 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11489 case PAIRED_BUILTIN_LX:
11490 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11493 /* Fall through. */
11496 /* Expand the paired predicates. */
11497 d = bdesc_paired_preds;
11498 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11499 if (d->code == fcode)
11500 return paired_expand_predicate_builtin (d->icode, exp, target);
11502 *expandedp = false;
11506 /* Binops that need to be initialized manually, but can be expanded
11507 automagically by rs6000_expand_binop_builtin. */
11508 static struct builtin_description bdesc_2arg_spe[] =
11510 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11511 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11512 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11513 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11514 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11515 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11516 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11517 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11518 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11519 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11520 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11521 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11522 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11523 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11524 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11525 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11526 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11527 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11528 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11529 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11530 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11531 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11534 /* Expand the builtin in EXP and store the result in TARGET. Store
11535 true in *EXPANDEDP if we found a builtin to expand.
11537 This expands the SPE builtins that are not simple unary and binary
11540 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11542 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11544 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11545 enum insn_code icode;
11546 enum machine_mode tmode, mode0;
11548 struct builtin_description *d;
11553 /* Syntax check for a 5-bit unsigned immediate. */
11556 case SPE_BUILTIN_EVSTDD:
11557 case SPE_BUILTIN_EVSTDH:
11558 case SPE_BUILTIN_EVSTDW:
11559 case SPE_BUILTIN_EVSTWHE:
11560 case SPE_BUILTIN_EVSTWHO:
11561 case SPE_BUILTIN_EVSTWWE:
11562 case SPE_BUILTIN_EVSTWWO:
11563 arg1 = CALL_EXPR_ARG (exp, 2);
11564 if (TREE_CODE (arg1) != INTEGER_CST
11565 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11567 error ("argument 2 must be a 5-bit unsigned literal");
11575 /* The evsplat*i instructions are not quite generic. */
11578 case SPE_BUILTIN_EVSPLATFI:
11579 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11581 case SPE_BUILTIN_EVSPLATI:
11582 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11588 d = (struct builtin_description *) bdesc_2arg_spe;
11589 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11590 if (d->code == fcode)
11591 return rs6000_expand_binop_builtin (d->icode, exp, target);
11593 d = (struct builtin_description *) bdesc_spe_predicates;
11594 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11595 if (d->code == fcode)
11596 return spe_expand_predicate_builtin (d->icode, exp, target);
11598 d = (struct builtin_description *) bdesc_spe_evsel;
11599 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11600 if (d->code == fcode)
11601 return spe_expand_evsel_builtin (d->icode, exp, target);
11605 case SPE_BUILTIN_EVSTDDX:
11606 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11607 case SPE_BUILTIN_EVSTDHX:
11608 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11609 case SPE_BUILTIN_EVSTDWX:
11610 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11611 case SPE_BUILTIN_EVSTWHEX:
11612 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11613 case SPE_BUILTIN_EVSTWHOX:
11614 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11615 case SPE_BUILTIN_EVSTWWEX:
11616 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11617 case SPE_BUILTIN_EVSTWWOX:
11618 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11619 case SPE_BUILTIN_EVSTDD:
11620 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11621 case SPE_BUILTIN_EVSTDH:
11622 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11623 case SPE_BUILTIN_EVSTDW:
11624 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11625 case SPE_BUILTIN_EVSTWHE:
11626 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11627 case SPE_BUILTIN_EVSTWHO:
11628 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11629 case SPE_BUILTIN_EVSTWWE:
11630 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11631 case SPE_BUILTIN_EVSTWWO:
11632 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11633 case SPE_BUILTIN_MFSPEFSCR:
11634 icode = CODE_FOR_spe_mfspefscr;
11635 tmode = insn_data[icode].operand[0].mode;
11638 || GET_MODE (target) != tmode
11639 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11640 target = gen_reg_rtx (tmode);
11642 pat = GEN_FCN (icode) (target);
11647 case SPE_BUILTIN_MTSPEFSCR:
11648 icode = CODE_FOR_spe_mtspefscr;
11649 arg0 = CALL_EXPR_ARG (exp, 0);
11650 op0 = expand_normal (arg0);
11651 mode0 = insn_data[icode].operand[0].mode;
11653 if (arg0 == error_mark_node)
11656 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11657 op0 = copy_to_mode_reg (mode0, op0);
11659 pat = GEN_FCN (icode) (op0);
11667 *expandedp = false;
11672 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11674 rtx pat, scratch, tmp;
11675 tree form = CALL_EXPR_ARG (exp, 0);
11676 tree arg0 = CALL_EXPR_ARG (exp, 1);
11677 tree arg1 = CALL_EXPR_ARG (exp, 2);
11678 rtx op0 = expand_normal (arg0);
11679 rtx op1 = expand_normal (arg1);
11680 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11681 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11683 enum rtx_code code;
11685 if (TREE_CODE (form) != INTEGER_CST)
11687 error ("argument 1 of __builtin_paired_predicate must be a constant");
11691 form_int = TREE_INT_CST_LOW (form);
11693 gcc_assert (mode0 == mode1);
11695 if (arg0 == error_mark_node || arg1 == error_mark_node)
11699 || GET_MODE (target) != SImode
11700 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11701 target = gen_reg_rtx (SImode);
11702 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11703 op0 = copy_to_mode_reg (mode0, op0);
11704 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11705 op1 = copy_to_mode_reg (mode1, op1);
11707 scratch = gen_reg_rtx (CCFPmode);
11709 pat = GEN_FCN (icode) (scratch, op0, op1);
11731 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11734 error ("argument 1 of __builtin_paired_predicate is out of range");
11738 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11739 emit_move_insn (target, tmp);
11744 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11746 rtx pat, scratch, tmp;
11747 tree form = CALL_EXPR_ARG (exp, 0);
11748 tree arg0 = CALL_EXPR_ARG (exp, 1);
11749 tree arg1 = CALL_EXPR_ARG (exp, 2);
11750 rtx op0 = expand_normal (arg0);
11751 rtx op1 = expand_normal (arg1);
11752 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11753 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11755 enum rtx_code code;
11757 if (TREE_CODE (form) != INTEGER_CST)
11759 error ("argument 1 of __builtin_spe_predicate must be a constant");
11763 form_int = TREE_INT_CST_LOW (form);
11765 gcc_assert (mode0 == mode1);
11767 if (arg0 == error_mark_node || arg1 == error_mark_node)
11771 || GET_MODE (target) != SImode
11772 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11773 target = gen_reg_rtx (SImode);
11775 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11776 op0 = copy_to_mode_reg (mode0, op0);
11777 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11778 op1 = copy_to_mode_reg (mode1, op1);
11780 scratch = gen_reg_rtx (CCmode);
11782 pat = GEN_FCN (icode) (scratch, op0, op1);
11787 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11788 _lower_. We use one compare, but look in different bits of the
11789 CR for each variant.
11791 There are 2 elements in each SPE simd type (upper/lower). The CR
11792 bits are set as follows:
11794 BIT0 | BIT 1 | BIT 2 | BIT 3
11795 U | L | (U | L) | (U & L)
11797 So, for an "all" relationship, BIT 3 would be set.
11798 For an "any" relationship, BIT 2 would be set. Etc.
11800 Following traditional nomenclature, these bits map to:
11802 BIT0 | BIT 1 | BIT 2 | BIT 3
11805 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11810 /* All variant. OV bit. */
11812 /* We need to get to the OV bit, which is the ORDERED bit. We
11813 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11814 that's ugly and will make validate_condition_mode die.
11815 So let's just use another pattern. */
11816 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11818 /* Any variant. EQ bit. */
11822 /* Upper variant. LT bit. */
11826 /* Lower variant. GT bit. */
11831 error ("argument 1 of __builtin_spe_predicate is out of range");
11835 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11836 emit_move_insn (target, tmp);
11841 /* The evsel builtins look like this:
11843 e = __builtin_spe_evsel_OP (a, b, c, d);
11845 and work like this:
11847 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11848 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11852 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11855 tree arg0 = CALL_EXPR_ARG (exp, 0);
11856 tree arg1 = CALL_EXPR_ARG (exp, 1);
11857 tree arg2 = CALL_EXPR_ARG (exp, 2);
11858 tree arg3 = CALL_EXPR_ARG (exp, 3);
11859 rtx op0 = expand_normal (arg0);
11860 rtx op1 = expand_normal (arg1);
11861 rtx op2 = expand_normal (arg2);
11862 rtx op3 = expand_normal (arg3);
11863 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11864 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11866 gcc_assert (mode0 == mode1);
11868 if (arg0 == error_mark_node || arg1 == error_mark_node
11869 || arg2 == error_mark_node || arg3 == error_mark_node)
11873 || GET_MODE (target) != mode0
11874 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11875 target = gen_reg_rtx (mode0);
11877 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11878 op0 = copy_to_mode_reg (mode0, op0);
11879 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11880 op1 = copy_to_mode_reg (mode0, op1);
11881 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11882 op2 = copy_to_mode_reg (mode0, op2);
11883 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11884 op3 = copy_to_mode_reg (mode0, op3);
11886 /* Generate the compare. */
11887 scratch = gen_reg_rtx (CCmode);
11888 pat = GEN_FCN (icode) (scratch, op0, op1);
11893 if (mode0 == V2SImode)
11894 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11896 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11901 /* Expand an expression EXP that calls a built-in function,
11902 with result going to TARGET if that's convenient
11903 (and in mode MODE if that's convenient).
11904 SUBTARGET may be used as the target for computing one of EXP's operands.
11905 IGNORE is nonzero if the value is to be ignored. */
11908 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11909 enum machine_mode mode ATTRIBUTE_UNUSED,
11910 int ignore ATTRIBUTE_UNUSED)
11912 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11913 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11914 const struct builtin_description *d;
11921 case RS6000_BUILTIN_RECIP:
11922 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11924 case RS6000_BUILTIN_RECIPF:
11925 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11927 case RS6000_BUILTIN_RSQRTF:
11928 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11930 case RS6000_BUILTIN_RSQRT:
11931 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11933 case RS6000_BUILTIN_BSWAP_HI:
11934 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11936 case POWER7_BUILTIN_BPERMD:
11937 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11938 ? CODE_FOR_bpermd_di
11939 : CODE_FOR_bpermd_si), exp, target);
11941 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11942 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11944 int icode = (int) CODE_FOR_altivec_lvsr;
11945 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11946 enum machine_mode mode = insn_data[icode].operand[1].mode;
11950 gcc_assert (TARGET_ALTIVEC);
11952 arg = CALL_EXPR_ARG (exp, 0);
11953 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11954 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11955 addr = memory_address (mode, op);
11956 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11960 /* For the load case need to negate the address. */
11961 op = gen_reg_rtx (GET_MODE (addr));
11962 emit_insn (gen_rtx_SET (VOIDmode, op,
11963 gen_rtx_NEG (GET_MODE (addr), addr)));
11965 op = gen_rtx_MEM (mode, op);
11968 || GET_MODE (target) != tmode
11969 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11970 target = gen_reg_rtx (tmode);
11972 /*pat = gen_altivec_lvsr (target, op);*/
11973 pat = GEN_FCN (icode) (target, op);
11981 case ALTIVEC_BUILTIN_VCFUX:
11982 case ALTIVEC_BUILTIN_VCFSX:
11983 case ALTIVEC_BUILTIN_VCTUXS:
11984 case ALTIVEC_BUILTIN_VCTSXS:
11985 /* FIXME: There's got to be a nicer way to handle this case than
11986 constructing a new CALL_EXPR. */
11987 if (call_expr_nargs (exp) == 1)
11989 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11990 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11998 if (TARGET_ALTIVEC)
12000 ret = altivec_expand_builtin (exp, target, &success);
12007 ret = spe_expand_builtin (exp, target, &success);
12012 if (TARGET_PAIRED_FLOAT)
12014 ret = paired_expand_builtin (exp, target, &success);
12020 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12022 /* Handle simple unary operations. */
12023 d = (struct builtin_description *) bdesc_1arg;
12024 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12025 if (d->code == fcode)
12026 return rs6000_expand_unop_builtin (d->icode, exp, target);
12028 /* Handle simple binary operations. */
12029 d = (struct builtin_description *) bdesc_2arg;
12030 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12031 if (d->code == fcode)
12032 return rs6000_expand_binop_builtin (d->icode, exp, target);
12034 /* Handle simple ternary operations. */
12036 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12037 if (d->code == fcode)
12038 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12040 gcc_unreachable ();
12044 rs6000_init_builtins (void)
12049 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12050 V2SF_type_node = build_vector_type (float_type_node, 2);
12051 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12052 V2DF_type_node = build_vector_type (double_type_node, 2);
12053 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12054 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12055 V4SF_type_node = build_vector_type (float_type_node, 4);
12056 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12057 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12059 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12060 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12061 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12062 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12064 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12065 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12066 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12067 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12069 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12070 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12071 'vector unsigned short'. */
12073 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12074 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12075 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12076 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12077 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12079 long_integer_type_internal_node = long_integer_type_node;
12080 long_unsigned_type_internal_node = long_unsigned_type_node;
12081 intQI_type_internal_node = intQI_type_node;
12082 uintQI_type_internal_node = unsigned_intQI_type_node;
12083 intHI_type_internal_node = intHI_type_node;
12084 uintHI_type_internal_node = unsigned_intHI_type_node;
12085 intSI_type_internal_node = intSI_type_node;
12086 uintSI_type_internal_node = unsigned_intSI_type_node;
12087 intDI_type_internal_node = intDI_type_node;
12088 uintDI_type_internal_node = unsigned_intDI_type_node;
12089 float_type_internal_node = float_type_node;
12090 double_type_internal_node = float_type_node;
12091 void_type_internal_node = void_type_node;
12093 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12095 builtin_mode_to_type[QImode][0] = integer_type_node;
12096 builtin_mode_to_type[HImode][0] = integer_type_node;
12097 builtin_mode_to_type[SImode][0] = intSI_type_node;
12098 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12099 builtin_mode_to_type[DImode][0] = intDI_type_node;
12100 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12101 builtin_mode_to_type[SFmode][0] = float_type_node;
12102 builtin_mode_to_type[DFmode][0] = double_type_node;
12103 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12104 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12105 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12106 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12107 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12108 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12109 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12110 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12111 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12112 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12113 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12114 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12115 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12117 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12118 get_identifier ("__bool char"),
12119 bool_char_type_node);
12120 TYPE_NAME (bool_char_type_node) = tdecl;
12121 (*lang_hooks.decls.pushdecl) (tdecl);
12122 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12123 get_identifier ("__bool short"),
12124 bool_short_type_node);
12125 TYPE_NAME (bool_short_type_node) = tdecl;
12126 (*lang_hooks.decls.pushdecl) (tdecl);
12127 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12128 get_identifier ("__bool int"),
12129 bool_int_type_node);
12130 TYPE_NAME (bool_int_type_node) = tdecl;
12131 (*lang_hooks.decls.pushdecl) (tdecl);
12132 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12134 TYPE_NAME (pixel_type_node) = tdecl;
12135 (*lang_hooks.decls.pushdecl) (tdecl);
12137 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12138 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12139 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12140 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12141 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12143 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12144 get_identifier ("__vector unsigned char"),
12145 unsigned_V16QI_type_node);
12146 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12147 (*lang_hooks.decls.pushdecl) (tdecl);
12148 tdecl = build_decl (BUILTINS_LOCATION,
12149 TYPE_DECL, get_identifier ("__vector signed char"),
12151 TYPE_NAME (V16QI_type_node) = tdecl;
12152 (*lang_hooks.decls.pushdecl) (tdecl);
12153 tdecl = build_decl (BUILTINS_LOCATION,
12154 TYPE_DECL, get_identifier ("__vector __bool char"),
12155 bool_V16QI_type_node);
12156 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12157 (*lang_hooks.decls.pushdecl) (tdecl);
12159 tdecl = build_decl (BUILTINS_LOCATION,
12160 TYPE_DECL, get_identifier ("__vector unsigned short"),
12161 unsigned_V8HI_type_node);
12162 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12163 (*lang_hooks.decls.pushdecl) (tdecl);
12164 tdecl = build_decl (BUILTINS_LOCATION,
12165 TYPE_DECL, get_identifier ("__vector signed short"),
12167 TYPE_NAME (V8HI_type_node) = tdecl;
12168 (*lang_hooks.decls.pushdecl) (tdecl);
12169 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12170 get_identifier ("__vector __bool short"),
12171 bool_V8HI_type_node);
12172 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12173 (*lang_hooks.decls.pushdecl) (tdecl);
12175 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12176 get_identifier ("__vector unsigned int"),
12177 unsigned_V4SI_type_node);
12178 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12179 (*lang_hooks.decls.pushdecl) (tdecl);
12180 tdecl = build_decl (BUILTINS_LOCATION,
12181 TYPE_DECL, get_identifier ("__vector signed int"),
12183 TYPE_NAME (V4SI_type_node) = tdecl;
12184 (*lang_hooks.decls.pushdecl) (tdecl);
12185 tdecl = build_decl (BUILTINS_LOCATION,
12186 TYPE_DECL, get_identifier ("__vector __bool int"),
12187 bool_V4SI_type_node);
12188 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12189 (*lang_hooks.decls.pushdecl) (tdecl);
12191 tdecl = build_decl (BUILTINS_LOCATION,
12192 TYPE_DECL, get_identifier ("__vector float"),
12194 TYPE_NAME (V4SF_type_node) = tdecl;
12195 (*lang_hooks.decls.pushdecl) (tdecl);
12196 tdecl = build_decl (BUILTINS_LOCATION,
12197 TYPE_DECL, get_identifier ("__vector __pixel"),
12198 pixel_V8HI_type_node);
12199 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12200 (*lang_hooks.decls.pushdecl) (tdecl);
12204 tdecl = build_decl (BUILTINS_LOCATION,
12205 TYPE_DECL, get_identifier ("__vector double"),
12207 TYPE_NAME (V2DF_type_node) = tdecl;
12208 (*lang_hooks.decls.pushdecl) (tdecl);
12210 tdecl = build_decl (BUILTINS_LOCATION,
12211 TYPE_DECL, get_identifier ("__vector long"),
12213 TYPE_NAME (V2DI_type_node) = tdecl;
12214 (*lang_hooks.decls.pushdecl) (tdecl);
12216 tdecl = build_decl (BUILTINS_LOCATION,
12217 TYPE_DECL, get_identifier ("__vector unsigned long"),
12218 unsigned_V2DI_type_node);
12219 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12220 (*lang_hooks.decls.pushdecl) (tdecl);
12222 tdecl = build_decl (BUILTINS_LOCATION,
12223 TYPE_DECL, get_identifier ("__vector __bool long"),
12224 bool_V2DI_type_node);
12225 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12226 (*lang_hooks.decls.pushdecl) (tdecl);
12229 if (TARGET_PAIRED_FLOAT)
12230 paired_init_builtins ();
12232 spe_init_builtins ();
12233 if (TARGET_ALTIVEC)
12234 altivec_init_builtins ();
12235 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12236 rs6000_common_init_builtins ();
12239 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12240 RS6000_BUILTIN_RECIP,
12241 "__builtin_recipdiv");
12242 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12243 RS6000_BUILTIN_RECIP);
12247 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12248 RS6000_BUILTIN_RECIPF,
12249 "__builtin_recipdivf");
12250 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12251 RS6000_BUILTIN_RECIPF);
12253 if (TARGET_FRSQRTE)
12255 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12256 RS6000_BUILTIN_RSQRT,
12257 "__builtin_rsqrt");
12258 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12259 RS6000_BUILTIN_RSQRT);
12261 if (TARGET_FRSQRTES)
12263 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12264 RS6000_BUILTIN_RSQRTF,
12265 "__builtin_rsqrtf");
12266 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12267 RS6000_BUILTIN_RSQRTF);
12269 if (TARGET_POPCNTD)
12271 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12272 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12273 POWER7_BUILTIN_BPERMD,
12274 "__builtin_bpermd");
12275 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12276 POWER7_BUILTIN_BPERMD);
12278 if (TARGET_POWERPC)
12280 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12281 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12282 unsigned_intHI_type_node,
12284 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12285 RS6000_BUILTIN_BSWAP_HI);
12289 /* AIX libm provides clog as __clog. */
12290 if (built_in_decls [BUILT_IN_CLOG])
12291 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12294 #ifdef SUBTARGET_INIT_BUILTINS
12295 SUBTARGET_INIT_BUILTINS;
12299 /* Returns the rs6000 builtin decl for CODE. */
12302 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12304 if (code >= RS6000_BUILTIN_COUNT)
12305 return error_mark_node;
12307 return rs6000_builtin_decls[code];
12310 /* Search through a set of builtins and enable the mask bits.
12311 DESC is an array of builtins.
12312 SIZE is the total number of builtins.
12313 START is the builtin enum at which to start.
12314 END is the builtin enum at which to end. */
12316 enable_mask_for_builtins (struct builtin_description *desc, int size,
12317 enum rs6000_builtins start,
12318 enum rs6000_builtins end)
12322 for (i = 0; i < size; ++i)
12323 if (desc[i].code == start)
12329 for (; i < size; ++i)
12331 /* Flip all the bits on. */
12332 desc[i].mask = target_flags;
12333 if (desc[i].code == end)
12339 spe_init_builtins (void)
12341 tree endlink = void_list_node;
12342 tree puint_type_node = build_pointer_type (unsigned_type_node);
12343 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12344 struct builtin_description *d;
12347 tree v2si_ftype_4_v2si
12348 = build_function_type
12349 (opaque_V2SI_type_node,
12350 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12351 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12352 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12353 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12356 tree v2sf_ftype_4_v2sf
12357 = build_function_type
12358 (opaque_V2SF_type_node,
12359 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12360 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12361 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12362 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12365 tree int_ftype_int_v2si_v2si
12366 = build_function_type
12367 (integer_type_node,
12368 tree_cons (NULL_TREE, integer_type_node,
12369 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12370 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12373 tree int_ftype_int_v2sf_v2sf
12374 = build_function_type
12375 (integer_type_node,
12376 tree_cons (NULL_TREE, integer_type_node,
12377 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12378 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12381 tree void_ftype_v2si_puint_int
12382 = build_function_type (void_type_node,
12383 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12384 tree_cons (NULL_TREE, puint_type_node,
12385 tree_cons (NULL_TREE,
12389 tree void_ftype_v2si_puint_char
12390 = build_function_type (void_type_node,
12391 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12392 tree_cons (NULL_TREE, puint_type_node,
12393 tree_cons (NULL_TREE,
12397 tree void_ftype_v2si_pv2si_int
12398 = build_function_type (void_type_node,
12399 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12400 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12401 tree_cons (NULL_TREE,
12405 tree void_ftype_v2si_pv2si_char
12406 = build_function_type (void_type_node,
12407 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12408 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12409 tree_cons (NULL_TREE,
12413 tree void_ftype_int
12414 = build_function_type (void_type_node,
12415 tree_cons (NULL_TREE, integer_type_node, endlink));
12417 tree int_ftype_void
12418 = build_function_type (integer_type_node, endlink);
12420 tree v2si_ftype_pv2si_int
12421 = build_function_type (opaque_V2SI_type_node,
12422 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12423 tree_cons (NULL_TREE, integer_type_node,
12426 tree v2si_ftype_puint_int
12427 = build_function_type (opaque_V2SI_type_node,
12428 tree_cons (NULL_TREE, puint_type_node,
12429 tree_cons (NULL_TREE, integer_type_node,
12432 tree v2si_ftype_pushort_int
12433 = build_function_type (opaque_V2SI_type_node,
12434 tree_cons (NULL_TREE, pushort_type_node,
12435 tree_cons (NULL_TREE, integer_type_node,
12438 tree v2si_ftype_signed_char
12439 = build_function_type (opaque_V2SI_type_node,
12440 tree_cons (NULL_TREE, signed_char_type_node,
12443 /* The initialization of the simple binary and unary builtins is
12444 done in rs6000_common_init_builtins, but we have to enable the
12445 mask bits here manually because we have run out of `target_flags'
12446 bits. We really need to redesign this mask business. */
12448 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12449 ARRAY_SIZE (bdesc_2arg),
12450 SPE_BUILTIN_EVADDW,
12451 SPE_BUILTIN_EVXOR);
12452 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12453 ARRAY_SIZE (bdesc_1arg),
12455 SPE_BUILTIN_EVSUBFUSIAAW);
12456 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12457 ARRAY_SIZE (bdesc_spe_predicates),
12458 SPE_BUILTIN_EVCMPEQ,
12459 SPE_BUILTIN_EVFSTSTLT);
12460 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12461 ARRAY_SIZE (bdesc_spe_evsel),
12462 SPE_BUILTIN_EVSEL_CMPGTS,
12463 SPE_BUILTIN_EVSEL_FSTSTEQ);
12465 (*lang_hooks.decls.pushdecl)
12466 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12467 get_identifier ("__ev64_opaque__"),
12468 opaque_V2SI_type_node));
12470 /* Initialize irregular SPE builtins. */
12472 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12473 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12474 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12475 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12476 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12477 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12478 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12479 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12480 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12481 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12482 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12483 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12484 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12485 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12486 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12487 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12488 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12489 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12492 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12493 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12494 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12495 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12496 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12497 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12498 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12499 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12500 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12501 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12502 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12503 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12504 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12505 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12506 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12507 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12508 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12509 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12510 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12511 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12512 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12513 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12516 d = (struct builtin_description *) bdesc_spe_predicates;
12517 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12521 switch (insn_data[d->icode].operand[1].mode)
12524 type = int_ftype_int_v2si_v2si;
12527 type = int_ftype_int_v2sf_v2sf;
12530 gcc_unreachable ();
12533 def_builtin (d->mask, d->name, type, d->code);
12536 /* Evsel predicates. */
12537 d = (struct builtin_description *) bdesc_spe_evsel;
12538 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12542 switch (insn_data[d->icode].operand[1].mode)
12545 type = v2si_ftype_4_v2si;
12548 type = v2sf_ftype_4_v2sf;
12551 gcc_unreachable ();
12554 def_builtin (d->mask, d->name, type, d->code);
12559 paired_init_builtins (void)
12561 const struct builtin_description *d;
12563 tree endlink = void_list_node;
12565 tree int_ftype_int_v2sf_v2sf
12566 = build_function_type
12567 (integer_type_node,
12568 tree_cons (NULL_TREE, integer_type_node,
12569 tree_cons (NULL_TREE, V2SF_type_node,
12570 tree_cons (NULL_TREE, V2SF_type_node,
12572 tree pcfloat_type_node =
12573 build_pointer_type (build_qualified_type
12574 (float_type_node, TYPE_QUAL_CONST));
12576 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12577 long_integer_type_node,
12580 tree void_ftype_v2sf_long_pcfloat =
12581 build_function_type_list (void_type_node,
12583 long_integer_type_node,
12588 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12589 PAIRED_BUILTIN_LX);
12592 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12593 PAIRED_BUILTIN_STX);
12596 d = bdesc_paired_preds;
12597 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12601 switch (insn_data[d->icode].operand[1].mode)
12604 type = int_ftype_int_v2sf_v2sf;
12607 gcc_unreachable ();
12610 def_builtin (d->mask, d->name, type, d->code);
12615 altivec_init_builtins (void)
12617 const struct builtin_description *d;
12618 const struct builtin_description_predicates *dp;
12622 tree pfloat_type_node = build_pointer_type (float_type_node);
12623 tree pint_type_node = build_pointer_type (integer_type_node);
12624 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12625 tree pchar_type_node = build_pointer_type (char_type_node);
12627 tree pvoid_type_node = build_pointer_type (void_type_node);
12629 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12630 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12631 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12632 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12634 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12636 tree int_ftype_opaque
12637 = build_function_type_list (integer_type_node,
12638 opaque_V4SI_type_node, NULL_TREE);
12639 tree opaque_ftype_opaque
12640 = build_function_type (integer_type_node,
12642 tree opaque_ftype_opaque_int
12643 = build_function_type_list (opaque_V4SI_type_node,
12644 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12645 tree opaque_ftype_opaque_opaque_int
12646 = build_function_type_list (opaque_V4SI_type_node,
12647 opaque_V4SI_type_node, opaque_V4SI_type_node,
12648 integer_type_node, NULL_TREE);
12649 tree int_ftype_int_opaque_opaque
12650 = build_function_type_list (integer_type_node,
12651 integer_type_node, opaque_V4SI_type_node,
12652 opaque_V4SI_type_node, NULL_TREE);
12653 tree int_ftype_int_v4si_v4si
12654 = build_function_type_list (integer_type_node,
12655 integer_type_node, V4SI_type_node,
12656 V4SI_type_node, NULL_TREE);
12657 tree v4sf_ftype_pcfloat
12658 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12659 tree void_ftype_pfloat_v4sf
12660 = build_function_type_list (void_type_node,
12661 pfloat_type_node, V4SF_type_node, NULL_TREE);
12662 tree v4si_ftype_pcint
12663 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12664 tree void_ftype_pint_v4si
12665 = build_function_type_list (void_type_node,
12666 pint_type_node, V4SI_type_node, NULL_TREE);
12667 tree v8hi_ftype_pcshort
12668 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12669 tree void_ftype_pshort_v8hi
12670 = build_function_type_list (void_type_node,
12671 pshort_type_node, V8HI_type_node, NULL_TREE);
12672 tree v16qi_ftype_pcchar
12673 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12674 tree void_ftype_pchar_v16qi
12675 = build_function_type_list (void_type_node,
12676 pchar_type_node, V16QI_type_node, NULL_TREE);
12677 tree void_ftype_v4si
12678 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12679 tree v8hi_ftype_void
12680 = build_function_type (V8HI_type_node, void_list_node);
12681 tree void_ftype_void
12682 = build_function_type (void_type_node, void_list_node);
12683 tree void_ftype_int
12684 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12686 tree opaque_ftype_long_pcvoid
12687 = build_function_type_list (opaque_V4SI_type_node,
12688 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12689 tree v16qi_ftype_long_pcvoid
12690 = build_function_type_list (V16QI_type_node,
12691 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12692 tree v8hi_ftype_long_pcvoid
12693 = build_function_type_list (V8HI_type_node,
12694 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12695 tree v4si_ftype_long_pcvoid
12696 = build_function_type_list (V4SI_type_node,
12697 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12699 tree void_ftype_opaque_long_pvoid
12700 = build_function_type_list (void_type_node,
12701 opaque_V4SI_type_node, long_integer_type_node,
12702 pvoid_type_node, NULL_TREE);
12703 tree void_ftype_v4si_long_pvoid
12704 = build_function_type_list (void_type_node,
12705 V4SI_type_node, long_integer_type_node,
12706 pvoid_type_node, NULL_TREE);
12707 tree void_ftype_v16qi_long_pvoid
12708 = build_function_type_list (void_type_node,
12709 V16QI_type_node, long_integer_type_node,
12710 pvoid_type_node, NULL_TREE);
12711 tree void_ftype_v8hi_long_pvoid
12712 = build_function_type_list (void_type_node,
12713 V8HI_type_node, long_integer_type_node,
12714 pvoid_type_node, NULL_TREE);
12715 tree int_ftype_int_v8hi_v8hi
12716 = build_function_type_list (integer_type_node,
12717 integer_type_node, V8HI_type_node,
12718 V8HI_type_node, NULL_TREE);
12719 tree int_ftype_int_v16qi_v16qi
12720 = build_function_type_list (integer_type_node,
12721 integer_type_node, V16QI_type_node,
12722 V16QI_type_node, NULL_TREE);
12723 tree int_ftype_int_v4sf_v4sf
12724 = build_function_type_list (integer_type_node,
12725 integer_type_node, V4SF_type_node,
12726 V4SF_type_node, NULL_TREE);
12727 tree int_ftype_int_v2df_v2df
12728 = build_function_type_list (integer_type_node,
12729 integer_type_node, V2DF_type_node,
12730 V2DF_type_node, NULL_TREE);
12731 tree v4si_ftype_v4si
12732 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12733 tree v8hi_ftype_v8hi
12734 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12735 tree v16qi_ftype_v16qi
12736 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12737 tree v4sf_ftype_v4sf
12738 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12739 tree v2df_ftype_v2df
12740 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12741 tree void_ftype_pcvoid_int_int
12742 = build_function_type_list (void_type_node,
12743 pcvoid_type_node, integer_type_node,
12744 integer_type_node, NULL_TREE);
12746 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12747 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12748 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12749 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12750 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12751 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12752 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12753 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12754 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12755 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12756 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12757 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12758 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12759 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12760 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12761 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12762 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12763 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12764 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12765 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12766 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12767 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12768 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12769 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12770 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12771 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12772 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12773 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12774 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12775 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12776 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12777 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12778 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12779 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12780 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12781 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12782 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12783 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12784 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12785 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12786 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12787 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12788 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12789 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12790 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12791 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12793 if (rs6000_cpu == PROCESSOR_CELL)
12795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12800 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12801 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12802 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12803 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12805 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12806 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12807 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12808 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12810 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12811 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12812 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12813 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12815 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12816 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12817 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12819 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12820 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12821 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12822 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12823 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12824 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12825 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12826 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12827 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12828 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12829 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12830 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12832 /* Add the DST variants. */
12834 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12835 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12837 /* Initialize the predicates. */
12838 dp = bdesc_altivec_preds;
12839 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12841 enum machine_mode mode1;
12843 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12844 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12845 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12846 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12851 mode1 = insn_data[dp->icode].operand[1].mode;
12856 type = int_ftype_int_opaque_opaque;
12859 type = int_ftype_int_v4si_v4si;
12862 type = int_ftype_int_v8hi_v8hi;
12865 type = int_ftype_int_v16qi_v16qi;
12868 type = int_ftype_int_v4sf_v4sf;
12871 type = int_ftype_int_v2df_v2df;
12874 gcc_unreachable ();
12877 def_builtin (dp->mask, dp->name, type, dp->code);
12880 /* Initialize the abs* operators. */
12882 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12884 enum machine_mode mode0;
12887 mode0 = insn_data[d->icode].operand[0].mode;
12892 type = v4si_ftype_v4si;
12895 type = v8hi_ftype_v8hi;
12898 type = v16qi_ftype_v16qi;
12901 type = v4sf_ftype_v4sf;
12904 type = v2df_ftype_v2df;
12907 gcc_unreachable ();
12910 def_builtin (d->mask, d->name, type, d->code);
12913 if (TARGET_ALTIVEC)
12917 /* Initialize target builtin that implements
12918 targetm.vectorize.builtin_mask_for_load. */
12920 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12921 v16qi_ftype_long_pcvoid,
12922 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12923 BUILT_IN_MD, NULL, NULL_TREE);
12924 TREE_READONLY (decl) = 1;
12925 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12926 altivec_builtin_mask_for_load = decl;
12929 /* Access to the vec_init patterns. */
12930 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12931 integer_type_node, integer_type_node,
12932 integer_type_node, NULL_TREE);
12933 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12934 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12936 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12937 short_integer_type_node,
12938 short_integer_type_node,
12939 short_integer_type_node,
12940 short_integer_type_node,
12941 short_integer_type_node,
12942 short_integer_type_node,
12943 short_integer_type_node, NULL_TREE);
12944 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12945 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12947 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12948 char_type_node, char_type_node,
12949 char_type_node, char_type_node,
12950 char_type_node, char_type_node,
12951 char_type_node, char_type_node,
12952 char_type_node, char_type_node,
12953 char_type_node, char_type_node,
12954 char_type_node, char_type_node,
12955 char_type_node, NULL_TREE);
12956 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12957 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12959 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12960 float_type_node, float_type_node,
12961 float_type_node, NULL_TREE);
12962 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12963 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12967 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12968 double_type_node, NULL_TREE);
12969 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12970 VSX_BUILTIN_VEC_INIT_V2DF);
12972 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12973 intDI_type_node, NULL_TREE);
12974 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12975 VSX_BUILTIN_VEC_INIT_V2DI);
12978 /* Access to the vec_set patterns. */
12979 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12981 integer_type_node, NULL_TREE);
12982 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12983 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12985 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12987 integer_type_node, NULL_TREE);
12988 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12989 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12991 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12993 integer_type_node, NULL_TREE);
12994 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12995 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12997 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12999 integer_type_node, NULL_TREE);
13000 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13001 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13005 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13007 integer_type_node, NULL_TREE);
13008 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13009 VSX_BUILTIN_VEC_SET_V2DF);
13011 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13013 integer_type_node, NULL_TREE);
13014 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13015 VSX_BUILTIN_VEC_SET_V2DI);
13018 /* Access to the vec_extract patterns. */
13019 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13020 integer_type_node, NULL_TREE);
13021 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13022 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13024 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13025 integer_type_node, NULL_TREE);
13026 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13027 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13029 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13030 integer_type_node, NULL_TREE);
13031 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13032 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13034 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13035 integer_type_node, NULL_TREE);
13036 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13037 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13041 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13042 integer_type_node, NULL_TREE);
13043 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13044 VSX_BUILTIN_VEC_EXT_V2DF);
13046 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13047 integer_type_node, NULL_TREE);
13048 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13049 VSX_BUILTIN_VEC_EXT_V2DI);
13053 /* Hash function for builtin functions with up to 3 arguments and a return
13056 builtin_hash_function (const void *hash_entry)
13060 const struct builtin_hash_struct *bh =
13061 (const struct builtin_hash_struct *) hash_entry;
13063 for (i = 0; i < 4; i++)
13065 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13066 ret = (ret * 2) + bh->uns_p[i];
13072 /* Compare builtin hash entries H1 and H2 for equivalence. */
13074 builtin_hash_eq (const void *h1, const void *h2)
13076 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13077 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13079 return ((p1->mode[0] == p2->mode[0])
13080 && (p1->mode[1] == p2->mode[1])
13081 && (p1->mode[2] == p2->mode[2])
13082 && (p1->mode[3] == p2->mode[3])
13083 && (p1->uns_p[0] == p2->uns_p[0])
13084 && (p1->uns_p[1] == p2->uns_p[1])
13085 && (p1->uns_p[2] == p2->uns_p[2])
13086 && (p1->uns_p[3] == p2->uns_p[3]));
13089 /* Map types for builtin functions with an explicit return type and up to 3
13090 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13091 of the argument. */
13093 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13094 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13095 enum rs6000_builtins builtin, const char *name)
13097 struct builtin_hash_struct h;
13098 struct builtin_hash_struct *h2;
13102 tree ret_type = NULL_TREE;
13103 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13106 /* Create builtin_hash_table. */
13107 if (builtin_hash_table == NULL)
13108 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13109 builtin_hash_eq, NULL);
13111 h.type = NULL_TREE;
13112 h.mode[0] = mode_ret;
13113 h.mode[1] = mode_arg0;
13114 h.mode[2] = mode_arg1;
13115 h.mode[3] = mode_arg2;
13121 /* If the builtin is a type that produces unsigned results or takes unsigned
13122 arguments, and it is returned as a decl for the vectorizer (such as
13123 widening multiplies, permute), make sure the arguments and return value
13124 are type correct. */
13127 /* unsigned 2 argument functions. */
13128 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13129 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13130 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13131 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13137 /* unsigned 3 argument functions. */
13138 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13139 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13140 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13141 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13142 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13143 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13144 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13145 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13146 case VSX_BUILTIN_VPERM_16QI_UNS:
13147 case VSX_BUILTIN_VPERM_8HI_UNS:
13148 case VSX_BUILTIN_VPERM_4SI_UNS:
13149 case VSX_BUILTIN_VPERM_2DI_UNS:
13150 case VSX_BUILTIN_XXSEL_16QI_UNS:
13151 case VSX_BUILTIN_XXSEL_8HI_UNS:
13152 case VSX_BUILTIN_XXSEL_4SI_UNS:
13153 case VSX_BUILTIN_XXSEL_2DI_UNS:
13160 /* signed permute functions with unsigned char mask. */
13161 case ALTIVEC_BUILTIN_VPERM_16QI:
13162 case ALTIVEC_BUILTIN_VPERM_8HI:
13163 case ALTIVEC_BUILTIN_VPERM_4SI:
13164 case ALTIVEC_BUILTIN_VPERM_4SF:
13165 case ALTIVEC_BUILTIN_VPERM_2DI:
13166 case ALTIVEC_BUILTIN_VPERM_2DF:
13167 case VSX_BUILTIN_VPERM_16QI:
13168 case VSX_BUILTIN_VPERM_8HI:
13169 case VSX_BUILTIN_VPERM_4SI:
13170 case VSX_BUILTIN_VPERM_4SF:
13171 case VSX_BUILTIN_VPERM_2DI:
13172 case VSX_BUILTIN_VPERM_2DF:
13176 /* unsigned args, signed return. */
13177 case VSX_BUILTIN_XVCVUXDDP_UNS:
13178 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13182 /* signed args, unsigned return. */
13183 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13184 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13192 /* Figure out how many args are present. */
13193 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13197 fatal_error ("internal error: builtin function %s had no type", name);
13199 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13200 if (!ret_type && h.uns_p[0])
13201 ret_type = builtin_mode_to_type[h.mode[0]][0];
13204 fatal_error ("internal error: builtin function %s had an unexpected "
13205 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13207 for (i = 0; i < num_args; i++)
13209 int m = (int) h.mode[i+1];
13210 int uns_p = h.uns_p[i+1];
13212 arg_type[i] = builtin_mode_to_type[m][uns_p];
13213 if (!arg_type[i] && uns_p)
13214 arg_type[i] = builtin_mode_to_type[m][0];
13217 fatal_error ("internal error: builtin function %s, argument %d "
13218 "had unexpected argument type %s", name, i,
13219 GET_MODE_NAME (m));
13222 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13223 if (*found == NULL)
13225 h2 = ggc_alloc_builtin_hash_struct ();
13227 *found = (void *)h2;
13228 args = void_list_node;
13230 for (i = num_args - 1; i >= 0; i--)
13231 args = tree_cons (NULL_TREE, arg_type[i], args);
13233 h2->type = build_function_type (ret_type, args);
13236 return ((struct builtin_hash_struct *)(*found))->type;
13240 rs6000_common_init_builtins (void)
13242 const struct builtin_description *d;
13245 tree opaque_ftype_opaque = NULL_TREE;
13246 tree opaque_ftype_opaque_opaque = NULL_TREE;
13247 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13248 tree v2si_ftype_qi = NULL_TREE;
13249 tree v2si_ftype_v2si_qi = NULL_TREE;
13250 tree v2si_ftype_int_qi = NULL_TREE;
13252 if (!TARGET_PAIRED_FLOAT)
13254 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13255 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13258 /* Add the ternary operators. */
13260 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13263 int mask = d->mask;
13265 if ((mask != 0 && (mask & target_flags) == 0)
13266 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13269 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13270 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13271 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13272 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13274 if (! (type = opaque_ftype_opaque_opaque_opaque))
13275 type = opaque_ftype_opaque_opaque_opaque
13276 = build_function_type_list (opaque_V4SI_type_node,
13277 opaque_V4SI_type_node,
13278 opaque_V4SI_type_node,
13279 opaque_V4SI_type_node,
13284 enum insn_code icode = d->icode;
13285 if (d->name == 0 || icode == CODE_FOR_nothing)
13288 type = builtin_function_type (insn_data[icode].operand[0].mode,
13289 insn_data[icode].operand[1].mode,
13290 insn_data[icode].operand[2].mode,
13291 insn_data[icode].operand[3].mode,
13295 def_builtin (d->mask, d->name, type, d->code);
13298 /* Add the binary operators. */
13300 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13302 enum machine_mode mode0, mode1, mode2;
13304 int mask = d->mask;
13306 if ((mask != 0 && (mask & target_flags) == 0)
13307 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13310 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13311 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13312 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13313 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13315 if (! (type = opaque_ftype_opaque_opaque))
13316 type = opaque_ftype_opaque_opaque
13317 = build_function_type_list (opaque_V4SI_type_node,
13318 opaque_V4SI_type_node,
13319 opaque_V4SI_type_node,
13324 enum insn_code icode = d->icode;
13325 if (d->name == 0 || icode == CODE_FOR_nothing)
13328 mode0 = insn_data[icode].operand[0].mode;
13329 mode1 = insn_data[icode].operand[1].mode;
13330 mode2 = insn_data[icode].operand[2].mode;
13332 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13334 if (! (type = v2si_ftype_v2si_qi))
13335 type = v2si_ftype_v2si_qi
13336 = build_function_type_list (opaque_V2SI_type_node,
13337 opaque_V2SI_type_node,
13342 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13343 && mode2 == QImode)
13345 if (! (type = v2si_ftype_int_qi))
13346 type = v2si_ftype_int_qi
13347 = build_function_type_list (opaque_V2SI_type_node,
13354 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13358 def_builtin (d->mask, d->name, type, d->code);
13361 /* Add the simple unary operators. */
13362 d = (struct builtin_description *) bdesc_1arg;
13363 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13365 enum machine_mode mode0, mode1;
13367 int mask = d->mask;
13369 if ((mask != 0 && (mask & target_flags) == 0)
13370 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13373 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13374 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13375 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13376 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13378 if (! (type = opaque_ftype_opaque))
13379 type = opaque_ftype_opaque
13380 = build_function_type_list (opaque_V4SI_type_node,
13381 opaque_V4SI_type_node,
13386 enum insn_code icode = d->icode;
13387 if (d->name == 0 || icode == CODE_FOR_nothing)
13390 mode0 = insn_data[icode].operand[0].mode;
13391 mode1 = insn_data[icode].operand[1].mode;
13393 if (mode0 == V2SImode && mode1 == QImode)
13395 if (! (type = v2si_ftype_qi))
13396 type = v2si_ftype_qi
13397 = build_function_type_list (opaque_V2SI_type_node,
13403 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13407 def_builtin (d->mask, d->name, type, d->code);
13412 rs6000_init_libfuncs (void)
13414 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13415 && !TARGET_POWER2 && !TARGET_POWERPC)
13417 /* AIX library routines for float->int conversion. */
13418 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13419 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13420 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13421 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13424 if (!TARGET_IEEEQUAD)
13425 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13426 if (!TARGET_XL_COMPAT)
13428 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13429 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13430 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13431 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13433 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13435 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13436 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13437 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13438 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13439 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13440 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13441 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13443 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13444 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13445 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13446 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13447 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13448 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13449 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13450 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13453 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13454 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13458 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13459 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13460 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13461 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13465 /* 32-bit SVR4 quad floating point routines. */
13467 set_optab_libfunc (add_optab, TFmode, "_q_add");
13468 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13469 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13470 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13471 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13472 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13473 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13475 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13476 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13477 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13478 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13479 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13480 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13482 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13483 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13484 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13485 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13486 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13487 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13488 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13489 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13494 /* Expand a block clear operation, and return 1 if successful. Return 0
13495 if we should let the compiler generate normal code.
13497 operands[0] is the destination
13498 operands[1] is the length
13499 operands[3] is the alignment */
13502 expand_block_clear (rtx operands[])
13504 rtx orig_dest = operands[0];
13505 rtx bytes_rtx = operands[1];
13506 rtx align_rtx = operands[3];
13507 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13508 HOST_WIDE_INT align;
13509 HOST_WIDE_INT bytes;
13514 /* If this is not a fixed size move, just call memcpy */
13518 /* This must be a fixed size alignment */
13519 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13520 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13522 /* Anything to clear? */
13523 bytes = INTVAL (bytes_rtx);
13527 /* Use the builtin memset after a point, to avoid huge code bloat.
13528 When optimize_size, avoid any significant code bloat; calling
13529 memset is about 4 instructions, so allow for one instruction to
13530 load zero and three to do clearing. */
13531 if (TARGET_ALTIVEC && align >= 128)
13533 else if (TARGET_POWERPC64 && align >= 32)
13535 else if (TARGET_SPE && align >= 64)
13540 if (optimize_size && bytes > 3 * clear_step)
13542 if (! optimize_size && bytes > 8 * clear_step)
13545 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13547 enum machine_mode mode = BLKmode;
13550 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13555 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13560 else if (bytes >= 8 && TARGET_POWERPC64
13561 /* 64-bit loads and stores require word-aligned
13563 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13568 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13569 { /* move 4 bytes */
13573 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13574 { /* move 2 bytes */
13578 else /* move 1 byte at a time */
13584 dest = adjust_address (orig_dest, mode, offset);
13586 emit_move_insn (dest, CONST0_RTX (mode));
13593 /* Expand a block move operation, and return 1 if successful. Return 0
13594 if we should let the compiler generate normal code.
13596 operands[0] is the destination
13597 operands[1] is the source
13598 operands[2] is the length
13599 operands[3] is the alignment */
13601 #define MAX_MOVE_REG 4
13604 expand_block_move (rtx operands[])
13606 rtx orig_dest = operands[0];
13607 rtx orig_src = operands[1];
13608 rtx bytes_rtx = operands[2];
13609 rtx align_rtx = operands[3];
13610 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13615 rtx stores[MAX_MOVE_REG];
13618 /* If this is not a fixed size move, just call memcpy */
13622 /* This must be a fixed size alignment */
13623 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13624 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13626 /* Anything to move? */
13627 bytes = INTVAL (bytes_rtx);
13631 if (bytes > rs6000_block_move_inline_limit)
13634 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13637 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13638 rtx (*mov) (rtx, rtx);
13640 enum machine_mode mode = BLKmode;
13643 /* Altivec first, since it will be faster than a string move
13644 when it applies, and usually not significantly larger. */
13645 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13649 gen_func.mov = gen_movv4si;
13651 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13655 gen_func.mov = gen_movv2si;
13657 else if (TARGET_STRING
13658 && bytes > 24 /* move up to 32 bytes at a time */
13664 && ! fixed_regs[10]
13665 && ! fixed_regs[11]
13666 && ! fixed_regs[12])
13668 move_bytes = (bytes > 32) ? 32 : bytes;
13669 gen_func.movmemsi = gen_movmemsi_8reg;
13671 else if (TARGET_STRING
13672 && bytes > 16 /* move up to 24 bytes at a time */
13678 && ! fixed_regs[10])
13680 move_bytes = (bytes > 24) ? 24 : bytes;
13681 gen_func.movmemsi = gen_movmemsi_6reg;
13683 else if (TARGET_STRING
13684 && bytes > 8 /* move up to 16 bytes at a time */
13688 && ! fixed_regs[8])
13690 move_bytes = (bytes > 16) ? 16 : bytes;
13691 gen_func.movmemsi = gen_movmemsi_4reg;
13693 else if (bytes >= 8 && TARGET_POWERPC64
13694 /* 64-bit loads and stores require word-aligned
13696 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13700 gen_func.mov = gen_movdi;
13702 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13703 { /* move up to 8 bytes at a time */
13704 move_bytes = (bytes > 8) ? 8 : bytes;
13705 gen_func.movmemsi = gen_movmemsi_2reg;
13707 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13708 { /* move 4 bytes */
13711 gen_func.mov = gen_movsi;
13713 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13714 { /* move 2 bytes */
13717 gen_func.mov = gen_movhi;
13719 else if (TARGET_STRING && bytes > 1)
13720 { /* move up to 4 bytes at a time */
13721 move_bytes = (bytes > 4) ? 4 : bytes;
13722 gen_func.movmemsi = gen_movmemsi_1reg;
13724 else /* move 1 byte at a time */
13728 gen_func.mov = gen_movqi;
13731 src = adjust_address (orig_src, mode, offset);
13732 dest = adjust_address (orig_dest, mode, offset);
13734 if (mode != BLKmode)
13736 rtx tmp_reg = gen_reg_rtx (mode);
13738 emit_insn ((*gen_func.mov) (tmp_reg, src));
13739 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13742 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13745 for (i = 0; i < num_reg; i++)
13746 emit_insn (stores[i]);
13750 if (mode == BLKmode)
13752 /* Move the address into scratch registers. The movmemsi
13753 patterns require zero offset. */
13754 if (!REG_P (XEXP (src, 0)))
13756 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13757 src = replace_equiv_address (src, src_reg);
13759 set_mem_size (src, GEN_INT (move_bytes));
13761 if (!REG_P (XEXP (dest, 0)))
13763 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13764 dest = replace_equiv_address (dest, dest_reg);
13766 set_mem_size (dest, GEN_INT (move_bytes));
13768 emit_insn ((*gen_func.movmemsi) (dest, src,
13769 GEN_INT (move_bytes & 31),
13778 /* Return a string to perform a load_multiple operation.
13779 operands[0] is the vector.
13780 operands[1] is the source address.
13781 operands[2] is the first destination register. */
13784 rs6000_output_load_multiple (rtx operands[3])
13786 /* We have to handle the case where the pseudo used to contain the address
13787 is assigned to one of the output registers. */
13789 int words = XVECLEN (operands[0], 0);
13792 if (XVECLEN (operands[0], 0) == 1)
13793 return "{l|lwz} %2,0(%1)";
13795 for (i = 0; i < words; i++)
13796 if (refers_to_regno_p (REGNO (operands[2]) + i,
13797 REGNO (operands[2]) + i + 1, operands[1], 0))
13801 xop[0] = GEN_INT (4 * (words-1));
13802 xop[1] = operands[1];
13803 xop[2] = operands[2];
13804 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13809 xop[0] = GEN_INT (4 * (words-1));
13810 xop[1] = operands[1];
13811 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13812 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);
13817 for (j = 0; j < words; j++)
13820 xop[0] = GEN_INT (j * 4);
13821 xop[1] = operands[1];
13822 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13823 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13825 xop[0] = GEN_INT (i * 4);
13826 xop[1] = operands[1];
13827 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13832 return "{lsi|lswi} %2,%1,%N0";
13836 /* A validation routine: say whether CODE, a condition code, and MODE
13837 match. The other alternatives either don't make sense or should
13838 never be generated. */
13841 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13843 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13844 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13845 && GET_MODE_CLASS (mode) == MODE_CC);
13847 /* These don't make sense. */
13848 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13849 || mode != CCUNSmode);
13851 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13852 || mode == CCUNSmode);
13854 gcc_assert (mode == CCFPmode
13855 || (code != ORDERED && code != UNORDERED
13856 && code != UNEQ && code != LTGT
13857 && code != UNGT && code != UNLT
13858 && code != UNGE && code != UNLE));
13860 /* These should never be generated except for
13861 flag_finite_math_only. */
13862 gcc_assert (mode != CCFPmode
13863 || flag_finite_math_only
13864 || (code != LE && code != GE
13865 && code != UNEQ && code != LTGT
13866 && code != UNGT && code != UNLT));
13868 /* These are invalid; the information is not there. */
13869 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13873 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13874 mask required to convert the result of a rotate insn into a shift
13875 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13878 includes_lshift_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 /* Similar, but for right shift. */
13890 includes_rshift_p (rtx shiftop, rtx andop)
13892 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13894 shift_mask >>= INTVAL (shiftop);
13896 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13899 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13900 to perform a left shift. It must have exactly SHIFTOP least
13901 significant 0's, then one or more 1's, then zero or more 0's. */
13904 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13906 if (GET_CODE (andop) == CONST_INT)
13908 HOST_WIDE_INT c, lsb, shift_mask;
13910 c = INTVAL (andop);
13911 if (c == 0 || c == ~0)
13915 shift_mask <<= INTVAL (shiftop);
13917 /* Find the least significant one bit. */
13920 /* It must coincide with the LSB of the shift mask. */
13921 if (-lsb != shift_mask)
13924 /* Invert to look for the next transition (if any). */
13927 /* Remove the low group of ones (originally low group of zeros). */
13930 /* Again find the lsb, and check we have all 1's above. */
13934 else if (GET_CODE (andop) == CONST_DOUBLE
13935 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13937 HOST_WIDE_INT low, high, lsb;
13938 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13940 low = CONST_DOUBLE_LOW (andop);
13941 if (HOST_BITS_PER_WIDE_INT < 64)
13942 high = CONST_DOUBLE_HIGH (andop);
13944 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13945 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13948 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13950 shift_mask_high = ~0;
13951 if (INTVAL (shiftop) > 32)
13952 shift_mask_high <<= INTVAL (shiftop) - 32;
13954 lsb = high & -high;
13956 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13962 lsb = high & -high;
13963 return high == -lsb;
13966 shift_mask_low = ~0;
13967 shift_mask_low <<= INTVAL (shiftop);
13971 if (-lsb != shift_mask_low)
13974 if (HOST_BITS_PER_WIDE_INT < 64)
13979 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13981 lsb = high & -high;
13982 return high == -lsb;
13986 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13992 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13993 to perform a left shift. It must have SHIFTOP or more least
13994 significant 0's, with the remainder of the word 1's. */
13997 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13999 if (GET_CODE (andop) == CONST_INT)
14001 HOST_WIDE_INT c, lsb, shift_mask;
14004 shift_mask <<= INTVAL (shiftop);
14005 c = INTVAL (andop);
14007 /* Find the least significant one bit. */
14010 /* It must be covered by the shift mask.
14011 This test also rejects c == 0. */
14012 if ((lsb & shift_mask) == 0)
14015 /* Check we have all 1's above the transition, and reject all 1's. */
14016 return c == -lsb && lsb != 1;
14018 else if (GET_CODE (andop) == CONST_DOUBLE
14019 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14021 HOST_WIDE_INT low, lsb, shift_mask_low;
14023 low = CONST_DOUBLE_LOW (andop);
14025 if (HOST_BITS_PER_WIDE_INT < 64)
14027 HOST_WIDE_INT high, shift_mask_high;
14029 high = CONST_DOUBLE_HIGH (andop);
14033 shift_mask_high = ~0;
14034 if (INTVAL (shiftop) > 32)
14035 shift_mask_high <<= INTVAL (shiftop) - 32;
14037 lsb = high & -high;
14039 if ((lsb & shift_mask_high) == 0)
14042 return high == -lsb;
14048 shift_mask_low = ~0;
14049 shift_mask_low <<= INTVAL (shiftop);
14053 if ((lsb & shift_mask_low) == 0)
14056 return low == -lsb && lsb != 1;
14062 /* Return 1 if operands will generate a valid arguments to rlwimi
14063 instruction for insert with right shift in 64-bit mode. The mask may
14064 not start on the first bit or stop on the last bit because wrap-around
14065 effects of instruction do not correspond to semantics of RTL insn. */
14068 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14070 if (INTVAL (startop) > 32
14071 && INTVAL (startop) < 64
14072 && INTVAL (sizeop) > 1
14073 && INTVAL (sizeop) + INTVAL (startop) < 64
14074 && INTVAL (shiftop) > 0
14075 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14076 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14082 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14083 for lfq and stfq insns iff the registers are hard registers. */
14086 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14088 /* We might have been passed a SUBREG. */
14089 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14092 /* We might have been passed non floating point registers. */
14093 if (!FP_REGNO_P (REGNO (reg1))
14094 || !FP_REGNO_P (REGNO (reg2)))
14097 return (REGNO (reg1) == REGNO (reg2) - 1);
14100 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14101 addr1 and addr2 must be in consecutive memory locations
14102 (addr2 == addr1 + 8). */
14105 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14108 unsigned int reg1, reg2;
14109 int offset1, offset2;
14111 /* The mems cannot be volatile. */
14112 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14115 addr1 = XEXP (mem1, 0);
14116 addr2 = XEXP (mem2, 0);
14118 /* Extract an offset (if used) from the first addr. */
14119 if (GET_CODE (addr1) == PLUS)
14121 /* If not a REG, return zero. */
14122 if (GET_CODE (XEXP (addr1, 0)) != REG)
14126 reg1 = REGNO (XEXP (addr1, 0));
14127 /* The offset must be constant! */
14128 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14130 offset1 = INTVAL (XEXP (addr1, 1));
14133 else if (GET_CODE (addr1) != REG)
14137 reg1 = REGNO (addr1);
14138 /* This was a simple (mem (reg)) expression. Offset is 0. */
14142 /* And now for the second addr. */
14143 if (GET_CODE (addr2) == PLUS)
14145 /* If not a REG, return zero. */
14146 if (GET_CODE (XEXP (addr2, 0)) != REG)
14150 reg2 = REGNO (XEXP (addr2, 0));
14151 /* The offset must be constant. */
14152 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14154 offset2 = INTVAL (XEXP (addr2, 1));
14157 else if (GET_CODE (addr2) != REG)
14161 reg2 = REGNO (addr2);
14162 /* This was a simple (mem (reg)) expression. Offset is 0. */
14166 /* Both of these must have the same base register. */
14170 /* The offset for the second addr must be 8 more than the first addr. */
14171 if (offset2 != offset1 + 8)
14174 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14181 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14183 static bool eliminated = false;
14186 if (mode != SDmode)
14187 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14190 rtx mem = cfun->machine->sdmode_stack_slot;
14191 gcc_assert (mem != NULL_RTX);
14195 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14196 cfun->machine->sdmode_stack_slot = mem;
14202 if (TARGET_DEBUG_ADDR)
14204 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14205 GET_MODE_NAME (mode));
14207 fprintf (stderr, "\tNULL_RTX\n");
14216 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14218 /* Don't walk into types. */
14219 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14221 *walk_subtrees = 0;
14225 switch (TREE_CODE (*tp))
14234 case VIEW_CONVERT_EXPR:
14235 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14245 enum reload_reg_type {
14247 VECTOR_REGISTER_TYPE,
14248 OTHER_REGISTER_TYPE
14251 static enum reload_reg_type
14252 rs6000_reload_register_type (enum reg_class rclass)
14258 return GPR_REGISTER_TYPE;
14263 return VECTOR_REGISTER_TYPE;
14266 return OTHER_REGISTER_TYPE;
14270 /* Inform reload about cases where moving X with a mode MODE to a register in
14271 RCLASS requires an extra scratch or immediate register. Return the class
14272 needed for the immediate register.
14274 For VSX and Altivec, we may need a register to convert sp+offset into
14278 rs6000_secondary_reload (bool in_p,
14280 reg_class_t rclass_i,
14281 enum machine_mode mode,
14282 secondary_reload_info *sri)
14284 enum reg_class rclass = (enum reg_class) rclass_i;
14285 reg_class_t ret = ALL_REGS;
14286 enum insn_code icode;
14287 bool default_p = false;
14289 sri->icode = CODE_FOR_nothing;
14291 /* Convert vector loads and stores into gprs to use an additional base
14293 icode = rs6000_vector_reload[mode][in_p != false];
14294 if (icode != CODE_FOR_nothing)
14297 sri->icode = CODE_FOR_nothing;
14298 sri->extra_cost = 0;
14300 if (GET_CODE (x) == MEM)
14302 rtx addr = XEXP (x, 0);
14304 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14305 an extra register in that case, but it would need an extra
14306 register if the addressing is reg+reg or (reg+reg)&(-16). */
14307 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14309 if (!legitimate_indirect_address_p (addr, false)
14310 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14312 sri->icode = icode;
14313 /* account for splitting the loads, and converting the
14314 address from reg+reg to reg. */
14315 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14316 + ((GET_CODE (addr) == AND) ? 1 : 0));
14319 /* Loads to and stores from vector registers can only do reg+reg
14320 addressing. Altivec registers can also do (reg+reg)&(-16). */
14321 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14322 || rclass == FLOAT_REGS || rclass == NO_REGS)
14324 if (!VECTOR_MEM_ALTIVEC_P (mode)
14325 && GET_CODE (addr) == AND
14326 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14327 && INTVAL (XEXP (addr, 1)) == -16
14328 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14329 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14331 sri->icode = icode;
14332 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14335 else if (!legitimate_indirect_address_p (addr, false)
14336 && (rclass == NO_REGS
14337 || !legitimate_indexed_address_p (addr, false)))
14339 sri->icode = icode;
14340 sri->extra_cost = 1;
14343 icode = CODE_FOR_nothing;
14345 /* Any other loads, including to pseudo registers which haven't been
14346 assigned to a register yet, default to require a scratch
14350 sri->icode = icode;
14351 sri->extra_cost = 2;
14354 else if (REG_P (x))
14356 int regno = true_regnum (x);
14358 icode = CODE_FOR_nothing;
14359 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14363 enum reg_class xclass = REGNO_REG_CLASS (regno);
14364 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14365 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14367 /* If memory is needed, use default_secondary_reload to create the
14369 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14382 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14384 gcc_assert (ret != ALL_REGS);
14386 if (TARGET_DEBUG_ADDR)
14389 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14391 reg_class_names[ret],
14392 in_p ? "true" : "false",
14393 reg_class_names[rclass],
14394 GET_MODE_NAME (mode));
14397 fprintf (stderr, ", default secondary reload");
14399 if (sri->icode != CODE_FOR_nothing)
14400 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14401 insn_data[sri->icode].name, sri->extra_cost);
14403 fprintf (stderr, "\n");
14411 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14412 to SP+reg addressing. */
14415 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14417 int regno = true_regnum (reg);
14418 enum machine_mode mode = GET_MODE (reg);
14419 enum reg_class rclass;
14421 rtx and_op2 = NULL_RTX;
14424 rtx scratch_or_premodify = scratch;
14428 if (TARGET_DEBUG_ADDR)
14430 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14431 store_p ? "store" : "load");
14432 fprintf (stderr, "reg:\n");
14434 fprintf (stderr, "mem:\n");
14436 fprintf (stderr, "scratch:\n");
14437 debug_rtx (scratch);
14440 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14441 gcc_assert (GET_CODE (mem) == MEM);
14442 rclass = REGNO_REG_CLASS (regno);
14443 addr = XEXP (mem, 0);
14447 /* GPRs can handle reg + small constant, all other addresses need to use
14448 the scratch register. */
14451 if (GET_CODE (addr) == AND)
14453 and_op2 = XEXP (addr, 1);
14454 addr = XEXP (addr, 0);
14457 if (GET_CODE (addr) == PRE_MODIFY)
14459 scratch_or_premodify = XEXP (addr, 0);
14460 gcc_assert (REG_P (scratch_or_premodify));
14461 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14462 addr = XEXP (addr, 1);
14465 if (GET_CODE (addr) == PLUS
14466 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14467 || and_op2 != NULL_RTX))
14469 addr_op1 = XEXP (addr, 0);
14470 addr_op2 = XEXP (addr, 1);
14471 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14473 if (!REG_P (addr_op2)
14474 && (GET_CODE (addr_op2) != CONST_INT
14475 || !satisfies_constraint_I (addr_op2)))
14477 if (TARGET_DEBUG_ADDR)
14480 "\nMove plus addr to register %s, mode = %s: ",
14481 rs6000_reg_names[REGNO (scratch)],
14482 GET_MODE_NAME (mode));
14483 debug_rtx (addr_op2);
14485 rs6000_emit_move (scratch, addr_op2, Pmode);
14486 addr_op2 = scratch;
14489 emit_insn (gen_rtx_SET (VOIDmode,
14490 scratch_or_premodify,
14491 gen_rtx_PLUS (Pmode,
14495 addr = scratch_or_premodify;
14496 scratch_or_premodify = scratch;
14498 else if (!legitimate_indirect_address_p (addr, false)
14499 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14501 if (TARGET_DEBUG_ADDR)
14503 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14504 rs6000_reg_names[REGNO (scratch_or_premodify)],
14505 GET_MODE_NAME (mode));
14508 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14509 addr = scratch_or_premodify;
14510 scratch_or_premodify = scratch;
14514 /* Float/Altivec registers can only handle reg+reg addressing. Move
14515 other addresses into a scratch register. */
14520 /* With float regs, we need to handle the AND ourselves, since we can't
14521 use the Altivec instruction with an implicit AND -16. Allow scalar
14522 loads to float registers to use reg+offset even if VSX. */
14523 if (GET_CODE (addr) == AND
14524 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14525 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14526 || INTVAL (XEXP (addr, 1)) != -16
14527 || !VECTOR_MEM_ALTIVEC_P (mode)))
14529 and_op2 = XEXP (addr, 1);
14530 addr = XEXP (addr, 0);
14533 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14534 as the address later. */
14535 if (GET_CODE (addr) == PRE_MODIFY
14536 && (!VECTOR_MEM_VSX_P (mode)
14537 || and_op2 != NULL_RTX
14538 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14540 scratch_or_premodify = XEXP (addr, 0);
14541 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14543 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14544 addr = XEXP (addr, 1);
14547 if (legitimate_indirect_address_p (addr, false) /* reg */
14548 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14549 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14550 || (GET_CODE (addr) == AND /* Altivec memory */
14551 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14552 && INTVAL (XEXP (addr, 1)) == -16
14553 && VECTOR_MEM_ALTIVEC_P (mode))
14554 || (rclass == FLOAT_REGS /* legacy float mem */
14555 && GET_MODE_SIZE (mode) == 8
14556 && and_op2 == NULL_RTX
14557 && scratch_or_premodify == scratch
14558 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14561 else if (GET_CODE (addr) == PLUS)
14563 addr_op1 = XEXP (addr, 0);
14564 addr_op2 = XEXP (addr, 1);
14565 gcc_assert (REG_P (addr_op1));
14567 if (TARGET_DEBUG_ADDR)
14569 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14570 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14571 debug_rtx (addr_op2);
14573 rs6000_emit_move (scratch, addr_op2, Pmode);
14574 emit_insn (gen_rtx_SET (VOIDmode,
14575 scratch_or_premodify,
14576 gen_rtx_PLUS (Pmode,
14579 addr = scratch_or_premodify;
14580 scratch_or_premodify = scratch;
14583 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14584 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14586 if (TARGET_DEBUG_ADDR)
14588 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14589 rs6000_reg_names[REGNO (scratch_or_premodify)],
14590 GET_MODE_NAME (mode));
14594 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14595 addr = scratch_or_premodify;
14596 scratch_or_premodify = scratch;
14600 gcc_unreachable ();
14605 gcc_unreachable ();
14608 /* If the original address involved a pre-modify that we couldn't use the VSX
14609 memory instruction with update, and we haven't taken care of already,
14610 store the address in the pre-modify register and use that as the
14612 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14614 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14615 addr = scratch_or_premodify;
14618 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14619 memory instruction, recreate the AND now, including the clobber which is
14620 generated by the general ANDSI3/ANDDI3 patterns for the
14621 andi. instruction. */
14622 if (and_op2 != NULL_RTX)
14624 if (! legitimate_indirect_address_p (addr, false))
14626 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14630 if (TARGET_DEBUG_ADDR)
14632 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14633 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14634 debug_rtx (and_op2);
14637 and_rtx = gen_rtx_SET (VOIDmode,
14639 gen_rtx_AND (Pmode,
14643 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14644 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14645 gen_rtvec (2, and_rtx, cc_clobber)));
14649 /* Adjust the address if it changed. */
14650 if (addr != XEXP (mem, 0))
14652 mem = change_address (mem, mode, addr);
14653 if (TARGET_DEBUG_ADDR)
14654 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14657 /* Now create the move. */
14659 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14661 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14666 /* Target hook to return the cover classes for Integrated Register Allocator.
14667 Cover classes is a set of non-intersected register classes covering all hard
14668 registers used for register allocation purpose. Any move between two
14669 registers of a cover class should be cheaper than load or store of the
14670 registers. The value is array of register classes with LIM_REG_CLASSES used
14673 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14674 account for the Altivec and Floating registers being subsets of the VSX
14675 register set under VSX, but distinct register sets on pre-VSX machines. */
14677 static const reg_class_t *
14678 rs6000_ira_cover_classes (void)
14680 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14681 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14683 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14686 /* Allocate a 64-bit stack slot to be used for copying SDmode
14687 values through if this function has any SDmode references. */
14690 rs6000_alloc_sdmode_stack_slot (void)
14694 gimple_stmt_iterator gsi;
14696 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14699 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14701 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14704 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14705 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14711 /* Check for any SDmode parameters of the function. */
14712 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14714 if (TREE_TYPE (t) == error_mark_node)
14717 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14718 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14720 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14721 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14729 rs6000_instantiate_decls (void)
14731 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14732 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14735 /* Given an rtx X being reloaded into a reg required to be
14736 in class CLASS, return the class of reg to actually use.
14737 In general this is just CLASS; but on some machines
14738 in some cases it is preferable to use a more restrictive class.
14740 On the RS/6000, we have to return NO_REGS when we want to reload a
14741 floating-point CONST_DOUBLE to force it to be copied to memory.
14743 We also don't want to reload integer values into floating-point
14744 registers if we can at all help it. In fact, this can
14745 cause reload to die, if it tries to generate a reload of CTR
14746 into a FP register and discovers it doesn't have the memory location
14749 ??? Would it be a good idea to have reload do the converse, that is
14750 try to reload floating modes into FP registers if possible?
14753 static enum reg_class
14754 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14756 enum machine_mode mode = GET_MODE (x);
14758 if (VECTOR_UNIT_VSX_P (mode)
14759 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14762 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14763 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14764 && easy_vector_constant (x, mode))
14765 return ALTIVEC_REGS;
14767 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14770 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14771 return GENERAL_REGS;
14773 /* For VSX, prefer the traditional registers for 64-bit values because we can
14774 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14775 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14776 prefer Altivec loads.. */
14777 if (rclass == VSX_REGS)
14779 if (GET_MODE_SIZE (mode) <= 8)
14782 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14783 return ALTIVEC_REGS;
14791 /* Debug version of rs6000_preferred_reload_class. */
14792 static enum reg_class
14793 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14795 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14798 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14800 reg_class_names[ret], reg_class_names[rclass],
14801 GET_MODE_NAME (GET_MODE (x)));
14807 /* If we are copying between FP or AltiVec registers and anything else, we need
14808 a memory location. The exception is when we are targeting ppc64 and the
14809 move to/from fpr to gpr instructions are available. Also, under VSX, you
14810 can copy vector registers from the FP register set to the Altivec register
14811 set and vice versa. */
14814 rs6000_secondary_memory_needed (enum reg_class class1,
14815 enum reg_class class2,
14816 enum machine_mode mode)
14818 if (class1 == class2)
14821 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14822 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14823 between these classes. But we need memory for other things that can go in
14824 FLOAT_REGS like SFmode. */
14826 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14827 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14828 || class1 == FLOAT_REGS))
14829 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14830 && class2 != FLOAT_REGS);
14832 if (class1 == VSX_REGS || class2 == VSX_REGS)
14835 if (class1 == FLOAT_REGS
14836 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14837 || ((mode != DFmode)
14838 && (mode != DDmode)
14839 && (mode != DImode))))
14842 if (class2 == FLOAT_REGS
14843 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14844 || ((mode != DFmode)
14845 && (mode != DDmode)
14846 && (mode != DImode))))
14849 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14855 /* Debug version of rs6000_secondary_memory_needed. */
14857 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14858 enum reg_class class2,
14859 enum machine_mode mode)
14861 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14864 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14865 "class2 = %s, mode = %s\n",
14866 ret ? "true" : "false", reg_class_names[class1],
14867 reg_class_names[class2], GET_MODE_NAME (mode));
14872 /* Return the register class of a scratch register needed to copy IN into
14873 or out of a register in RCLASS in MODE. If it can be done directly,
14874 NO_REGS is returned. */
14876 static enum reg_class
14877 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14882 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14884 && MACHOPIC_INDIRECT
14888 /* We cannot copy a symbolic operand directly into anything
14889 other than BASE_REGS for TARGET_ELF. So indicate that a
14890 register from BASE_REGS is needed as an intermediate
14893 On Darwin, pic addresses require a load from memory, which
14894 needs a base register. */
14895 if (rclass != BASE_REGS
14896 && (GET_CODE (in) == SYMBOL_REF
14897 || GET_CODE (in) == HIGH
14898 || GET_CODE (in) == LABEL_REF
14899 || GET_CODE (in) == CONST))
14903 if (GET_CODE (in) == REG)
14905 regno = REGNO (in);
14906 if (regno >= FIRST_PSEUDO_REGISTER)
14908 regno = true_regnum (in);
14909 if (regno >= FIRST_PSEUDO_REGISTER)
14913 else if (GET_CODE (in) == SUBREG)
14915 regno = true_regnum (in);
14916 if (regno >= FIRST_PSEUDO_REGISTER)
14922 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14924 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14925 || (regno >= 0 && INT_REGNO_P (regno)))
14928 /* Constants, memory, and FP registers can go into FP registers. */
14929 if ((regno == -1 || FP_REGNO_P (regno))
14930 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14931 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14933 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14936 && (regno == -1 || VSX_REGNO_P (regno))
14937 && VSX_REG_CLASS_P (rclass))
14940 /* Memory, and AltiVec registers can go into AltiVec registers. */
14941 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14942 && rclass == ALTIVEC_REGS)
14945 /* We can copy among the CR registers. */
14946 if ((rclass == CR_REGS || rclass == CR0_REGS)
14947 && regno >= 0 && CR_REGNO_P (regno))
14950 /* Otherwise, we need GENERAL_REGS. */
14951 return GENERAL_REGS;
14954 /* Debug version of rs6000_secondary_reload_class. */
14955 static enum reg_class
14956 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14957 enum machine_mode mode, rtx in)
14959 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14961 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14962 "mode = %s, input rtx:\n",
14963 reg_class_names[ret], reg_class_names[rclass],
14964 GET_MODE_NAME (mode));
14970 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14973 rs6000_cannot_change_mode_class (enum machine_mode from,
14974 enum machine_mode to,
14975 enum reg_class rclass)
14977 unsigned from_size = GET_MODE_SIZE (from);
14978 unsigned to_size = GET_MODE_SIZE (to);
14980 if (from_size != to_size)
14982 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14983 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14984 && reg_classes_intersect_p (xclass, rclass));
14987 if (TARGET_E500_DOUBLE
14988 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14989 || (((to) == TFmode) + ((from) == TFmode)) == 1
14990 || (((to) == DDmode) + ((from) == DDmode)) == 1
14991 || (((to) == TDmode) + ((from) == TDmode)) == 1
14992 || (((to) == DImode) + ((from) == DImode)) == 1))
14995 /* Since the VSX register set includes traditional floating point registers
14996 and altivec registers, just check for the size being different instead of
14997 trying to check whether the modes are vector modes. Otherwise it won't
14998 allow say DF and DI to change classes. */
14999 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15000 return (from_size != 8 && from_size != 16);
15002 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15003 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15006 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15007 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15013 /* Debug version of rs6000_cannot_change_mode_class. */
15015 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15016 enum machine_mode to,
15017 enum reg_class rclass)
15019 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15022 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15023 "to = %s, rclass = %s\n",
15024 ret ? "true" : "false",
15025 GET_MODE_NAME (from), GET_MODE_NAME (to),
15026 reg_class_names[rclass]);
15031 /* Given a comparison operation, return the bit number in CCR to test. We
15032 know this is a valid comparison.
15034 SCC_P is 1 if this is for an scc. That means that %D will have been
15035 used instead of %C, so the bits will be in different places.
15037 Return -1 if OP isn't a valid comparison for some reason. */
15040 ccr_bit (rtx op, int scc_p)
15042 enum rtx_code code = GET_CODE (op);
15043 enum machine_mode cc_mode;
15048 if (!COMPARISON_P (op))
15051 reg = XEXP (op, 0);
15053 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15055 cc_mode = GET_MODE (reg);
15056 cc_regnum = REGNO (reg);
15057 base_bit = 4 * (cc_regnum - CR0_REGNO);
15059 validate_condition_mode (code, cc_mode);
15061 /* When generating a sCOND operation, only positive conditions are
15064 || code == EQ || code == GT || code == LT || code == UNORDERED
15065 || code == GTU || code == LTU);
15070 return scc_p ? base_bit + 3 : base_bit + 2;
15072 return base_bit + 2;
15073 case GT: case GTU: case UNLE:
15074 return base_bit + 1;
15075 case LT: case LTU: case UNGE:
15077 case ORDERED: case UNORDERED:
15078 return base_bit + 3;
15081 /* If scc, we will have done a cror to put the bit in the
15082 unordered position. So test that bit. For integer, this is ! LT
15083 unless this is an scc insn. */
15084 return scc_p ? base_bit + 3 : base_bit;
15087 return scc_p ? base_bit + 3 : base_bit + 1;
15090 gcc_unreachable ();
15094 /* Return the GOT register. */
15097 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15099 /* The second flow pass currently (June 1999) can't update
15100 regs_ever_live without disturbing other parts of the compiler, so
15101 update it here to make the prolog/epilogue code happy. */
15102 if (!can_create_pseudo_p ()
15103 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15104 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15106 crtl->uses_pic_offset_table = 1;
15108 return pic_offset_table_rtx;
15111 /* Function to init struct machine_function.
15112 This will be called, via a pointer variable,
15113 from push_function_context. */
15115 static struct machine_function *
15116 rs6000_init_machine_status (void)
15118 return ggc_alloc_cleared_machine_function ();
15121 /* These macros test for integers and extract the low-order bits. */
15123 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15124 && GET_MODE (X) == VOIDmode)
15126 #define INT_LOWPART(X) \
15127 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15130 extract_MB (rtx op)
15133 unsigned long val = INT_LOWPART (op);
15135 /* If the high bit is zero, the value is the first 1 bit we find
15137 if ((val & 0x80000000) == 0)
15139 gcc_assert (val & 0xffffffff);
15142 while (((val <<= 1) & 0x80000000) == 0)
15147 /* If the high bit is set and the low bit is not, or the mask is all
15148 1's, the value is zero. */
15149 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15152 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15155 while (((val >>= 1) & 1) != 0)
15162 extract_ME (rtx op)
15165 unsigned long val = INT_LOWPART (op);
15167 /* If the low bit is zero, the value is the first 1 bit we find from
15169 if ((val & 1) == 0)
15171 gcc_assert (val & 0xffffffff);
15174 while (((val >>= 1) & 1) == 0)
15180 /* If the low bit is set and the high bit is not, or the mask is all
15181 1's, the value is 31. */
15182 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15185 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15188 while (((val <<= 1) & 0x80000000) != 0)
15194 /* Locate some local-dynamic symbol still in use by this function
15195 so that we can print its name in some tls_ld pattern. */
15197 static const char *
15198 rs6000_get_some_local_dynamic_name (void)
15202 if (cfun->machine->some_ld_name)
15203 return cfun->machine->some_ld_name;
15205 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15207 && for_each_rtx (&PATTERN (insn),
15208 rs6000_get_some_local_dynamic_name_1, 0))
15209 return cfun->machine->some_ld_name;
15211 gcc_unreachable ();
15214 /* Helper function for rs6000_get_some_local_dynamic_name. */
15217 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15221 if (GET_CODE (x) == SYMBOL_REF)
15223 const char *str = XSTR (x, 0);
15224 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15226 cfun->machine->some_ld_name = str;
15234 /* Write out a function code label. */
15237 rs6000_output_function_entry (FILE *file, const char *fname)
15239 if (fname[0] != '.')
15241 switch (DEFAULT_ABI)
15244 gcc_unreachable ();
15250 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15259 RS6000_OUTPUT_BASENAME (file, fname);
15262 /* Print an operand. Recognize special options, documented below. */
15265 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15266 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15268 #define SMALL_DATA_RELOC "sda21"
15269 #define SMALL_DATA_REG 0
15273 print_operand (FILE *file, rtx x, int code)
15277 unsigned HOST_WIDE_INT uval;
15282 /* Write out an instruction after the call which may be replaced
15283 with glue code by the loader. This depends on the AIX version. */
15284 asm_fprintf (file, RS6000_CALL_GLUE);
15287 /* %a is output_address. */
15290 /* If X is a constant integer whose low-order 5 bits are zero,
15291 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15292 in the AIX assembler where "sri" with a zero shift count
15293 writes a trash instruction. */
15294 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15301 /* If constant, low-order 16 bits of constant, unsigned.
15302 Otherwise, write normally. */
15304 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15306 print_operand (file, x, 0);
15310 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15311 for 64-bit mask direction. */
15312 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15315 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15319 /* X is a CR register. Print the number of the GT bit of the CR. */
15320 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15321 output_operand_lossage ("invalid %%c value");
15323 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15327 /* Like 'J' but get to the GT bit only. */
15328 gcc_assert (GET_CODE (x) == REG);
15330 /* Bit 1 is GT bit. */
15331 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15333 /* Add one for shift count in rlinm for scc. */
15334 fprintf (file, "%d", i + 1);
15338 /* X is a CR register. Print the number of the EQ bit of the CR */
15339 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15340 output_operand_lossage ("invalid %%E value");
15342 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15346 /* X is a CR register. Print the shift count needed to move it
15347 to the high-order four bits. */
15348 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15349 output_operand_lossage ("invalid %%f value");
15351 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15355 /* Similar, but print the count for the rotate in the opposite
15357 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15358 output_operand_lossage ("invalid %%F value");
15360 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15364 /* X is a constant integer. If it is negative, print "m",
15365 otherwise print "z". This is to make an aze or ame insn. */
15366 if (GET_CODE (x) != CONST_INT)
15367 output_operand_lossage ("invalid %%G value");
15368 else if (INTVAL (x) >= 0)
15375 /* If constant, output low-order five bits. Otherwise, write
15378 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15380 print_operand (file, x, 0);
15384 /* If constant, output low-order six bits. Otherwise, write
15387 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15389 print_operand (file, x, 0);
15393 /* Print `i' if this is a constant, else nothing. */
15399 /* Write the bit number in CCR for jump. */
15400 i = ccr_bit (x, 0);
15402 output_operand_lossage ("invalid %%j code");
15404 fprintf (file, "%d", i);
15408 /* Similar, but add one for shift count in rlinm for scc and pass
15409 scc flag to `ccr_bit'. */
15410 i = ccr_bit (x, 1);
15412 output_operand_lossage ("invalid %%J code");
15414 /* If we want bit 31, write a shift count of zero, not 32. */
15415 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15419 /* X must be a constant. Write the 1's complement of the
15422 output_operand_lossage ("invalid %%k value");
15424 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15428 /* X must be a symbolic constant on ELF. Write an
15429 expression suitable for an 'addi' that adds in the low 16
15430 bits of the MEM. */
15431 if (GET_CODE (x) == CONST)
15433 if (GET_CODE (XEXP (x, 0)) != PLUS
15434 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15435 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15436 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15437 output_operand_lossage ("invalid %%K value");
15439 print_operand_address (file, x);
15440 fputs ("@l", file);
15443 /* %l is output_asm_label. */
15446 /* Write second word of DImode or DFmode reference. Works on register
15447 or non-indexed memory only. */
15448 if (GET_CODE (x) == REG)
15449 fputs (reg_names[REGNO (x) + 1], file);
15450 else if (GET_CODE (x) == MEM)
15452 /* Handle possible auto-increment. Since it is pre-increment and
15453 we have already done it, we can just use an offset of word. */
15454 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15455 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15456 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15458 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15459 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15462 output_address (XEXP (adjust_address_nv (x, SImode,
15466 if (small_data_operand (x, GET_MODE (x)))
15467 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15468 reg_names[SMALL_DATA_REG]);
15473 /* MB value for a mask operand. */
15474 if (! mask_operand (x, SImode))
15475 output_operand_lossage ("invalid %%m value");
15477 fprintf (file, "%d", extract_MB (x));
15481 /* ME value for a mask operand. */
15482 if (! mask_operand (x, SImode))
15483 output_operand_lossage ("invalid %%M value");
15485 fprintf (file, "%d", extract_ME (x));
15488 /* %n outputs the negative of its operand. */
15491 /* Write the number of elements in the vector times 4. */
15492 if (GET_CODE (x) != PARALLEL)
15493 output_operand_lossage ("invalid %%N value");
15495 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15499 /* Similar, but subtract 1 first. */
15500 if (GET_CODE (x) != PARALLEL)
15501 output_operand_lossage ("invalid %%O value");
15503 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15507 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15509 || INT_LOWPART (x) < 0
15510 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15511 output_operand_lossage ("invalid %%p value");
15513 fprintf (file, "%d", i);
15517 /* The operand must be an indirect memory reference. The result
15518 is the register name. */
15519 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15520 || REGNO (XEXP (x, 0)) >= 32)
15521 output_operand_lossage ("invalid %%P value");
15523 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15527 /* This outputs the logical code corresponding to a boolean
15528 expression. The expression may have one or both operands
15529 negated (if one, only the first one). For condition register
15530 logical operations, it will also treat the negated
15531 CR codes as NOTs, but not handle NOTs of them. */
15533 const char *const *t = 0;
15535 enum rtx_code code = GET_CODE (x);
15536 static const char * const tbl[3][3] = {
15537 { "and", "andc", "nor" },
15538 { "or", "orc", "nand" },
15539 { "xor", "eqv", "xor" } };
15543 else if (code == IOR)
15545 else if (code == XOR)
15548 output_operand_lossage ("invalid %%q value");
15550 if (GET_CODE (XEXP (x, 0)) != NOT)
15554 if (GET_CODE (XEXP (x, 1)) == NOT)
15572 /* X is a CR register. Print the mask for `mtcrf'. */
15573 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15574 output_operand_lossage ("invalid %%R value");
15576 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15580 /* Low 5 bits of 32 - value */
15582 output_operand_lossage ("invalid %%s value");
15584 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15588 /* PowerPC64 mask position. All 0's is excluded.
15589 CONST_INT 32-bit mask is considered sign-extended so any
15590 transition must occur within the CONST_INT, not on the boundary. */
15591 if (! mask64_operand (x, DImode))
15592 output_operand_lossage ("invalid %%S value");
15594 uval = INT_LOWPART (x);
15596 if (uval & 1) /* Clear Left */
15598 #if HOST_BITS_PER_WIDE_INT > 64
15599 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15603 else /* Clear Right */
15606 #if HOST_BITS_PER_WIDE_INT > 64
15607 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15613 gcc_assert (i >= 0);
15614 fprintf (file, "%d", i);
15618 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15619 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15621 /* Bit 3 is OV bit. */
15622 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15624 /* If we want bit 31, write a shift count of zero, not 32. */
15625 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15629 /* Print the symbolic name of a branch target register. */
15630 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15631 && REGNO (x) != CTR_REGNO))
15632 output_operand_lossage ("invalid %%T value");
15633 else if (REGNO (x) == LR_REGNO)
15634 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15636 fputs ("ctr", file);
15640 /* High-order 16 bits of constant for use in unsigned operand. */
15642 output_operand_lossage ("invalid %%u value");
15644 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15645 (INT_LOWPART (x) >> 16) & 0xffff);
15649 /* High-order 16 bits of constant for use in signed operand. */
15651 output_operand_lossage ("invalid %%v value");
15653 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15654 (INT_LOWPART (x) >> 16) & 0xffff);
15658 /* Print `u' if this has an auto-increment or auto-decrement. */
15659 if (GET_CODE (x) == MEM
15660 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15661 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15662 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15667 /* Print the trap code for this operand. */
15668 switch (GET_CODE (x))
15671 fputs ("eq", file); /* 4 */
15674 fputs ("ne", file); /* 24 */
15677 fputs ("lt", file); /* 16 */
15680 fputs ("le", file); /* 20 */
15683 fputs ("gt", file); /* 8 */
15686 fputs ("ge", file); /* 12 */
15689 fputs ("llt", file); /* 2 */
15692 fputs ("lle", file); /* 6 */
15695 fputs ("lgt", file); /* 1 */
15698 fputs ("lge", file); /* 5 */
15701 gcc_unreachable ();
15706 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15709 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15710 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15712 print_operand (file, x, 0);
15716 /* MB value for a PowerPC64 rldic operand. */
15717 val = (GET_CODE (x) == CONST_INT
15718 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15723 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15724 if ((val <<= 1) < 0)
15727 #if HOST_BITS_PER_WIDE_INT == 32
15728 if (GET_CODE (x) == CONST_INT && i >= 0)
15729 i += 32; /* zero-extend high-part was all 0's */
15730 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15732 val = CONST_DOUBLE_LOW (x);
15738 for ( ; i < 64; i++)
15739 if ((val <<= 1) < 0)
15744 fprintf (file, "%d", i + 1);
15748 /* X is a FPR or Altivec register used in a VSX context. */
15749 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15750 output_operand_lossage ("invalid %%x value");
15753 int reg = REGNO (x);
15754 int vsx_reg = (FP_REGNO_P (reg)
15756 : reg - FIRST_ALTIVEC_REGNO + 32);
15758 #ifdef TARGET_REGNAMES
15759 if (TARGET_REGNAMES)
15760 fprintf (file, "%%vs%d", vsx_reg);
15763 fprintf (file, "%d", vsx_reg);
15768 if (GET_CODE (x) == MEM
15769 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15770 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15771 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15776 /* Like 'L', for third word of TImode */
15777 if (GET_CODE (x) == REG)
15778 fputs (reg_names[REGNO (x) + 2], file);
15779 else if (GET_CODE (x) == MEM)
15781 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15782 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15783 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15784 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15785 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15787 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15788 if (small_data_operand (x, GET_MODE (x)))
15789 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15790 reg_names[SMALL_DATA_REG]);
15795 /* X is a SYMBOL_REF. Write out the name preceded by a
15796 period and without any trailing data in brackets. Used for function
15797 names. If we are configured for System V (or the embedded ABI) on
15798 the PowerPC, do not emit the period, since those systems do not use
15799 TOCs and the like. */
15800 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15802 /* Mark the decl as referenced so that cgraph will output the
15804 if (SYMBOL_REF_DECL (x))
15805 mark_decl_referenced (SYMBOL_REF_DECL (x));
15807 /* For macho, check to see if we need a stub. */
15810 const char *name = XSTR (x, 0);
15812 if (darwin_emit_branch_islands
15813 && MACHOPIC_INDIRECT
15814 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15815 name = machopic_indirection_name (x, /*stub_p=*/true);
15817 assemble_name (file, name);
15819 else if (!DOT_SYMBOLS)
15820 assemble_name (file, XSTR (x, 0));
15822 rs6000_output_function_entry (file, XSTR (x, 0));
15826 /* Like 'L', for last word of TImode. */
15827 if (GET_CODE (x) == REG)
15828 fputs (reg_names[REGNO (x) + 3], file);
15829 else if (GET_CODE (x) == MEM)
15831 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15832 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15833 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15834 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15835 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15837 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15838 if (small_data_operand (x, GET_MODE (x)))
15839 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15840 reg_names[SMALL_DATA_REG]);
15844 /* Print AltiVec or SPE memory operand. */
15849 gcc_assert (GET_CODE (x) == MEM);
15853 /* Ugly hack because %y is overloaded. */
15854 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15855 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15856 || GET_MODE (x) == TFmode
15857 || GET_MODE (x) == TImode))
15859 /* Handle [reg]. */
15860 if (GET_CODE (tmp) == REG)
15862 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15865 /* Handle [reg+UIMM]. */
15866 else if (GET_CODE (tmp) == PLUS &&
15867 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15871 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15873 x = INTVAL (XEXP (tmp, 1));
15874 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15878 /* Fall through. Must be [reg+reg]. */
15880 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15881 && GET_CODE (tmp) == AND
15882 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15883 && INTVAL (XEXP (tmp, 1)) == -16)
15884 tmp = XEXP (tmp, 0);
15885 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15886 && GET_CODE (tmp) == PRE_MODIFY)
15887 tmp = XEXP (tmp, 1);
15888 if (GET_CODE (tmp) == REG)
15889 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15892 if (!GET_CODE (tmp) == PLUS
15893 || !REG_P (XEXP (tmp, 0))
15894 || !REG_P (XEXP (tmp, 1)))
15896 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15900 if (REGNO (XEXP (tmp, 0)) == 0)
15901 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15902 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15904 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15905 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15911 if (GET_CODE (x) == REG)
15912 fprintf (file, "%s", reg_names[REGNO (x)]);
15913 else if (GET_CODE (x) == MEM)
15915 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15916 know the width from the mode. */
15917 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15918 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15919 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15920 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15921 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15922 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15923 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15924 output_address (XEXP (XEXP (x, 0), 1));
15926 output_address (XEXP (x, 0));
15929 output_addr_const (file, x);
15933 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15937 output_operand_lossage ("invalid %%xn code");
15941 /* Print the address of an operand. */
15944 print_operand_address (FILE *file, rtx x)
15946 if (GET_CODE (x) == REG)
15947 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15948 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15949 || GET_CODE (x) == LABEL_REF)
15951 output_addr_const (file, x);
15952 if (small_data_operand (x, GET_MODE (x)))
15953 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15954 reg_names[SMALL_DATA_REG]);
15956 gcc_assert (!TARGET_TOC);
15958 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15960 gcc_assert (REG_P (XEXP (x, 0)));
15961 if (REGNO (XEXP (x, 0)) == 0)
15962 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15963 reg_names[ REGNO (XEXP (x, 0)) ]);
15965 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15966 reg_names[ REGNO (XEXP (x, 1)) ]);
15968 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15969 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15970 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15972 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15973 && CONSTANT_P (XEXP (x, 1)))
15975 fprintf (file, "lo16(");
15976 output_addr_const (file, XEXP (x, 1));
15977 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15980 else if (legitimate_constant_pool_address_p (x, true))
15982 /* This hack along with a corresponding hack in
15983 rs6000_output_addr_const_extra arranges to output addends
15984 where the assembler expects to find them. eg.
15986 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15987 without this hack would be output as "x@toc+8@l(9)". We
15988 want "x+8@toc@l(9)". */
15989 output_addr_const (file, tocrel_base);
15990 if (GET_CODE (x) == LO_SUM)
15991 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15993 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15996 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15997 && CONSTANT_P (XEXP (x, 1)))
15999 output_addr_const (file, XEXP (x, 1));
16000 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16004 gcc_unreachable ();
16007 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
16010 rs6000_output_addr_const_extra (FILE *file, rtx x)
16012 if (GET_CODE (x) == UNSPEC)
16013 switch (XINT (x, 1))
16015 case UNSPEC_TOCREL:
16016 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16017 output_addr_const (file, XVECEXP (x, 0, 0));
16018 if (x == tocrel_base && tocrel_offset != const0_rtx)
16020 if (INTVAL (tocrel_offset) >= 0)
16021 fprintf (file, "+");
16022 output_addr_const (file, tocrel_offset);
16024 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16027 assemble_name (file, toc_label_name);
16029 else if (TARGET_ELF)
16030 fputs ("@toc", file);
16034 case UNSPEC_MACHOPIC_OFFSET:
16035 output_addr_const (file, XVECEXP (x, 0, 0));
16037 machopic_output_function_base_name (file);
16044 /* Target hook for assembling integer objects. The PowerPC version has
16045 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16046 is defined. It also needs to handle DI-mode objects on 64-bit
16050 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16052 #ifdef RELOCATABLE_NEEDS_FIXUP
16053 /* Special handling for SI values. */
16054 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16056 static int recurse = 0;
16058 /* For -mrelocatable, we mark all addresses that need to be fixed up
16059 in the .fixup section. */
16060 if (TARGET_RELOCATABLE
16061 && in_section != toc_section
16062 && in_section != text_section
16063 && !unlikely_text_section_p (in_section)
16065 && GET_CODE (x) != CONST_INT
16066 && GET_CODE (x) != CONST_DOUBLE
16072 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16074 ASM_OUTPUT_LABEL (asm_out_file, buf);
16075 fprintf (asm_out_file, "\t.long\t(");
16076 output_addr_const (asm_out_file, x);
16077 fprintf (asm_out_file, ")@fixup\n");
16078 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16079 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16080 fprintf (asm_out_file, "\t.long\t");
16081 assemble_name (asm_out_file, buf);
16082 fprintf (asm_out_file, "\n\t.previous\n");
16086 /* Remove initial .'s to turn a -mcall-aixdesc function
16087 address into the address of the descriptor, not the function
16089 else if (GET_CODE (x) == SYMBOL_REF
16090 && XSTR (x, 0)[0] == '.'
16091 && DEFAULT_ABI == ABI_AIX)
16093 const char *name = XSTR (x, 0);
16094 while (*name == '.')
16097 fprintf (asm_out_file, "\t.long\t%s\n", name);
16101 #endif /* RELOCATABLE_NEEDS_FIXUP */
16102 return default_assemble_integer (x, size, aligned_p);
16105 #ifdef HAVE_GAS_HIDDEN
16106 /* Emit an assembler directive to set symbol visibility for DECL to
16107 VISIBILITY_TYPE. */
16110 rs6000_assemble_visibility (tree decl, int vis)
16112 /* Functions need to have their entry point symbol visibility set as
16113 well as their descriptor symbol visibility. */
16114 if (DEFAULT_ABI == ABI_AIX
16116 && TREE_CODE (decl) == FUNCTION_DECL)
16118 static const char * const visibility_types[] = {
16119 NULL, "internal", "hidden", "protected"
16122 const char *name, *type;
16124 name = ((* targetm.strip_name_encoding)
16125 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16126 type = visibility_types[vis];
16128 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16129 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16132 default_assemble_visibility (decl, vis);
16137 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16139 /* Reversal of FP compares takes care -- an ordered compare
16140 becomes an unordered compare and vice versa. */
16141 if (mode == CCFPmode
16142 && (!flag_finite_math_only
16143 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16144 || code == UNEQ || code == LTGT))
16145 return reverse_condition_maybe_unordered (code);
16147 return reverse_condition (code);
16150 /* Generate a compare for CODE. Return a brand-new rtx that
16151 represents the result of the compare. */
16154 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16156 enum machine_mode comp_mode;
16157 rtx compare_result;
16158 enum rtx_code code = GET_CODE (cmp);
16159 rtx op0 = XEXP (cmp, 0);
16160 rtx op1 = XEXP (cmp, 1);
16162 if (FLOAT_MODE_P (mode))
16163 comp_mode = CCFPmode;
16164 else if (code == GTU || code == LTU
16165 || code == GEU || code == LEU)
16166 comp_mode = CCUNSmode;
16167 else if ((code == EQ || code == NE)
16168 && GET_CODE (op0) == SUBREG
16169 && GET_CODE (op1) == SUBREG
16170 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16171 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16172 /* These are unsigned values, perhaps there will be a later
16173 ordering compare that can be shared with this one.
16174 Unfortunately we cannot detect the signedness of the operands
16175 for non-subregs. */
16176 comp_mode = CCUNSmode;
16178 comp_mode = CCmode;
16180 /* First, the compare. */
16181 compare_result = gen_reg_rtx (comp_mode);
16183 /* E500 FP compare instructions on the GPRs. Yuck! */
16184 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16185 && FLOAT_MODE_P (mode))
16187 rtx cmp, or_result, compare_result2;
16188 enum machine_mode op_mode = GET_MODE (op0);
16190 if (op_mode == VOIDmode)
16191 op_mode = GET_MODE (op1);
16193 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16194 This explains the following mess. */
16198 case EQ: case UNEQ: case NE: case LTGT:
16202 cmp = (flag_finite_math_only && !flag_trapping_math)
16203 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16204 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16208 cmp = (flag_finite_math_only && !flag_trapping_math)
16209 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16210 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16214 cmp = (flag_finite_math_only && !flag_trapping_math)
16215 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16216 : gen_cmptfeq_gpr (compare_result, op0, op1);
16220 gcc_unreachable ();
16224 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16228 cmp = (flag_finite_math_only && !flag_trapping_math)
16229 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16230 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16234 cmp = (flag_finite_math_only && !flag_trapping_math)
16235 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16236 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16240 cmp = (flag_finite_math_only && !flag_trapping_math)
16241 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16242 : gen_cmptfgt_gpr (compare_result, op0, op1);
16246 gcc_unreachable ();
16250 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16254 cmp = (flag_finite_math_only && !flag_trapping_math)
16255 ? gen_tstsflt_gpr (compare_result, op0, op1)
16256 : gen_cmpsflt_gpr (compare_result, op0, op1);
16260 cmp = (flag_finite_math_only && !flag_trapping_math)
16261 ? gen_tstdflt_gpr (compare_result, op0, op1)
16262 : gen_cmpdflt_gpr (compare_result, op0, op1);
16266 cmp = (flag_finite_math_only && !flag_trapping_math)
16267 ? gen_tsttflt_gpr (compare_result, op0, op1)
16268 : gen_cmptflt_gpr (compare_result, op0, op1);
16272 gcc_unreachable ();
16276 gcc_unreachable ();
16279 /* Synthesize LE and GE from LT/GT || EQ. */
16280 if (code == LE || code == GE || code == LEU || code == GEU)
16286 case LE: code = LT; break;
16287 case GE: code = GT; break;
16288 case LEU: code = LT; break;
16289 case GEU: code = GT; break;
16290 default: gcc_unreachable ();
16293 compare_result2 = gen_reg_rtx (CCFPmode);
16299 cmp = (flag_finite_math_only && !flag_trapping_math)
16300 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16301 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16305 cmp = (flag_finite_math_only && !flag_trapping_math)
16306 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16307 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16311 cmp = (flag_finite_math_only && !flag_trapping_math)
16312 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16313 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16317 gcc_unreachable ();
16321 /* OR them together. */
16322 or_result = gen_reg_rtx (CCFPmode);
16323 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16325 compare_result = or_result;
16330 if (code == NE || code == LTGT)
16340 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16341 CLOBBERs to match cmptf_internal2 pattern. */
16342 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16343 && GET_MODE (op0) == TFmode
16344 && !TARGET_IEEEQUAD
16345 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16346 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16348 gen_rtx_SET (VOIDmode,
16350 gen_rtx_COMPARE (comp_mode, op0, op1)),
16351 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16352 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16353 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16354 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16355 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16356 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16357 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16358 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16359 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16360 else if (GET_CODE (op1) == UNSPEC
16361 && XINT (op1, 1) == UNSPEC_SP_TEST)
16363 rtx op1b = XVECEXP (op1, 0, 0);
16364 comp_mode = CCEQmode;
16365 compare_result = gen_reg_rtx (CCEQmode);
16367 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16369 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16372 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16373 gen_rtx_COMPARE (comp_mode, op0, op1)));
16376 /* Some kinds of FP comparisons need an OR operation;
16377 under flag_finite_math_only we don't bother. */
16378 if (FLOAT_MODE_P (mode)
16379 && !flag_finite_math_only
16380 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16381 && (code == LE || code == GE
16382 || code == UNEQ || code == LTGT
16383 || code == UNGT || code == UNLT))
16385 enum rtx_code or1, or2;
16386 rtx or1_rtx, or2_rtx, compare2_rtx;
16387 rtx or_result = gen_reg_rtx (CCEQmode);
16391 case LE: or1 = LT; or2 = EQ; break;
16392 case GE: or1 = GT; or2 = EQ; break;
16393 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16394 case LTGT: or1 = LT; or2 = GT; break;
16395 case UNGT: or1 = UNORDERED; or2 = GT; break;
16396 case UNLT: or1 = UNORDERED; or2 = LT; break;
16397 default: gcc_unreachable ();
16399 validate_condition_mode (or1, comp_mode);
16400 validate_condition_mode (or2, comp_mode);
16401 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16402 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16403 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16404 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16406 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16408 compare_result = or_result;
16412 validate_condition_mode (code, GET_MODE (compare_result));
16414 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16418 /* Emit the RTL for an sISEL pattern. */
16421 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16423 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16427 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16430 enum machine_mode op_mode;
16431 enum rtx_code cond_code;
16432 rtx result = operands[0];
16434 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16436 rs6000_emit_sISEL (mode, operands);
16440 condition_rtx = rs6000_generate_compare (operands[1], mode);
16441 cond_code = GET_CODE (condition_rtx);
16443 if (FLOAT_MODE_P (mode)
16444 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16448 PUT_MODE (condition_rtx, SImode);
16449 t = XEXP (condition_rtx, 0);
16451 gcc_assert (cond_code == NE || cond_code == EQ);
16453 if (cond_code == NE)
16454 emit_insn (gen_e500_flip_gt_bit (t, t));
16456 emit_insn (gen_move_from_CR_gt_bit (result, t));
16460 if (cond_code == NE
16461 || cond_code == GE || cond_code == LE
16462 || cond_code == GEU || cond_code == LEU
16463 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16465 rtx not_result = gen_reg_rtx (CCEQmode);
16466 rtx not_op, rev_cond_rtx;
16467 enum machine_mode cc_mode;
16469 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16471 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16472 SImode, XEXP (condition_rtx, 0), const0_rtx);
16473 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16474 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16475 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16478 op_mode = GET_MODE (XEXP (operands[1], 0));
16479 if (op_mode == VOIDmode)
16480 op_mode = GET_MODE (XEXP (operands[1], 1));
16482 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16484 PUT_MODE (condition_rtx, DImode);
16485 convert_move (result, condition_rtx, 0);
16489 PUT_MODE (condition_rtx, SImode);
16490 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16494 /* Emit a branch of kind CODE to location LOC. */
16497 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16499 rtx condition_rtx, loc_ref;
16501 condition_rtx = rs6000_generate_compare (operands[0], mode);
16502 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16503 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16504 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16505 loc_ref, pc_rtx)));
16508 /* Return the string to output a conditional branch to LABEL, which is
16509 the operand number of the label, or -1 if the branch is really a
16510 conditional return.
16512 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16513 condition code register and its mode specifies what kind of
16514 comparison we made.
16516 REVERSED is nonzero if we should reverse the sense of the comparison.
16518 INSN is the insn. */
16521 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16523 static char string[64];
16524 enum rtx_code code = GET_CODE (op);
16525 rtx cc_reg = XEXP (op, 0);
16526 enum machine_mode mode = GET_MODE (cc_reg);
16527 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16528 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16529 int really_reversed = reversed ^ need_longbranch;
16535 validate_condition_mode (code, mode);
16537 /* Work out which way this really branches. We could use
16538 reverse_condition_maybe_unordered here always but this
16539 makes the resulting assembler clearer. */
16540 if (really_reversed)
16542 /* Reversal of FP compares takes care -- an ordered compare
16543 becomes an unordered compare and vice versa. */
16544 if (mode == CCFPmode)
16545 code = reverse_condition_maybe_unordered (code);
16547 code = reverse_condition (code);
16550 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16552 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16557 /* Opposite of GT. */
16566 gcc_unreachable ();
16572 /* Not all of these are actually distinct opcodes, but
16573 we distinguish them for clarity of the resulting assembler. */
16574 case NE: case LTGT:
16575 ccode = "ne"; break;
16576 case EQ: case UNEQ:
16577 ccode = "eq"; break;
16579 ccode = "ge"; break;
16580 case GT: case GTU: case UNGT:
16581 ccode = "gt"; break;
16583 ccode = "le"; break;
16584 case LT: case LTU: case UNLT:
16585 ccode = "lt"; break;
16586 case UNORDERED: ccode = "un"; break;
16587 case ORDERED: ccode = "nu"; break;
16588 case UNGE: ccode = "nl"; break;
16589 case UNLE: ccode = "ng"; break;
16591 gcc_unreachable ();
16594 /* Maybe we have a guess as to how likely the branch is.
16595 The old mnemonics don't have a way to specify this information. */
16597 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16598 if (note != NULL_RTX)
16600 /* PROB is the difference from 50%. */
16601 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16603 /* Only hint for highly probable/improbable branches on newer
16604 cpus as static prediction overrides processor dynamic
16605 prediction. For older cpus we may as well always hint, but
16606 assume not taken for branches that are very close to 50% as a
16607 mispredicted taken branch is more expensive than a
16608 mispredicted not-taken branch. */
16609 if (rs6000_always_hint
16610 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16611 && br_prob_note_reliable_p (note)))
16613 if (abs (prob) > REG_BR_PROB_BASE / 20
16614 && ((prob > 0) ^ need_longbranch))
16622 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16624 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16626 /* We need to escape any '%' characters in the reg_names string.
16627 Assume they'd only be the first character.... */
16628 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16630 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16634 /* If the branch distance was too far, we may have to use an
16635 unconditional branch to go the distance. */
16636 if (need_longbranch)
16637 s += sprintf (s, ",$+8\n\tb %s", label);
16639 s += sprintf (s, ",%s", label);
16645 /* Return the string to flip the GT bit on a CR. */
16647 output_e500_flip_gt_bit (rtx dst, rtx src)
16649 static char string[64];
16652 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16653 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16656 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16657 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16659 sprintf (string, "crnot %d,%d", a, b);
16663 /* Return insn for VSX or Altivec comparisons. */
16666 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16669 enum machine_mode mode = GET_MODE (op0);
16677 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16683 mask = gen_reg_rtx (mode);
16684 emit_insn (gen_rtx_SET (VOIDmode,
16686 gen_rtx_fmt_ee (code, mode, op0, op1)));
16693 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16694 DMODE is expected destination mode. This is a recursive function. */
16697 rs6000_emit_vector_compare (enum rtx_code rcode,
16699 enum machine_mode dmode)
16702 bool swap_operands = false;
16703 bool try_again = false;
16705 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16706 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16708 /* See if the comparison works as is. */
16709 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16717 swap_operands = true;
16722 swap_operands = true;
16730 /* Invert condition and try again.
16731 e.g., A != B becomes ~(A==B). */
16733 enum rtx_code rev_code;
16734 enum insn_code nor_code;
16737 rev_code = reverse_condition_maybe_unordered (rcode);
16738 if (rev_code == UNKNOWN)
16741 nor_code = optab_handler (one_cmpl_optab, dmode);
16742 if (nor_code == CODE_FOR_nothing)
16745 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16749 mask = gen_reg_rtx (dmode);
16750 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16758 /* Try GT/GTU/LT/LTU OR EQ */
16761 enum insn_code ior_code;
16762 enum rtx_code new_code;
16783 gcc_unreachable ();
16786 ior_code = optab_handler (ior_optab, dmode);
16787 if (ior_code == CODE_FOR_nothing)
16790 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16794 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16798 mask = gen_reg_rtx (dmode);
16799 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16817 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16822 /* You only get two chances. */
16826 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16827 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16828 operands for the relation operation COND. */
16831 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16832 rtx cond, rtx cc_op0, rtx cc_op1)
16834 enum machine_mode dest_mode = GET_MODE (dest);
16835 enum rtx_code rcode = GET_CODE (cond);
16836 enum machine_mode cc_mode = CCmode;
16840 bool invert_move = false;
16842 if (VECTOR_UNIT_NONE_P (dest_mode))
16847 /* Swap operands if we can, and fall back to doing the operation as
16848 specified, and doing a NOR to invert the test. */
16854 /* Invert condition and try again.
16855 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16856 invert_move = true;
16857 rcode = reverse_condition_maybe_unordered (rcode);
16858 if (rcode == UNKNOWN)
16862 /* Mark unsigned tests with CCUNSmode. */
16867 cc_mode = CCUNSmode;
16874 /* Get the vector mask for the given relational operations. */
16875 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16883 op_true = op_false;
16887 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16888 emit_insn (gen_rtx_SET (VOIDmode,
16890 gen_rtx_IF_THEN_ELSE (dest_mode,
16897 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16898 operands of the last comparison is nonzero/true, FALSE_COND if it
16899 is zero/false. Return 0 if the hardware has no such operation. */
16902 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16904 enum rtx_code code = GET_CODE (op);
16905 rtx op0 = XEXP (op, 0);
16906 rtx op1 = XEXP (op, 1);
16907 REAL_VALUE_TYPE c1;
16908 enum machine_mode compare_mode = GET_MODE (op0);
16909 enum machine_mode result_mode = GET_MODE (dest);
16911 bool is_against_zero;
16913 /* These modes should always match. */
16914 if (GET_MODE (op1) != compare_mode
16915 /* In the isel case however, we can use a compare immediate, so
16916 op1 may be a small constant. */
16917 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16919 if (GET_MODE (true_cond) != result_mode)
16921 if (GET_MODE (false_cond) != result_mode)
16924 /* First, work out if the hardware can do this at all, or
16925 if it's too slow.... */
16926 if (!FLOAT_MODE_P (compare_mode))
16929 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16932 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16933 && SCALAR_FLOAT_MODE_P (compare_mode))
16936 is_against_zero = op1 == CONST0_RTX (compare_mode);
16938 /* A floating-point subtract might overflow, underflow, or produce
16939 an inexact result, thus changing the floating-point flags, so it
16940 can't be generated if we care about that. It's safe if one side
16941 of the construct is zero, since then no subtract will be
16943 if (SCALAR_FLOAT_MODE_P (compare_mode)
16944 && flag_trapping_math && ! is_against_zero)
16947 /* Eliminate half of the comparisons by switching operands, this
16948 makes the remaining code simpler. */
16949 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16950 || code == LTGT || code == LT || code == UNLE)
16952 code = reverse_condition_maybe_unordered (code);
16954 true_cond = false_cond;
16958 /* UNEQ and LTGT take four instructions for a comparison with zero,
16959 it'll probably be faster to use a branch here too. */
16960 if (code == UNEQ && HONOR_NANS (compare_mode))
16963 if (GET_CODE (op1) == CONST_DOUBLE)
16964 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16966 /* We're going to try to implement comparisons by performing
16967 a subtract, then comparing against zero. Unfortunately,
16968 Inf - Inf is NaN which is not zero, and so if we don't
16969 know that the operand is finite and the comparison
16970 would treat EQ different to UNORDERED, we can't do it. */
16971 if (HONOR_INFINITIES (compare_mode)
16972 && code != GT && code != UNGE
16973 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16974 /* Constructs of the form (a OP b ? a : b) are safe. */
16975 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16976 || (! rtx_equal_p (op0, true_cond)
16977 && ! rtx_equal_p (op1, true_cond))))
16980 /* At this point we know we can use fsel. */
16982 /* Reduce the comparison to a comparison against zero. */
16983 if (! is_against_zero)
16985 temp = gen_reg_rtx (compare_mode);
16986 emit_insn (gen_rtx_SET (VOIDmode, temp,
16987 gen_rtx_MINUS (compare_mode, op0, op1)));
16989 op1 = CONST0_RTX (compare_mode);
16992 /* If we don't care about NaNs we can reduce some of the comparisons
16993 down to faster ones. */
16994 if (! HONOR_NANS (compare_mode))
17000 true_cond = false_cond;
17013 /* Now, reduce everything down to a GE. */
17020 temp = gen_reg_rtx (compare_mode);
17021 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17026 temp = gen_reg_rtx (compare_mode);
17027 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17032 temp = gen_reg_rtx (compare_mode);
17033 emit_insn (gen_rtx_SET (VOIDmode, temp,
17034 gen_rtx_NEG (compare_mode,
17035 gen_rtx_ABS (compare_mode, op0))));
17040 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17041 temp = gen_reg_rtx (result_mode);
17042 emit_insn (gen_rtx_SET (VOIDmode, temp,
17043 gen_rtx_IF_THEN_ELSE (result_mode,
17044 gen_rtx_GE (VOIDmode,
17046 true_cond, false_cond)));
17047 false_cond = true_cond;
17050 temp = gen_reg_rtx (compare_mode);
17051 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17056 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17057 temp = gen_reg_rtx (result_mode);
17058 emit_insn (gen_rtx_SET (VOIDmode, temp,
17059 gen_rtx_IF_THEN_ELSE (result_mode,
17060 gen_rtx_GE (VOIDmode,
17062 true_cond, false_cond)));
17063 true_cond = false_cond;
17066 temp = gen_reg_rtx (compare_mode);
17067 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17072 gcc_unreachable ();
17075 emit_insn (gen_rtx_SET (VOIDmode, dest,
17076 gen_rtx_IF_THEN_ELSE (result_mode,
17077 gen_rtx_GE (VOIDmode,
17079 true_cond, false_cond)));
17083 /* Same as above, but for ints (isel). */
17086 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17088 rtx condition_rtx, cr;
17089 enum machine_mode mode = GET_MODE (dest);
17090 enum rtx_code cond_code;
17091 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17094 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17097 /* We still have to do the compare, because isel doesn't do a
17098 compare, it just looks at the CRx bits set by a previous compare
17100 condition_rtx = rs6000_generate_compare (op, mode);
17101 cond_code = GET_CODE (condition_rtx);
17102 cr = XEXP (condition_rtx, 0);
17103 signedp = GET_MODE (cr) == CCmode;
17105 isel_func = (mode == SImode
17106 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17107 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17111 case LT: case GT: case LTU: case GTU: case EQ:
17112 /* isel handles these directly. */
17116 /* We need to swap the sense of the comparison. */
17119 true_cond = false_cond;
17121 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17126 false_cond = force_reg (mode, false_cond);
17127 if (true_cond != const0_rtx)
17128 true_cond = force_reg (mode, true_cond);
17130 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17136 output_isel (rtx *operands)
17138 enum rtx_code code;
17140 code = GET_CODE (operands[1]);
17142 gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
17144 return "isel %0,%2,%3,%j1";
17148 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17150 enum machine_mode mode = GET_MODE (op0);
17154 /* VSX/altivec have direct min/max insns. */
17155 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
17157 emit_insn (gen_rtx_SET (VOIDmode,
17159 gen_rtx_fmt_ee (code, mode, op0, op1)));
17163 if (code == SMAX || code == SMIN)
17168 if (code == SMAX || code == UMAX)
17169 target = emit_conditional_move (dest, c, op0, op1, mode,
17170 op0, op1, mode, 0);
17172 target = emit_conditional_move (dest, c, op0, op1, mode,
17173 op1, op0, mode, 0);
17174 gcc_assert (target);
17175 if (target != dest)
17176 emit_move_insn (dest, target);
17179 /* Emit instructions to perform a load-reserved/store-conditional operation.
17180 The operation performed is an atomic
17181 (set M (CODE:MODE M OP))
17182 If not NULL, BEFORE is atomically set to M before the operation, and
17183 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17184 If SYNC_P then a memory barrier is emitted before the operation.
17185 Either OP or M may be wrapped in a NOT operation. */
17188 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17189 rtx m, rtx op, rtx before_param, rtx after_param,
17192 enum machine_mode used_mode;
17193 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17196 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17197 rtx shift = NULL_RTX;
17200 emit_insn (gen_lwsync ());
17204 /* If this is smaller than SImode, we'll have to use SImode with
17206 if (mode == QImode || mode == HImode)
17210 if (MEM_ALIGN (used_m) >= 32)
17213 if (BYTES_BIG_ENDIAN)
17214 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17216 shift = GEN_INT (ishift);
17217 used_m = change_address (used_m, SImode, 0);
17221 rtx addrSI, aligned_addr;
17222 int shift_mask = mode == QImode ? 0x18 : 0x10;
17224 addrSI = gen_lowpart_common (SImode,
17225 force_reg (Pmode, XEXP (used_m, 0)));
17226 addrSI = force_reg (SImode, addrSI);
17227 shift = gen_reg_rtx (SImode);
17229 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17230 GEN_INT (shift_mask)));
17231 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17233 aligned_addr = expand_binop (Pmode, and_optab,
17235 GEN_INT (-4), NULL_RTX,
17236 1, OPTAB_LIB_WIDEN);
17237 used_m = change_address (used_m, SImode, aligned_addr);
17238 set_mem_align (used_m, 32);
17240 /* It's safe to keep the old alias set of USED_M, because
17241 the operation is atomic and only affects the original
17245 if (GET_CODE (op) == NOT)
17247 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17248 oldop = gen_rtx_NOT (SImode, oldop);
17251 oldop = lowpart_subreg (SImode, op, mode);
17257 newop = expand_binop (SImode, and_optab,
17258 oldop, GEN_INT (imask), NULL_RTX,
17259 1, OPTAB_LIB_WIDEN);
17260 emit_insn (gen_ashlsi3 (newop, newop, shift));
17263 case NOT: /* NAND */
17264 newop = expand_binop (SImode, ior_optab,
17265 oldop, GEN_INT (~imask), NULL_RTX,
17266 1, OPTAB_LIB_WIDEN);
17267 emit_insn (gen_rotlsi3 (newop, newop, shift));
17271 newop = expand_binop (SImode, ior_optab,
17272 oldop, GEN_INT (~imask), NULL_RTX,
17273 1, OPTAB_LIB_WIDEN);
17274 emit_insn (gen_rotlsi3 (newop, newop, shift));
17282 newop = expand_binop (SImode, and_optab,
17283 oldop, GEN_INT (imask), NULL_RTX,
17284 1, OPTAB_LIB_WIDEN);
17285 emit_insn (gen_ashlsi3 (newop, newop, shift));
17287 mask = gen_reg_rtx (SImode);
17288 emit_move_insn (mask, GEN_INT (imask));
17289 emit_insn (gen_ashlsi3 (mask, mask, shift));
17292 newop = gen_rtx_PLUS (SImode, m, newop);
17294 newop = gen_rtx_MINUS (SImode, m, newop);
17295 newop = gen_rtx_AND (SImode, newop, mask);
17296 newop = gen_rtx_IOR (SImode, newop,
17297 gen_rtx_AND (SImode,
17298 gen_rtx_NOT (SImode, mask),
17304 gcc_unreachable ();
17308 used_mode = SImode;
17309 before = gen_reg_rtx (used_mode);
17310 after = gen_reg_rtx (used_mode);
17315 before = before_param;
17316 after = after_param;
17318 if (before == NULL_RTX)
17319 before = gen_reg_rtx (used_mode);
17320 if (after == NULL_RTX)
17321 after = gen_reg_rtx (used_mode);
17324 if ((code == PLUS || code == MINUS)
17325 && used_mode != mode)
17326 the_op = op; /* Computed above. */
17327 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17328 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17329 else if (code == NOT)
17330 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17331 gen_rtx_NOT (used_mode, m),
17332 gen_rtx_NOT (used_mode, op));
17334 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17336 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17337 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17338 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17339 gen_rtx_UNSPEC (used_mode,
17340 gen_rtvec (1, the_op),
17342 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17344 if ((code == PLUS || code == MINUS) && used_mode != mode)
17345 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17346 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17348 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17349 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17351 /* Shift and mask the return values properly. */
17352 if (used_mode != mode && before_param)
17354 emit_insn (gen_lshrsi3 (before, before, shift));
17355 convert_move (before_param, before, 1);
17358 if (used_mode != mode && after_param)
17360 emit_insn (gen_lshrsi3 (after, after, shift));
17361 convert_move (after_param, after, 1);
17364 /* The previous sequence will end with a branch that's dependent on
17365 the conditional store, so placing an isync will ensure that no
17366 other instructions (especially, no load or store instructions)
17367 can start before the atomic operation completes. */
17369 emit_insn (gen_isync ());
17372 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17373 COND is true. Mark the jump as unlikely to be taken. */
17376 emit_unlikely_jump (rtx cond, rtx label)
17378 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17381 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17382 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17383 add_reg_note (x, REG_BR_PROB, very_unlikely);
17386 /* A subroutine of the atomic operation splitters. Emit a load-locked
17387 instruction in MODE. */
17390 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17392 rtx (*fn) (rtx, rtx) = NULL;
17393 if (mode == SImode)
17394 fn = gen_load_locked_si;
17395 else if (mode == DImode)
17396 fn = gen_load_locked_di;
17397 emit_insn (fn (reg, mem));
17400 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17401 instruction in MODE. */
17404 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17406 rtx (*fn) (rtx, rtx, rtx) = NULL;
17407 if (mode == SImode)
17408 fn = gen_store_conditional_si;
17409 else if (mode == DImode)
17410 fn = gen_store_conditional_di;
17412 /* Emit sync before stwcx. to address PPC405 Erratum. */
17413 if (PPC405_ERRATUM77)
17414 emit_insn (gen_memory_barrier ());
17416 emit_insn (fn (res, mem, val));
17419 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17420 to perform. MEM is the memory on which to operate. VAL is the second
17421 operand of the binary operator. BEFORE and AFTER are optional locations to
17422 return the value of MEM either before of after the operation. SCRATCH is
17423 a scratch register. */
17426 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17427 rtx before, rtx after, rtx scratch)
17429 enum machine_mode mode = GET_MODE (mem);
17430 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17432 emit_insn (gen_lwsync ());
17434 label = gen_label_rtx ();
17435 emit_label (label);
17436 label = gen_rtx_LABEL_REF (VOIDmode, label);
17438 if (before == NULL_RTX)
17440 emit_load_locked (mode, before, mem);
17443 x = gen_rtx_IOR (mode,
17444 gen_rtx_NOT (mode, before),
17445 gen_rtx_NOT (mode, val));
17446 else if (code == AND)
17447 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17449 x = gen_rtx_fmt_ee (code, mode, before, val);
17451 if (after != NULL_RTX)
17452 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17453 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17455 emit_store_conditional (mode, cond, mem, scratch);
17457 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17458 emit_unlikely_jump (x, label);
17460 emit_insn (gen_isync ());
17463 /* Expand an atomic compare and swap operation. MEM is the memory on which
17464 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17465 value to be stored. SCRATCH is a scratch GPR. */
17468 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17471 enum machine_mode mode = GET_MODE (mem);
17472 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17474 emit_insn (gen_lwsync ());
17476 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17477 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17478 emit_label (XEXP (label1, 0));
17480 emit_load_locked (mode, retval, mem);
17482 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17483 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17485 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17486 emit_unlikely_jump (x, label2);
17488 emit_move_insn (scratch, newval);
17489 emit_store_conditional (mode, cond, mem, scratch);
17491 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17492 emit_unlikely_jump (x, label1);
17494 emit_insn (gen_isync ());
17495 emit_label (XEXP (label2, 0));
17498 /* Expand an atomic test and set operation. MEM is the memory on which
17499 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17502 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17504 enum machine_mode mode = GET_MODE (mem);
17505 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17507 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17508 emit_label (XEXP (label, 0));
17510 emit_load_locked (mode, retval, mem);
17511 emit_move_insn (scratch, val);
17512 emit_store_conditional (mode, cond, mem, scratch);
17514 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17515 emit_unlikely_jump (x, label);
17517 emit_insn (gen_isync ());
17521 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17523 enum machine_mode mode = GET_MODE (mem);
17524 rtx addrSI, align, wdst, shift, mask;
17525 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17526 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17528 /* Shift amount for subword relative to aligned word. */
17529 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17530 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17531 shift = gen_reg_rtx (SImode);
17532 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17533 GEN_INT (shift_mask)));
17534 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17536 /* Shift and mask old value into position within word. */
17537 oldval = convert_modes (SImode, mode, oldval, 1);
17538 oldval = expand_binop (SImode, and_optab,
17539 oldval, GEN_INT (imask), NULL_RTX,
17540 1, OPTAB_LIB_WIDEN);
17541 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17543 /* Shift and mask new value into position within word. */
17544 newval = convert_modes (SImode, mode, newval, 1);
17545 newval = expand_binop (SImode, and_optab,
17546 newval, GEN_INT (imask), NULL_RTX,
17547 1, OPTAB_LIB_WIDEN);
17548 emit_insn (gen_ashlsi3 (newval, newval, shift));
17550 /* Mask for insertion. */
17551 mask = gen_reg_rtx (SImode);
17552 emit_move_insn (mask, GEN_INT (imask));
17553 emit_insn (gen_ashlsi3 (mask, mask, shift));
17555 /* Address of aligned word containing subword. */
17556 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17557 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17558 mem = change_address (mem, SImode, align);
17559 set_mem_align (mem, 32);
17560 MEM_VOLATILE_P (mem) = 1;
17562 wdst = gen_reg_rtx (SImode);
17563 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17564 oldval, newval, mem));
17566 /* Shift the result back. */
17567 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17569 emit_move_insn (dst, gen_lowpart (mode, wdst));
17573 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17574 rtx oldval, rtx newval, rtx mem,
17577 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17579 emit_insn (gen_lwsync ());
17580 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17581 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17582 emit_label (XEXP (label1, 0));
17584 emit_load_locked (SImode, scratch, mem);
17586 /* Mask subword within loaded value for comparison with oldval.
17587 Use UNSPEC_AND to avoid clobber.*/
17588 emit_insn (gen_rtx_SET (SImode, dest,
17589 gen_rtx_UNSPEC (SImode,
17590 gen_rtvec (2, scratch, mask),
17593 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17594 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17596 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17597 emit_unlikely_jump (x, label2);
17599 /* Clear subword within loaded value for insertion of new value. */
17600 emit_insn (gen_rtx_SET (SImode, scratch,
17601 gen_rtx_AND (SImode,
17602 gen_rtx_NOT (SImode, mask), scratch)));
17603 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17604 emit_store_conditional (SImode, cond, mem, scratch);
17606 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17607 emit_unlikely_jump (x, label1);
17609 emit_insn (gen_isync ());
17610 emit_label (XEXP (label2, 0));
17614 /* Emit instructions to move SRC to DST. Called by splitters for
17615 multi-register moves. It will emit at most one instruction for
17616 each register that is accessed; that is, it won't emit li/lis pairs
17617 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17621 rs6000_split_multireg_move (rtx dst, rtx src)
17623 /* The register number of the first register being moved. */
17625 /* The mode that is to be moved. */
17626 enum machine_mode mode;
17627 /* The mode that the move is being done in, and its size. */
17628 enum machine_mode reg_mode;
17630 /* The number of registers that will be moved. */
17633 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17634 mode = GET_MODE (dst);
17635 nregs = hard_regno_nregs[reg][mode];
17636 if (FP_REGNO_P (reg))
17637 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17638 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17639 else if (ALTIVEC_REGNO_P (reg))
17640 reg_mode = V16QImode;
17641 else if (TARGET_E500_DOUBLE && mode == TFmode)
17644 reg_mode = word_mode;
17645 reg_mode_size = GET_MODE_SIZE (reg_mode);
17647 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17649 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17651 /* Move register range backwards, if we might have destructive
17654 for (i = nregs - 1; i >= 0; i--)
17655 emit_insn (gen_rtx_SET (VOIDmode,
17656 simplify_gen_subreg (reg_mode, dst, mode,
17657 i * reg_mode_size),
17658 simplify_gen_subreg (reg_mode, src, mode,
17659 i * reg_mode_size)));
17665 bool used_update = false;
17666 rtx restore_basereg = NULL_RTX;
17668 if (MEM_P (src) && INT_REGNO_P (reg))
17672 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17673 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17676 breg = XEXP (XEXP (src, 0), 0);
17677 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17678 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17679 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17680 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17681 src = replace_equiv_address (src, breg);
17683 else if (! rs6000_offsettable_memref_p (src))
17685 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17687 rtx basereg = XEXP (XEXP (src, 0), 0);
17690 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17691 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17692 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17693 used_update = true;
17696 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17697 XEXP (XEXP (src, 0), 1)));
17698 src = replace_equiv_address (src, basereg);
17702 rtx basereg = gen_rtx_REG (Pmode, reg);
17703 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17704 src = replace_equiv_address (src, basereg);
17708 breg = XEXP (src, 0);
17709 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17710 breg = XEXP (breg, 0);
17712 /* If the base register we are using to address memory is
17713 also a destination reg, then change that register last. */
17715 && REGNO (breg) >= REGNO (dst)
17716 && REGNO (breg) < REGNO (dst) + nregs)
17717 j = REGNO (breg) - REGNO (dst);
17719 else if (MEM_P (dst) && INT_REGNO_P (reg))
17723 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17724 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17727 breg = XEXP (XEXP (dst, 0), 0);
17728 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17729 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17730 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17732 /* We have to update the breg before doing the store.
17733 Use store with update, if available. */
17737 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17738 emit_insn (TARGET_32BIT
17739 ? (TARGET_POWERPC64
17740 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17741 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17742 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17743 used_update = true;
17746 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17747 dst = replace_equiv_address (dst, breg);
17749 else if (!rs6000_offsettable_memref_p (dst)
17750 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17752 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17754 rtx basereg = XEXP (XEXP (dst, 0), 0);
17757 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17758 emit_insn (gen_rtx_SET (VOIDmode,
17759 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17760 used_update = true;
17763 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17764 XEXP (XEXP (dst, 0), 1)));
17765 dst = replace_equiv_address (dst, basereg);
17769 rtx basereg = XEXP (XEXP (dst, 0), 0);
17770 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17771 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17773 && REG_P (offsetreg)
17774 && REGNO (basereg) != REGNO (offsetreg));
17775 if (REGNO (basereg) == 0)
17777 rtx tmp = offsetreg;
17778 offsetreg = basereg;
17781 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17782 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17783 dst = replace_equiv_address (dst, basereg);
17786 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17787 gcc_assert (rs6000_offsettable_memref_p (dst));
17790 for (i = 0; i < nregs; i++)
17792 /* Calculate index to next subword. */
17797 /* If compiler already emitted move of first word by
17798 store with update, no need to do anything. */
17799 if (j == 0 && used_update)
17802 emit_insn (gen_rtx_SET (VOIDmode,
17803 simplify_gen_subreg (reg_mode, dst, mode,
17804 j * reg_mode_size),
17805 simplify_gen_subreg (reg_mode, src, mode,
17806 j * reg_mode_size)));
17808 if (restore_basereg != NULL_RTX)
17809 emit_insn (restore_basereg);
17814 /* This page contains routines that are used to determine what the
17815 function prologue and epilogue code will do and write them out. */
17817 /* Return the first fixed-point register that is required to be
17818 saved. 32 if none. */
17821 first_reg_to_save (void)
17825 /* Find lowest numbered live register. */
17826 for (first_reg = 13; first_reg <= 31; first_reg++)
17827 if (df_regs_ever_live_p (first_reg)
17828 && (! call_used_regs[first_reg]
17829 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17830 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17831 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17832 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17837 && crtl->uses_pic_offset_table
17838 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17839 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17845 /* Similar, for FP regs. */
17848 first_fp_reg_to_save (void)
17852 /* Find lowest numbered live register. */
17853 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17854 if (df_regs_ever_live_p (first_reg))
17860 /* Similar, for AltiVec regs. */
17863 first_altivec_reg_to_save (void)
17867 /* Stack frame remains as is unless we are in AltiVec ABI. */
17868 if (! TARGET_ALTIVEC_ABI)
17869 return LAST_ALTIVEC_REGNO + 1;
17871 /* On Darwin, the unwind routines are compiled without
17872 TARGET_ALTIVEC, and use save_world to save/restore the
17873 altivec registers when necessary. */
17874 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17875 && ! TARGET_ALTIVEC)
17876 return FIRST_ALTIVEC_REGNO + 20;
17878 /* Find lowest numbered live register. */
17879 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17880 if (df_regs_ever_live_p (i))
17886 /* Return a 32-bit mask of the AltiVec registers we need to set in
17887 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17888 the 32-bit word is 0. */
17890 static unsigned int
17891 compute_vrsave_mask (void)
17893 unsigned int i, mask = 0;
17895 /* On Darwin, the unwind routines are compiled without
17896 TARGET_ALTIVEC, and use save_world to save/restore the
17897 call-saved altivec registers when necessary. */
17898 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17899 && ! TARGET_ALTIVEC)
17902 /* First, find out if we use _any_ altivec registers. */
17903 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17904 if (df_regs_ever_live_p (i))
17905 mask |= ALTIVEC_REG_BIT (i);
17910 /* Next, remove the argument registers from the set. These must
17911 be in the VRSAVE mask set by the caller, so we don't need to add
17912 them in again. More importantly, the mask we compute here is
17913 used to generate CLOBBERs in the set_vrsave insn, and we do not
17914 wish the argument registers to die. */
17915 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17916 mask &= ~ALTIVEC_REG_BIT (i);
17918 /* Similarly, remove the return value from the set. */
17921 diddle_return_value (is_altivec_return_reg, &yes);
17923 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17929 /* For a very restricted set of circumstances, we can cut down the
17930 size of prologues/epilogues by calling our own save/restore-the-world
17934 compute_save_world_info (rs6000_stack_t *info_ptr)
17936 info_ptr->world_save_p = 1;
17937 info_ptr->world_save_p
17938 = (WORLD_SAVE_P (info_ptr)
17939 && DEFAULT_ABI == ABI_DARWIN
17940 && ! (cfun->calls_setjmp && flag_exceptions)
17941 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17942 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17943 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17944 && info_ptr->cr_save_p);
17946 /* This will not work in conjunction with sibcalls. Make sure there
17947 are none. (This check is expensive, but seldom executed.) */
17948 if (WORLD_SAVE_P (info_ptr))
17951 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17952 if ( GET_CODE (insn) == CALL_INSN
17953 && SIBLING_CALL_P (insn))
17955 info_ptr->world_save_p = 0;
17960 if (WORLD_SAVE_P (info_ptr))
17962 /* Even if we're not touching VRsave, make sure there's room on the
17963 stack for it, if it looks like we're calling SAVE_WORLD, which
17964 will attempt to save it. */
17965 info_ptr->vrsave_size = 4;
17967 /* If we are going to save the world, we need to save the link register too. */
17968 info_ptr->lr_save_p = 1;
17970 /* "Save" the VRsave register too if we're saving the world. */
17971 if (info_ptr->vrsave_mask == 0)
17972 info_ptr->vrsave_mask = compute_vrsave_mask ();
17974 /* Because the Darwin register save/restore routines only handle
17975 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17977 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17978 && (info_ptr->first_altivec_reg_save
17979 >= FIRST_SAVED_ALTIVEC_REGNO));
17986 is_altivec_return_reg (rtx reg, void *xyes)
17988 bool *yes = (bool *) xyes;
17989 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17994 /* Calculate the stack information for the current function. This is
17995 complicated by having two separate calling sequences, the AIX calling
17996 sequence and the V.4 calling sequence.
17998 AIX (and Darwin/Mac OS X) stack frames look like:
18000 SP----> +---------------------------------------+
18001 | back chain to caller | 0 0
18002 +---------------------------------------+
18003 | saved CR | 4 8 (8-11)
18004 +---------------------------------------+
18006 +---------------------------------------+
18007 | reserved for compilers | 12 24
18008 +---------------------------------------+
18009 | reserved for binders | 16 32
18010 +---------------------------------------+
18011 | saved TOC pointer | 20 40
18012 +---------------------------------------+
18013 | Parameter save area (P) | 24 48
18014 +---------------------------------------+
18015 | Alloca space (A) | 24+P etc.
18016 +---------------------------------------+
18017 | Local variable space (L) | 24+P+A
18018 +---------------------------------------+
18019 | Float/int conversion temporary (X) | 24+P+A+L
18020 +---------------------------------------+
18021 | Save area for AltiVec registers (W) | 24+P+A+L+X
18022 +---------------------------------------+
18023 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18024 +---------------------------------------+
18025 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18026 +---------------------------------------+
18027 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18028 +---------------------------------------+
18029 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18030 +---------------------------------------+
18031 old SP->| back chain to caller's caller |
18032 +---------------------------------------+
18034 The required alignment for AIX configurations is two words (i.e., 8
18038 V.4 stack frames look like:
18040 SP----> +---------------------------------------+
18041 | back chain to caller | 0
18042 +---------------------------------------+
18043 | caller's saved LR | 4
18044 +---------------------------------------+
18045 | Parameter save area (P) | 8
18046 +---------------------------------------+
18047 | Alloca space (A) | 8+P
18048 +---------------------------------------+
18049 | Varargs save area (V) | 8+P+A
18050 +---------------------------------------+
18051 | Local variable space (L) | 8+P+A+V
18052 +---------------------------------------+
18053 | Float/int conversion temporary (X) | 8+P+A+V+L
18054 +---------------------------------------+
18055 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18056 +---------------------------------------+
18057 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18058 +---------------------------------------+
18059 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18060 +---------------------------------------+
18061 | SPE: area for 64-bit GP registers |
18062 +---------------------------------------+
18063 | SPE alignment padding |
18064 +---------------------------------------+
18065 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18066 +---------------------------------------+
18067 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18068 +---------------------------------------+
18069 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18070 +---------------------------------------+
18071 old SP->| back chain to caller's caller |
18072 +---------------------------------------+
18074 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18075 given. (But note below and in sysv4.h that we require only 8 and
18076 may round up the size of our stack frame anyways. The historical
18077 reason is early versions of powerpc-linux which didn't properly
18078 align the stack at program startup. A happy side-effect is that
18079 -mno-eabi libraries can be used with -meabi programs.)
18081 The EABI configuration defaults to the V.4 layout. However,
18082 the stack alignment requirements may differ. If -mno-eabi is not
18083 given, the required stack alignment is 8 bytes; if -mno-eabi is
18084 given, the required alignment is 16 bytes. (But see V.4 comment
18087 #ifndef ABI_STACK_BOUNDARY
18088 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18091 static rs6000_stack_t *
18092 rs6000_stack_info (void)
18094 static rs6000_stack_t info;
18095 rs6000_stack_t *info_ptr = &info;
18096 int reg_size = TARGET_32BIT ? 4 : 8;
18100 HOST_WIDE_INT non_fixed_size;
18102 memset (&info, 0, sizeof (info));
18106 /* Cache value so we don't rescan instruction chain over and over. */
18107 if (cfun->machine->insn_chain_scanned_p == 0)
18108 cfun->machine->insn_chain_scanned_p
18109 = spe_func_has_64bit_regs_p () + 1;
18110 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18113 /* Select which calling sequence. */
18114 info_ptr->abi = DEFAULT_ABI;
18116 /* Calculate which registers need to be saved & save area size. */
18117 info_ptr->first_gp_reg_save = first_reg_to_save ();
18118 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18119 even if it currently looks like we won't. Reload may need it to
18120 get at a constant; if so, it will have already created a constant
18121 pool entry for it. */
18122 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18123 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18124 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18125 && crtl->uses_const_pool
18126 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18127 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18129 first_gp = info_ptr->first_gp_reg_save;
18131 info_ptr->gp_size = reg_size * (32 - first_gp);
18133 /* For the SPE, we have an additional upper 32-bits on each GPR.
18134 Ideally we should save the entire 64-bits only when the upper
18135 half is used in SIMD instructions. Since we only record
18136 registers live (not the size they are used in), this proves
18137 difficult because we'd have to traverse the instruction chain at
18138 the right time, taking reload into account. This is a real pain,
18139 so we opt to save the GPRs in 64-bits always if but one register
18140 gets used in 64-bits. Otherwise, all the registers in the frame
18141 get saved in 32-bits.
18143 So... since when we save all GPRs (except the SP) in 64-bits, the
18144 traditional GP save area will be empty. */
18145 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18146 info_ptr->gp_size = 0;
18148 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18149 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18151 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18152 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18153 - info_ptr->first_altivec_reg_save);
18155 /* Does this function call anything? */
18156 info_ptr->calls_p = (! current_function_is_leaf
18157 || cfun->machine->ra_needs_full_frame);
18159 /* Determine if we need to save the link register. */
18160 if ((DEFAULT_ABI == ABI_AIX
18162 && !TARGET_PROFILE_KERNEL)
18163 #ifdef TARGET_RELOCATABLE
18164 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18166 || (info_ptr->first_fp_reg_save != 64
18167 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
18168 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18169 || info_ptr->calls_p
18170 || rs6000_ra_ever_killed ())
18172 info_ptr->lr_save_p = 1;
18173 df_set_regs_ever_live (LR_REGNO, true);
18176 /* Determine if we need to save the condition code registers. */
18177 if (df_regs_ever_live_p (CR2_REGNO)
18178 || df_regs_ever_live_p (CR3_REGNO)
18179 || df_regs_ever_live_p (CR4_REGNO))
18181 info_ptr->cr_save_p = 1;
18182 if (DEFAULT_ABI == ABI_V4)
18183 info_ptr->cr_size = reg_size;
18186 /* If the current function calls __builtin_eh_return, then we need
18187 to allocate stack space for registers that will hold data for
18188 the exception handler. */
18189 if (crtl->calls_eh_return)
18192 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18195 /* SPE saves EH registers in 64-bits. */
18196 ehrd_size = i * (TARGET_SPE_ABI
18197 && info_ptr->spe_64bit_regs_used != 0
18198 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18203 /* Determine various sizes. */
18204 info_ptr->reg_size = reg_size;
18205 info_ptr->fixed_size = RS6000_SAVE_AREA;
18206 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18207 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18208 TARGET_ALTIVEC ? 16 : 8);
18209 if (FRAME_GROWS_DOWNWARD)
18210 info_ptr->vars_size
18211 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18212 + info_ptr->parm_size,
18213 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18214 - (info_ptr->fixed_size + info_ptr->vars_size
18215 + info_ptr->parm_size);
18217 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18218 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18220 info_ptr->spe_gp_size = 0;
18222 if (TARGET_ALTIVEC_ABI)
18223 info_ptr->vrsave_mask = compute_vrsave_mask ();
18225 info_ptr->vrsave_mask = 0;
18227 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18228 info_ptr->vrsave_size = 4;
18230 info_ptr->vrsave_size = 0;
18232 compute_save_world_info (info_ptr);
18234 /* Calculate the offsets. */
18235 switch (DEFAULT_ABI)
18239 gcc_unreachable ();
18243 info_ptr->fp_save_offset = - info_ptr->fp_size;
18244 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18246 if (TARGET_ALTIVEC_ABI)
18248 info_ptr->vrsave_save_offset
18249 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18251 /* Align stack so vector save area is on a quadword boundary.
18252 The padding goes above the vectors. */
18253 if (info_ptr->altivec_size != 0)
18254 info_ptr->altivec_padding_size
18255 = info_ptr->vrsave_save_offset & 0xF;
18257 info_ptr->altivec_padding_size = 0;
18259 info_ptr->altivec_save_offset
18260 = info_ptr->vrsave_save_offset
18261 - info_ptr->altivec_padding_size
18262 - info_ptr->altivec_size;
18263 gcc_assert (info_ptr->altivec_size == 0
18264 || info_ptr->altivec_save_offset % 16 == 0);
18266 /* Adjust for AltiVec case. */
18267 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18270 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18271 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18272 info_ptr->lr_save_offset = 2*reg_size;
18276 info_ptr->fp_save_offset = - info_ptr->fp_size;
18277 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18278 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18280 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18282 /* Align stack so SPE GPR save area is aligned on a
18283 double-word boundary. */
18284 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18285 info_ptr->spe_padding_size
18286 = 8 - (-info_ptr->cr_save_offset % 8);
18288 info_ptr->spe_padding_size = 0;
18290 info_ptr->spe_gp_save_offset
18291 = info_ptr->cr_save_offset
18292 - info_ptr->spe_padding_size
18293 - info_ptr->spe_gp_size;
18295 /* Adjust for SPE case. */
18296 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18298 else if (TARGET_ALTIVEC_ABI)
18300 info_ptr->vrsave_save_offset
18301 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18303 /* Align stack so vector save area is on a quadword boundary. */
18304 if (info_ptr->altivec_size != 0)
18305 info_ptr->altivec_padding_size
18306 = 16 - (-info_ptr->vrsave_save_offset % 16);
18308 info_ptr->altivec_padding_size = 0;
18310 info_ptr->altivec_save_offset
18311 = info_ptr->vrsave_save_offset
18312 - info_ptr->altivec_padding_size
18313 - info_ptr->altivec_size;
18315 /* Adjust for AltiVec case. */
18316 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18319 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18320 info_ptr->ehrd_offset -= ehrd_size;
18321 info_ptr->lr_save_offset = reg_size;
18325 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18326 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18327 + info_ptr->gp_size
18328 + info_ptr->altivec_size
18329 + info_ptr->altivec_padding_size
18330 + info_ptr->spe_gp_size
18331 + info_ptr->spe_padding_size
18333 + info_ptr->cr_size
18334 + info_ptr->vrsave_size,
18337 non_fixed_size = (info_ptr->vars_size
18338 + info_ptr->parm_size
18339 + info_ptr->save_size);
18341 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18342 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18344 /* Determine if we need to allocate any stack frame:
18346 For AIX we need to push the stack if a frame pointer is needed
18347 (because the stack might be dynamically adjusted), if we are
18348 debugging, if we make calls, or if the sum of fp_save, gp_save,
18349 and local variables are more than the space needed to save all
18350 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18351 + 18*8 = 288 (GPR13 reserved).
18353 For V.4 we don't have the stack cushion that AIX uses, but assume
18354 that the debugger can handle stackless frames. */
18356 if (info_ptr->calls_p)
18357 info_ptr->push_p = 1;
18359 else if (DEFAULT_ABI == ABI_V4)
18360 info_ptr->push_p = non_fixed_size != 0;
18362 else if (frame_pointer_needed)
18363 info_ptr->push_p = 1;
18365 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18366 info_ptr->push_p = 1;
18369 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18371 /* Zero offsets if we're not saving those registers. */
18372 if (info_ptr->fp_size == 0)
18373 info_ptr->fp_save_offset = 0;
18375 if (info_ptr->gp_size == 0)
18376 info_ptr->gp_save_offset = 0;
18378 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18379 info_ptr->altivec_save_offset = 0;
18381 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18382 info_ptr->vrsave_save_offset = 0;
18384 if (! TARGET_SPE_ABI
18385 || info_ptr->spe_64bit_regs_used == 0
18386 || info_ptr->spe_gp_size == 0)
18387 info_ptr->spe_gp_save_offset = 0;
18389 if (! info_ptr->lr_save_p)
18390 info_ptr->lr_save_offset = 0;
18392 if (! info_ptr->cr_save_p)
18393 info_ptr->cr_save_offset = 0;
18398 /* Return true if the current function uses any GPRs in 64-bit SIMD
18402 spe_func_has_64bit_regs_p (void)
18406 /* Functions that save and restore all the call-saved registers will
18407 need to save/restore the registers in 64-bits. */
18408 if (crtl->calls_eh_return
18409 || cfun->calls_setjmp
18410 || crtl->has_nonlocal_goto)
18413 insns = get_insns ();
18415 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18421 /* FIXME: This should be implemented with attributes...
18423 (set_attr "spe64" "true")....then,
18424 if (get_spe64(insn)) return true;
18426 It's the only reliable way to do the stuff below. */
18428 i = PATTERN (insn);
18429 if (GET_CODE (i) == SET)
18431 enum machine_mode mode = GET_MODE (SET_SRC (i));
18433 if (SPE_VECTOR_MODE (mode))
18435 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18445 debug_stack_info (rs6000_stack_t *info)
18447 const char *abi_string;
18450 info = rs6000_stack_info ();
18452 fprintf (stderr, "\nStack information for function %s:\n",
18453 ((current_function_decl && DECL_NAME (current_function_decl))
18454 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18459 default: abi_string = "Unknown"; break;
18460 case ABI_NONE: abi_string = "NONE"; break;
18461 case ABI_AIX: abi_string = "AIX"; break;
18462 case ABI_DARWIN: abi_string = "Darwin"; break;
18463 case ABI_V4: abi_string = "V.4"; break;
18466 fprintf (stderr, "\tABI = %5s\n", abi_string);
18468 if (TARGET_ALTIVEC_ABI)
18469 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18471 if (TARGET_SPE_ABI)
18472 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18474 if (info->first_gp_reg_save != 32)
18475 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18477 if (info->first_fp_reg_save != 64)
18478 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18480 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18481 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18482 info->first_altivec_reg_save);
18484 if (info->lr_save_p)
18485 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18487 if (info->cr_save_p)
18488 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18490 if (info->vrsave_mask)
18491 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18494 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18497 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18499 if (info->gp_save_offset)
18500 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18502 if (info->fp_save_offset)
18503 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18505 if (info->altivec_save_offset)
18506 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18507 info->altivec_save_offset);
18509 if (info->spe_gp_save_offset)
18510 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18511 info->spe_gp_save_offset);
18513 if (info->vrsave_save_offset)
18514 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18515 info->vrsave_save_offset);
18517 if (info->lr_save_offset)
18518 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18520 if (info->cr_save_offset)
18521 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18523 if (info->varargs_save_offset)
18524 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18526 if (info->total_size)
18527 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18530 if (info->vars_size)
18531 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18534 if (info->parm_size)
18535 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18537 if (info->fixed_size)
18538 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18541 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18543 if (info->spe_gp_size)
18544 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18547 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18549 if (info->altivec_size)
18550 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18552 if (info->vrsave_size)
18553 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18555 if (info->altivec_padding_size)
18556 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18557 info->altivec_padding_size);
18559 if (info->spe_padding_size)
18560 fprintf (stderr, "\tspe_padding_size = %5d\n",
18561 info->spe_padding_size);
18564 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18566 if (info->save_size)
18567 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18569 if (info->reg_size != 4)
18570 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18572 fprintf (stderr, "\n");
18576 rs6000_return_addr (int count, rtx frame)
18578 /* Currently we don't optimize very well between prolog and body
18579 code and for PIC code the code can be actually quite bad, so
18580 don't try to be too clever here. */
18581 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18583 cfun->machine->ra_needs_full_frame = 1;
18590 plus_constant (copy_to_reg
18591 (gen_rtx_MEM (Pmode,
18592 memory_address (Pmode, frame))),
18593 RETURN_ADDRESS_OFFSET)));
18596 cfun->machine->ra_need_lr = 1;
18597 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18600 /* Say whether a function is a candidate for sibcall handling or not.
18601 We do not allow indirect calls to be optimized into sibling calls.
18602 Also, we can't do it if there are any vector parameters; there's
18603 nowhere to put the VRsave code so it works; note that functions with
18604 vector parameters are required to have a prototype, so the argument
18605 type info must be available here. (The tail recursion case can work
18606 with vector parameters, but there's no way to distinguish here.) */
18608 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18613 if (TARGET_ALTIVEC_VRSAVE)
18615 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18616 type; type = TREE_CHAIN (type))
18618 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18622 if (DEFAULT_ABI == ABI_DARWIN
18623 || ((*targetm.binds_local_p) (decl)
18624 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18626 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18628 if (!lookup_attribute ("longcall", attr_list)
18629 || lookup_attribute ("shortcall", attr_list))
18636 /* NULL if INSN insn is valid within a low-overhead loop.
18637 Otherwise return why doloop cannot be applied.
18638 PowerPC uses the COUNT register for branch on table instructions. */
18640 static const char *
18641 rs6000_invalid_within_doloop (const_rtx insn)
18644 return "Function call in the loop.";
18647 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18648 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18649 return "Computed branch in the loop.";
18655 rs6000_ra_ever_killed (void)
18661 if (cfun->is_thunk)
18664 if (cfun->machine->lr_save_state)
18665 return cfun->machine->lr_save_state - 1;
18667 /* regs_ever_live has LR marked as used if any sibcalls are present,
18668 but this should not force saving and restoring in the
18669 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18670 clobbers LR, so that is inappropriate. */
18672 /* Also, the prologue can generate a store into LR that
18673 doesn't really count, like this:
18676 bcl to set PIC register
18680 When we're called from the epilogue, we need to avoid counting
18681 this as a store. */
18683 push_topmost_sequence ();
18684 top = get_insns ();
18685 pop_topmost_sequence ();
18686 reg = gen_rtx_REG (Pmode, LR_REGNO);
18688 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18694 if (!SIBLING_CALL_P (insn))
18697 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18699 else if (set_of (reg, insn) != NULL_RTX
18700 && !prologue_epilogue_contains (insn))
18707 /* Emit instructions needed to load the TOC register.
18708 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18709 a constant pool; or for SVR4 -fpic. */
18712 rs6000_emit_load_toc_table (int fromprolog)
18715 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18717 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18720 rtx lab, tmp1, tmp2, got;
18722 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18723 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18725 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18727 got = rs6000_got_sym ();
18728 tmp1 = tmp2 = dest;
18731 tmp1 = gen_reg_rtx (Pmode);
18732 tmp2 = gen_reg_rtx (Pmode);
18734 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18735 emit_move_insn (tmp1,
18736 gen_rtx_REG (Pmode, LR_REGNO));
18737 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18738 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18740 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18742 emit_insn (gen_load_toc_v4_pic_si ());
18743 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18745 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18748 rtx temp0 = (fromprolog
18749 ? gen_rtx_REG (Pmode, 0)
18750 : gen_reg_rtx (Pmode));
18756 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18757 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18759 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18760 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18762 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18763 emit_move_insn (dest,
18764 gen_rtx_REG (Pmode, LR_REGNO));
18765 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18771 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18772 lab = gen_label_rtx ();
18773 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18774 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18775 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18777 emit_insn (gen_addsi3 (dest, temp0, dest));
18779 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18781 /* This is for AIX code running in non-PIC ELF32. */
18784 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18785 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18787 emit_insn (gen_elf_high (dest, realsym));
18788 emit_insn (gen_elf_low (dest, dest, realsym));
18792 gcc_assert (DEFAULT_ABI == ABI_AIX);
18795 emit_insn (gen_load_toc_aix_si (dest));
18797 emit_insn (gen_load_toc_aix_di (dest));
18801 /* Emit instructions to restore the link register after determining where
18802 its value has been stored. */
18805 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18807 rs6000_stack_t *info = rs6000_stack_info ();
18810 operands[0] = source;
18811 operands[1] = scratch;
18813 if (info->lr_save_p)
18815 rtx frame_rtx = stack_pointer_rtx;
18816 HOST_WIDE_INT sp_offset = 0;
18819 if (frame_pointer_needed
18820 || cfun->calls_alloca
18821 || info->total_size > 32767)
18823 tmp = gen_frame_mem (Pmode, frame_rtx);
18824 emit_move_insn (operands[1], tmp);
18825 frame_rtx = operands[1];
18827 else if (info->push_p)
18828 sp_offset = info->total_size;
18830 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18831 tmp = gen_frame_mem (Pmode, tmp);
18832 emit_move_insn (tmp, operands[0]);
18835 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18837 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18838 state of lr_save_p so any change from here on would be a bug. In
18839 particular, stop rs6000_ra_ever_killed from considering the SET
18840 of lr we may have added just above. */
18841 cfun->machine->lr_save_state = info->lr_save_p + 1;
18844 static GTY(()) alias_set_type set = -1;
18847 get_TOC_alias_set (void)
18850 set = new_alias_set ();
18854 /* This returns nonzero if the current function uses the TOC. This is
18855 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18856 is generated by the ABI_V4 load_toc_* patterns. */
18863 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18866 rtx pat = PATTERN (insn);
18869 if (GET_CODE (pat) == PARALLEL)
18870 for (i = 0; i < XVECLEN (pat, 0); i++)
18872 rtx sub = XVECEXP (pat, 0, i);
18873 if (GET_CODE (sub) == USE)
18875 sub = XEXP (sub, 0);
18876 if (GET_CODE (sub) == UNSPEC
18877 && XINT (sub, 1) == UNSPEC_TOC)
18887 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18889 rtx tocrel, tocreg;
18891 if (TARGET_DEBUG_ADDR)
18893 if (GET_CODE (symbol) == SYMBOL_REF)
18894 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18898 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18899 GET_RTX_NAME (GET_CODE (symbol)));
18900 debug_rtx (symbol);
18904 if (!can_create_pseudo_p ())
18905 df_set_regs_ever_live (TOC_REGISTER, true);
18907 tocrel = gen_rtx_CONST (Pmode,
18908 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18910 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18911 if (TARGET_CMODEL != CMODEL_SMALL)
18913 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18914 if (largetoc_reg != NULL)
18916 emit_move_insn (largetoc_reg, hi);
18919 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18922 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18925 /* Issue assembly directives that create a reference to the given DWARF
18926 FRAME_TABLE_LABEL from the current function section. */
18928 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18930 fprintf (asm_out_file, "\t.ref %s\n",
18931 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18934 /* If _Unwind_* has been called from within the same module,
18935 toc register is not guaranteed to be saved to 40(1) on function
18936 entry. Save it there in that case. */
18939 rs6000_aix_emit_builtin_unwind_init (void)
18942 rtx stack_top = gen_reg_rtx (Pmode);
18943 rtx opcode_addr = gen_reg_rtx (Pmode);
18944 rtx opcode = gen_reg_rtx (SImode);
18945 rtx tocompare = gen_reg_rtx (SImode);
18946 rtx no_toc_save_needed = gen_label_rtx ();
18948 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18949 emit_move_insn (stack_top, mem);
18951 mem = gen_frame_mem (Pmode,
18952 gen_rtx_PLUS (Pmode, stack_top,
18953 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18954 emit_move_insn (opcode_addr, mem);
18955 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18956 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18957 : 0xE8410028, SImode));
18959 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18960 SImode, NULL_RTX, NULL_RTX,
18961 no_toc_save_needed, -1);
18963 mem = gen_frame_mem (Pmode,
18964 gen_rtx_PLUS (Pmode, stack_top,
18965 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18966 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18967 emit_label (no_toc_save_needed);
18970 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18971 and the change to the stack pointer. */
18974 rs6000_emit_stack_tie (void)
18976 rtx mem = gen_frame_mem (BLKmode,
18977 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18979 emit_insn (gen_stack_tie (mem));
18982 /* Emit the correct code for allocating stack space, as insns.
18983 If COPY_REG, make sure a copy of the old frame is left there.
18984 The generated code may use hard register 0 as a temporary. */
18987 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18990 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18991 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18992 rtx todec = gen_int_mode (-size, Pmode);
18995 if (INTVAL (todec) != -size)
18997 warning (0, "stack frame too large");
18998 emit_insn (gen_trap ());
19002 if (crtl->limit_stack)
19004 if (REG_P (stack_limit_rtx)
19005 && REGNO (stack_limit_rtx) > 1
19006 && REGNO (stack_limit_rtx) <= 31)
19008 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19009 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19012 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19014 && DEFAULT_ABI == ABI_V4)
19016 rtx toload = gen_rtx_CONST (VOIDmode,
19017 gen_rtx_PLUS (Pmode,
19021 emit_insn (gen_elf_high (tmp_reg, toload));
19022 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19023 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19027 warning (0, "stack limit expression is not supported");
19031 emit_move_insn (copy_reg, stack_reg);
19035 /* Need a note here so that try_split doesn't get confused. */
19036 if (get_last_insn () == NULL_RTX)
19037 emit_note (NOTE_INSN_DELETED);
19038 insn = emit_move_insn (tmp_reg, todec);
19039 try_split (PATTERN (insn), insn, 0);
19043 insn = emit_insn (TARGET_32BIT
19044 ? gen_movsi_update_stack (stack_reg, stack_reg,
19046 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19047 todec, stack_reg));
19048 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19049 it now and set the alias set/attributes. The above gen_*_update
19050 calls will generate a PARALLEL with the MEM set being the first
19052 par = PATTERN (insn);
19053 gcc_assert (GET_CODE (par) == PARALLEL);
19054 set = XVECEXP (par, 0, 0);
19055 gcc_assert (GET_CODE (set) == SET);
19056 mem = SET_DEST (set);
19057 gcc_assert (MEM_P (mem));
19058 MEM_NOTRAP_P (mem) = 1;
19059 set_mem_alias_set (mem, get_frame_alias_set ());
19061 RTX_FRAME_RELATED_P (insn) = 1;
19062 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19063 gen_rtx_SET (VOIDmode, stack_reg,
19064 gen_rtx_PLUS (Pmode, stack_reg,
19065 GEN_INT (-size))));
19068 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19070 #if PROBE_INTERVAL > 32768
19071 #error Cannot use indexed addressing mode for stack probing
19074 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19075 inclusive. These are offsets from the current stack pointer. */
19078 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19080 /* See if we have a constant small number of probes to generate. If so,
19081 that's the easy case. */
19082 if (first + size <= 32768)
19086 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19087 it exceeds SIZE. If only one probe is needed, this will not
19088 generate any code. Then probe at FIRST + SIZE. */
19089 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19090 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19092 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19095 /* Otherwise, do the same as above, but in a loop. Note that we must be
19096 extra careful with variables wrapping around because we might be at
19097 the very top (or the very bottom) of the address space and we have
19098 to be able to handle this case properly; in particular, we use an
19099 equality test for the loop condition. */
19102 HOST_WIDE_INT rounded_size;
19103 rtx r12 = gen_rtx_REG (Pmode, 12);
19104 rtx r0 = gen_rtx_REG (Pmode, 0);
19106 /* Sanity check for the addressing mode we're going to use. */
19107 gcc_assert (first <= 32768);
19109 /* Step 1: round SIZE to the previous multiple of the interval. */
19111 rounded_size = size & -PROBE_INTERVAL;
19114 /* Step 2: compute initial and final value of the loop counter. */
19116 /* TEST_ADDR = SP + FIRST. */
19117 emit_insn (gen_rtx_SET (VOIDmode, r12,
19118 plus_constant (stack_pointer_rtx, -first)));
19120 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19121 if (rounded_size > 32768)
19123 emit_move_insn (r0, GEN_INT (-rounded_size));
19124 emit_insn (gen_rtx_SET (VOIDmode, r0,
19125 gen_rtx_PLUS (Pmode, r12, r0)));
19128 emit_insn (gen_rtx_SET (VOIDmode, r0,
19129 plus_constant (r12, -rounded_size)));
19132 /* Step 3: the loop
19134 while (TEST_ADDR != LAST_ADDR)
19136 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19140 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19141 until it is equal to ROUNDED_SIZE. */
19144 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19146 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19149 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19150 that SIZE is equal to ROUNDED_SIZE. */
19152 if (size != rounded_size)
19153 emit_stack_probe (plus_constant (r12, rounded_size - size));
19157 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19158 absolute addresses. */
19161 output_probe_stack_range (rtx reg1, rtx reg2)
19163 static int labelno = 0;
19164 char loop_lab[32], end_lab[32];
19167 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19168 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19170 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19172 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19176 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19178 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19180 fputs ("\tbeq 0,", asm_out_file);
19181 assemble_name_raw (asm_out_file, end_lab);
19182 fputc ('\n', asm_out_file);
19184 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19185 xops[1] = GEN_INT (-PROBE_INTERVAL);
19186 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19188 /* Probe at TEST_ADDR and branch. */
19189 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19190 fprintf (asm_out_file, "\tb ");
19191 assemble_name_raw (asm_out_file, loop_lab);
19192 fputc ('\n', asm_out_file);
19194 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19199 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19200 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19201 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19202 deduce these equivalences by itself so it wasn't necessary to hold
19203 its hand so much. */
19206 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19207 rtx reg2, rtx rreg)
19211 /* copy_rtx will not make unique copies of registers, so we need to
19212 ensure we don't have unwanted sharing here. */
19214 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19217 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19219 real = copy_rtx (PATTERN (insn));
19221 if (reg2 != NULL_RTX)
19222 real = replace_rtx (real, reg2, rreg);
19224 real = replace_rtx (real, reg,
19225 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19226 STACK_POINTER_REGNUM),
19229 /* We expect that 'real' is either a SET or a PARALLEL containing
19230 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19231 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19233 if (GET_CODE (real) == SET)
19237 temp = simplify_rtx (SET_SRC (set));
19239 SET_SRC (set) = temp;
19240 temp = simplify_rtx (SET_DEST (set));
19242 SET_DEST (set) = temp;
19243 if (GET_CODE (SET_DEST (set)) == MEM)
19245 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19247 XEXP (SET_DEST (set), 0) = temp;
19254 gcc_assert (GET_CODE (real) == PARALLEL);
19255 for (i = 0; i < XVECLEN (real, 0); i++)
19256 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19258 rtx set = XVECEXP (real, 0, i);
19260 temp = simplify_rtx (SET_SRC (set));
19262 SET_SRC (set) = temp;
19263 temp = simplify_rtx (SET_DEST (set));
19265 SET_DEST (set) = temp;
19266 if (GET_CODE (SET_DEST (set)) == MEM)
19268 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19270 XEXP (SET_DEST (set), 0) = temp;
19272 RTX_FRAME_RELATED_P (set) = 1;
19276 RTX_FRAME_RELATED_P (insn) = 1;
19277 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19280 /* Returns an insn that has a vrsave set operation with the
19281 appropriate CLOBBERs. */
19284 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19287 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19288 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19291 = gen_rtx_SET (VOIDmode,
19293 gen_rtx_UNSPEC_VOLATILE (SImode,
19294 gen_rtvec (2, reg, vrsave),
19295 UNSPECV_SET_VRSAVE));
19299 /* We need to clobber the registers in the mask so the scheduler
19300 does not move sets to VRSAVE before sets of AltiVec registers.
19302 However, if the function receives nonlocal gotos, reload will set
19303 all call saved registers live. We will end up with:
19305 (set (reg 999) (mem))
19306 (parallel [ (set (reg vrsave) (unspec blah))
19307 (clobber (reg 999))])
19309 The clobber will cause the store into reg 999 to be dead, and
19310 flow will attempt to delete an epilogue insn. In this case, we
19311 need an unspec use/set of the register. */
19313 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19314 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19316 if (!epiloguep || call_used_regs [i])
19317 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19318 gen_rtx_REG (V4SImode, i));
19321 rtx reg = gen_rtx_REG (V4SImode, i);
19324 = gen_rtx_SET (VOIDmode,
19326 gen_rtx_UNSPEC (V4SImode,
19327 gen_rtvec (1, reg), 27));
19331 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19333 for (i = 0; i < nclobs; ++i)
19334 XVECEXP (insn, 0, i) = clobs[i];
19339 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19340 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19343 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19344 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19346 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19347 rtx replacea, replaceb;
19349 int_rtx = GEN_INT (offset);
19351 /* Some cases that need register indexed addressing. */
19352 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19353 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19354 || (TARGET_E500_DOUBLE && mode == DFmode)
19356 && SPE_VECTOR_MODE (mode)
19357 && !SPE_CONST_OFFSET_OK (offset)))
19359 /* Whomever calls us must make sure r11 is available in the
19360 flow path of instructions in the prologue. */
19361 offset_rtx = gen_rtx_REG (Pmode, 11);
19362 emit_move_insn (offset_rtx, int_rtx);
19364 replacea = offset_rtx;
19365 replaceb = int_rtx;
19369 offset_rtx = int_rtx;
19370 replacea = NULL_RTX;
19371 replaceb = NULL_RTX;
19374 reg = gen_rtx_REG (mode, regno);
19375 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19376 mem = gen_frame_mem (mode, addr);
19378 insn = emit_move_insn (mem, reg);
19380 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19383 /* Emit an offset memory reference suitable for a frame store, while
19384 converting to a valid addressing mode. */
19387 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19389 rtx int_rtx, offset_rtx;
19391 int_rtx = GEN_INT (offset);
19393 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19394 || (TARGET_E500_DOUBLE && mode == DFmode))
19396 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19397 emit_move_insn (offset_rtx, int_rtx);
19400 offset_rtx = int_rtx;
19402 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19405 /* Look for user-defined global regs. We should not save and restore these,
19406 and cannot use stmw/lmw if there are any in its range. */
19409 no_global_regs_above (int first, bool gpr)
19412 int last = gpr ? 32 : 64;
19413 for (i = first; i < last; i++)
19414 if (global_regs[i])
19419 #ifndef TARGET_FIX_AND_CONTINUE
19420 #define TARGET_FIX_AND_CONTINUE 0
19423 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19424 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19425 #define LAST_SAVRES_REGISTER 31
19426 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19428 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19430 /* Temporary holding space for an out-of-line register save/restore
19432 static char savres_routine_name[30];
19434 /* Return the name for an out-of-line register save/restore routine.
19435 We are saving/restoring GPRs if GPR is true. */
19438 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19439 bool savep, bool gpr, bool lr)
19441 const char *prefix = "";
19442 const char *suffix = "";
19444 /* Different targets are supposed to define
19445 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19446 routine name could be defined with:
19448 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19450 This is a nice idea in practice, but in reality, things are
19451 complicated in several ways:
19453 - ELF targets have save/restore routines for GPRs.
19455 - SPE targets use different prefixes for 32/64-bit registers, and
19456 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19458 - PPC64 ELF targets have routines for save/restore of GPRs that
19459 differ in what they do with the link register, so having a set
19460 prefix doesn't work. (We only use one of the save routines at
19461 the moment, though.)
19463 - PPC32 elf targets have "exit" versions of the restore routines
19464 that restore the link register and can save some extra space.
19465 These require an extra suffix. (There are also "tail" versions
19466 of the restore routines and "GOT" versions of the save routines,
19467 but we don't generate those at present. Same problems apply,
19470 We deal with all this by synthesizing our own prefix/suffix and
19471 using that for the simple sprintf call shown above. */
19474 /* No floating point saves on the SPE. */
19478 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19480 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19485 else if (DEFAULT_ABI == ABI_V4)
19491 prefix = savep ? "_savegpr_" : "_restgpr_";
19493 prefix = savep ? "_savefpr_" : "_restfpr_";
19498 else if (DEFAULT_ABI == ABI_AIX)
19500 #ifndef POWERPC_LINUX
19501 /* No out-of-line save/restore routines for GPRs on AIX. */
19502 gcc_assert (!TARGET_AIX || !gpr);
19508 ? (lr ? "_savegpr0_" : "_savegpr1_")
19509 : (lr ? "_restgpr0_" : "_restgpr1_"));
19510 #ifdef POWERPC_LINUX
19512 prefix = (savep ? "_savefpr_" : "_restfpr_");
19516 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19517 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19520 else if (DEFAULT_ABI == ABI_DARWIN)
19521 sorry ("Out-of-line save/restore routines not supported on Darwin");
19523 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19525 return savres_routine_name;
19528 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19529 We are saving/restoring GPRs if GPR is true. */
19532 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19535 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19537 int select = ((savep ? 1 : 0) << 2
19539 /* On the SPE, we never have any FPRs, but we do have
19540 32/64-bit versions of the routines. */
19541 ? (info->spe_64bit_regs_used ? 1 : 0)
19542 : (gpr ? 1 : 0)) << 1)
19545 /* Don't generate bogus routine names. */
19546 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19547 && regno <= LAST_SAVRES_REGISTER);
19549 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19555 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19557 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19558 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19559 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19565 /* Emit a sequence of insns, including a stack tie if needed, for
19566 resetting the stack pointer. If SAVRES is true, then don't reset the
19567 stack pointer, but move the base of the frame into r11 for use by
19568 out-of-line register restore routines. */
19571 rs6000_emit_stack_reset (rs6000_stack_t *info,
19572 rtx sp_reg_rtx, rtx frame_reg_rtx,
19573 int sp_offset, bool savres)
19575 /* This blockage is needed so that sched doesn't decide to move
19576 the sp change before the register restores. */
19577 if (frame_reg_rtx != sp_reg_rtx
19579 && info->spe_64bit_regs_used != 0
19580 && info->first_gp_reg_save != 32))
19581 rs6000_emit_stack_tie ();
19583 if (frame_reg_rtx != sp_reg_rtx)
19585 if (sp_offset != 0)
19587 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19588 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19589 GEN_INT (sp_offset)));
19592 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19594 else if (sp_offset != 0)
19596 /* If we are restoring registers out-of-line, we will be using the
19597 "exit" variants of the restore routines, which will reset the
19598 stack for us. But we do need to point r11 into the right place
19599 for those routines. */
19600 rtx dest_reg = (savres
19601 ? gen_rtx_REG (Pmode, 11)
19604 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19605 GEN_INT (sp_offset)));
19612 /* Construct a parallel rtx describing the effect of a call to an
19613 out-of-line register save/restore routine. */
19616 rs6000_make_savres_rtx (rs6000_stack_t *info,
19617 rtx frame_reg_rtx, int save_area_offset,
19618 enum machine_mode reg_mode,
19619 bool savep, bool gpr, bool lr)
19622 int offset, start_reg, end_reg, n_regs;
19623 int reg_size = GET_MODE_SIZE (reg_mode);
19629 ? info->first_gp_reg_save
19630 : info->first_fp_reg_save);
19631 end_reg = gpr ? 32 : 64;
19632 n_regs = end_reg - start_reg;
19633 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19636 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19638 RTVEC_ELT (p, offset++)
19639 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19641 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19642 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19643 RTVEC_ELT (p, offset++)
19644 = gen_rtx_USE (VOIDmode,
19645 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19649 for (i = 0; i < end_reg - start_reg; i++)
19651 rtx addr, reg, mem;
19652 reg = gen_rtx_REG (reg_mode, start_reg + i);
19653 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19654 GEN_INT (save_area_offset + reg_size*i));
19655 mem = gen_frame_mem (reg_mode, addr);
19657 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19659 savep ? reg : mem);
19664 rtx addr, reg, mem;
19665 reg = gen_rtx_REG (Pmode, 0);
19666 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19667 GEN_INT (info->lr_save_offset));
19668 mem = gen_frame_mem (Pmode, addr);
19669 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19672 return gen_rtx_PARALLEL (VOIDmode, p);
19675 /* Determine whether the gp REG is really used. */
19678 rs6000_reg_live_or_pic_offset_p (int reg)
19680 return ((df_regs_ever_live_p (reg)
19681 && (!call_used_regs[reg]
19682 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19683 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19684 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19685 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19686 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19690 SAVRES_MULTIPLE = 0x1,
19691 SAVRES_INLINE_FPRS = 0x2,
19692 SAVRES_INLINE_GPRS = 0x4,
19693 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19694 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19695 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19698 /* Determine the strategy for savings/restoring registers. */
19701 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19702 int using_static_chain_p, int sibcall)
19704 bool using_multiple_p;
19706 bool savres_fprs_inline;
19707 bool savres_gprs_inline;
19708 bool noclobber_global_gprs
19709 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19712 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19713 && (!TARGET_SPE_ABI
19714 || info->spe_64bit_regs_used == 0)
19715 && info->first_gp_reg_save < 31
19716 && noclobber_global_gprs);
19717 /* Don't bother to try to save things out-of-line if r11 is occupied
19718 by the static chain. It would require too much fiddling and the
19719 static chain is rarely used anyway. */
19720 common = (using_static_chain_p
19722 || crtl->calls_eh_return
19723 || !info->lr_save_p
19724 || cfun->machine->ra_need_lr
19725 || info->total_size > 32767);
19726 savres_fprs_inline = (common
19727 || info->first_fp_reg_save == 64
19728 || !no_global_regs_above (info->first_fp_reg_save,
19730 /* The out-of-line FP routines use
19731 double-precision stores; we can't use those
19732 routines if we don't have such stores. */
19733 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19734 || FP_SAVE_INLINE (info->first_fp_reg_save));
19735 savres_gprs_inline = (common
19736 /* Saving CR interferes with the exit routines
19737 used on the SPE, so just punt here. */
19740 && info->spe_64bit_regs_used != 0
19741 && info->cr_save_p != 0)
19742 || info->first_gp_reg_save == 32
19743 || !noclobber_global_gprs
19744 || GP_SAVE_INLINE (info->first_gp_reg_save));
19747 /* If we are going to use store multiple, then don't even bother
19748 with the out-of-line routines, since the store-multiple instruction
19749 will always be smaller. */
19750 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19753 /* The situation is more complicated with load multiple. We'd
19754 prefer to use the out-of-line routines for restores, since the
19755 "exit" out-of-line routines can handle the restore of LR and
19756 the frame teardown. But we can only use the out-of-line
19757 routines if we know that we've used store multiple or
19758 out-of-line routines in the prologue, i.e. if we've saved all
19759 the registers from first_gp_reg_save. Otherwise, we risk
19760 loading garbage from the stack. Furthermore, we can only use
19761 the "exit" out-of-line gpr restore if we haven't saved any
19763 bool saved_all = !savres_gprs_inline || using_multiple_p;
19765 if (saved_all && info->first_fp_reg_save != 64)
19766 /* We can't use the exit routine; use load multiple if it's
19768 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19771 strategy = (using_multiple_p
19772 | (savres_fprs_inline << 1)
19773 | (savres_gprs_inline << 2));
19774 #ifdef POWERPC_LINUX
19777 if (!savres_fprs_inline)
19778 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19779 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19780 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19783 if (TARGET_AIX && !savres_fprs_inline)
19784 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19789 /* Emit function prologue as insns. */
19792 rs6000_emit_prologue (void)
19794 rs6000_stack_t *info = rs6000_stack_info ();
19795 enum machine_mode reg_mode = Pmode;
19796 int reg_size = TARGET_32BIT ? 4 : 8;
19797 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19798 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19799 rtx frame_reg_rtx = sp_reg_rtx;
19800 rtx cr_save_rtx = NULL_RTX;
19803 int saving_FPRs_inline;
19804 int saving_GPRs_inline;
19805 int using_store_multiple;
19806 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19807 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19808 && call_used_regs[STATIC_CHAIN_REGNUM]);
19809 HOST_WIDE_INT sp_offset = 0;
19811 if (flag_stack_usage)
19812 current_function_static_stack_size = info->total_size;
19814 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19815 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19817 if (TARGET_FIX_AND_CONTINUE)
19819 /* gdb on darwin arranges to forward a function from the old
19820 address by modifying the first 5 instructions of the function
19821 to branch to the overriding function. This is necessary to
19822 permit function pointers that point to the old function to
19823 actually forward to the new function. */
19824 emit_insn (gen_nop ());
19825 emit_insn (gen_nop ());
19826 emit_insn (gen_nop ());
19827 emit_insn (gen_nop ());
19828 emit_insn (gen_nop ());
19831 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19833 reg_mode = V2SImode;
19837 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19838 /*static_chain_p=*/using_static_chain_p,
19840 using_store_multiple = strategy & SAVRES_MULTIPLE;
19841 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19842 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19844 /* For V.4, update stack before we do any saving and set back pointer. */
19845 if (! WORLD_SAVE_P (info)
19847 && (DEFAULT_ABI == ABI_V4
19848 || crtl->calls_eh_return))
19850 bool need_r11 = (TARGET_SPE
19851 ? (!saving_GPRs_inline
19852 && info->spe_64bit_regs_used == 0)
19853 : (!saving_FPRs_inline || !saving_GPRs_inline));
19854 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19856 if (info->total_size < 32767)
19857 sp_offset = info->total_size;
19859 frame_reg_rtx = copy_reg;
19860 else if (info->cr_save_p
19862 || info->first_fp_reg_save < 64
19863 || info->first_gp_reg_save < 32
19864 || info->altivec_size != 0
19865 || info->vrsave_mask != 0
19866 || crtl->calls_eh_return)
19868 copy_reg = frame_ptr_rtx;
19869 frame_reg_rtx = copy_reg;
19873 /* The prologue won't be saving any regs so there is no need
19874 to set up a frame register to access any frame save area.
19875 We also won't be using sp_offset anywhere below, but set
19876 the correct value anyway to protect against future
19877 changes to this function. */
19878 sp_offset = info->total_size;
19880 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19881 if (frame_reg_rtx != sp_reg_rtx)
19882 rs6000_emit_stack_tie ();
19885 /* Handle world saves specially here. */
19886 if (WORLD_SAVE_P (info))
19893 /* save_world expects lr in r0. */
19894 reg0 = gen_rtx_REG (Pmode, 0);
19895 if (info->lr_save_p)
19897 insn = emit_move_insn (reg0,
19898 gen_rtx_REG (Pmode, LR_REGNO));
19899 RTX_FRAME_RELATED_P (insn) = 1;
19902 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19903 assumptions about the offsets of various bits of the stack
19905 gcc_assert (info->gp_save_offset == -220
19906 && info->fp_save_offset == -144
19907 && info->lr_save_offset == 8
19908 && info->cr_save_offset == 4
19911 && (!crtl->calls_eh_return
19912 || info->ehrd_offset == -432)
19913 && info->vrsave_save_offset == -224
19914 && info->altivec_save_offset == -416);
19916 treg = gen_rtx_REG (SImode, 11);
19917 emit_move_insn (treg, GEN_INT (-info->total_size));
19919 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19920 in R11. It also clobbers R12, so beware! */
19922 /* Preserve CR2 for save_world prologues */
19924 sz += 32 - info->first_gp_reg_save;
19925 sz += 64 - info->first_fp_reg_save;
19926 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19927 p = rtvec_alloc (sz);
19929 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19930 gen_rtx_REG (SImode,
19932 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19933 gen_rtx_SYMBOL_REF (Pmode,
19935 /* We do floats first so that the instruction pattern matches
19937 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19939 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19940 ? DFmode : SFmode),
19941 info->first_fp_reg_save + i);
19942 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19943 GEN_INT (info->fp_save_offset
19944 + sp_offset + 8 * i));
19945 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19946 ? DFmode : SFmode), addr);
19948 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19950 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19952 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19953 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19954 GEN_INT (info->altivec_save_offset
19955 + sp_offset + 16 * i));
19956 rtx mem = gen_frame_mem (V4SImode, addr);
19958 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19960 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19962 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19963 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19964 GEN_INT (info->gp_save_offset
19965 + sp_offset + reg_size * i));
19966 rtx mem = gen_frame_mem (reg_mode, addr);
19968 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19972 /* CR register traditionally saved as CR2. */
19973 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19974 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19975 GEN_INT (info->cr_save_offset
19977 rtx mem = gen_frame_mem (reg_mode, addr);
19979 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19981 /* Explain about use of R0. */
19982 if (info->lr_save_p)
19984 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19985 GEN_INT (info->lr_save_offset
19987 rtx mem = gen_frame_mem (reg_mode, addr);
19989 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19991 /* Explain what happens to the stack pointer. */
19993 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19994 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19997 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19998 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19999 treg, GEN_INT (-info->total_size));
20000 sp_offset = info->total_size;
20003 /* If we use the link register, get it into r0. */
20004 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20006 rtx addr, reg, mem;
20008 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20009 gen_rtx_REG (Pmode, LR_REGNO));
20010 RTX_FRAME_RELATED_P (insn) = 1;
20012 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
20013 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
20015 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20016 GEN_INT (info->lr_save_offset + sp_offset));
20017 reg = gen_rtx_REG (Pmode, 0);
20018 mem = gen_rtx_MEM (Pmode, addr);
20019 /* This should not be of rs6000_sr_alias_set, because of
20020 __builtin_return_address. */
20022 insn = emit_move_insn (mem, reg);
20023 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20024 NULL_RTX, NULL_RTX);
20028 /* If we need to save CR, put it into r12 or r11. */
20029 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20034 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20036 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20037 RTX_FRAME_RELATED_P (insn) = 1;
20038 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20039 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20040 But that's OK. All we have to do is specify that _one_ condition
20041 code register is saved in this stack slot. The thrower's epilogue
20042 will then restore all the call-saved registers.
20043 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20044 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20045 gen_rtx_REG (SImode, CR2_REGNO));
20046 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20049 /* Do any required saving of fpr's. If only one or two to save, do
20050 it ourselves. Otherwise, call function. */
20051 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20054 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20055 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20056 && ! call_used_regs[info->first_fp_reg_save+i]))
20057 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20058 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20060 info->first_fp_reg_save + i,
20061 info->fp_save_offset + sp_offset + 8 * i,
20064 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20068 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20069 info->fp_save_offset + sp_offset,
20071 /*savep=*/true, /*gpr=*/false,
20073 & SAVRES_NOINLINE_FPRS_SAVES_LR)
20075 insn = emit_insn (par);
20076 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20077 NULL_RTX, NULL_RTX);
20080 /* Save GPRs. This is done as a PARALLEL if we are using
20081 the store-multiple instructions. */
20082 if (!WORLD_SAVE_P (info)
20084 && info->spe_64bit_regs_used != 0
20085 && info->first_gp_reg_save != 32)
20088 rtx spe_save_area_ptr;
20090 /* Determine whether we can address all of the registers that need
20091 to be saved with an offset from the stack pointer that fits in
20092 the small const field for SPE memory instructions. */
20093 int spe_regs_addressable_via_sp
20094 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20095 + (32 - info->first_gp_reg_save - 1) * reg_size)
20096 && saving_GPRs_inline);
20099 if (spe_regs_addressable_via_sp)
20101 spe_save_area_ptr = frame_reg_rtx;
20102 spe_offset = info->spe_gp_save_offset + sp_offset;
20106 /* Make r11 point to the start of the SPE save area. We need
20107 to be careful here if r11 is holding the static chain. If
20108 it is, then temporarily save it in r0. We would use r0 as
20109 our base register here, but using r0 as a base register in
20110 loads and stores means something different from what we
20112 int ool_adjust = (saving_GPRs_inline
20114 : (info->first_gp_reg_save
20115 - (FIRST_SAVRES_REGISTER+1))*8);
20116 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20117 + sp_offset - ool_adjust);
20119 if (using_static_chain_p)
20121 rtx r0 = gen_rtx_REG (Pmode, 0);
20122 gcc_assert (info->first_gp_reg_save > 11);
20124 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20127 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20128 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20130 GEN_INT (offset)));
20131 /* We need to make sure the move to r11 gets noted for
20132 properly outputting unwind information. */
20133 if (!saving_GPRs_inline)
20134 rs6000_frame_related (insn, frame_reg_rtx, offset,
20135 NULL_RTX, NULL_RTX);
20139 if (saving_GPRs_inline)
20141 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20142 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20144 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20145 rtx offset, addr, mem;
20147 /* We're doing all this to ensure that the offset fits into
20148 the immediate offset of 'evstdd'. */
20149 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20151 offset = GEN_INT (reg_size * i + spe_offset);
20152 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20153 mem = gen_rtx_MEM (V2SImode, addr);
20155 insn = emit_move_insn (mem, reg);
20157 rs6000_frame_related (insn, spe_save_area_ptr,
20158 info->spe_gp_save_offset
20159 + sp_offset + reg_size * i,
20160 offset, const0_rtx);
20167 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20169 /*savep=*/true, /*gpr=*/true,
20171 insn = emit_insn (par);
20172 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20173 NULL_RTX, NULL_RTX);
20177 /* Move the static chain pointer back. */
20178 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20179 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20181 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20185 /* Need to adjust r11 (r12) if we saved any FPRs. */
20186 if (info->first_fp_reg_save != 64)
20188 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20190 rtx offset = GEN_INT (sp_offset
20191 + (-8 * (64-info->first_fp_reg_save)));
20192 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20195 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20196 info->gp_save_offset + sp_offset,
20198 /*savep=*/true, /*gpr=*/true,
20200 & SAVRES_NOINLINE_GPRS_SAVES_LR)
20202 insn = emit_insn (par);
20203 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20204 NULL_RTX, NULL_RTX);
20206 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20210 p = rtvec_alloc (32 - info->first_gp_reg_save);
20211 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20213 rtx addr, reg, mem;
20214 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20215 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20216 GEN_INT (info->gp_save_offset
20219 mem = gen_frame_mem (reg_mode, addr);
20221 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20223 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20224 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20225 NULL_RTX, NULL_RTX);
20227 else if (!WORLD_SAVE_P (info))
20230 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20231 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20233 rtx addr, reg, mem;
20234 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20236 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20237 GEN_INT (info->gp_save_offset
20240 mem = gen_frame_mem (reg_mode, addr);
20242 insn = emit_move_insn (mem, reg);
20243 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20244 NULL_RTX, NULL_RTX);
20248 /* ??? There's no need to emit actual instructions here, but it's the
20249 easiest way to get the frame unwind information emitted. */
20250 if (crtl->calls_eh_return)
20252 unsigned int i, regno;
20254 /* In AIX ABI we need to pretend we save r2 here. */
20257 rtx addr, reg, mem;
20259 reg = gen_rtx_REG (reg_mode, 2);
20260 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20261 GEN_INT (sp_offset + 5 * reg_size));
20262 mem = gen_frame_mem (reg_mode, addr);
20264 insn = emit_move_insn (mem, reg);
20265 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20266 NULL_RTX, NULL_RTX);
20267 PATTERN (insn) = gen_blockage ();
20272 regno = EH_RETURN_DATA_REGNO (i);
20273 if (regno == INVALID_REGNUM)
20276 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20277 info->ehrd_offset + sp_offset
20278 + reg_size * (int) i,
20283 /* Save CR if we use any that must be preserved. */
20284 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20286 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20287 GEN_INT (info->cr_save_offset + sp_offset));
20288 rtx mem = gen_frame_mem (SImode, addr);
20289 /* See the large comment above about why CR2_REGNO is used. */
20290 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20292 /* If r12 was used to hold the original sp, copy cr into r0 now
20294 if (REGNO (frame_reg_rtx) == 12)
20298 cr_save_rtx = gen_rtx_REG (SImode, 0);
20299 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20300 RTX_FRAME_RELATED_P (insn) = 1;
20301 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20302 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20304 insn = emit_move_insn (mem, cr_save_rtx);
20306 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20307 NULL_RTX, NULL_RTX);
20310 /* Update stack and set back pointer unless this is V.4,
20311 for which it was done previously. */
20312 if (!WORLD_SAVE_P (info) && info->push_p
20313 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20315 rtx copy_reg = NULL;
20317 if (info->total_size < 32767)
20318 sp_offset = info->total_size;
20319 else if (info->altivec_size != 0
20320 || info->vrsave_mask != 0)
20322 copy_reg = frame_ptr_rtx;
20323 frame_reg_rtx = copy_reg;
20326 sp_offset = info->total_size;
20327 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20328 if (frame_reg_rtx != sp_reg_rtx)
20329 rs6000_emit_stack_tie ();
20332 /* Set frame pointer, if needed. */
20333 if (frame_pointer_needed)
20335 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20337 RTX_FRAME_RELATED_P (insn) = 1;
20340 /* Save AltiVec registers if needed. Save here because the red zone does
20341 not include AltiVec registers. */
20342 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20346 /* There should be a non inline version of this, for when we
20347 are saving lots of vector registers. */
20348 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20349 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20351 rtx areg, savereg, mem;
20354 offset = info->altivec_save_offset + sp_offset
20355 + 16 * (i - info->first_altivec_reg_save);
20357 savereg = gen_rtx_REG (V4SImode, i);
20359 areg = gen_rtx_REG (Pmode, 0);
20360 emit_move_insn (areg, GEN_INT (offset));
20362 /* AltiVec addressing mode is [reg+reg]. */
20363 mem = gen_frame_mem (V4SImode,
20364 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20366 insn = emit_move_insn (mem, savereg);
20368 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20369 areg, GEN_INT (offset));
20373 /* VRSAVE is a bit vector representing which AltiVec registers
20374 are used. The OS uses this to determine which vector
20375 registers to save on a context switch. We need to save
20376 VRSAVE on the stack frame, add whatever AltiVec registers we
20377 used in this function, and do the corresponding magic in the
20380 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20381 && info->vrsave_mask != 0)
20383 rtx reg, mem, vrsave;
20386 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20387 as frame_reg_rtx and r11 as the static chain pointer for
20388 nested functions. */
20389 reg = gen_rtx_REG (SImode, 0);
20390 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20392 emit_insn (gen_get_vrsave_internal (reg));
20394 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20396 if (!WORLD_SAVE_P (info))
20399 offset = info->vrsave_save_offset + sp_offset;
20400 mem = gen_frame_mem (SImode,
20401 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20402 GEN_INT (offset)));
20403 insn = emit_move_insn (mem, reg);
20406 /* Include the registers in the mask. */
20407 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20409 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20412 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20413 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20414 || (DEFAULT_ABI == ABI_V4
20415 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20416 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20418 /* If emit_load_toc_table will use the link register, we need to save
20419 it. We use R12 for this purpose because emit_load_toc_table
20420 can use register 0. This allows us to use a plain 'blr' to return
20421 from the procedure more often. */
20422 int save_LR_around_toc_setup = (TARGET_ELF
20423 && DEFAULT_ABI != ABI_AIX
20425 && ! info->lr_save_p
20426 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20427 if (save_LR_around_toc_setup)
20429 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20431 insn = emit_move_insn (frame_ptr_rtx, lr);
20432 RTX_FRAME_RELATED_P (insn) = 1;
20434 rs6000_emit_load_toc_table (TRUE);
20436 insn = emit_move_insn (lr, frame_ptr_rtx);
20437 RTX_FRAME_RELATED_P (insn) = 1;
20440 rs6000_emit_load_toc_table (TRUE);
20444 if (DEFAULT_ABI == ABI_DARWIN
20445 && flag_pic && crtl->uses_pic_offset_table)
20447 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20448 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20450 /* Save and restore LR locally around this call (in R0). */
20451 if (!info->lr_save_p)
20452 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20454 emit_insn (gen_load_macho_picbase (src));
20456 emit_move_insn (gen_rtx_REG (Pmode,
20457 RS6000_PIC_OFFSET_TABLE_REGNUM),
20460 if (!info->lr_save_p)
20461 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20466 /* Write function prologue. */
20469 rs6000_output_function_prologue (FILE *file,
20470 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20472 rs6000_stack_t *info = rs6000_stack_info ();
20474 if (TARGET_DEBUG_STACK)
20475 debug_stack_info (info);
20477 /* Write .extern for any function we will call to save and restore
20479 if (info->first_fp_reg_save < 64
20480 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20483 int regno = info->first_fp_reg_save - 32;
20485 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20486 /*gpr=*/false, /*lr=*/false);
20487 fprintf (file, "\t.extern %s\n", name);
20489 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20490 /*gpr=*/false, /*lr=*/true);
20491 fprintf (file, "\t.extern %s\n", name);
20494 /* Write .extern for AIX common mode routines, if needed. */
20495 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20497 fputs ("\t.extern __mulh\n", file);
20498 fputs ("\t.extern __mull\n", file);
20499 fputs ("\t.extern __divss\n", file);
20500 fputs ("\t.extern __divus\n", file);
20501 fputs ("\t.extern __quoss\n", file);
20502 fputs ("\t.extern __quous\n", file);
20503 common_mode_defined = 1;
20506 if (! HAVE_prologue)
20512 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20513 the "toplevel" insn chain. */
20514 emit_note (NOTE_INSN_DELETED);
20515 rs6000_emit_prologue ();
20516 emit_note (NOTE_INSN_DELETED);
20518 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20522 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20524 INSN_ADDRESSES_NEW (insn, addr);
20529 prologue = get_insns ();
20532 if (TARGET_DEBUG_STACK)
20533 debug_rtx_list (prologue, 100);
20535 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20539 rs6000_pic_labelno++;
20542 /* Non-zero if vmx regs are restored before the frame pop, zero if
20543 we restore after the pop when possible. */
20544 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20546 /* Reload CR from REG. */
20549 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20554 if (using_mfcr_multiple)
20556 for (i = 0; i < 8; i++)
20557 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20559 gcc_assert (count);
20562 if (using_mfcr_multiple && count > 1)
20567 p = rtvec_alloc (count);
20570 for (i = 0; i < 8; i++)
20571 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20573 rtvec r = rtvec_alloc (2);
20574 RTVEC_ELT (r, 0) = reg;
20575 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20576 RTVEC_ELT (p, ndx) =
20577 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20578 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20581 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20582 gcc_assert (ndx == count);
20585 for (i = 0; i < 8; i++)
20586 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20588 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20594 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20595 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20596 below stack pointer not cloberred by signals. */
20599 offset_below_red_zone_p (HOST_WIDE_INT offset)
20601 return offset < (DEFAULT_ABI == ABI_V4
20603 : TARGET_32BIT ? -220 : -288);
20606 /* Emit function epilogue as insns. */
20609 rs6000_emit_epilogue (int sibcall)
20611 rs6000_stack_t *info;
20612 int restoring_GPRs_inline;
20613 int restoring_FPRs_inline;
20614 int using_load_multiple;
20615 int using_mtcr_multiple;
20616 int use_backchain_to_restore_sp;
20620 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20621 rtx frame_reg_rtx = sp_reg_rtx;
20622 rtx cfa_restores = NULL_RTX;
20624 rtx cr_save_reg = NULL_RTX;
20625 enum machine_mode reg_mode = Pmode;
20626 int reg_size = TARGET_32BIT ? 4 : 8;
20629 info = rs6000_stack_info ();
20631 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20633 reg_mode = V2SImode;
20637 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20638 /*static_chain_p=*/0, sibcall);
20639 using_load_multiple = strategy & SAVRES_MULTIPLE;
20640 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20641 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20642 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20643 || rs6000_cpu == PROCESSOR_PPC603
20644 || rs6000_cpu == PROCESSOR_PPC750
20646 /* Restore via the backchain when we have a large frame, since this
20647 is more efficient than an addis, addi pair. The second condition
20648 here will not trigger at the moment; We don't actually need a
20649 frame pointer for alloca, but the generic parts of the compiler
20650 give us one anyway. */
20651 use_backchain_to_restore_sp = (info->total_size > 32767
20652 || info->total_size
20653 + (info->lr_save_p ? info->lr_save_offset : 0)
20655 || (cfun->calls_alloca
20656 && !frame_pointer_needed));
20657 restore_lr = (info->lr_save_p
20658 && (restoring_FPRs_inline
20659 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20660 && (restoring_GPRs_inline
20661 || info->first_fp_reg_save < 64));
20663 if (WORLD_SAVE_P (info))
20667 const char *alloc_rname;
20670 /* eh_rest_world_r10 will return to the location saved in the LR
20671 stack slot (which is not likely to be our caller.)
20672 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20673 rest_world is similar, except any R10 parameter is ignored.
20674 The exception-handling stuff that was here in 2.95 is no
20675 longer necessary. */
20679 + 32 - info->first_gp_reg_save
20680 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20681 + 63 + 1 - info->first_fp_reg_save);
20683 strcpy (rname, ((crtl->calls_eh_return) ?
20684 "*eh_rest_world_r10" : "*rest_world"));
20685 alloc_rname = ggc_strdup (rname);
20688 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20689 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20690 gen_rtx_REG (Pmode,
20693 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20694 /* The instruction pattern requires a clobber here;
20695 it is shared with the restVEC helper. */
20697 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20700 /* CR register traditionally saved as CR2. */
20701 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20702 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20703 GEN_INT (info->cr_save_offset));
20704 rtx mem = gen_frame_mem (reg_mode, addr);
20706 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20709 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20711 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20712 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20713 GEN_INT (info->gp_save_offset
20715 rtx mem = gen_frame_mem (reg_mode, addr);
20717 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20719 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20721 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20722 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20723 GEN_INT (info->altivec_save_offset
20725 rtx mem = gen_frame_mem (V4SImode, addr);
20727 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20729 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20731 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20732 ? DFmode : SFmode),
20733 info->first_fp_reg_save + i);
20734 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20735 GEN_INT (info->fp_save_offset
20737 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20738 ? DFmode : SFmode), addr);
20740 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20743 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20745 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20747 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20749 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20751 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20752 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20757 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20759 sp_offset = info->total_size;
20761 /* Restore AltiVec registers if we must do so before adjusting the
20763 if (TARGET_ALTIVEC_ABI
20764 && info->altivec_size != 0
20765 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20766 || (DEFAULT_ABI != ABI_V4
20767 && offset_below_red_zone_p (info->altivec_save_offset))))
20771 if (use_backchain_to_restore_sp)
20773 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20774 emit_move_insn (frame_reg_rtx,
20775 gen_rtx_MEM (Pmode, sp_reg_rtx));
20778 else if (frame_pointer_needed)
20779 frame_reg_rtx = hard_frame_pointer_rtx;
20781 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20782 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20784 rtx addr, areg, mem, reg;
20786 areg = gen_rtx_REG (Pmode, 0);
20788 (areg, GEN_INT (info->altivec_save_offset
20790 + 16 * (i - info->first_altivec_reg_save)));
20792 /* AltiVec addressing mode is [reg+reg]. */
20793 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20794 mem = gen_frame_mem (V4SImode, addr);
20796 reg = gen_rtx_REG (V4SImode, i);
20797 emit_move_insn (reg, mem);
20798 if (offset_below_red_zone_p (info->altivec_save_offset
20799 + (i - info->first_altivec_reg_save)
20801 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20806 /* Restore VRSAVE if we must do so before adjusting the stack. */
20808 && TARGET_ALTIVEC_VRSAVE
20809 && info->vrsave_mask != 0
20810 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20811 || (DEFAULT_ABI != ABI_V4
20812 && offset_below_red_zone_p (info->vrsave_save_offset))))
20814 rtx addr, mem, reg;
20816 if (frame_reg_rtx == sp_reg_rtx)
20818 if (use_backchain_to_restore_sp)
20820 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20821 emit_move_insn (frame_reg_rtx,
20822 gen_rtx_MEM (Pmode, sp_reg_rtx));
20825 else if (frame_pointer_needed)
20826 frame_reg_rtx = hard_frame_pointer_rtx;
20829 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20830 GEN_INT (info->vrsave_save_offset + sp_offset));
20831 mem = gen_frame_mem (SImode, addr);
20832 reg = gen_rtx_REG (SImode, 12);
20833 emit_move_insn (reg, mem);
20835 emit_insn (generate_set_vrsave (reg, info, 1));
20839 /* If we have a large stack frame, restore the old stack pointer
20840 using the backchain. */
20841 if (use_backchain_to_restore_sp)
20843 if (frame_reg_rtx == sp_reg_rtx)
20845 /* Under V.4, don't reset the stack pointer until after we're done
20846 loading the saved registers. */
20847 if (DEFAULT_ABI == ABI_V4)
20848 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20850 insn = emit_move_insn (frame_reg_rtx,
20851 gen_rtx_MEM (Pmode, sp_reg_rtx));
20854 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20855 && DEFAULT_ABI == ABI_V4)
20856 /* frame_reg_rtx has been set up by the altivec restore. */
20860 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20861 frame_reg_rtx = sp_reg_rtx;
20864 /* If we have a frame pointer, we can restore the old stack pointer
20866 else if (frame_pointer_needed)
20868 frame_reg_rtx = sp_reg_rtx;
20869 if (DEFAULT_ABI == ABI_V4)
20870 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20871 /* Prevent reordering memory accesses against stack pointer restore. */
20872 else if (cfun->calls_alloca
20873 || offset_below_red_zone_p (-info->total_size))
20875 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20876 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20877 MEM_NOTRAP_P (mem1) = 1;
20878 MEM_NOTRAP_P (mem2) = 1;
20879 emit_insn (gen_frame_tie (mem1, mem2));
20882 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20883 GEN_INT (info->total_size)));
20886 else if (info->push_p
20887 && DEFAULT_ABI != ABI_V4
20888 && !crtl->calls_eh_return)
20890 /* Prevent reordering memory accesses against stack pointer restore. */
20891 if (cfun->calls_alloca
20892 || offset_below_red_zone_p (-info->total_size))
20894 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20895 MEM_NOTRAP_P (mem) = 1;
20896 emit_insn (gen_stack_tie (mem));
20898 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20899 GEN_INT (info->total_size)));
20902 if (insn && frame_reg_rtx == sp_reg_rtx)
20906 REG_NOTES (insn) = cfa_restores;
20907 cfa_restores = NULL_RTX;
20909 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20910 RTX_FRAME_RELATED_P (insn) = 1;
20913 /* Restore AltiVec registers if we have not done so already. */
20914 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20915 && TARGET_ALTIVEC_ABI
20916 && info->altivec_size != 0
20917 && (DEFAULT_ABI == ABI_V4
20918 || !offset_below_red_zone_p (info->altivec_save_offset)))
20922 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20923 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20925 rtx addr, areg, mem, reg;
20927 areg = gen_rtx_REG (Pmode, 0);
20929 (areg, GEN_INT (info->altivec_save_offset
20931 + 16 * (i - info->first_altivec_reg_save)));
20933 /* AltiVec addressing mode is [reg+reg]. */
20934 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20935 mem = gen_frame_mem (V4SImode, addr);
20937 reg = gen_rtx_REG (V4SImode, i);
20938 emit_move_insn (reg, mem);
20939 if (DEFAULT_ABI == ABI_V4)
20940 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20945 /* Restore VRSAVE if we have not done so already. */
20946 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20948 && TARGET_ALTIVEC_VRSAVE
20949 && info->vrsave_mask != 0
20950 && (DEFAULT_ABI == ABI_V4
20951 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20953 rtx addr, mem, reg;
20955 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20956 GEN_INT (info->vrsave_save_offset + sp_offset));
20957 mem = gen_frame_mem (SImode, addr);
20958 reg = gen_rtx_REG (SImode, 12);
20959 emit_move_insn (reg, mem);
20961 emit_insn (generate_set_vrsave (reg, info, 1));
20964 /* Get the old lr if we saved it. If we are restoring registers
20965 out-of-line, then the out-of-line routines can do this for us. */
20966 if (restore_lr && restoring_GPRs_inline)
20968 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20969 info->lr_save_offset + sp_offset);
20971 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20974 /* Get the old cr if we saved it. */
20975 if (info->cr_save_p)
20977 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20978 GEN_INT (info->cr_save_offset + sp_offset));
20979 rtx mem = gen_frame_mem (SImode, addr);
20981 cr_save_reg = gen_rtx_REG (SImode,
20982 DEFAULT_ABI == ABI_AIX
20983 && !restoring_GPRs_inline
20984 && info->first_fp_reg_save < 64
20986 emit_move_insn (cr_save_reg, mem);
20989 /* Set LR here to try to overlap restores below. LR is always saved
20990 above incoming stack, so it never needs REG_CFA_RESTORE. */
20991 if (restore_lr && restoring_GPRs_inline)
20992 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20993 gen_rtx_REG (Pmode, 0));
20995 /* Load exception handler data registers, if needed. */
20996 if (crtl->calls_eh_return)
20998 unsigned int i, regno;
21002 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21003 GEN_INT (sp_offset + 5 * reg_size));
21004 rtx mem = gen_frame_mem (reg_mode, addr);
21006 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21013 regno = EH_RETURN_DATA_REGNO (i);
21014 if (regno == INVALID_REGNUM)
21017 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21018 info->ehrd_offset + sp_offset
21019 + reg_size * (int) i);
21021 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21025 /* Restore GPRs. This is done as a PARALLEL if we are using
21026 the load-multiple instructions. */
21028 && info->spe_64bit_regs_used != 0
21029 && info->first_gp_reg_save != 32)
21031 /* Determine whether we can address all of the registers that need
21032 to be saved with an offset from the stack pointer that fits in
21033 the small const field for SPE memory instructions. */
21034 int spe_regs_addressable_via_sp
21035 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21036 + (32 - info->first_gp_reg_save - 1) * reg_size)
21037 && restoring_GPRs_inline);
21040 if (spe_regs_addressable_via_sp)
21041 spe_offset = info->spe_gp_save_offset + sp_offset;
21044 rtx old_frame_reg_rtx = frame_reg_rtx;
21045 /* Make r11 point to the start of the SPE save area. We worried about
21046 not clobbering it when we were saving registers in the prologue.
21047 There's no need to worry here because the static chain is passed
21048 anew to every function. */
21049 int ool_adjust = (restoring_GPRs_inline
21051 : (info->first_gp_reg_save
21052 - (FIRST_SAVRES_REGISTER+1))*8);
21054 if (frame_reg_rtx == sp_reg_rtx)
21055 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21056 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21057 GEN_INT (info->spe_gp_save_offset
21060 /* Keep the invariant that frame_reg_rtx + sp_offset points
21061 at the top of the stack frame. */
21062 sp_offset = -info->spe_gp_save_offset;
21067 if (restoring_GPRs_inline)
21069 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21070 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21072 rtx offset, addr, mem, reg;
21074 /* We're doing all this to ensure that the immediate offset
21075 fits into the immediate field of 'evldd'. */
21076 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21078 offset = GEN_INT (spe_offset + reg_size * i);
21079 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21080 mem = gen_rtx_MEM (V2SImode, addr);
21081 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21083 insn = emit_move_insn (reg, mem);
21084 if (DEFAULT_ABI == ABI_V4)
21086 if (frame_pointer_needed
21087 && info->first_gp_reg_save + i
21088 == HARD_FRAME_POINTER_REGNUM)
21090 add_reg_note (insn, REG_CFA_DEF_CFA,
21091 plus_constant (frame_reg_rtx,
21093 RTX_FRAME_RELATED_P (insn) = 1;
21096 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21105 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21107 /*savep=*/false, /*gpr=*/true,
21109 emit_jump_insn (par);
21110 /* We don't want anybody else emitting things after we jumped
21115 else if (!restoring_GPRs_inline)
21117 /* We are jumping to an out-of-line function. */
21118 bool can_use_exit = info->first_fp_reg_save == 64;
21121 /* Emit stack reset code if we need it. */
21123 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21124 sp_offset, can_use_exit);
21127 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21130 GEN_INT (sp_offset - info->fp_size)));
21131 if (REGNO (frame_reg_rtx) == 11)
21132 sp_offset += info->fp_size;
21135 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21136 info->gp_save_offset, reg_mode,
21137 /*savep=*/false, /*gpr=*/true,
21138 /*lr=*/can_use_exit);
21142 if (info->cr_save_p)
21144 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21145 if (DEFAULT_ABI == ABI_V4)
21147 = alloc_reg_note (REG_CFA_RESTORE,
21148 gen_rtx_REG (SImode, CR2_REGNO),
21152 emit_jump_insn (par);
21154 /* We don't want anybody else emitting things after we jumped
21159 insn = emit_insn (par);
21160 if (DEFAULT_ABI == ABI_V4)
21162 if (frame_pointer_needed)
21164 add_reg_note (insn, REG_CFA_DEF_CFA,
21165 plus_constant (frame_reg_rtx, sp_offset));
21166 RTX_FRAME_RELATED_P (insn) = 1;
21169 for (i = info->first_gp_reg_save; i < 32; i++)
21171 = alloc_reg_note (REG_CFA_RESTORE,
21172 gen_rtx_REG (reg_mode, i), cfa_restores);
21175 else if (using_load_multiple)
21178 p = rtvec_alloc (32 - info->first_gp_reg_save);
21179 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21181 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21182 GEN_INT (info->gp_save_offset
21185 rtx mem = gen_frame_mem (reg_mode, addr);
21186 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21188 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21189 if (DEFAULT_ABI == ABI_V4)
21190 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21193 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21194 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21196 add_reg_note (insn, REG_CFA_DEF_CFA,
21197 plus_constant (frame_reg_rtx, sp_offset));
21198 RTX_FRAME_RELATED_P (insn) = 1;
21203 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21204 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21206 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21207 GEN_INT (info->gp_save_offset
21210 rtx mem = gen_frame_mem (reg_mode, addr);
21211 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21213 insn = emit_move_insn (reg, mem);
21214 if (DEFAULT_ABI == ABI_V4)
21216 if (frame_pointer_needed
21217 && info->first_gp_reg_save + i
21218 == HARD_FRAME_POINTER_REGNUM)
21220 add_reg_note (insn, REG_CFA_DEF_CFA,
21221 plus_constant (frame_reg_rtx, sp_offset));
21222 RTX_FRAME_RELATED_P (insn) = 1;
21225 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21231 if (restore_lr && !restoring_GPRs_inline)
21233 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21234 info->lr_save_offset + sp_offset);
21236 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21237 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21238 gen_rtx_REG (Pmode, 0));
21241 /* Restore fpr's if we need to do it without calling a function. */
21242 if (restoring_FPRs_inline)
21243 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21244 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21245 && ! call_used_regs[info->first_fp_reg_save+i]))
21247 rtx addr, mem, reg;
21248 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21249 GEN_INT (info->fp_save_offset
21252 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21253 ? DFmode : SFmode), addr);
21254 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21255 ? DFmode : SFmode),
21256 info->first_fp_reg_save + i);
21258 emit_move_insn (reg, mem);
21259 if (DEFAULT_ABI == ABI_V4)
21260 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21264 /* If we saved cr, restore it here. Just those that were used. */
21265 if (info->cr_save_p)
21267 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21268 if (DEFAULT_ABI == ABI_V4)
21270 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21274 /* If this is V.4, unwind the stack pointer after all of the loads
21276 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21277 sp_offset, !restoring_FPRs_inline);
21282 REG_NOTES (insn) = cfa_restores;
21283 cfa_restores = NULL_RTX;
21285 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21286 RTX_FRAME_RELATED_P (insn) = 1;
21289 if (crtl->calls_eh_return)
21291 rtx sa = EH_RETURN_STACKADJ_RTX;
21292 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21298 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21299 if (! restoring_FPRs_inline)
21300 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21302 p = rtvec_alloc (2);
21304 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21305 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21306 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21307 : gen_rtx_CLOBBER (VOIDmode,
21308 gen_rtx_REG (Pmode, 65)));
21310 /* If we have to restore more than two FP registers, branch to the
21311 restore function. It will return to our caller. */
21312 if (! restoring_FPRs_inline)
21317 sym = rs6000_savres_routine_sym (info,
21321 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21322 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21323 gen_rtx_REG (Pmode,
21324 DEFAULT_ABI == ABI_AIX
21326 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21329 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21330 GEN_INT (info->fp_save_offset + 8*i));
21331 mem = gen_frame_mem (DFmode, addr);
21333 RTVEC_ELT (p, i+4) =
21334 gen_rtx_SET (VOIDmode,
21335 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21340 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21344 /* Write function epilogue. */
21347 rs6000_output_function_epilogue (FILE *file,
21348 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21350 if (! HAVE_epilogue)
21352 rtx insn = get_last_insn ();
21353 /* If the last insn was a BARRIER, we don't have to write anything except
21354 the trace table. */
21355 if (GET_CODE (insn) == NOTE)
21356 insn = prev_nonnote_insn (insn);
21357 if (insn == 0 || GET_CODE (insn) != BARRIER)
21359 /* This is slightly ugly, but at least we don't have two
21360 copies of the epilogue-emitting code. */
21363 /* A NOTE_INSN_DELETED is supposed to be at the start
21364 and end of the "toplevel" insn chain. */
21365 emit_note (NOTE_INSN_DELETED);
21366 rs6000_emit_epilogue (FALSE);
21367 emit_note (NOTE_INSN_DELETED);
21369 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21373 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21375 INSN_ADDRESSES_NEW (insn, addr);
21380 if (TARGET_DEBUG_STACK)
21381 debug_rtx_list (get_insns (), 100);
21382 final (get_insns (), file, FALSE);
21388 macho_branch_islands ();
21389 /* Mach-O doesn't support labels at the end of objects, so if
21390 it looks like we might want one, insert a NOP. */
21392 rtx insn = get_last_insn ();
21395 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21396 insn = PREV_INSN (insn);
21400 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21401 fputs ("\tnop\n", file);
21405 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21408 We don't output a traceback table if -finhibit-size-directive was
21409 used. The documentation for -finhibit-size-directive reads
21410 ``don't output a @code{.size} assembler directive, or anything
21411 else that would cause trouble if the function is split in the
21412 middle, and the two halves are placed at locations far apart in
21413 memory.'' The traceback table has this property, since it
21414 includes the offset from the start of the function to the
21415 traceback table itself.
21417 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21418 different traceback table. */
21419 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21420 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21422 const char *fname = NULL;
21423 const char *language_string = lang_hooks.name;
21424 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21426 int optional_tbtab;
21427 rs6000_stack_t *info = rs6000_stack_info ();
21429 if (rs6000_traceback == traceback_full)
21430 optional_tbtab = 1;
21431 else if (rs6000_traceback == traceback_part)
21432 optional_tbtab = 0;
21434 optional_tbtab = !optimize_size && !TARGET_ELF;
21436 if (optional_tbtab)
21438 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21439 while (*fname == '.') /* V.4 encodes . in the name */
21442 /* Need label immediately before tbtab, so we can compute
21443 its offset from the function start. */
21444 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21445 ASM_OUTPUT_LABEL (file, fname);
21448 /* The .tbtab pseudo-op can only be used for the first eight
21449 expressions, since it can't handle the possibly variable
21450 length fields that follow. However, if you omit the optional
21451 fields, the assembler outputs zeros for all optional fields
21452 anyways, giving each variable length field is minimum length
21453 (as defined in sys/debug.h). Thus we can not use the .tbtab
21454 pseudo-op at all. */
21456 /* An all-zero word flags the start of the tbtab, for debuggers
21457 that have to find it by searching forward from the entry
21458 point or from the current pc. */
21459 fputs ("\t.long 0\n", file);
21461 /* Tbtab format type. Use format type 0. */
21462 fputs ("\t.byte 0,", file);
21464 /* Language type. Unfortunately, there does not seem to be any
21465 official way to discover the language being compiled, so we
21466 use language_string.
21467 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21468 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21469 a number, so for now use 9. LTO isn't assigned a number either,
21470 so for now use 0. */
21471 if (! strcmp (language_string, "GNU C")
21472 || ! strcmp (language_string, "GNU GIMPLE"))
21474 else if (! strcmp (language_string, "GNU F77")
21475 || ! strcmp (language_string, "GNU Fortran"))
21477 else if (! strcmp (language_string, "GNU Pascal"))
21479 else if (! strcmp (language_string, "GNU Ada"))
21481 else if (! strcmp (language_string, "GNU C++")
21482 || ! strcmp (language_string, "GNU Objective-C++"))
21484 else if (! strcmp (language_string, "GNU Java"))
21486 else if (! strcmp (language_string, "GNU Objective-C"))
21489 gcc_unreachable ();
21490 fprintf (file, "%d,", i);
21492 /* 8 single bit fields: global linkage (not set for C extern linkage,
21493 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21494 from start of procedure stored in tbtab, internal function, function
21495 has controlled storage, function has no toc, function uses fp,
21496 function logs/aborts fp operations. */
21497 /* Assume that fp operations are used if any fp reg must be saved. */
21498 fprintf (file, "%d,",
21499 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21501 /* 6 bitfields: function is interrupt handler, name present in
21502 proc table, function calls alloca, on condition directives
21503 (controls stack walks, 3 bits), saves condition reg, saves
21505 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21506 set up as a frame pointer, even when there is no alloca call. */
21507 fprintf (file, "%d,",
21508 ((optional_tbtab << 6)
21509 | ((optional_tbtab & frame_pointer_needed) << 5)
21510 | (info->cr_save_p << 1)
21511 | (info->lr_save_p)));
21513 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21515 fprintf (file, "%d,",
21516 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21518 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21519 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21521 if (optional_tbtab)
21523 /* Compute the parameter info from the function decl argument
21526 int next_parm_info_bit = 31;
21528 for (decl = DECL_ARGUMENTS (current_function_decl);
21529 decl; decl = DECL_CHAIN (decl))
21531 rtx parameter = DECL_INCOMING_RTL (decl);
21532 enum machine_mode mode = GET_MODE (parameter);
21534 if (GET_CODE (parameter) == REG)
21536 if (SCALAR_FLOAT_MODE_P (mode))
21557 gcc_unreachable ();
21560 /* If only one bit will fit, don't or in this entry. */
21561 if (next_parm_info_bit > 0)
21562 parm_info |= (bits << (next_parm_info_bit - 1));
21563 next_parm_info_bit -= 2;
21567 fixed_parms += ((GET_MODE_SIZE (mode)
21568 + (UNITS_PER_WORD - 1))
21570 next_parm_info_bit -= 1;
21576 /* Number of fixed point parameters. */
21577 /* This is actually the number of words of fixed point parameters; thus
21578 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21579 fprintf (file, "%d,", fixed_parms);
21581 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21583 /* This is actually the number of fp registers that hold parameters;
21584 and thus the maximum value is 13. */
21585 /* Set parameters on stack bit if parameters are not in their original
21586 registers, regardless of whether they are on the stack? Xlc
21587 seems to set the bit when not optimizing. */
21588 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21590 if (! optional_tbtab)
21593 /* Optional fields follow. Some are variable length. */
21595 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21596 11 double float. */
21597 /* There is an entry for each parameter in a register, in the order that
21598 they occur in the parameter list. Any intervening arguments on the
21599 stack are ignored. If the list overflows a long (max possible length
21600 34 bits) then completely leave off all elements that don't fit. */
21601 /* Only emit this long if there was at least one parameter. */
21602 if (fixed_parms || float_parms)
21603 fprintf (file, "\t.long %d\n", parm_info);
21605 /* Offset from start of code to tb table. */
21606 fputs ("\t.long ", file);
21607 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21608 RS6000_OUTPUT_BASENAME (file, fname);
21610 rs6000_output_function_entry (file, fname);
21613 /* Interrupt handler mask. */
21614 /* Omit this long, since we never set the interrupt handler bit
21617 /* Number of CTL (controlled storage) anchors. */
21618 /* Omit this long, since the has_ctl bit is never set above. */
21620 /* Displacement into stack of each CTL anchor. */
21621 /* Omit this list of longs, because there are no CTL anchors. */
21623 /* Length of function name. */
21626 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21628 /* Function name. */
21629 assemble_string (fname, strlen (fname));
21631 /* Register for alloca automatic storage; this is always reg 31.
21632 Only emit this if the alloca bit was set above. */
21633 if (frame_pointer_needed)
21634 fputs ("\t.byte 31\n", file);
21636 fputs ("\t.align 2\n", file);
21640 /* A C compound statement that outputs the assembler code for a thunk
21641 function, used to implement C++ virtual function calls with
21642 multiple inheritance. The thunk acts as a wrapper around a virtual
21643 function, adjusting the implicit object parameter before handing
21644 control off to the real function.
21646 First, emit code to add the integer DELTA to the location that
21647 contains the incoming first argument. Assume that this argument
21648 contains a pointer, and is the one used to pass the `this' pointer
21649 in C++. This is the incoming argument *before* the function
21650 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21651 values of all other incoming arguments.
21653 After the addition, emit code to jump to FUNCTION, which is a
21654 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21655 not touch the return address. Hence returning from FUNCTION will
21656 return to whoever called the current `thunk'.
21658 The effect must be as if FUNCTION had been called directly with the
21659 adjusted first argument. This macro is responsible for emitting
21660 all of the code for a thunk function; output_function_prologue()
21661 and output_function_epilogue() are not invoked.
21663 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21664 been extracted from it.) It might possibly be useful on some
21665 targets, but probably not.
21667 If you do not define this macro, the target-independent code in the
21668 C++ frontend will generate a less efficient heavyweight thunk that
21669 calls FUNCTION instead of jumping to it. The generic approach does
21670 not support varargs. */
21673 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21674 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21677 rtx this_rtx, insn, funexp;
21679 reload_completed = 1;
21680 epilogue_completed = 1;
21682 /* Mark the end of the (empty) prologue. */
21683 emit_note (NOTE_INSN_PROLOGUE_END);
21685 /* Find the "this" pointer. If the function returns a structure,
21686 the structure return pointer is in r3. */
21687 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21688 this_rtx = gen_rtx_REG (Pmode, 4);
21690 this_rtx = gen_rtx_REG (Pmode, 3);
21692 /* Apply the constant offset, if required. */
21694 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21696 /* Apply the offset from the vtable, if required. */
21699 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21700 rtx tmp = gen_rtx_REG (Pmode, 12);
21702 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21703 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21705 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21706 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21710 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21712 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21714 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21717 /* Generate a tail call to the target function. */
21718 if (!TREE_USED (function))
21720 assemble_external (function);
21721 TREE_USED (function) = 1;
21723 funexp = XEXP (DECL_RTL (function), 0);
21724 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21727 if (MACHOPIC_INDIRECT)
21728 funexp = machopic_indirect_call_target (funexp);
21731 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21732 generate sibcall RTL explicitly. */
21733 insn = emit_call_insn (
21734 gen_rtx_PARALLEL (VOIDmode,
21736 gen_rtx_CALL (VOIDmode,
21737 funexp, const0_rtx),
21738 gen_rtx_USE (VOIDmode, const0_rtx),
21739 gen_rtx_USE (VOIDmode,
21740 gen_rtx_REG (SImode,
21742 gen_rtx_RETURN (VOIDmode))));
21743 SIBLING_CALL_P (insn) = 1;
21746 /* Run just enough of rest_of_compilation to get the insns emitted.
21747 There's not really enough bulk here to make other passes such as
21748 instruction scheduling worth while. Note that use_thunk calls
21749 assemble_start_function and assemble_end_function. */
21750 insn = get_insns ();
21751 insn_locators_alloc ();
21752 shorten_branches (insn);
21753 final_start_function (insn, file, 1);
21754 final (insn, file, 1);
21755 final_end_function ();
21757 reload_completed = 0;
21758 epilogue_completed = 0;
21761 /* A quick summary of the various types of 'constant-pool tables'
21764 Target Flags Name One table per
21765 AIX (none) AIX TOC object file
21766 AIX -mfull-toc AIX TOC object file
21767 AIX -mminimal-toc AIX minimal TOC translation unit
21768 SVR4/EABI (none) SVR4 SDATA object file
21769 SVR4/EABI -fpic SVR4 pic object file
21770 SVR4/EABI -fPIC SVR4 PIC translation unit
21771 SVR4/EABI -mrelocatable EABI TOC function
21772 SVR4/EABI -maix AIX TOC object file
21773 SVR4/EABI -maix -mminimal-toc
21774 AIX minimal TOC translation unit
21776 Name Reg. Set by entries contains:
21777 made by addrs? fp? sum?
21779 AIX TOC 2 crt0 as Y option option
21780 AIX minimal TOC 30 prolog gcc Y Y option
21781 SVR4 SDATA 13 crt0 gcc N Y N
21782 SVR4 pic 30 prolog ld Y not yet N
21783 SVR4 PIC 30 prolog gcc Y option option
21784 EABI TOC 30 prolog gcc Y option option
21788 /* Hash functions for the hash table. */
21791 rs6000_hash_constant (rtx k)
21793 enum rtx_code code = GET_CODE (k);
21794 enum machine_mode mode = GET_MODE (k);
21795 unsigned result = (code << 3) ^ mode;
21796 const char *format;
21799 format = GET_RTX_FORMAT (code);
21800 flen = strlen (format);
21806 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21809 if (mode != VOIDmode)
21810 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21822 for (; fidx < flen; fidx++)
21823 switch (format[fidx])
21828 const char *str = XSTR (k, fidx);
21829 len = strlen (str);
21830 result = result * 613 + len;
21831 for (i = 0; i < len; i++)
21832 result = result * 613 + (unsigned) str[i];
21837 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21841 result = result * 613 + (unsigned) XINT (k, fidx);
21844 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21845 result = result * 613 + (unsigned) XWINT (k, fidx);
21849 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21850 result = result * 613 + (unsigned) (XWINT (k, fidx)
21857 gcc_unreachable ();
21864 toc_hash_function (const void *hash_entry)
21866 const struct toc_hash_struct *thc =
21867 (const struct toc_hash_struct *) hash_entry;
21868 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21871 /* Compare H1 and H2 for equivalence. */
21874 toc_hash_eq (const void *h1, const void *h2)
21876 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21877 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21879 if (((const struct toc_hash_struct *) h1)->key_mode
21880 != ((const struct toc_hash_struct *) h2)->key_mode)
21883 return rtx_equal_p (r1, r2);
21886 /* These are the names given by the C++ front-end to vtables, and
21887 vtable-like objects. Ideally, this logic should not be here;
21888 instead, there should be some programmatic way of inquiring as
21889 to whether or not an object is a vtable. */
21891 #define VTABLE_NAME_P(NAME) \
21892 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21893 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21894 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21895 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21896 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21898 #ifdef NO_DOLLAR_IN_LABEL
21899 /* Return a GGC-allocated character string translating dollar signs in
21900 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21903 rs6000_xcoff_strip_dollar (const char *name)
21908 p = strchr (name, '$');
21910 if (p == 0 || p == name)
21913 len = strlen (name);
21914 strip = (char *) alloca (len + 1);
21915 strcpy (strip, name);
21916 p = strchr (strip, '$');
21920 p = strchr (p + 1, '$');
21923 return ggc_alloc_string (strip, len);
21928 rs6000_output_symbol_ref (FILE *file, rtx x)
21930 /* Currently C++ toc references to vtables can be emitted before it
21931 is decided whether the vtable is public or private. If this is
21932 the case, then the linker will eventually complain that there is
21933 a reference to an unknown section. Thus, for vtables only,
21934 we emit the TOC reference to reference the symbol and not the
21936 const char *name = XSTR (x, 0);
21938 if (VTABLE_NAME_P (name))
21940 RS6000_OUTPUT_BASENAME (file, name);
21943 assemble_name (file, name);
21946 /* Output a TOC entry. We derive the entry name from what is being
21950 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21953 const char *name = buf;
21955 HOST_WIDE_INT offset = 0;
21957 gcc_assert (!TARGET_NO_TOC);
21959 /* When the linker won't eliminate them, don't output duplicate
21960 TOC entries (this happens on AIX if there is any kind of TOC,
21961 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21963 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21965 struct toc_hash_struct *h;
21968 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21969 time because GGC is not initialized at that point. */
21970 if (toc_hash_table == NULL)
21971 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21972 toc_hash_eq, NULL);
21974 h = ggc_alloc_toc_hash_struct ();
21976 h->key_mode = mode;
21977 h->labelno = labelno;
21979 found = htab_find_slot (toc_hash_table, h, INSERT);
21980 if (*found == NULL)
21982 else /* This is indeed a duplicate.
21983 Set this label equal to that label. */
21985 fputs ("\t.set ", file);
21986 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21987 fprintf (file, "%d,", labelno);
21988 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21989 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21995 /* If we're going to put a double constant in the TOC, make sure it's
21996 aligned properly when strict alignment is on. */
21997 if (GET_CODE (x) == CONST_DOUBLE
21998 && STRICT_ALIGNMENT
21999 && GET_MODE_BITSIZE (mode) >= 64
22000 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22001 ASM_OUTPUT_ALIGN (file, 3);
22004 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22006 /* Handle FP constants specially. Note that if we have a minimal
22007 TOC, things we put here aren't actually in the TOC, so we can allow
22009 if (GET_CODE (x) == CONST_DOUBLE &&
22010 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22012 REAL_VALUE_TYPE rv;
22015 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22016 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22017 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22019 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22023 if (TARGET_MINIMAL_TOC)
22024 fputs (DOUBLE_INT_ASM_OP, file);
22026 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22027 k[0] & 0xffffffff, k[1] & 0xffffffff,
22028 k[2] & 0xffffffff, k[3] & 0xffffffff);
22029 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22030 k[0] & 0xffffffff, k[1] & 0xffffffff,
22031 k[2] & 0xffffffff, k[3] & 0xffffffff);
22036 if (TARGET_MINIMAL_TOC)
22037 fputs ("\t.long ", file);
22039 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22040 k[0] & 0xffffffff, k[1] & 0xffffffff,
22041 k[2] & 0xffffffff, k[3] & 0xffffffff);
22042 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22043 k[0] & 0xffffffff, k[1] & 0xffffffff,
22044 k[2] & 0xffffffff, k[3] & 0xffffffff);
22048 else if (GET_CODE (x) == CONST_DOUBLE &&
22049 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22051 REAL_VALUE_TYPE rv;
22054 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22056 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22057 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22059 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22063 if (TARGET_MINIMAL_TOC)
22064 fputs (DOUBLE_INT_ASM_OP, file);
22066 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22067 k[0] & 0xffffffff, k[1] & 0xffffffff);
22068 fprintf (file, "0x%lx%08lx\n",
22069 k[0] & 0xffffffff, k[1] & 0xffffffff);
22074 if (TARGET_MINIMAL_TOC)
22075 fputs ("\t.long ", file);
22077 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22078 k[0] & 0xffffffff, k[1] & 0xffffffff);
22079 fprintf (file, "0x%lx,0x%lx\n",
22080 k[0] & 0xffffffff, k[1] & 0xffffffff);
22084 else if (GET_CODE (x) == CONST_DOUBLE &&
22085 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22087 REAL_VALUE_TYPE rv;
22090 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22091 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22092 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22094 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22098 if (TARGET_MINIMAL_TOC)
22099 fputs (DOUBLE_INT_ASM_OP, file);
22101 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22102 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22107 if (TARGET_MINIMAL_TOC)
22108 fputs ("\t.long ", file);
22110 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22111 fprintf (file, "0x%lx\n", l & 0xffffffff);
22115 else if (GET_MODE (x) == VOIDmode
22116 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22118 unsigned HOST_WIDE_INT low;
22119 HOST_WIDE_INT high;
22121 if (GET_CODE (x) == CONST_DOUBLE)
22123 low = CONST_DOUBLE_LOW (x);
22124 high = CONST_DOUBLE_HIGH (x);
22127 #if HOST_BITS_PER_WIDE_INT == 32
22130 high = (low & 0x80000000) ? ~0 : 0;
22134 low = INTVAL (x) & 0xffffffff;
22135 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22139 /* TOC entries are always Pmode-sized, but since this
22140 is a bigendian machine then if we're putting smaller
22141 integer constants in the TOC we have to pad them.
22142 (This is still a win over putting the constants in
22143 a separate constant pool, because then we'd have
22144 to have both a TOC entry _and_ the actual constant.)
22146 For a 32-bit target, CONST_INT values are loaded and shifted
22147 entirely within `low' and can be stored in one TOC entry. */
22149 /* It would be easy to make this work, but it doesn't now. */
22150 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22152 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22154 #if HOST_BITS_PER_WIDE_INT == 32
22155 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22156 POINTER_SIZE, &low, &high, 0);
22159 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22160 high = (HOST_WIDE_INT) low >> 32;
22167 if (TARGET_MINIMAL_TOC)
22168 fputs (DOUBLE_INT_ASM_OP, file);
22170 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22171 (long) high & 0xffffffff, (long) low & 0xffffffff);
22172 fprintf (file, "0x%lx%08lx\n",
22173 (long) high & 0xffffffff, (long) low & 0xffffffff);
22178 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22180 if (TARGET_MINIMAL_TOC)
22181 fputs ("\t.long ", file);
22183 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22184 (long) high & 0xffffffff, (long) low & 0xffffffff);
22185 fprintf (file, "0x%lx,0x%lx\n",
22186 (long) high & 0xffffffff, (long) low & 0xffffffff);
22190 if (TARGET_MINIMAL_TOC)
22191 fputs ("\t.long ", file);
22193 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22194 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22200 if (GET_CODE (x) == CONST)
22202 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22203 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22205 base = XEXP (XEXP (x, 0), 0);
22206 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22209 switch (GET_CODE (base))
22212 name = XSTR (base, 0);
22216 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22217 CODE_LABEL_NUMBER (XEXP (base, 0)));
22221 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22225 gcc_unreachable ();
22228 if (TARGET_MINIMAL_TOC)
22229 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22232 fputs ("\t.tc ", file);
22233 RS6000_OUTPUT_BASENAME (file, name);
22236 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22238 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22240 fputs ("[TC],", file);
22243 /* Currently C++ toc references to vtables can be emitted before it
22244 is decided whether the vtable is public or private. If this is
22245 the case, then the linker will eventually complain that there is
22246 a TOC reference to an unknown section. Thus, for vtables only,
22247 we emit the TOC reference to reference the symbol and not the
22249 if (VTABLE_NAME_P (name))
22251 RS6000_OUTPUT_BASENAME (file, name);
22253 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22254 else if (offset > 0)
22255 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22258 output_addr_const (file, x);
22262 /* Output an assembler pseudo-op to write an ASCII string of N characters
22263 starting at P to FILE.
22265 On the RS/6000, we have to do this using the .byte operation and
22266 write out special characters outside the quoted string.
22267 Also, the assembler is broken; very long strings are truncated,
22268 so we must artificially break them up early. */
22271 output_ascii (FILE *file, const char *p, int n)
22274 int i, count_string;
22275 const char *for_string = "\t.byte \"";
22276 const char *for_decimal = "\t.byte ";
22277 const char *to_close = NULL;
22280 for (i = 0; i < n; i++)
22283 if (c >= ' ' && c < 0177)
22286 fputs (for_string, file);
22289 /* Write two quotes to get one. */
22297 for_decimal = "\"\n\t.byte ";
22301 if (count_string >= 512)
22303 fputs (to_close, file);
22305 for_string = "\t.byte \"";
22306 for_decimal = "\t.byte ";
22314 fputs (for_decimal, file);
22315 fprintf (file, "%d", c);
22317 for_string = "\n\t.byte \"";
22318 for_decimal = ", ";
22324 /* Now close the string if we have written one. Then end the line. */
22326 fputs (to_close, file);
22329 /* Generate a unique section name for FILENAME for a section type
22330 represented by SECTION_DESC. Output goes into BUF.
22332 SECTION_DESC can be any string, as long as it is different for each
22333 possible section type.
22335 We name the section in the same manner as xlc. The name begins with an
22336 underscore followed by the filename (after stripping any leading directory
22337 names) with the last period replaced by the string SECTION_DESC. If
22338 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22342 rs6000_gen_section_name (char **buf, const char *filename,
22343 const char *section_desc)
22345 const char *q, *after_last_slash, *last_period = 0;
22349 after_last_slash = filename;
22350 for (q = filename; *q; q++)
22353 after_last_slash = q + 1;
22354 else if (*q == '.')
22358 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22359 *buf = (char *) xmalloc (len);
22364 for (q = after_last_slash; *q; q++)
22366 if (q == last_period)
22368 strcpy (p, section_desc);
22369 p += strlen (section_desc);
22373 else if (ISALNUM (*q))
22377 if (last_period == 0)
22378 strcpy (p, section_desc);
22383 /* Emit profile function. */
22386 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22388 /* Non-standard profiling for kernels, which just saves LR then calls
22389 _mcount without worrying about arg saves. The idea is to change
22390 the function prologue as little as possible as it isn't easy to
22391 account for arg save/restore code added just for _mcount. */
22392 if (TARGET_PROFILE_KERNEL)
22395 if (DEFAULT_ABI == ABI_AIX)
22397 #ifndef NO_PROFILE_COUNTERS
22398 # define NO_PROFILE_COUNTERS 0
22400 if (NO_PROFILE_COUNTERS)
22401 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22402 LCT_NORMAL, VOIDmode, 0);
22406 const char *label_name;
22409 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22410 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22411 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22413 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22414 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22417 else if (DEFAULT_ABI == ABI_DARWIN)
22419 const char *mcount_name = RS6000_MCOUNT;
22420 int caller_addr_regno = LR_REGNO;
22422 /* Be conservative and always set this, at least for now. */
22423 crtl->uses_pic_offset_table = 1;
22426 /* For PIC code, set up a stub and collect the caller's address
22427 from r0, which is where the prologue puts it. */
22428 if (MACHOPIC_INDIRECT
22429 && crtl->uses_pic_offset_table)
22430 caller_addr_regno = 0;
22432 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22433 LCT_NORMAL, VOIDmode, 1,
22434 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22438 /* Write function profiler code. */
22441 output_function_profiler (FILE *file, int labelno)
22445 switch (DEFAULT_ABI)
22448 gcc_unreachable ();
22453 warning (0, "no profiling of 64-bit code for this ABI");
22456 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22457 fprintf (file, "\tmflr %s\n", reg_names[0]);
22458 if (NO_PROFILE_COUNTERS)
22460 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22461 reg_names[0], reg_names[1]);
22463 else if (TARGET_SECURE_PLT && flag_pic)
22465 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22466 reg_names[0], reg_names[1]);
22467 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22468 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22469 reg_names[12], reg_names[12]);
22470 assemble_name (file, buf);
22471 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22472 assemble_name (file, buf);
22473 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22475 else if (flag_pic == 1)
22477 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22478 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22479 reg_names[0], reg_names[1]);
22480 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22481 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22482 assemble_name (file, buf);
22483 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22485 else if (flag_pic > 1)
22487 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22488 reg_names[0], reg_names[1]);
22489 /* Now, we need to get the address of the label. */
22490 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22491 assemble_name (file, buf);
22492 fputs ("-.\n1:", file);
22493 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22494 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22495 reg_names[0], reg_names[11]);
22496 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22497 reg_names[0], reg_names[0], reg_names[11]);
22501 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22502 assemble_name (file, buf);
22503 fputs ("@ha\n", file);
22504 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22505 reg_names[0], reg_names[1]);
22506 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22507 assemble_name (file, buf);
22508 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22511 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22512 fprintf (file, "\tbl %s%s\n",
22513 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22518 if (!TARGET_PROFILE_KERNEL)
22520 /* Don't do anything, done in output_profile_hook (). */
22524 gcc_assert (!TARGET_32BIT);
22526 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22527 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22529 if (cfun->static_chain_decl != NULL)
22531 asm_fprintf (file, "\tstd %s,24(%s)\n",
22532 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22533 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22534 asm_fprintf (file, "\tld %s,24(%s)\n",
22535 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22538 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22546 /* The following variable value is the last issued insn. */
22548 static rtx last_scheduled_insn;
22550 /* The following variable helps to balance issuing of load and
22551 store instructions */
22553 static int load_store_pendulum;
22555 /* Power4 load update and store update instructions are cracked into a
22556 load or store and an integer insn which are executed in the same cycle.
22557 Branches have their own dispatch slot which does not count against the
22558 GCC issue rate, but it changes the program flow so there are no other
22559 instructions to issue in this cycle. */
22562 rs6000_variable_issue_1 (rtx insn, int more)
22564 last_scheduled_insn = insn;
22565 if (GET_CODE (PATTERN (insn)) == USE
22566 || GET_CODE (PATTERN (insn)) == CLOBBER)
22568 cached_can_issue_more = more;
22569 return cached_can_issue_more;
22572 if (insn_terminates_group_p (insn, current_group))
22574 cached_can_issue_more = 0;
22575 return cached_can_issue_more;
22578 /* If no reservation, but reach here */
22579 if (recog_memoized (insn) < 0)
22582 if (rs6000_sched_groups)
22584 if (is_microcoded_insn (insn))
22585 cached_can_issue_more = 0;
22586 else if (is_cracked_insn (insn))
22587 cached_can_issue_more = more > 2 ? more - 2 : 0;
22589 cached_can_issue_more = more - 1;
22591 return cached_can_issue_more;
22594 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22597 cached_can_issue_more = more - 1;
22598 return cached_can_issue_more;
22602 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22604 int r = rs6000_variable_issue_1 (insn, more);
22606 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22610 /* Adjust the cost of a scheduling dependency. Return the new cost of
22611 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22614 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22616 enum attr_type attr_type;
22618 if (! recog_memoized (insn))
22621 switch (REG_NOTE_KIND (link))
22625 /* Data dependency; DEP_INSN writes a register that INSN reads
22626 some cycles later. */
22628 /* Separate a load from a narrower, dependent store. */
22629 if (rs6000_sched_groups
22630 && GET_CODE (PATTERN (insn)) == SET
22631 && GET_CODE (PATTERN (dep_insn)) == SET
22632 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22633 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22634 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22635 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22638 attr_type = get_attr_type (insn);
22643 /* Tell the first scheduling pass about the latency between
22644 a mtctr and bctr (and mtlr and br/blr). The first
22645 scheduling pass will not know about this latency since
22646 the mtctr instruction, which has the latency associated
22647 to it, will be generated by reload. */
22648 return TARGET_POWER ? 5 : 4;
22650 /* Leave some extra cycles between a compare and its
22651 dependent branch, to inhibit expensive mispredicts. */
22652 if ((rs6000_cpu_attr == CPU_PPC603
22653 || rs6000_cpu_attr == CPU_PPC604
22654 || rs6000_cpu_attr == CPU_PPC604E
22655 || rs6000_cpu_attr == CPU_PPC620
22656 || rs6000_cpu_attr == CPU_PPC630
22657 || rs6000_cpu_attr == CPU_PPC750
22658 || rs6000_cpu_attr == CPU_PPC7400
22659 || rs6000_cpu_attr == CPU_PPC7450
22660 || rs6000_cpu_attr == CPU_POWER4
22661 || rs6000_cpu_attr == CPU_POWER5
22662 || rs6000_cpu_attr == CPU_POWER7
22663 || rs6000_cpu_attr == CPU_CELL)
22664 && recog_memoized (dep_insn)
22665 && (INSN_CODE (dep_insn) >= 0))
22667 switch (get_attr_type (dep_insn))
22671 case TYPE_DELAYED_COMPARE:
22672 case TYPE_IMUL_COMPARE:
22673 case TYPE_LMUL_COMPARE:
22674 case TYPE_FPCOMPARE:
22675 case TYPE_CR_LOGICAL:
22676 case TYPE_DELAYED_CR:
22685 case TYPE_STORE_UX:
22687 case TYPE_FPSTORE_U:
22688 case TYPE_FPSTORE_UX:
22689 if ((rs6000_cpu == PROCESSOR_POWER6)
22690 && recog_memoized (dep_insn)
22691 && (INSN_CODE (dep_insn) >= 0))
22694 if (GET_CODE (PATTERN (insn)) != SET)
22695 /* If this happens, we have to extend this to schedule
22696 optimally. Return default for now. */
22699 /* Adjust the cost for the case where the value written
22700 by a fixed point operation is used as the address
22701 gen value on a store. */
22702 switch (get_attr_type (dep_insn))
22709 if (! store_data_bypass_p (dep_insn, insn))
22713 case TYPE_LOAD_EXT:
22714 case TYPE_LOAD_EXT_U:
22715 case TYPE_LOAD_EXT_UX:
22716 case TYPE_VAR_SHIFT_ROTATE:
22717 case TYPE_VAR_DELAYED_COMPARE:
22719 if (! store_data_bypass_p (dep_insn, insn))
22725 case TYPE_FAST_COMPARE:
22728 case TYPE_INSERT_WORD:
22729 case TYPE_INSERT_DWORD:
22730 case TYPE_FPLOAD_U:
22731 case TYPE_FPLOAD_UX:
22733 case TYPE_STORE_UX:
22734 case TYPE_FPSTORE_U:
22735 case TYPE_FPSTORE_UX:
22737 if (! store_data_bypass_p (dep_insn, insn))
22745 case TYPE_IMUL_COMPARE:
22746 case TYPE_LMUL_COMPARE:
22748 if (! store_data_bypass_p (dep_insn, insn))
22754 if (! store_data_bypass_p (dep_insn, insn))
22760 if (! store_data_bypass_p (dep_insn, insn))
22773 case TYPE_LOAD_EXT:
22774 case TYPE_LOAD_EXT_U:
22775 case TYPE_LOAD_EXT_UX:
22776 if ((rs6000_cpu == PROCESSOR_POWER6)
22777 && recog_memoized (dep_insn)
22778 && (INSN_CODE (dep_insn) >= 0))
22781 /* Adjust the cost for the case where the value written
22782 by a fixed point instruction is used within the address
22783 gen portion of a subsequent load(u)(x) */
22784 switch (get_attr_type (dep_insn))
22791 if (set_to_load_agen (dep_insn, insn))
22795 case TYPE_LOAD_EXT:
22796 case TYPE_LOAD_EXT_U:
22797 case TYPE_LOAD_EXT_UX:
22798 case TYPE_VAR_SHIFT_ROTATE:
22799 case TYPE_VAR_DELAYED_COMPARE:
22801 if (set_to_load_agen (dep_insn, insn))
22807 case TYPE_FAST_COMPARE:
22810 case TYPE_INSERT_WORD:
22811 case TYPE_INSERT_DWORD:
22812 case TYPE_FPLOAD_U:
22813 case TYPE_FPLOAD_UX:
22815 case TYPE_STORE_UX:
22816 case TYPE_FPSTORE_U:
22817 case TYPE_FPSTORE_UX:
22819 if (set_to_load_agen (dep_insn, insn))
22827 case TYPE_IMUL_COMPARE:
22828 case TYPE_LMUL_COMPARE:
22830 if (set_to_load_agen (dep_insn, insn))
22836 if (set_to_load_agen (dep_insn, insn))
22842 if (set_to_load_agen (dep_insn, insn))
22853 if ((rs6000_cpu == PROCESSOR_POWER6)
22854 && recog_memoized (dep_insn)
22855 && (INSN_CODE (dep_insn) >= 0)
22856 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22863 /* Fall out to return default cost. */
22867 case REG_DEP_OUTPUT:
22868 /* Output dependency; DEP_INSN writes a register that INSN writes some
22870 if ((rs6000_cpu == PROCESSOR_POWER6)
22871 && recog_memoized (dep_insn)
22872 && (INSN_CODE (dep_insn) >= 0))
22874 attr_type = get_attr_type (insn);
22879 if (get_attr_type (dep_insn) == TYPE_FP)
22883 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22891 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22896 gcc_unreachable ();
22902 /* Debug version of rs6000_adjust_cost. */
22905 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22907 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22913 switch (REG_NOTE_KIND (link))
22915 default: dep = "unknown depencency"; break;
22916 case REG_DEP_TRUE: dep = "data dependency"; break;
22917 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22918 case REG_DEP_ANTI: dep = "anti depencency"; break;
22922 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22923 "%s, insn:\n", ret, cost, dep);
22931 /* The function returns a true if INSN is microcoded.
22932 Return false otherwise. */
22935 is_microcoded_insn (rtx insn)
22937 if (!insn || !NONDEBUG_INSN_P (insn)
22938 || GET_CODE (PATTERN (insn)) == USE
22939 || GET_CODE (PATTERN (insn)) == CLOBBER)
22942 if (rs6000_cpu_attr == CPU_CELL)
22943 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22945 if (rs6000_sched_groups)
22947 enum attr_type type = get_attr_type (insn);
22948 if (type == TYPE_LOAD_EXT_U
22949 || type == TYPE_LOAD_EXT_UX
22950 || type == TYPE_LOAD_UX
22951 || type == TYPE_STORE_UX
22952 || type == TYPE_MFCR)
22959 /* The function returns true if INSN is cracked into 2 instructions
22960 by the processor (and therefore occupies 2 issue slots). */
22963 is_cracked_insn (rtx insn)
22965 if (!insn || !NONDEBUG_INSN_P (insn)
22966 || GET_CODE (PATTERN (insn)) == USE
22967 || GET_CODE (PATTERN (insn)) == CLOBBER)
22970 if (rs6000_sched_groups)
22972 enum attr_type type = get_attr_type (insn);
22973 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22974 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22975 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22976 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22977 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22978 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22979 || type == TYPE_IDIV || type == TYPE_LDIV
22980 || type == TYPE_INSERT_WORD)
22987 /* The function returns true if INSN can be issued only from
22988 the branch slot. */
22991 is_branch_slot_insn (rtx insn)
22993 if (!insn || !NONDEBUG_INSN_P (insn)
22994 || GET_CODE (PATTERN (insn)) == USE
22995 || GET_CODE (PATTERN (insn)) == CLOBBER)
22998 if (rs6000_sched_groups)
23000 enum attr_type type = get_attr_type (insn);
23001 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23009 /* The function returns true if out_inst sets a value that is
23010 used in the address generation computation of in_insn */
23012 set_to_load_agen (rtx out_insn, rtx in_insn)
23014 rtx out_set, in_set;
23016 /* For performance reasons, only handle the simple case where
23017 both loads are a single_set. */
23018 out_set = single_set (out_insn);
23021 in_set = single_set (in_insn);
23023 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23029 /* The function returns true if the target storage location of
23030 out_insn is adjacent to the target storage location of in_insn */
23031 /* Return 1 if memory locations are adjacent. */
23034 adjacent_mem_locations (rtx insn1, rtx insn2)
23037 rtx a = get_store_dest (PATTERN (insn1));
23038 rtx b = get_store_dest (PATTERN (insn2));
23040 if ((GET_CODE (XEXP (a, 0)) == REG
23041 || (GET_CODE (XEXP (a, 0)) == PLUS
23042 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23043 && (GET_CODE (XEXP (b, 0)) == REG
23044 || (GET_CODE (XEXP (b, 0)) == PLUS
23045 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23047 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23050 if (GET_CODE (XEXP (a, 0)) == PLUS)
23052 reg0 = XEXP (XEXP (a, 0), 0);
23053 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23056 reg0 = XEXP (a, 0);
23058 if (GET_CODE (XEXP (b, 0)) == PLUS)
23060 reg1 = XEXP (XEXP (b, 0), 0);
23061 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23064 reg1 = XEXP (b, 0);
23066 val_diff = val1 - val0;
23068 return ((REGNO (reg0) == REGNO (reg1))
23069 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23070 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23076 /* A C statement (sans semicolon) to update the integer scheduling
23077 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23078 INSN earlier, reduce the priority to execute INSN later. Do not
23079 define this macro if you do not need to adjust the scheduling
23080 priorities of insns. */
23083 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23085 /* On machines (like the 750) which have asymmetric integer units,
23086 where one integer unit can do multiply and divides and the other
23087 can't, reduce the priority of multiply/divide so it is scheduled
23088 before other integer operations. */
23091 if (! INSN_P (insn))
23094 if (GET_CODE (PATTERN (insn)) == USE)
23097 switch (rs6000_cpu_attr) {
23099 switch (get_attr_type (insn))
23106 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23107 priority, priority);
23108 if (priority >= 0 && priority < 0x01000000)
23115 if (insn_must_be_first_in_group (insn)
23116 && reload_completed
23117 && current_sched_info->sched_max_insns_priority
23118 && rs6000_sched_restricted_insns_priority)
23121 /* Prioritize insns that can be dispatched only in the first
23123 if (rs6000_sched_restricted_insns_priority == 1)
23124 /* Attach highest priority to insn. This means that in
23125 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23126 precede 'priority' (critical path) considerations. */
23127 return current_sched_info->sched_max_insns_priority;
23128 else if (rs6000_sched_restricted_insns_priority == 2)
23129 /* Increase priority of insn by a minimal amount. This means that in
23130 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23131 considerations precede dispatch-slot restriction considerations. */
23132 return (priority + 1);
23135 if (rs6000_cpu == PROCESSOR_POWER6
23136 && ((load_store_pendulum == -2 && is_load_insn (insn))
23137 || (load_store_pendulum == 2 && is_store_insn (insn))))
23138 /* Attach highest priority to insn if the scheduler has just issued two
23139 stores and this instruction is a load, or two loads and this instruction
23140 is a store. Power6 wants loads and stores scheduled alternately
23142 return current_sched_info->sched_max_insns_priority;
23147 /* Return true if the instruction is nonpipelined on the Cell. */
23149 is_nonpipeline_insn (rtx insn)
23151 enum attr_type type;
23152 if (!insn || !NONDEBUG_INSN_P (insn)
23153 || GET_CODE (PATTERN (insn)) == USE
23154 || GET_CODE (PATTERN (insn)) == CLOBBER)
23157 type = get_attr_type (insn);
23158 if (type == TYPE_IMUL
23159 || type == TYPE_IMUL2
23160 || type == TYPE_IMUL3
23161 || type == TYPE_LMUL
23162 || type == TYPE_IDIV
23163 || type == TYPE_LDIV
23164 || type == TYPE_SDIV
23165 || type == TYPE_DDIV
23166 || type == TYPE_SSQRT
23167 || type == TYPE_DSQRT
23168 || type == TYPE_MFCR
23169 || type == TYPE_MFCRF
23170 || type == TYPE_MFJMPR)
23178 /* Return how many instructions the machine can issue per cycle. */
23181 rs6000_issue_rate (void)
23183 /* Unless scheduling for register pressure, use issue rate of 1 for
23184 first scheduling pass to decrease degradation. */
23185 if (!reload_completed && !flag_sched_pressure)
23188 switch (rs6000_cpu_attr) {
23189 case CPU_RIOS1: /* ? */
23191 case CPU_PPC601: /* ? */
23200 case CPU_PPCE300C2:
23201 case CPU_PPCE300C3:
23202 case CPU_PPCE500MC:
23203 case CPU_PPCE500MC64:
23223 /* Return how many instructions to look ahead for better insn
23227 rs6000_use_sched_lookahead (void)
23229 if (rs6000_cpu_attr == CPU_PPC8540)
23231 if (rs6000_cpu_attr == CPU_CELL)
23232 return (reload_completed ? 8 : 0);
23236 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23238 rs6000_use_sched_lookahead_guard (rtx insn)
23240 if (rs6000_cpu_attr != CPU_CELL)
23243 if (insn == NULL_RTX || !INSN_P (insn))
23246 if (!reload_completed
23247 || is_nonpipeline_insn (insn)
23248 || is_microcoded_insn (insn))
23254 /* Determine is PAT refers to memory. */
23257 is_mem_ref (rtx pat)
23263 /* stack_tie does not produce any real memory traffic. */
23264 if (GET_CODE (pat) == UNSPEC
23265 && XINT (pat, 1) == UNSPEC_TIE)
23268 if (GET_CODE (pat) == MEM)
23271 /* Recursively process the pattern. */
23272 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23274 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23277 ret |= is_mem_ref (XEXP (pat, i));
23278 else if (fmt[i] == 'E')
23279 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23280 ret |= is_mem_ref (XVECEXP (pat, i, j));
23286 /* Determine if PAT is a PATTERN of a load insn. */
23289 is_load_insn1 (rtx pat)
23291 if (!pat || pat == NULL_RTX)
23294 if (GET_CODE (pat) == SET)
23295 return is_mem_ref (SET_SRC (pat));
23297 if (GET_CODE (pat) == PARALLEL)
23301 for (i = 0; i < XVECLEN (pat, 0); i++)
23302 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23309 /* Determine if INSN loads from memory. */
23312 is_load_insn (rtx insn)
23314 if (!insn || !INSN_P (insn))
23317 if (GET_CODE (insn) == CALL_INSN)
23320 return is_load_insn1 (PATTERN (insn));
23323 /* Determine if PAT is a PATTERN of a store insn. */
23326 is_store_insn1 (rtx pat)
23328 if (!pat || pat == NULL_RTX)
23331 if (GET_CODE (pat) == SET)
23332 return is_mem_ref (SET_DEST (pat));
23334 if (GET_CODE (pat) == PARALLEL)
23338 for (i = 0; i < XVECLEN (pat, 0); i++)
23339 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23346 /* Determine if INSN stores to memory. */
23349 is_store_insn (rtx insn)
23351 if (!insn || !INSN_P (insn))
23354 return is_store_insn1 (PATTERN (insn));
23357 /* Return the dest of a store insn. */
23360 get_store_dest (rtx pat)
23362 gcc_assert (is_store_insn1 (pat));
23364 if (GET_CODE (pat) == SET)
23365 return SET_DEST (pat);
23366 else if (GET_CODE (pat) == PARALLEL)
23370 for (i = 0; i < XVECLEN (pat, 0); i++)
23372 rtx inner_pat = XVECEXP (pat, 0, i);
23373 if (GET_CODE (inner_pat) == SET
23374 && is_mem_ref (SET_DEST (inner_pat)))
23378 /* We shouldn't get here, because we should have either a simple
23379 store insn or a store with update which are covered above. */
23383 /* Returns whether the dependence between INSN and NEXT is considered
23384 costly by the given target. */
23387 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23392 /* If the flag is not enabled - no dependence is considered costly;
23393 allow all dependent insns in the same group.
23394 This is the most aggressive option. */
23395 if (rs6000_sched_costly_dep == no_dep_costly)
23398 /* If the flag is set to 1 - a dependence is always considered costly;
23399 do not allow dependent instructions in the same group.
23400 This is the most conservative option. */
23401 if (rs6000_sched_costly_dep == all_deps_costly)
23404 insn = DEP_PRO (dep);
23405 next = DEP_CON (dep);
23407 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23408 && is_load_insn (next)
23409 && is_store_insn (insn))
23410 /* Prevent load after store in the same group. */
23413 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23414 && is_load_insn (next)
23415 && is_store_insn (insn)
23416 && DEP_TYPE (dep) == REG_DEP_TRUE)
23417 /* Prevent load after store in the same group if it is a true
23421 /* The flag is set to X; dependences with latency >= X are considered costly,
23422 and will not be scheduled in the same group. */
23423 if (rs6000_sched_costly_dep <= max_dep_latency
23424 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23430 /* Return the next insn after INSN that is found before TAIL is reached,
23431 skipping any "non-active" insns - insns that will not actually occupy
23432 an issue slot. Return NULL_RTX if such an insn is not found. */
23435 get_next_active_insn (rtx insn, rtx tail)
23437 if (insn == NULL_RTX || insn == tail)
23442 insn = NEXT_INSN (insn);
23443 if (insn == NULL_RTX || insn == tail)
23448 || (NONJUMP_INSN_P (insn)
23449 && GET_CODE (PATTERN (insn)) != USE
23450 && GET_CODE (PATTERN (insn)) != CLOBBER
23451 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23457 /* We are about to begin issuing insns for this clock cycle. */
23460 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23461 rtx *ready ATTRIBUTE_UNUSED,
23462 int *pn_ready ATTRIBUTE_UNUSED,
23463 int clock_var ATTRIBUTE_UNUSED)
23465 int n_ready = *pn_ready;
23468 fprintf (dump, "// rs6000_sched_reorder :\n");
23470 /* Reorder the ready list, if the second to last ready insn
23471 is a nonepipeline insn. */
23472 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23474 if (is_nonpipeline_insn (ready[n_ready - 1])
23475 && (recog_memoized (ready[n_ready - 2]) > 0))
23476 /* Simply swap first two insns. */
23478 rtx tmp = ready[n_ready - 1];
23479 ready[n_ready - 1] = ready[n_ready - 2];
23480 ready[n_ready - 2] = tmp;
23484 if (rs6000_cpu == PROCESSOR_POWER6)
23485 load_store_pendulum = 0;
23487 return rs6000_issue_rate ();
23490 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23493 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23494 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23497 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23499 /* For Power6, we need to handle some special cases to try and keep the
23500 store queue from overflowing and triggering expensive flushes.
23502 This code monitors how load and store instructions are being issued
23503 and skews the ready list one way or the other to increase the likelihood
23504 that a desired instruction is issued at the proper time.
23506 A couple of things are done. First, we maintain a "load_store_pendulum"
23507 to track the current state of load/store issue.
23509 - If the pendulum is at zero, then no loads or stores have been
23510 issued in the current cycle so we do nothing.
23512 - If the pendulum is 1, then a single load has been issued in this
23513 cycle and we attempt to locate another load in the ready list to
23516 - If the pendulum is -2, then two stores have already been
23517 issued in this cycle, so we increase the priority of the first load
23518 in the ready list to increase it's likelihood of being chosen first
23521 - If the pendulum is -1, then a single store has been issued in this
23522 cycle and we attempt to locate another store in the ready list to
23523 issue with it, preferring a store to an adjacent memory location to
23524 facilitate store pairing in the store queue.
23526 - If the pendulum is 2, then two loads have already been
23527 issued in this cycle, so we increase the priority of the first store
23528 in the ready list to increase it's likelihood of being chosen first
23531 - If the pendulum < -2 or > 2, then do nothing.
23533 Note: This code covers the most common scenarios. There exist non
23534 load/store instructions which make use of the LSU and which
23535 would need to be accounted for to strictly model the behavior
23536 of the machine. Those instructions are currently unaccounted
23537 for to help minimize compile time overhead of this code.
23539 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23545 if (is_store_insn (last_scheduled_insn))
23546 /* Issuing a store, swing the load_store_pendulum to the left */
23547 load_store_pendulum--;
23548 else if (is_load_insn (last_scheduled_insn))
23549 /* Issuing a load, swing the load_store_pendulum to the right */
23550 load_store_pendulum++;
23552 return cached_can_issue_more;
23554 /* If the pendulum is balanced, or there is only one instruction on
23555 the ready list, then all is well, so return. */
23556 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23557 return cached_can_issue_more;
23559 if (load_store_pendulum == 1)
23561 /* A load has been issued in this cycle. Scan the ready list
23562 for another load to issue with it */
23567 if (is_load_insn (ready[pos]))
23569 /* Found a load. Move it to the head of the ready list,
23570 and adjust it's priority so that it is more likely to
23573 for (i=pos; i<*pn_ready-1; i++)
23574 ready[i] = ready[i + 1];
23575 ready[*pn_ready-1] = tmp;
23577 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23578 INSN_PRIORITY (tmp)++;
23584 else if (load_store_pendulum == -2)
23586 /* Two stores have been issued in this cycle. Increase the
23587 priority of the first load in the ready list to favor it for
23588 issuing in the next cycle. */
23593 if (is_load_insn (ready[pos])
23595 && INSN_PRIORITY_KNOWN (ready[pos]))
23597 INSN_PRIORITY (ready[pos])++;
23599 /* Adjust the pendulum to account for the fact that a load
23600 was found and increased in priority. This is to prevent
23601 increasing the priority of multiple loads */
23602 load_store_pendulum--;
23609 else if (load_store_pendulum == -1)
23611 /* A store has been issued in this cycle. Scan the ready list for
23612 another store to issue with it, preferring a store to an adjacent
23614 int first_store_pos = -1;
23620 if (is_store_insn (ready[pos]))
23622 /* Maintain the index of the first store found on the
23624 if (first_store_pos == -1)
23625 first_store_pos = pos;
23627 if (is_store_insn (last_scheduled_insn)
23628 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23630 /* Found an adjacent store. Move it to the head of the
23631 ready list, and adjust it's priority so that it is
23632 more likely to stay there */
23634 for (i=pos; i<*pn_ready-1; i++)
23635 ready[i] = ready[i + 1];
23636 ready[*pn_ready-1] = tmp;
23638 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23639 INSN_PRIORITY (tmp)++;
23641 first_store_pos = -1;
23649 if (first_store_pos >= 0)
23651 /* An adjacent store wasn't found, but a non-adjacent store was,
23652 so move the non-adjacent store to the front of the ready
23653 list, and adjust its priority so that it is more likely to
23655 tmp = ready[first_store_pos];
23656 for (i=first_store_pos; i<*pn_ready-1; i++)
23657 ready[i] = ready[i + 1];
23658 ready[*pn_ready-1] = tmp;
23659 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23660 INSN_PRIORITY (tmp)++;
23663 else if (load_store_pendulum == 2)
23665 /* Two loads have been issued in this cycle. Increase the priority
23666 of the first store in the ready list to favor it for issuing in
23672 if (is_store_insn (ready[pos])
23674 && INSN_PRIORITY_KNOWN (ready[pos]))
23676 INSN_PRIORITY (ready[pos])++;
23678 /* Adjust the pendulum to account for the fact that a store
23679 was found and increased in priority. This is to prevent
23680 increasing the priority of multiple stores */
23681 load_store_pendulum++;
23690 return cached_can_issue_more;
23693 /* Return whether the presence of INSN causes a dispatch group termination
23694 of group WHICH_GROUP.
23696 If WHICH_GROUP == current_group, this function will return true if INSN
23697 causes the termination of the current group (i.e, the dispatch group to
23698 which INSN belongs). This means that INSN will be the last insn in the
23699 group it belongs to.
23701 If WHICH_GROUP == previous_group, this function will return true if INSN
23702 causes the termination of the previous group (i.e, the dispatch group that
23703 precedes the group to which INSN belongs). This means that INSN will be
23704 the first insn in the group it belongs to). */
23707 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23714 first = insn_must_be_first_in_group (insn);
23715 last = insn_must_be_last_in_group (insn);
23720 if (which_group == current_group)
23722 else if (which_group == previous_group)
23730 insn_must_be_first_in_group (rtx insn)
23732 enum attr_type type;
23735 || GET_CODE (insn) == NOTE
23736 || DEBUG_INSN_P (insn)
23737 || GET_CODE (PATTERN (insn)) == USE
23738 || GET_CODE (PATTERN (insn)) == CLOBBER)
23741 switch (rs6000_cpu)
23743 case PROCESSOR_POWER5:
23744 if (is_cracked_insn (insn))
23746 case PROCESSOR_POWER4:
23747 if (is_microcoded_insn (insn))
23750 if (!rs6000_sched_groups)
23753 type = get_attr_type (insn);
23760 case TYPE_DELAYED_CR:
23761 case TYPE_CR_LOGICAL:
23775 case PROCESSOR_POWER6:
23776 type = get_attr_type (insn);
23780 case TYPE_INSERT_DWORD:
23784 case TYPE_VAR_SHIFT_ROTATE:
23791 case TYPE_INSERT_WORD:
23792 case TYPE_DELAYED_COMPARE:
23793 case TYPE_IMUL_COMPARE:
23794 case TYPE_LMUL_COMPARE:
23795 case TYPE_FPCOMPARE:
23806 case TYPE_LOAD_EXT_UX:
23808 case TYPE_STORE_UX:
23809 case TYPE_FPLOAD_U:
23810 case TYPE_FPLOAD_UX:
23811 case TYPE_FPSTORE_U:
23812 case TYPE_FPSTORE_UX:
23818 case PROCESSOR_POWER7:
23819 type = get_attr_type (insn);
23823 case TYPE_CR_LOGICAL:
23830 case TYPE_DELAYED_COMPARE:
23831 case TYPE_VAR_DELAYED_COMPARE:
23837 case TYPE_LOAD_EXT:
23838 case TYPE_LOAD_EXT_U:
23839 case TYPE_LOAD_EXT_UX:
23841 case TYPE_STORE_UX:
23842 case TYPE_FPLOAD_U:
23843 case TYPE_FPLOAD_UX:
23844 case TYPE_FPSTORE_U:
23845 case TYPE_FPSTORE_UX:
23861 insn_must_be_last_in_group (rtx insn)
23863 enum attr_type type;
23866 || GET_CODE (insn) == NOTE
23867 || DEBUG_INSN_P (insn)
23868 || GET_CODE (PATTERN (insn)) == USE
23869 || GET_CODE (PATTERN (insn)) == CLOBBER)
23872 switch (rs6000_cpu) {
23873 case PROCESSOR_POWER4:
23874 case PROCESSOR_POWER5:
23875 if (is_microcoded_insn (insn))
23878 if (is_branch_slot_insn (insn))
23882 case PROCESSOR_POWER6:
23883 type = get_attr_type (insn);
23890 case TYPE_VAR_SHIFT_ROTATE:
23897 case TYPE_DELAYED_COMPARE:
23898 case TYPE_IMUL_COMPARE:
23899 case TYPE_LMUL_COMPARE:
23900 case TYPE_FPCOMPARE:
23914 case PROCESSOR_POWER7:
23915 type = get_attr_type (insn);
23923 case TYPE_LOAD_EXT_U:
23924 case TYPE_LOAD_EXT_UX:
23925 case TYPE_STORE_UX:
23938 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23939 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23942 is_costly_group (rtx *group_insns, rtx next_insn)
23945 int issue_rate = rs6000_issue_rate ();
23947 for (i = 0; i < issue_rate; i++)
23949 sd_iterator_def sd_it;
23951 rtx insn = group_insns[i];
23956 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23958 rtx next = DEP_CON (dep);
23960 if (next == next_insn
23961 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23969 /* Utility of the function redefine_groups.
23970 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23971 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23972 to keep it "far" (in a separate group) from GROUP_INSNS, following
23973 one of the following schemes, depending on the value of the flag
23974 -minsert_sched_nops = X:
23975 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23976 in order to force NEXT_INSN into a separate group.
23977 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23978 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23979 insertion (has a group just ended, how many vacant issue slots remain in the
23980 last group, and how many dispatch groups were encountered so far). */
23983 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23984 rtx next_insn, bool *group_end, int can_issue_more,
23989 int issue_rate = rs6000_issue_rate ();
23990 bool end = *group_end;
23993 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23994 return can_issue_more;
23996 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23997 return can_issue_more;
23999 force = is_costly_group (group_insns, next_insn);
24001 return can_issue_more;
24003 if (sched_verbose > 6)
24004 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24005 *group_count ,can_issue_more);
24007 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24010 can_issue_more = 0;
24012 /* Since only a branch can be issued in the last issue_slot, it is
24013 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24014 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24015 in this case the last nop will start a new group and the branch
24016 will be forced to the new group. */
24017 if (can_issue_more && !is_branch_slot_insn (next_insn))
24020 while (can_issue_more > 0)
24023 emit_insn_before (nop, next_insn);
24031 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24033 int n_nops = rs6000_sched_insert_nops;
24035 /* Nops can't be issued from the branch slot, so the effective
24036 issue_rate for nops is 'issue_rate - 1'. */
24037 if (can_issue_more == 0)
24038 can_issue_more = issue_rate;
24040 if (can_issue_more == 0)
24042 can_issue_more = issue_rate - 1;
24045 for (i = 0; i < issue_rate; i++)
24047 group_insns[i] = 0;
24054 emit_insn_before (nop, next_insn);
24055 if (can_issue_more == issue_rate - 1) /* new group begins */
24058 if (can_issue_more == 0)
24060 can_issue_more = issue_rate - 1;
24063 for (i = 0; i < issue_rate; i++)
24065 group_insns[i] = 0;
24071 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24074 /* Is next_insn going to start a new group? */
24077 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24078 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24079 || (can_issue_more < issue_rate &&
24080 insn_terminates_group_p (next_insn, previous_group)));
24081 if (*group_end && end)
24084 if (sched_verbose > 6)
24085 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24086 *group_count, can_issue_more);
24087 return can_issue_more;
24090 return can_issue_more;
24093 /* This function tries to synch the dispatch groups that the compiler "sees"
24094 with the dispatch groups that the processor dispatcher is expected to
24095 form in practice. It tries to achieve this synchronization by forcing the
24096 estimated processor grouping on the compiler (as opposed to the function
24097 'pad_goups' which tries to force the scheduler's grouping on the processor).
24099 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24100 examines the (estimated) dispatch groups that will be formed by the processor
24101 dispatcher. It marks these group boundaries to reflect the estimated
24102 processor grouping, overriding the grouping that the scheduler had marked.
24103 Depending on the value of the flag '-minsert-sched-nops' this function can
24104 force certain insns into separate groups or force a certain distance between
24105 them by inserting nops, for example, if there exists a "costly dependence"
24108 The function estimates the group boundaries that the processor will form as
24109 follows: It keeps track of how many vacant issue slots are available after
24110 each insn. A subsequent insn will start a new group if one of the following
24112 - no more vacant issue slots remain in the current dispatch group.
24113 - only the last issue slot, which is the branch slot, is vacant, but the next
24114 insn is not a branch.
24115 - only the last 2 or less issue slots, including the branch slot, are vacant,
24116 which means that a cracked insn (which occupies two issue slots) can't be
24117 issued in this group.
24118 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24119 start a new group. */
24122 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24124 rtx insn, next_insn;
24126 int can_issue_more;
24129 int group_count = 0;
24133 issue_rate = rs6000_issue_rate ();
24134 group_insns = XALLOCAVEC (rtx, issue_rate);
24135 for (i = 0; i < issue_rate; i++)
24137 group_insns[i] = 0;
24139 can_issue_more = issue_rate;
24141 insn = get_next_active_insn (prev_head_insn, tail);
24144 while (insn != NULL_RTX)
24146 slot = (issue_rate - can_issue_more);
24147 group_insns[slot] = insn;
24149 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24150 if (insn_terminates_group_p (insn, current_group))
24151 can_issue_more = 0;
24153 next_insn = get_next_active_insn (insn, tail);
24154 if (next_insn == NULL_RTX)
24155 return group_count + 1;
24157 /* Is next_insn going to start a new group? */
24159 = (can_issue_more == 0
24160 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24161 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24162 || (can_issue_more < issue_rate &&
24163 insn_terminates_group_p (next_insn, previous_group)));
24165 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24166 next_insn, &group_end, can_issue_more,
24172 can_issue_more = 0;
24173 for (i = 0; i < issue_rate; i++)
24175 group_insns[i] = 0;
24179 if (GET_MODE (next_insn) == TImode && can_issue_more)
24180 PUT_MODE (next_insn, VOIDmode);
24181 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24182 PUT_MODE (next_insn, TImode);
24185 if (can_issue_more == 0)
24186 can_issue_more = issue_rate;
24189 return group_count;
24192 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24193 dispatch group boundaries that the scheduler had marked. Pad with nops
24194 any dispatch groups which have vacant issue slots, in order to force the
24195 scheduler's grouping on the processor dispatcher. The function
24196 returns the number of dispatch groups found. */
24199 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24201 rtx insn, next_insn;
24204 int can_issue_more;
24206 int group_count = 0;
24208 /* Initialize issue_rate. */
24209 issue_rate = rs6000_issue_rate ();
24210 can_issue_more = issue_rate;
24212 insn = get_next_active_insn (prev_head_insn, tail);
24213 next_insn = get_next_active_insn (insn, tail);
24215 while (insn != NULL_RTX)
24218 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24220 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24222 if (next_insn == NULL_RTX)
24227 /* If the scheduler had marked group termination at this location
24228 (between insn and next_insn), and neither insn nor next_insn will
24229 force group termination, pad the group with nops to force group
24232 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24233 && !insn_terminates_group_p (insn, current_group)
24234 && !insn_terminates_group_p (next_insn, previous_group))
24236 if (!is_branch_slot_insn (next_insn))
24239 while (can_issue_more)
24242 emit_insn_before (nop, next_insn);
24247 can_issue_more = issue_rate;
24252 next_insn = get_next_active_insn (insn, tail);
24255 return group_count;
24258 /* We're beginning a new block. Initialize data structures as necessary. */
24261 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24262 int sched_verbose ATTRIBUTE_UNUSED,
24263 int max_ready ATTRIBUTE_UNUSED)
24265 last_scheduled_insn = NULL_RTX;
24266 load_store_pendulum = 0;
24269 /* The following function is called at the end of scheduling BB.
24270 After reload, it inserts nops at insn group bundling. */
24273 rs6000_sched_finish (FILE *dump, int sched_verbose)
24278 fprintf (dump, "=== Finishing schedule.\n");
24280 if (reload_completed && rs6000_sched_groups)
24282 /* Do not run sched_finish hook when selective scheduling enabled. */
24283 if (sel_sched_p ())
24286 if (rs6000_sched_insert_nops == sched_finish_none)
24289 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24290 n_groups = pad_groups (dump, sched_verbose,
24291 current_sched_info->prev_head,
24292 current_sched_info->next_tail);
24294 n_groups = redefine_groups (dump, sched_verbose,
24295 current_sched_info->prev_head,
24296 current_sched_info->next_tail);
24298 if (sched_verbose >= 6)
24300 fprintf (dump, "ngroups = %d\n", n_groups);
24301 print_rtl (dump, current_sched_info->prev_head);
24302 fprintf (dump, "Done finish_sched\n");
24307 struct _rs6000_sched_context
24309 short cached_can_issue_more;
24310 rtx last_scheduled_insn;
24311 int load_store_pendulum;
24314 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24315 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24317 /* Allocate store for new scheduling context. */
24319 rs6000_alloc_sched_context (void)
24321 return xmalloc (sizeof (rs6000_sched_context_def));
24324 /* If CLEAN_P is true then initializes _SC with clean data,
24325 and from the global context otherwise. */
24327 rs6000_init_sched_context (void *_sc, bool clean_p)
24329 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24333 sc->cached_can_issue_more = 0;
24334 sc->last_scheduled_insn = NULL_RTX;
24335 sc->load_store_pendulum = 0;
24339 sc->cached_can_issue_more = cached_can_issue_more;
24340 sc->last_scheduled_insn = last_scheduled_insn;
24341 sc->load_store_pendulum = load_store_pendulum;
24345 /* Sets the global scheduling context to the one pointed to by _SC. */
24347 rs6000_set_sched_context (void *_sc)
24349 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24351 gcc_assert (sc != NULL);
24353 cached_can_issue_more = sc->cached_can_issue_more;
24354 last_scheduled_insn = sc->last_scheduled_insn;
24355 load_store_pendulum = sc->load_store_pendulum;
24360 rs6000_free_sched_context (void *_sc)
24362 gcc_assert (_sc != NULL);
24368 /* Length in units of the trampoline for entering a nested function. */
24371 rs6000_trampoline_size (void)
24375 switch (DEFAULT_ABI)
24378 gcc_unreachable ();
24381 ret = (TARGET_32BIT) ? 12 : 24;
24386 ret = (TARGET_32BIT) ? 40 : 48;
24393 /* Emit RTL insns to initialize the variable parts of a trampoline.
24394 FNADDR is an RTX for the address of the function's pure code.
24395 CXT is an RTX for the static chain value for the function. */
24398 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24400 int regsize = (TARGET_32BIT) ? 4 : 8;
24401 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24402 rtx ctx_reg = force_reg (Pmode, cxt);
24403 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24405 switch (DEFAULT_ABI)
24408 gcc_unreachable ();
24410 /* Under AIX, just build the 3 word function descriptor */
24413 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24414 rtx fn_reg = gen_reg_rtx (Pmode);
24415 rtx toc_reg = gen_reg_rtx (Pmode);
24417 /* Macro to shorten the code expansions below. */
24418 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24420 m_tramp = replace_equiv_address (m_tramp, addr);
24422 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24423 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24424 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24425 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24426 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24432 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24435 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24436 LCT_NORMAL, VOIDmode, 4,
24438 GEN_INT (rs6000_trampoline_size ()), SImode,
24446 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24447 identifier as an argument, so the front end shouldn't look it up. */
24450 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24452 return is_attribute_p ("altivec", attr_id);
24455 /* Handle the "altivec" attribute. The attribute may have
24456 arguments as follows:
24458 __attribute__((altivec(vector__)))
24459 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24460 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24462 and may appear more than once (e.g., 'vector bool char') in a
24463 given declaration. */
24466 rs6000_handle_altivec_attribute (tree *node,
24467 tree name ATTRIBUTE_UNUSED,
24469 int flags ATTRIBUTE_UNUSED,
24470 bool *no_add_attrs)
24472 tree type = *node, result = NULL_TREE;
24473 enum machine_mode mode;
24476 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24477 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24478 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24481 while (POINTER_TYPE_P (type)
24482 || TREE_CODE (type) == FUNCTION_TYPE
24483 || TREE_CODE (type) == METHOD_TYPE
24484 || TREE_CODE (type) == ARRAY_TYPE)
24485 type = TREE_TYPE (type);
24487 mode = TYPE_MODE (type);
24489 /* Check for invalid AltiVec type qualifiers. */
24490 if (type == long_double_type_node)
24491 error ("use of %<long double%> in AltiVec types is invalid");
24492 else if (type == boolean_type_node)
24493 error ("use of boolean types in AltiVec types is invalid");
24494 else if (TREE_CODE (type) == COMPLEX_TYPE)
24495 error ("use of %<complex%> in AltiVec types is invalid");
24496 else if (DECIMAL_FLOAT_MODE_P (mode))
24497 error ("use of decimal floating point types in AltiVec types is invalid");
24498 else if (!TARGET_VSX)
24500 if (type == long_unsigned_type_node || type == long_integer_type_node)
24503 error ("use of %<long%> in AltiVec types is invalid for "
24504 "64-bit code without -mvsx");
24505 else if (rs6000_warn_altivec_long)
24506 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24509 else if (type == long_long_unsigned_type_node
24510 || type == long_long_integer_type_node)
24511 error ("use of %<long long%> in AltiVec types is invalid without "
24513 else if (type == double_type_node)
24514 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24517 switch (altivec_type)
24520 unsigned_p = TYPE_UNSIGNED (type);
24524 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24527 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24530 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24533 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24535 case SFmode: result = V4SF_type_node; break;
24536 case DFmode: result = V2DF_type_node; break;
24537 /* If the user says 'vector int bool', we may be handed the 'bool'
24538 attribute _before_ the 'vector' attribute, and so select the
24539 proper type in the 'b' case below. */
24540 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24541 case V2DImode: case V2DFmode:
24549 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24550 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24551 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24552 case QImode: case V16QImode: result = bool_V16QI_type_node;
24559 case V8HImode: result = pixel_V8HI_type_node;
24565 /* Propagate qualifiers attached to the element type
24566 onto the vector type. */
24567 if (result && result != type && TYPE_QUALS (type))
24568 result = build_qualified_type (result, TYPE_QUALS (type));
24570 *no_add_attrs = true; /* No need to hang on to the attribute. */
24573 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24578 /* AltiVec defines four built-in scalar types that serve as vector
24579 elements; we must teach the compiler how to mangle them. */
24581 static const char *
24582 rs6000_mangle_type (const_tree type)
24584 type = TYPE_MAIN_VARIANT (type);
24586 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24587 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24590 if (type == bool_char_type_node) return "U6__boolc";
24591 if (type == bool_short_type_node) return "U6__bools";
24592 if (type == pixel_type_node) return "u7__pixel";
24593 if (type == bool_int_type_node) return "U6__booli";
24594 if (type == bool_long_type_node) return "U6__booll";
24596 /* Mangle IBM extended float long double as `g' (__float128) on
24597 powerpc*-linux where long-double-64 previously was the default. */
24598 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24600 && TARGET_LONG_DOUBLE_128
24601 && !TARGET_IEEEQUAD)
24604 /* For all other types, use normal C++ mangling. */
24608 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24609 struct attribute_spec.handler. */
24612 rs6000_handle_longcall_attribute (tree *node, tree name,
24613 tree args ATTRIBUTE_UNUSED,
24614 int flags ATTRIBUTE_UNUSED,
24615 bool *no_add_attrs)
24617 if (TREE_CODE (*node) != FUNCTION_TYPE
24618 && TREE_CODE (*node) != FIELD_DECL
24619 && TREE_CODE (*node) != TYPE_DECL)
24621 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24623 *no_add_attrs = true;
24629 /* Set longcall attributes on all functions declared when
24630 rs6000_default_long_calls is true. */
24632 rs6000_set_default_type_attributes (tree type)
24634 if (rs6000_default_long_calls
24635 && (TREE_CODE (type) == FUNCTION_TYPE
24636 || TREE_CODE (type) == METHOD_TYPE))
24637 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24639 TYPE_ATTRIBUTES (type));
24642 darwin_set_default_type_attributes (type);
24646 /* Return a reference suitable for calling a function with the
24647 longcall attribute. */
24650 rs6000_longcall_ref (rtx call_ref)
24652 const char *call_name;
24655 if (GET_CODE (call_ref) != SYMBOL_REF)
24658 /* System V adds '.' to the internal name, so skip them. */
24659 call_name = XSTR (call_ref, 0);
24660 if (*call_name == '.')
24662 while (*call_name == '.')
24665 node = get_identifier (call_name);
24666 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24669 return force_reg (Pmode, call_ref);
24672 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24673 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24676 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24677 struct attribute_spec.handler. */
24679 rs6000_handle_struct_attribute (tree *node, tree name,
24680 tree args ATTRIBUTE_UNUSED,
24681 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24684 if (DECL_P (*node))
24686 if (TREE_CODE (*node) == TYPE_DECL)
24687 type = &TREE_TYPE (*node);
24692 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24693 || TREE_CODE (*type) == UNION_TYPE)))
24695 warning (OPT_Wattributes, "%qE attribute ignored", name);
24696 *no_add_attrs = true;
24699 else if ((is_attribute_p ("ms_struct", name)
24700 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24701 || ((is_attribute_p ("gcc_struct", name)
24702 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24704 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24706 *no_add_attrs = true;
24713 rs6000_ms_bitfield_layout_p (const_tree record_type)
24715 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24716 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24717 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24720 #ifdef USING_ELFOS_H
24722 /* A get_unnamed_section callback, used for switching to toc_section. */
24725 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24727 if (DEFAULT_ABI == ABI_AIX
24728 && TARGET_MINIMAL_TOC
24729 && !TARGET_RELOCATABLE)
24731 if (!toc_initialized)
24733 toc_initialized = 1;
24734 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24735 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24736 fprintf (asm_out_file, "\t.tc ");
24737 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24738 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24739 fprintf (asm_out_file, "\n");
24741 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24742 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24743 fprintf (asm_out_file, " = .+32768\n");
24746 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24748 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24749 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24752 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24753 if (!toc_initialized)
24755 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24756 fprintf (asm_out_file, " = .+32768\n");
24757 toc_initialized = 1;
24762 /* Implement TARGET_ASM_INIT_SECTIONS. */
24765 rs6000_elf_asm_init_sections (void)
24768 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24771 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24772 SDATA2_SECTION_ASM_OP);
24775 /* Implement TARGET_SELECT_RTX_SECTION. */
24778 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24779 unsigned HOST_WIDE_INT align)
24781 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24782 return toc_section;
24784 return default_elf_select_rtx_section (mode, x, align);
24787 /* For a SYMBOL_REF, set generic flags and then perform some
24788 target-specific processing.
24790 When the AIX ABI is requested on a non-AIX system, replace the
24791 function name with the real name (with a leading .) rather than the
24792 function descriptor name. This saves a lot of overriding code to
24793 read the prefixes. */
24796 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24798 default_encode_section_info (decl, rtl, first);
24801 && TREE_CODE (decl) == FUNCTION_DECL
24803 && DEFAULT_ABI == ABI_AIX)
24805 rtx sym_ref = XEXP (rtl, 0);
24806 size_t len = strlen (XSTR (sym_ref, 0));
24807 char *str = XALLOCAVEC (char, len + 2);
24809 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24810 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24815 compare_section_name (const char *section, const char *templ)
24819 len = strlen (templ);
24820 return (strncmp (section, templ, len) == 0
24821 && (section[len] == 0 || section[len] == '.'));
24825 rs6000_elf_in_small_data_p (const_tree decl)
24827 if (rs6000_sdata == SDATA_NONE)
24830 /* We want to merge strings, so we never consider them small data. */
24831 if (TREE_CODE (decl) == STRING_CST)
24834 /* Functions are never in the small data area. */
24835 if (TREE_CODE (decl) == FUNCTION_DECL)
24838 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24840 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24841 if (compare_section_name (section, ".sdata")
24842 || compare_section_name (section, ".sdata2")
24843 || compare_section_name (section, ".gnu.linkonce.s")
24844 || compare_section_name (section, ".sbss")
24845 || compare_section_name (section, ".sbss2")
24846 || compare_section_name (section, ".gnu.linkonce.sb")
24847 || strcmp (section, ".PPC.EMB.sdata0") == 0
24848 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24853 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24856 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24857 /* If it's not public, and we're not going to reference it there,
24858 there's no need to put it in the small data section. */
24859 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24866 #endif /* USING_ELFOS_H */
24868 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24871 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24873 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24876 /* Return a REG that occurs in ADDR with coefficient 1.
24877 ADDR can be effectively incremented by incrementing REG.
24879 r0 is special and we must not select it as an address
24880 register by this routine since our caller will try to
24881 increment the returned register via an "la" instruction. */
24884 find_addr_reg (rtx addr)
24886 while (GET_CODE (addr) == PLUS)
24888 if (GET_CODE (XEXP (addr, 0)) == REG
24889 && REGNO (XEXP (addr, 0)) != 0)
24890 addr = XEXP (addr, 0);
24891 else if (GET_CODE (XEXP (addr, 1)) == REG
24892 && REGNO (XEXP (addr, 1)) != 0)
24893 addr = XEXP (addr, 1);
24894 else if (CONSTANT_P (XEXP (addr, 0)))
24895 addr = XEXP (addr, 1);
24896 else if (CONSTANT_P (XEXP (addr, 1)))
24897 addr = XEXP (addr, 0);
24899 gcc_unreachable ();
24901 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24906 rs6000_fatal_bad_address (rtx op)
24908 fatal_insn ("bad address", op);
24913 typedef struct branch_island_d {
24914 tree function_name;
24919 DEF_VEC_O(branch_island);
24920 DEF_VEC_ALLOC_O(branch_island,gc);
24922 static VEC(branch_island,gc) *branch_islands;
24924 /* Remember to generate a branch island for far calls to the given
24928 add_compiler_branch_island (tree label_name, tree function_name,
24931 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24933 bi->function_name = function_name;
24934 bi->label_name = label_name;
24935 bi->line_number = line_number;
24938 /* Generate far-jump branch islands for everything recorded in
24939 branch_islands. Invoked immediately after the last instruction of
24940 the epilogue has been emitted; the branch islands must be appended
24941 to, and contiguous with, the function body. Mach-O stubs are
24942 generated in machopic_output_stub(). */
24945 macho_branch_islands (void)
24949 while (!VEC_empty (branch_island, branch_islands))
24951 branch_island *bi = VEC_last (branch_island, branch_islands);
24952 const char *label = IDENTIFIER_POINTER (bi->label_name);
24953 const char *name = IDENTIFIER_POINTER (bi->function_name);
24954 char name_buf[512];
24955 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24956 if (name[0] == '*' || name[0] == '&')
24957 strcpy (name_buf, name+1);
24961 strcpy (name_buf+1, name);
24963 strcpy (tmp_buf, "\n");
24964 strcat (tmp_buf, label);
24965 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24966 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24967 dbxout_stabd (N_SLINE, bi->line_number);
24968 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24971 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24972 strcat (tmp_buf, label);
24973 strcat (tmp_buf, "_pic\n");
24974 strcat (tmp_buf, label);
24975 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24977 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24978 strcat (tmp_buf, name_buf);
24979 strcat (tmp_buf, " - ");
24980 strcat (tmp_buf, label);
24981 strcat (tmp_buf, "_pic)\n");
24983 strcat (tmp_buf, "\tmtlr r0\n");
24985 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24986 strcat (tmp_buf, name_buf);
24987 strcat (tmp_buf, " - ");
24988 strcat (tmp_buf, label);
24989 strcat (tmp_buf, "_pic)\n");
24991 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24995 strcat (tmp_buf, ":\nlis r12,hi16(");
24996 strcat (tmp_buf, name_buf);
24997 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24998 strcat (tmp_buf, name_buf);
24999 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25001 output_asm_insn (tmp_buf, 0);
25002 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25003 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25004 dbxout_stabd (N_SLINE, bi->line_number);
25005 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25006 VEC_pop (branch_island, branch_islands);
25010 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25011 already there or not. */
25014 no_previous_def (tree function_name)
25019 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25020 if (function_name == bi->function_name)
25025 /* GET_PREV_LABEL gets the label name from the previous definition of
25029 get_prev_label (tree function_name)
25034 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25035 if (function_name == bi->function_name)
25036 return bi->label_name;
25040 /* INSN is either a function call or a millicode call. It may have an
25041 unconditional jump in its delay slot.
25043 CALL_DEST is the routine we are calling. */
25046 output_call (rtx insn, rtx *operands, int dest_operand_number,
25047 int cookie_operand_number)
25049 static char buf[256];
25050 if (darwin_emit_branch_islands
25051 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25052 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25055 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25057 if (no_previous_def (funname))
25059 rtx label_rtx = gen_label_rtx ();
25060 char *label_buf, temp_buf[256];
25061 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25062 CODE_LABEL_NUMBER (label_rtx));
25063 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25064 labelname = get_identifier (label_buf);
25065 add_compiler_branch_island (labelname, funname, insn_line (insn));
25068 labelname = get_prev_label (funname);
25070 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25071 instruction will reach 'foo', otherwise link as 'bl L42'".
25072 "L42" should be a 'branch island', that will do a far jump to
25073 'foo'. Branch islands are generated in
25074 macho_branch_islands(). */
25075 sprintf (buf, "jbsr %%z%d,%.246s",
25076 dest_operand_number, IDENTIFIER_POINTER (labelname));
25079 sprintf (buf, "bl %%z%d", dest_operand_number);
25083 /* Generate PIC and indirect symbol stubs. */
25086 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25088 unsigned int length;
25089 char *symbol_name, *lazy_ptr_name;
25090 char *local_label_0;
25091 static int label = 0;
25093 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25094 symb = (*targetm.strip_name_encoding) (symb);
25097 length = strlen (symb);
25098 symbol_name = XALLOCAVEC (char, length + 32);
25099 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25101 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25102 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25105 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25107 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25111 fprintf (file, "\t.align 5\n");
25113 fprintf (file, "%s:\n", stub);
25114 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25117 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25118 sprintf (local_label_0, "\"L%011d$spb\"", label);
25120 fprintf (file, "\tmflr r0\n");
25121 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25122 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25123 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25124 lazy_ptr_name, local_label_0);
25125 fprintf (file, "\tmtlr r0\n");
25126 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25127 (TARGET_64BIT ? "ldu" : "lwzu"),
25128 lazy_ptr_name, local_label_0);
25129 fprintf (file, "\tmtctr r12\n");
25130 fprintf (file, "\tbctr\n");
25134 fprintf (file, "\t.align 4\n");
25136 fprintf (file, "%s:\n", stub);
25137 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25139 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25140 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25141 (TARGET_64BIT ? "ldu" : "lwzu"),
25143 fprintf (file, "\tmtctr r12\n");
25144 fprintf (file, "\tbctr\n");
25147 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25148 fprintf (file, "%s:\n", lazy_ptr_name);
25149 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25150 fprintf (file, "%sdyld_stub_binding_helper\n",
25151 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25154 /* Legitimize PIC addresses. If the address is already
25155 position-independent, we return ORIG. Newly generated
25156 position-independent addresses go into a reg. This is REG if non
25157 zero, otherwise we allocate register(s) as necessary. */
25159 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25162 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25167 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25168 reg = gen_reg_rtx (Pmode);
25170 if (GET_CODE (orig) == CONST)
25174 if (GET_CODE (XEXP (orig, 0)) == PLUS
25175 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25178 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25180 /* Use a different reg for the intermediate value, as
25181 it will be marked UNCHANGING. */
25182 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25183 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25186 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25189 if (GET_CODE (offset) == CONST_INT)
25191 if (SMALL_INT (offset))
25192 return plus_constant (base, INTVAL (offset));
25193 else if (! reload_in_progress && ! reload_completed)
25194 offset = force_reg (Pmode, offset);
25197 rtx mem = force_const_mem (Pmode, orig);
25198 return machopic_legitimize_pic_address (mem, Pmode, reg);
25201 return gen_rtx_PLUS (Pmode, base, offset);
25204 /* Fall back on generic machopic code. */
25205 return machopic_legitimize_pic_address (orig, mode, reg);
25208 /* Output a .machine directive for the Darwin assembler, and call
25209 the generic start_file routine. */
25212 rs6000_darwin_file_start (void)
25214 static const struct
25220 { "ppc64", "ppc64", MASK_64BIT },
25221 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25222 { "power4", "ppc970", 0 },
25223 { "G5", "ppc970", 0 },
25224 { "7450", "ppc7450", 0 },
25225 { "7400", "ppc7400", MASK_ALTIVEC },
25226 { "G4", "ppc7400", 0 },
25227 { "750", "ppc750", 0 },
25228 { "740", "ppc750", 0 },
25229 { "G3", "ppc750", 0 },
25230 { "604e", "ppc604e", 0 },
25231 { "604", "ppc604", 0 },
25232 { "603e", "ppc603", 0 },
25233 { "603", "ppc603", 0 },
25234 { "601", "ppc601", 0 },
25235 { NULL, "ppc", 0 } };
25236 const char *cpu_id = "";
25239 rs6000_file_start ();
25240 darwin_file_start ();
25242 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25243 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25244 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25245 && rs6000_select[i].string[0] != '\0')
25246 cpu_id = rs6000_select[i].string;
25248 /* Look through the mapping array. Pick the first name that either
25249 matches the argument, has a bit set in IF_SET that is also set
25250 in the target flags, or has a NULL name. */
25253 while (mapping[i].arg != NULL
25254 && strcmp (mapping[i].arg, cpu_id) != 0
25255 && (mapping[i].if_set & target_flags) == 0)
25258 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25261 #endif /* TARGET_MACHO */
25265 rs6000_elf_reloc_rw_mask (void)
25269 else if (DEFAULT_ABI == ABI_AIX)
25275 /* Record an element in the table of global constructors. SYMBOL is
25276 a SYMBOL_REF of the function to be called; PRIORITY is a number
25277 between 0 and MAX_INIT_PRIORITY.
25279 This differs from default_named_section_asm_out_constructor in
25280 that we have special handling for -mrelocatable. */
25283 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25285 const char *section = ".ctors";
25288 if (priority != DEFAULT_INIT_PRIORITY)
25290 sprintf (buf, ".ctors.%.5u",
25291 /* Invert the numbering so the linker puts us in the proper
25292 order; constructors are run from right to left, and the
25293 linker sorts in increasing order. */
25294 MAX_INIT_PRIORITY - priority);
25298 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25299 assemble_align (POINTER_SIZE);
25301 if (TARGET_RELOCATABLE)
25303 fputs ("\t.long (", asm_out_file);
25304 output_addr_const (asm_out_file, symbol);
25305 fputs (")@fixup\n", asm_out_file);
25308 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25312 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25314 const char *section = ".dtors";
25317 if (priority != DEFAULT_INIT_PRIORITY)
25319 sprintf (buf, ".dtors.%.5u",
25320 /* Invert the numbering so the linker puts us in the proper
25321 order; constructors are run from right to left, and the
25322 linker sorts in increasing order. */
25323 MAX_INIT_PRIORITY - priority);
25327 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25328 assemble_align (POINTER_SIZE);
25330 if (TARGET_RELOCATABLE)
25332 fputs ("\t.long (", asm_out_file);
25333 output_addr_const (asm_out_file, symbol);
25334 fputs (")@fixup\n", asm_out_file);
25337 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25341 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25345 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25346 ASM_OUTPUT_LABEL (file, name);
25347 fputs (DOUBLE_INT_ASM_OP, file);
25348 rs6000_output_function_entry (file, name);
25349 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25352 fputs ("\t.size\t", file);
25353 assemble_name (file, name);
25354 fputs (",24\n\t.type\t.", file);
25355 assemble_name (file, name);
25356 fputs (",@function\n", file);
25357 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25359 fputs ("\t.globl\t.", file);
25360 assemble_name (file, name);
25365 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25366 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25367 rs6000_output_function_entry (file, name);
25368 fputs (":\n", file);
25372 if (TARGET_RELOCATABLE
25373 && !TARGET_SECURE_PLT
25374 && (get_pool_size () != 0 || crtl->profile)
25379 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25381 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25382 fprintf (file, "\t.long ");
25383 assemble_name (file, buf);
25385 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25386 assemble_name (file, buf);
25390 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25391 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25393 if (DEFAULT_ABI == ABI_AIX)
25395 const char *desc_name, *orig_name;
25397 orig_name = (*targetm.strip_name_encoding) (name);
25398 desc_name = orig_name;
25399 while (*desc_name == '.')
25402 if (TREE_PUBLIC (decl))
25403 fprintf (file, "\t.globl %s\n", desc_name);
25405 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25406 fprintf (file, "%s:\n", desc_name);
25407 fprintf (file, "\t.long %s\n", orig_name);
25408 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25409 if (DEFAULT_ABI == ABI_AIX)
25410 fputs ("\t.long 0\n", file);
25411 fprintf (file, "\t.previous\n");
25413 ASM_OUTPUT_LABEL (file, name);
25417 rs6000_elf_end_indicate_exec_stack (void)
25420 file_end_indicate_exec_stack ();
25426 rs6000_xcoff_asm_output_anchor (rtx symbol)
25430 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25431 SYMBOL_REF_BLOCK_OFFSET (symbol));
25432 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25436 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25438 fputs (GLOBAL_ASM_OP, stream);
25439 RS6000_OUTPUT_BASENAME (stream, name);
25440 putc ('\n', stream);
25443 /* A get_unnamed_decl callback, used for read-only sections. PTR
25444 points to the section string variable. */
25447 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25449 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25450 *(const char *const *) directive,
25451 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25454 /* Likewise for read-write sections. */
25457 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25459 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25460 *(const char *const *) directive,
25461 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25464 /* A get_unnamed_section callback, used for switching to toc_section. */
25467 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25469 if (TARGET_MINIMAL_TOC)
25471 /* toc_section is always selected at least once from
25472 rs6000_xcoff_file_start, so this is guaranteed to
25473 always be defined once and only once in each file. */
25474 if (!toc_initialized)
25476 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25477 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25478 toc_initialized = 1;
25480 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25481 (TARGET_32BIT ? "" : ",3"));
25484 fputs ("\t.toc\n", asm_out_file);
25487 /* Implement TARGET_ASM_INIT_SECTIONS. */
25490 rs6000_xcoff_asm_init_sections (void)
25492 read_only_data_section
25493 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25494 &xcoff_read_only_section_name);
25496 private_data_section
25497 = get_unnamed_section (SECTION_WRITE,
25498 rs6000_xcoff_output_readwrite_section_asm_op,
25499 &xcoff_private_data_section_name);
25501 read_only_private_data_section
25502 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25503 &xcoff_private_data_section_name);
25506 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25508 readonly_data_section = read_only_data_section;
25509 exception_section = data_section;
25513 rs6000_xcoff_reloc_rw_mask (void)
25519 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25520 tree decl ATTRIBUTE_UNUSED)
25523 static const char * const suffix[3] = { "PR", "RO", "RW" };
25525 if (flags & SECTION_CODE)
25527 else if (flags & SECTION_WRITE)
25532 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25533 (flags & SECTION_CODE) ? "." : "",
25534 name, suffix[smclass], flags & SECTION_ENTSIZE);
25538 rs6000_xcoff_select_section (tree decl, int reloc,
25539 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25541 if (decl_readonly_section (decl, reloc))
25543 if (TREE_PUBLIC (decl))
25544 return read_only_data_section;
25546 return read_only_private_data_section;
25550 if (TREE_PUBLIC (decl))
25551 return data_section;
25553 return private_data_section;
25558 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25562 /* Use select_section for private and uninitialized data. */
25563 if (!TREE_PUBLIC (decl)
25564 || DECL_COMMON (decl)
25565 || DECL_INITIAL (decl) == NULL_TREE
25566 || DECL_INITIAL (decl) == error_mark_node
25567 || (flag_zero_initialized_in_bss
25568 && initializer_zerop (DECL_INITIAL (decl))))
25571 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25572 name = (*targetm.strip_name_encoding) (name);
25573 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25576 /* Select section for constant in constant pool.
25578 On RS/6000, all constants are in the private read-only data area.
25579 However, if this is being placed in the TOC it must be output as a
25583 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25584 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25586 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25587 return toc_section;
25589 return read_only_private_data_section;
25592 /* Remove any trailing [DS] or the like from the symbol name. */
25594 static const char *
25595 rs6000_xcoff_strip_name_encoding (const char *name)
25600 len = strlen (name);
25601 if (name[len - 1] == ']')
25602 return ggc_alloc_string (name, len - 4);
25607 /* Section attributes. AIX is always PIC. */
25609 static unsigned int
25610 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25612 unsigned int align;
25613 unsigned int flags = default_section_type_flags (decl, name, reloc);
25615 /* Align to at least UNIT size. */
25616 if (flags & SECTION_CODE)
25617 align = MIN_UNITS_PER_WORD;
25619 /* Increase alignment of large objects if not already stricter. */
25620 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25621 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25622 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25624 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25627 /* Output at beginning of assembler file.
25629 Initialize the section names for the RS/6000 at this point.
25631 Specify filename, including full path, to assembler.
25633 We want to go into the TOC section so at least one .toc will be emitted.
25634 Also, in order to output proper .bs/.es pairs, we need at least one static
25635 [RW] section emitted.
25637 Finally, declare mcount when profiling to make the assembler happy. */
25640 rs6000_xcoff_file_start (void)
25642 rs6000_gen_section_name (&xcoff_bss_section_name,
25643 main_input_filename, ".bss_");
25644 rs6000_gen_section_name (&xcoff_private_data_section_name,
25645 main_input_filename, ".rw_");
25646 rs6000_gen_section_name (&xcoff_read_only_section_name,
25647 main_input_filename, ".ro_");
25649 fputs ("\t.file\t", asm_out_file);
25650 output_quoted_string (asm_out_file, main_input_filename);
25651 fputc ('\n', asm_out_file);
25652 if (write_symbols != NO_DEBUG)
25653 switch_to_section (private_data_section);
25654 switch_to_section (text_section);
25656 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25657 rs6000_file_start ();
25660 /* Output at end of assembler file.
25661 On the RS/6000, referencing data should automatically pull in text. */
25664 rs6000_xcoff_file_end (void)
25666 switch_to_section (text_section);
25667 fputs ("_section_.text:\n", asm_out_file);
25668 switch_to_section (data_section);
25669 fputs (TARGET_32BIT
25670 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25673 #endif /* TARGET_XCOFF */
25675 /* Compute a (partial) cost for rtx X. Return true if the complete
25676 cost has been computed, and false if subexpressions should be
25677 scanned. In either case, *TOTAL contains the cost result. */
25680 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25683 enum machine_mode mode = GET_MODE (x);
25687 /* On the RS/6000, if it is valid in the insn, it is free. */
25689 if (((outer_code == SET
25690 || outer_code == PLUS
25691 || outer_code == MINUS)
25692 && (satisfies_constraint_I (x)
25693 || satisfies_constraint_L (x)))
25694 || (outer_code == AND
25695 && (satisfies_constraint_K (x)
25697 ? satisfies_constraint_L (x)
25698 : satisfies_constraint_J (x))
25699 || mask_operand (x, mode)
25701 && mask64_operand (x, DImode))))
25702 || ((outer_code == IOR || outer_code == XOR)
25703 && (satisfies_constraint_K (x)
25705 ? satisfies_constraint_L (x)
25706 : satisfies_constraint_J (x))))
25707 || outer_code == ASHIFT
25708 || outer_code == ASHIFTRT
25709 || outer_code == LSHIFTRT
25710 || outer_code == ROTATE
25711 || outer_code == ROTATERT
25712 || outer_code == ZERO_EXTRACT
25713 || (outer_code == MULT
25714 && satisfies_constraint_I (x))
25715 || ((outer_code == DIV || outer_code == UDIV
25716 || outer_code == MOD || outer_code == UMOD)
25717 && exact_log2 (INTVAL (x)) >= 0)
25718 || (outer_code == COMPARE
25719 && (satisfies_constraint_I (x)
25720 || satisfies_constraint_K (x)))
25721 || (outer_code == EQ
25722 && (satisfies_constraint_I (x)
25723 || satisfies_constraint_K (x)
25725 ? satisfies_constraint_L (x)
25726 : satisfies_constraint_J (x))))
25727 || (outer_code == GTU
25728 && satisfies_constraint_I (x))
25729 || (outer_code == LTU
25730 && satisfies_constraint_P (x)))
25735 else if ((outer_code == PLUS
25736 && reg_or_add_cint_operand (x, VOIDmode))
25737 || (outer_code == MINUS
25738 && reg_or_sub_cint_operand (x, VOIDmode))
25739 || ((outer_code == SET
25740 || outer_code == IOR
25741 || outer_code == XOR)
25743 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25745 *total = COSTS_N_INSNS (1);
25751 if (mode == DImode && code == CONST_DOUBLE)
25753 if ((outer_code == IOR || outer_code == XOR)
25754 && CONST_DOUBLE_HIGH (x) == 0
25755 && (CONST_DOUBLE_LOW (x)
25756 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25761 else if ((outer_code == AND && and64_2_operand (x, DImode))
25762 || ((outer_code == SET
25763 || outer_code == IOR
25764 || outer_code == XOR)
25765 && CONST_DOUBLE_HIGH (x) == 0))
25767 *total = COSTS_N_INSNS (1);
25777 /* When optimizing for size, MEM should be slightly more expensive
25778 than generating address, e.g., (plus (reg) (const)).
25779 L1 cache latency is about two instructions. */
25780 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25788 if (mode == DFmode)
25790 if (GET_CODE (XEXP (x, 0)) == MULT)
25792 /* FNMA accounted in outer NEG. */
25793 if (outer_code == NEG)
25794 *total = rs6000_cost->dmul - rs6000_cost->fp;
25796 *total = rs6000_cost->dmul;
25799 *total = rs6000_cost->fp;
25801 else if (mode == SFmode)
25803 /* FNMA accounted in outer NEG. */
25804 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25807 *total = rs6000_cost->fp;
25810 *total = COSTS_N_INSNS (1);
25814 if (mode == DFmode)
25816 if (GET_CODE (XEXP (x, 0)) == MULT
25817 || GET_CODE (XEXP (x, 1)) == MULT)
25819 /* FNMA accounted in outer NEG. */
25820 if (outer_code == NEG)
25821 *total = rs6000_cost->dmul - rs6000_cost->fp;
25823 *total = rs6000_cost->dmul;
25826 *total = rs6000_cost->fp;
25828 else if (mode == SFmode)
25830 /* FNMA accounted in outer NEG. */
25831 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25834 *total = rs6000_cost->fp;
25837 *total = COSTS_N_INSNS (1);
25841 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25842 && satisfies_constraint_I (XEXP (x, 1)))
25844 if (INTVAL (XEXP (x, 1)) >= -256
25845 && INTVAL (XEXP (x, 1)) <= 255)
25846 *total = rs6000_cost->mulsi_const9;
25848 *total = rs6000_cost->mulsi_const;
25850 /* FMA accounted in outer PLUS/MINUS. */
25851 else if ((mode == DFmode || mode == SFmode)
25852 && (outer_code == PLUS || outer_code == MINUS))
25854 else if (mode == DFmode)
25855 *total = rs6000_cost->dmul;
25856 else if (mode == SFmode)
25857 *total = rs6000_cost->fp;
25858 else if (mode == DImode)
25859 *total = rs6000_cost->muldi;
25861 *total = rs6000_cost->mulsi;
25866 if (FLOAT_MODE_P (mode))
25868 *total = mode == DFmode ? rs6000_cost->ddiv
25869 : rs6000_cost->sdiv;
25876 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25877 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25879 if (code == DIV || code == MOD)
25881 *total = COSTS_N_INSNS (2);
25884 *total = COSTS_N_INSNS (1);
25888 if (GET_MODE (XEXP (x, 1)) == DImode)
25889 *total = rs6000_cost->divdi;
25891 *total = rs6000_cost->divsi;
25893 /* Add in shift and subtract for MOD. */
25894 if (code == MOD || code == UMOD)
25895 *total += COSTS_N_INSNS (2);
25900 *total = COSTS_N_INSNS (4);
25904 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25908 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25912 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25924 *total = COSTS_N_INSNS (1);
25932 /* Handle mul_highpart. */
25933 if (outer_code == TRUNCATE
25934 && GET_CODE (XEXP (x, 0)) == MULT)
25936 if (mode == DImode)
25937 *total = rs6000_cost->muldi;
25939 *total = rs6000_cost->mulsi;
25942 else if (outer_code == AND)
25945 *total = COSTS_N_INSNS (1);
25950 if (GET_CODE (XEXP (x, 0)) == MEM)
25953 *total = COSTS_N_INSNS (1);
25959 if (!FLOAT_MODE_P (mode))
25961 *total = COSTS_N_INSNS (1);
25967 case UNSIGNED_FLOAT:
25970 case FLOAT_TRUNCATE:
25971 *total = rs6000_cost->fp;
25975 if (mode == DFmode)
25978 *total = rs6000_cost->fp;
25982 switch (XINT (x, 1))
25985 *total = rs6000_cost->fp;
25997 *total = COSTS_N_INSNS (1);
26000 else if (FLOAT_MODE_P (mode)
26001 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26003 *total = rs6000_cost->fp;
26011 /* Carry bit requires mode == Pmode.
26012 NEG or PLUS already counted so only add one. */
26014 && (outer_code == NEG || outer_code == PLUS))
26016 *total = COSTS_N_INSNS (1);
26019 if (outer_code == SET)
26021 if (XEXP (x, 1) == const0_rtx)
26023 if (TARGET_ISEL && !TARGET_MFCRF)
26024 *total = COSTS_N_INSNS (8);
26026 *total = COSTS_N_INSNS (2);
26029 else if (mode == Pmode)
26031 *total = COSTS_N_INSNS (3);
26040 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26042 if (TARGET_ISEL && !TARGET_MFCRF)
26043 *total = COSTS_N_INSNS (8);
26045 *total = COSTS_N_INSNS (2);
26049 if (outer_code == COMPARE)
26063 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26066 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26069 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26072 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26073 "total = %d, speed = %s, x:\n",
26074 ret ? "complete" : "scan inner",
26075 GET_RTX_NAME (code),
26076 GET_RTX_NAME (outer_code),
26078 speed ? "true" : "false");
26085 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26088 rs6000_debug_address_cost (rtx x, bool speed)
26090 int ret = TARGET_ADDRESS_COST (x, speed);
26092 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26093 ret, speed ? "true" : "false");
26100 /* A C expression returning the cost of moving data from a register of class
26101 CLASS1 to one of CLASS2. */
26104 rs6000_register_move_cost (enum machine_mode mode,
26105 reg_class_t from, reg_class_t to)
26109 /* Moves from/to GENERAL_REGS. */
26110 if (reg_classes_intersect_p (to, GENERAL_REGS)
26111 || reg_classes_intersect_p (from, GENERAL_REGS))
26113 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26116 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26117 ret = (rs6000_memory_move_cost (mode, from, false)
26118 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26120 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26122 else if (from == CR_REGS)
26125 /* Power6 has slower LR/CTR moves so make them more expensive than
26126 memory in order to bias spills to memory .*/
26127 else if (rs6000_cpu == PROCESSOR_POWER6
26128 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26129 ret = 6 * hard_regno_nregs[0][mode];
26132 /* A move will cost one instruction per GPR moved. */
26133 ret = 2 * hard_regno_nregs[0][mode];
26136 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26137 else if (VECTOR_UNIT_VSX_P (mode)
26138 && reg_classes_intersect_p (to, VSX_REGS)
26139 && reg_classes_intersect_p (from, VSX_REGS))
26140 ret = 2 * hard_regno_nregs[32][mode];
26142 /* Moving between two similar registers is just one instruction. */
26143 else if (reg_classes_intersect_p (to, from))
26144 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26146 /* Everything else has to go through GENERAL_REGS. */
26148 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26149 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26151 if (TARGET_DEBUG_COST)
26153 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26154 ret, GET_MODE_NAME (mode), reg_class_names[from],
26155 reg_class_names[to]);
26160 /* A C expressions returning the cost of moving data of MODE from a register to
26164 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26165 bool in ATTRIBUTE_UNUSED)
26169 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26170 ret = 4 * hard_regno_nregs[0][mode];
26171 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26172 ret = 4 * hard_regno_nregs[32][mode];
26173 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26174 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26176 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26178 if (TARGET_DEBUG_COST)
26180 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26181 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26186 /* Returns a code for a target-specific builtin that implements
26187 reciprocal of the function, or NULL_TREE if not available. */
26190 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26191 bool sqrt ATTRIBUTE_UNUSED)
26193 if (optimize_insn_for_size_p ())
26199 case VSX_BUILTIN_XVSQRTDP:
26200 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26203 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26205 case VSX_BUILTIN_XVSQRTSP:
26206 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26209 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26218 case BUILT_IN_SQRT:
26219 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26222 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26224 case BUILT_IN_SQRTF:
26225 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26228 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26235 /* Load up a constant. If the mode is a vector mode, splat the value across
26236 all of the vector elements. */
26239 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26243 if (mode == SFmode || mode == DFmode)
26245 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26246 reg = force_reg (mode, d);
26248 else if (mode == V4SFmode)
26250 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26251 rtvec v = gen_rtvec (4, d, d, d, d);
26252 reg = gen_reg_rtx (mode);
26253 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26255 else if (mode == V2DFmode)
26257 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26258 rtvec v = gen_rtvec (2, d, d);
26259 reg = gen_reg_rtx (mode);
26260 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26263 gcc_unreachable ();
26268 /* Generate a FMADD instruction:
26269 dst = (m1 * m2) + a
26271 generating different RTL based on the fused multiply/add switch. */
26274 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26276 enum machine_mode mode = GET_MODE (dst);
26278 if (!TARGET_FUSED_MADD)
26280 /* For the simple ops, use the generator function, rather than assuming
26281 that the RTL is standard. */
26282 enum insn_code mcode = optab_handler (smul_optab, mode);
26283 enum insn_code acode = optab_handler (add_optab, mode);
26284 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26285 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26286 rtx mreg = gen_reg_rtx (mode);
26288 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26289 emit_insn (gen_mul (mreg, m1, m2));
26290 emit_insn (gen_add (dst, mreg, a));
26294 emit_insn (gen_rtx_SET (VOIDmode, dst,
26295 gen_rtx_PLUS (mode,
26296 gen_rtx_MULT (mode, m1, m2),
26300 /* Generate a FMSUB instruction:
26301 dst = (m1 * m2) - a
26303 generating different RTL based on the fused multiply/add switch. */
26306 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26308 enum machine_mode mode = GET_MODE (dst);
26310 if (!TARGET_FUSED_MADD
26311 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26313 /* For the simple ops, use the generator function, rather than assuming
26314 that the RTL is standard. */
26315 enum insn_code mcode = optab_handler (smul_optab, mode);
26316 enum insn_code scode = optab_handler (add_optab, mode);
26317 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26318 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26319 rtx mreg = gen_reg_rtx (mode);
26321 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26322 emit_insn (gen_mul (mreg, m1, m2));
26323 emit_insn (gen_sub (dst, mreg, a));
26327 emit_insn (gen_rtx_SET (VOIDmode, dst,
26328 gen_rtx_MINUS (mode,
26329 gen_rtx_MULT (mode, m1, m2),
26333 /* Generate a FNMSUB instruction:
26334 dst = - ((m1 * m2) - a)
26336 Which is equivalent to (except in the prescence of -0.0):
26337 dst = a - (m1 * m2)
26339 generating different RTL based on the fast-math and fused multiply/add
26343 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26345 enum machine_mode mode = GET_MODE (dst);
26347 if (!TARGET_FUSED_MADD)
26349 /* For the simple ops, use the generator function, rather than assuming
26350 that the RTL is standard. */
26351 enum insn_code mcode = optab_handler (smul_optab, mode);
26352 enum insn_code scode = optab_handler (sub_optab, mode);
26353 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26354 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26355 rtx mreg = gen_reg_rtx (mode);
26357 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26358 emit_insn (gen_mul (mreg, m1, m2));
26359 emit_insn (gen_sub (dst, a, mreg));
26364 rtx m = gen_rtx_MULT (mode, m1, m2);
26366 if (!HONOR_SIGNED_ZEROS (mode))
26367 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26370 emit_insn (gen_rtx_SET (VOIDmode, dst,
26372 gen_rtx_MINUS (mode, m, a))));
26376 /* Newton-Raphson approximation of floating point divide with just 2 passes
26377 (either single precision floating point, or newer machines with higher
26378 accuracy estimates). Support both scalar and vector divide. Assumes no
26379 trapping math and finite arguments. */
26382 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26384 enum machine_mode mode = GET_MODE (dst);
26385 rtx x0, e0, e1, y1, u0, v0;
26386 enum insn_code code = optab_handler (smul_optab, mode);
26387 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26388 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26390 gcc_assert (code != CODE_FOR_nothing);
26392 /* x0 = 1./d estimate */
26393 x0 = gen_reg_rtx (mode);
26394 emit_insn (gen_rtx_SET (VOIDmode, x0,
26395 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26398 e0 = gen_reg_rtx (mode);
26399 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26401 e1 = gen_reg_rtx (mode);
26402 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26404 y1 = gen_reg_rtx (mode);
26405 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26407 u0 = gen_reg_rtx (mode);
26408 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26410 v0 = gen_reg_rtx (mode);
26411 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26413 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26416 /* Newton-Raphson approximation of floating point divide that has a low
26417 precision estimate. Assumes no trapping math and finite arguments. */
26420 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26422 enum machine_mode mode = GET_MODE (dst);
26423 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26424 enum insn_code code = optab_handler (smul_optab, mode);
26425 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26427 gcc_assert (code != CODE_FOR_nothing);
26429 one = rs6000_load_constant_and_splat (mode, dconst1);
26431 /* x0 = 1./d estimate */
26432 x0 = gen_reg_rtx (mode);
26433 emit_insn (gen_rtx_SET (VOIDmode, x0,
26434 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26437 e0 = gen_reg_rtx (mode);
26438 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26440 y1 = gen_reg_rtx (mode);
26441 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26443 e1 = gen_reg_rtx (mode);
26444 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26446 y2 = gen_reg_rtx (mode);
26447 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26449 e2 = gen_reg_rtx (mode);
26450 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26452 y3 = gen_reg_rtx (mode);
26453 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26455 u0 = gen_reg_rtx (mode);
26456 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26458 v0 = gen_reg_rtx (mode);
26459 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26461 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26464 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26465 add a reg_note saying that this was a division. Support both scalar and
26466 vector divide. Assumes no trapping math and finite arguments. */
26469 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26471 enum machine_mode mode = GET_MODE (dst);
26473 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26474 rs6000_emit_swdiv_high_precision (dst, n, d);
26476 rs6000_emit_swdiv_low_precision (dst, n, d);
26479 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26482 /* Newton-Raphson approximation of single/double-precision floating point
26483 rsqrt. Assumes no trapping math and finite arguments. */
26486 rs6000_emit_swrsqrt (rtx dst, rtx src)
26488 enum machine_mode mode = GET_MODE (src);
26489 rtx x0 = gen_reg_rtx (mode);
26490 rtx y = gen_reg_rtx (mode);
26491 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26492 REAL_VALUE_TYPE dconst3_2;
26495 enum insn_code code = optab_handler (smul_optab, mode);
26496 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26498 gcc_assert (code != CODE_FOR_nothing);
26500 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26501 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26502 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26504 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26506 /* x0 = rsqrt estimate */
26507 emit_insn (gen_rtx_SET (VOIDmode, x0,
26508 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26511 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26512 rs6000_emit_msub (y, src, halfthree, src);
26514 for (i = 0; i < passes; i++)
26516 rtx x1 = gen_reg_rtx (mode);
26517 rtx u = gen_reg_rtx (mode);
26518 rtx v = gen_reg_rtx (mode);
26520 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26521 emit_insn (gen_mul (u, x0, x0));
26522 rs6000_emit_nmsub (v, y, u, halfthree);
26523 emit_insn (gen_mul (x1, x0, v));
26527 emit_move_insn (dst, x0);
26531 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26532 (Power7) targets. DST is the target, and SRC is the argument operand. */
26535 rs6000_emit_popcount (rtx dst, rtx src)
26537 enum machine_mode mode = GET_MODE (dst);
26540 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26541 if (TARGET_POPCNTD)
26543 if (mode == SImode)
26544 emit_insn (gen_popcntdsi2 (dst, src));
26546 emit_insn (gen_popcntddi2 (dst, src));
26550 tmp1 = gen_reg_rtx (mode);
26552 if (mode == SImode)
26554 emit_insn (gen_popcntbsi2 (tmp1, src));
26555 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26557 tmp2 = force_reg (SImode, tmp2);
26558 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26562 emit_insn (gen_popcntbdi2 (tmp1, src));
26563 tmp2 = expand_mult (DImode, tmp1,
26564 GEN_INT ((HOST_WIDE_INT)
26565 0x01010101 << 32 | 0x01010101),
26567 tmp2 = force_reg (DImode, tmp2);
26568 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26573 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26574 target, and SRC is the argument operand. */
26577 rs6000_emit_parity (rtx dst, rtx src)
26579 enum machine_mode mode = GET_MODE (dst);
26582 tmp = gen_reg_rtx (mode);
26584 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26587 if (mode == SImode)
26589 emit_insn (gen_popcntbsi2 (tmp, src));
26590 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26594 emit_insn (gen_popcntbdi2 (tmp, src));
26595 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26600 if (mode == SImode)
26602 /* Is mult+shift >= shift+xor+shift+xor? */
26603 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26605 rtx tmp1, tmp2, tmp3, tmp4;
26607 tmp1 = gen_reg_rtx (SImode);
26608 emit_insn (gen_popcntbsi2 (tmp1, src));
26610 tmp2 = gen_reg_rtx (SImode);
26611 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26612 tmp3 = gen_reg_rtx (SImode);
26613 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26615 tmp4 = gen_reg_rtx (SImode);
26616 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26617 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26620 rs6000_emit_popcount (tmp, src);
26621 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26625 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26626 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26628 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26630 tmp1 = gen_reg_rtx (DImode);
26631 emit_insn (gen_popcntbdi2 (tmp1, src));
26633 tmp2 = gen_reg_rtx (DImode);
26634 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26635 tmp3 = gen_reg_rtx (DImode);
26636 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26638 tmp4 = gen_reg_rtx (DImode);
26639 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26640 tmp5 = gen_reg_rtx (DImode);
26641 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26643 tmp6 = gen_reg_rtx (DImode);
26644 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26645 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26648 rs6000_emit_popcount (tmp, src);
26649 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26653 /* Return an RTX representing where to find the function value of a
26654 function returning MODE. */
26656 rs6000_complex_function_value (enum machine_mode mode)
26658 unsigned int regno;
26660 enum machine_mode inner = GET_MODE_INNER (mode);
26661 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26663 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26664 regno = FP_ARG_RETURN;
26667 regno = GP_ARG_RETURN;
26669 /* 32-bit is OK since it'll go in r3/r4. */
26670 if (TARGET_32BIT && inner_bytes >= 4)
26671 return gen_rtx_REG (mode, regno);
26674 if (inner_bytes >= 8)
26675 return gen_rtx_REG (mode, regno);
26677 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26679 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26680 GEN_INT (inner_bytes));
26681 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26684 /* Target hook for TARGET_FUNCTION_VALUE.
26686 On the SPE, both FPs and vectors are returned in r3.
26688 On RS/6000 an integer value is in r3 and a floating-point value is in
26689 fp1, unless -msoft-float. */
26692 rs6000_function_value (const_tree valtype,
26693 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26694 bool outgoing ATTRIBUTE_UNUSED)
26696 enum machine_mode mode;
26697 unsigned int regno;
26699 /* Special handling for structs in darwin64. */
26701 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26703 CUMULATIVE_ARGS valcum;
26707 valcum.fregno = FP_ARG_MIN_REG;
26708 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26709 /* Do a trial code generation as if this were going to be passed as
26710 an argument; if any part goes in memory, we return NULL. */
26711 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26714 /* Otherwise fall through to standard ABI rules. */
26717 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26719 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26720 return gen_rtx_PARALLEL (DImode,
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),
26730 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26732 return gen_rtx_PARALLEL (DCmode,
26734 gen_rtx_EXPR_LIST (VOIDmode,
26735 gen_rtx_REG (SImode, GP_ARG_RETURN),
26737 gen_rtx_EXPR_LIST (VOIDmode,
26738 gen_rtx_REG (SImode,
26739 GP_ARG_RETURN + 1),
26741 gen_rtx_EXPR_LIST (VOIDmode,
26742 gen_rtx_REG (SImode,
26743 GP_ARG_RETURN + 2),
26745 gen_rtx_EXPR_LIST (VOIDmode,
26746 gen_rtx_REG (SImode,
26747 GP_ARG_RETURN + 3),
26751 mode = TYPE_MODE (valtype);
26752 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26753 || POINTER_TYPE_P (valtype))
26754 mode = TARGET_32BIT ? SImode : DImode;
26756 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26757 /* _Decimal128 must use an even/odd register pair. */
26758 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26759 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26760 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26761 regno = FP_ARG_RETURN;
26762 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26763 && targetm.calls.split_complex_arg)
26764 return rs6000_complex_function_value (mode);
26765 else if (TREE_CODE (valtype) == VECTOR_TYPE
26766 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26767 && ALTIVEC_VECTOR_MODE (mode))
26768 regno = ALTIVEC_ARG_RETURN;
26769 else if (TREE_CODE (valtype) == VECTOR_TYPE
26770 && TARGET_VSX && TARGET_ALTIVEC_ABI
26771 && VSX_VECTOR_MODE (mode))
26772 regno = ALTIVEC_ARG_RETURN;
26773 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26774 && (mode == DFmode || mode == DCmode
26775 || mode == TFmode || mode == TCmode))
26776 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26778 regno = GP_ARG_RETURN;
26780 return gen_rtx_REG (mode, regno);
26783 /* Define how to find the value returned by a library function
26784 assuming the value has mode MODE. */
26786 rs6000_libcall_value (enum machine_mode mode)
26788 unsigned int regno;
26790 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26792 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26793 return gen_rtx_PARALLEL (DImode,
26795 gen_rtx_EXPR_LIST (VOIDmode,
26796 gen_rtx_REG (SImode, GP_ARG_RETURN),
26798 gen_rtx_EXPR_LIST (VOIDmode,
26799 gen_rtx_REG (SImode,
26800 GP_ARG_RETURN + 1),
26804 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26805 /* _Decimal128 must use an even/odd register pair. */
26806 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26807 else if (SCALAR_FLOAT_MODE_P (mode)
26808 && TARGET_HARD_FLOAT && TARGET_FPRS
26809 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26810 regno = FP_ARG_RETURN;
26811 else if (ALTIVEC_VECTOR_MODE (mode)
26812 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26813 regno = ALTIVEC_ARG_RETURN;
26814 else if (VSX_VECTOR_MODE (mode)
26815 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26816 regno = ALTIVEC_ARG_RETURN;
26817 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26818 return rs6000_complex_function_value (mode);
26819 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26820 && (mode == DFmode || mode == DCmode
26821 || mode == TFmode || mode == TCmode))
26822 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26824 regno = GP_ARG_RETURN;
26826 return gen_rtx_REG (mode, regno);
26830 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26831 Frame pointer elimination is automatically handled.
26833 For the RS/6000, if frame pointer elimination is being done, we would like
26834 to convert ap into fp, not sp.
26836 We need r30 if -mminimal-toc was specified, and there are constant pool
26840 rs6000_can_eliminate (const int from, const int to)
26842 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26843 ? ! frame_pointer_needed
26844 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26845 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26849 /* Define the offset between two registers, FROM to be eliminated and its
26850 replacement TO, at the start of a routine. */
26852 rs6000_initial_elimination_offset (int from, int to)
26854 rs6000_stack_t *info = rs6000_stack_info ();
26855 HOST_WIDE_INT offset;
26857 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26858 offset = info->push_p ? 0 : -info->total_size;
26859 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26861 offset = info->push_p ? 0 : -info->total_size;
26862 if (FRAME_GROWS_DOWNWARD)
26863 offset += info->fixed_size + info->vars_size + info->parm_size;
26865 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26866 offset = FRAME_GROWS_DOWNWARD
26867 ? info->fixed_size + info->vars_size + info->parm_size
26869 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26870 offset = info->total_size;
26871 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26872 offset = info->push_p ? info->total_size : 0;
26873 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26876 gcc_unreachable ();
26882 rs6000_dwarf_register_span (rtx reg)
26886 unsigned regno = REGNO (reg);
26887 enum machine_mode mode = GET_MODE (reg);
26891 && (SPE_VECTOR_MODE (GET_MODE (reg))
26892 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26893 && mode != SFmode && mode != SDmode && mode != SCmode)))
26898 regno = REGNO (reg);
26900 /* The duality of the SPE register size wreaks all kinds of havoc.
26901 This is a way of distinguishing r0 in 32-bits from r0 in
26903 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26904 gcc_assert (words <= 4);
26905 for (i = 0; i < words; i++, regno++)
26907 if (BYTES_BIG_ENDIAN)
26909 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26910 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26914 parts[2 * i] = gen_rtx_REG (SImode, regno);
26915 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26919 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26922 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26925 rs6000_init_dwarf_reg_sizes_extra (tree address)
26930 enum machine_mode mode = TYPE_MODE (char_type_node);
26931 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26932 rtx mem = gen_rtx_MEM (BLKmode, addr);
26933 rtx value = gen_int_mode (4, mode);
26935 for (i = 1201; i < 1232; i++)
26937 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26938 HOST_WIDE_INT offset
26939 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26941 emit_move_insn (adjust_address (mem, mode, offset), value);
26946 /* Map internal gcc register numbers to DWARF2 register numbers. */
26949 rs6000_dbx_register_number (unsigned int regno)
26951 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26953 if (regno == MQ_REGNO)
26955 if (regno == LR_REGNO)
26957 if (regno == CTR_REGNO)
26959 if (CR_REGNO_P (regno))
26960 return regno - CR0_REGNO + 86;
26961 if (regno == CA_REGNO)
26962 return 101; /* XER */
26963 if (ALTIVEC_REGNO_P (regno))
26964 return regno - FIRST_ALTIVEC_REGNO + 1124;
26965 if (regno == VRSAVE_REGNO)
26967 if (regno == VSCR_REGNO)
26969 if (regno == SPE_ACC_REGNO)
26971 if (regno == SPEFSCR_REGNO)
26973 /* SPE high reg number. We get these values of regno from
26974 rs6000_dwarf_register_span. */
26975 gcc_assert (regno >= 1200 && regno < 1232);
26979 /* target hook eh_return_filter_mode */
26980 static enum machine_mode
26981 rs6000_eh_return_filter_mode (void)
26983 return TARGET_32BIT ? SImode : word_mode;
26986 /* Target hook for scalar_mode_supported_p. */
26988 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26990 if (DECIMAL_FLOAT_MODE_P (mode))
26991 return default_decimal_float_supported_p ();
26993 return default_scalar_mode_supported_p (mode);
26996 /* Target hook for vector_mode_supported_p. */
26998 rs6000_vector_mode_supported_p (enum machine_mode mode)
27001 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27004 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27007 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27014 /* Target hook for invalid_arg_for_unprototyped_fn. */
27015 static const char *
27016 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27018 return (!rs6000_darwin64_abi
27020 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27021 && (funcdecl == NULL_TREE
27022 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27023 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27024 ? N_("AltiVec argument passed to unprototyped function")
27028 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27029 setup by using __stack_chk_fail_local hidden function instead of
27030 calling __stack_chk_fail directly. Otherwise it is better to call
27031 __stack_chk_fail directly. */
27034 rs6000_stack_protect_fail (void)
27036 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27037 ? default_hidden_stack_protect_fail ()
27038 : default_external_stack_protect_fail ();
27042 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27043 int num_operands ATTRIBUTE_UNUSED)
27045 if (rs6000_warn_cell_microcode)
27048 int insn_code_number = recog_memoized (insn);
27049 location_t location = locator_location (INSN_LOCATOR (insn));
27051 /* Punt on insns we cannot recognize. */
27052 if (insn_code_number < 0)
27055 temp = get_insn_template (insn_code_number, insn);
27057 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27058 warning_at (location, OPT_mwarn_cell_microcode,
27059 "emitting microcode insn %s\t[%s] #%d",
27060 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27061 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27062 warning_at (location, OPT_mwarn_cell_microcode,
27063 "emitting conditional microcode insn %s\t[%s] #%d",
27064 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27069 /* Allocate a stack temp and fixup the address so it meets the particular
27070 memory requirements (either offetable or REG+REG addressing). */
27073 rs6000_allocate_stack_temp (enum machine_mode mode,
27074 bool offsettable_p,
27077 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27078 rtx addr = XEXP (stack, 0);
27079 int strict_p = (reload_in_progress || reload_completed);
27081 if (!legitimate_indirect_address_p (addr, strict_p))
27084 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27085 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27087 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27088 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27094 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27095 to such a form to deal with memory reference instructions like STFIWX that
27096 only take reg+reg addressing. */
27099 rs6000_address_for_fpconvert (rtx x)
27101 int strict_p = (reload_in_progress || reload_completed);
27104 gcc_assert (MEM_P (x));
27105 addr = XEXP (x, 0);
27106 if (! legitimate_indirect_address_p (addr, strict_p)
27107 && ! legitimate_indexed_address_p (addr, strict_p))
27108 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27113 /* Expand 32-bit int -> floating point conversions. Return true if
27117 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27119 enum machine_mode dmode = GET_MODE (dest);
27120 rtx (*func_si) (rtx, rtx, rtx, rtx);
27121 rtx (*func_si_mem) (rtx, rtx);
27122 rtx (*func_di) (rtx, rtx);
27125 gcc_assert (GET_MODE (src) == SImode);
27127 if (dmode == SFmode)
27131 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27132 func_si = gen_floatunssisf2_lfiwzx;
27133 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27134 func_di = gen_floatunsdisf2;
27138 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27139 func_si = gen_floatsisf2_lfiwax;
27140 func_si_mem = gen_floatsisf2_lfiwax_mem;
27141 func_di = gen_floatdisf2;
27145 else if (dmode == DFmode)
27149 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27150 func_si = gen_floatunssidf2_lfiwzx;
27151 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27152 func_di = gen_floatunsdidf2;
27156 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27157 func_si = gen_floatsidf2_lfiwax;
27158 func_si_mem = gen_floatsidf2_lfiwax_mem;
27159 func_di = gen_floatdidf2;
27164 gcc_unreachable ();
27168 src = rs6000_address_for_fpconvert (src);
27169 emit_insn (func_si_mem (dest, src));
27171 else if (!TARGET_MFPGPR)
27173 reg = gen_reg_rtx (DImode);
27174 stack = rs6000_allocate_stack_temp (SImode, false, true);
27175 emit_insn (func_si (dest, src, stack, reg));
27180 src = force_reg (SImode, src);
27181 reg = convert_to_mode (DImode, src, unsigned_p);
27182 emit_insn (func_di (dest, reg));
27186 #include "gt-rs6000.h"