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,
1088 static unsigned int rs6000_units_per_simd_word (enum machine_mode);
1090 static void def_builtin (int, const char *, tree, int);
1091 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1092 static void rs6000_init_builtins (void);
1093 static tree rs6000_builtin_decl (unsigned, bool);
1095 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1096 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1097 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1098 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1099 static void altivec_init_builtins (void);
1100 static unsigned builtin_hash_function (const void *);
1101 static int builtin_hash_eq (const void *, const void *);
1102 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1103 enum machine_mode, enum machine_mode,
1104 enum rs6000_builtins, const char *name);
1105 static void rs6000_common_init_builtins (void);
1106 static void rs6000_init_libfuncs (void);
1108 static void paired_init_builtins (void);
1109 static rtx paired_expand_builtin (tree, rtx, bool *);
1110 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1111 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1112 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1114 static void enable_mask_for_builtins (struct builtin_description *, int,
1115 enum rs6000_builtins,
1116 enum rs6000_builtins);
1117 static void spe_init_builtins (void);
1118 static rtx spe_expand_builtin (tree, rtx, bool *);
1119 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1120 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1121 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1122 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1123 static rs6000_stack_t *rs6000_stack_info (void);
1124 static void debug_stack_info (rs6000_stack_t *);
1126 static rtx altivec_expand_builtin (tree, rtx, bool *);
1127 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1128 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1129 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1130 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1131 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1132 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1133 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1134 static rtx altivec_expand_vec_set_builtin (tree);
1135 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1136 static int get_element_number (tree, tree);
1137 static void rs6000_option_override (void);
1138 static bool rs6000_handle_option (size_t, const char *, int);
1139 static void rs6000_parse_tls_size_option (void);
1140 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1141 static int first_altivec_reg_to_save (void);
1142 static unsigned int compute_vrsave_mask (void);
1143 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1144 static void is_altivec_return_reg (rtx, void *);
1145 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1146 int easy_vector_constant (rtx, enum machine_mode);
1147 static rtx rs6000_dwarf_register_span (rtx);
1148 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1149 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1150 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1151 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1152 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1153 static rtx rs6000_delegitimize_address (rtx);
1154 static rtx rs6000_tls_get_addr (void);
1155 static rtx rs6000_got_sym (void);
1156 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1157 static const char *rs6000_get_some_local_dynamic_name (void);
1158 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1159 static rtx rs6000_complex_function_value (enum machine_mode);
1160 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1161 enum machine_mode, const_tree);
1162 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1163 HOST_WIDE_INT, int);
1164 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1167 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1170 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1171 const_tree, HOST_WIDE_INT,
1173 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1174 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1175 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1177 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1179 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1180 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1181 enum machine_mode, tree,
1183 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1185 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1187 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1189 static void macho_branch_islands (void);
1190 static int no_previous_def (tree function_name);
1191 static tree get_prev_label (tree function_name);
1192 static void rs6000_darwin_file_start (void);
1195 static tree rs6000_build_builtin_va_list (void);
1196 static void rs6000_va_start (tree, rtx);
1197 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1198 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1199 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1200 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1201 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1202 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1204 static tree rs6000_stack_protect_fail (void);
1206 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1209 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1212 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1214 = rs6000_legitimize_reload_address;
1216 static bool rs6000_mode_dependent_address_p (const_rtx);
1217 static bool rs6000_mode_dependent_address (const_rtx);
1218 static bool rs6000_debug_mode_dependent_address (const_rtx);
1219 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1220 = rs6000_mode_dependent_address;
1222 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1223 enum machine_mode, rtx);
1224 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1227 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1228 enum machine_mode, rtx)
1229 = rs6000_secondary_reload_class;
1231 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1232 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1234 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1235 = rs6000_preferred_reload_class;
1237 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1240 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1244 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1246 = rs6000_secondary_memory_needed;
1248 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1251 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1255 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1258 = rs6000_cannot_change_mode_class;
1260 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1262 struct secondary_reload_info *);
1264 static const reg_class_t *rs6000_ira_cover_classes (void);
1266 const int INSN_NOT_AVAILABLE = -1;
1267 static enum machine_mode rs6000_eh_return_filter_mode (void);
1268 static bool rs6000_can_eliminate (const int, const int);
1269 static void rs6000_trampoline_init (rtx, tree, rtx);
1271 /* Hash table stuff for keeping track of TOC entries. */
1273 struct GTY(()) toc_hash_struct
1275 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1276 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1278 enum machine_mode key_mode;
1282 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1284 /* Hash table to keep track of the argument types for builtin functions. */
1286 struct GTY(()) builtin_hash_struct
1289 enum machine_mode mode[4]; /* return value + 3 arguments. */
1290 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1293 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1295 /* Default register names. */
1296 char rs6000_reg_names[][8] =
1298 "0", "1", "2", "3", "4", "5", "6", "7",
1299 "8", "9", "10", "11", "12", "13", "14", "15",
1300 "16", "17", "18", "19", "20", "21", "22", "23",
1301 "24", "25", "26", "27", "28", "29", "30", "31",
1302 "0", "1", "2", "3", "4", "5", "6", "7",
1303 "8", "9", "10", "11", "12", "13", "14", "15",
1304 "16", "17", "18", "19", "20", "21", "22", "23",
1305 "24", "25", "26", "27", "28", "29", "30", "31",
1306 "mq", "lr", "ctr","ap",
1307 "0", "1", "2", "3", "4", "5", "6", "7",
1309 /* AltiVec registers. */
1310 "0", "1", "2", "3", "4", "5", "6", "7",
1311 "8", "9", "10", "11", "12", "13", "14", "15",
1312 "16", "17", "18", "19", "20", "21", "22", "23",
1313 "24", "25", "26", "27", "28", "29", "30", "31",
1315 /* SPE registers. */
1316 "spe_acc", "spefscr",
1317 /* Soft frame pointer. */
1321 #ifdef TARGET_REGNAMES
1322 static const char alt_reg_names[][8] =
1324 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1325 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1326 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1327 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1328 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1329 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1330 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1331 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1332 "mq", "lr", "ctr", "ap",
1333 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1335 /* AltiVec registers. */
1336 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1337 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1338 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1339 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1341 /* SPE registers. */
1342 "spe_acc", "spefscr",
1343 /* Soft frame pointer. */
1348 /* Table of valid machine attributes. */
1350 static const struct attribute_spec rs6000_attribute_table[] =
1352 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1353 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1354 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1355 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1356 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1357 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1358 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1359 SUBTARGET_ATTRIBUTE_TABLE,
1361 { NULL, 0, 0, false, false, false, NULL }
1364 #ifndef MASK_STRICT_ALIGN
1365 #define MASK_STRICT_ALIGN 0
1367 #ifndef TARGET_PROFILE_KERNEL
1368 #define TARGET_PROFILE_KERNEL 0
1371 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1372 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1374 /* Initialize the GCC target structure. */
1375 #undef TARGET_ATTRIBUTE_TABLE
1376 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1377 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1378 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1379 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1380 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1382 #undef TARGET_ASM_ALIGNED_DI_OP
1383 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1385 /* Default unaligned ops are only provided for ELF. Find the ops needed
1386 for non-ELF systems. */
1387 #ifndef OBJECT_FORMAT_ELF
1389 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1391 #undef TARGET_ASM_UNALIGNED_HI_OP
1392 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1393 #undef TARGET_ASM_UNALIGNED_SI_OP
1394 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1395 #undef TARGET_ASM_UNALIGNED_DI_OP
1396 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1399 #undef TARGET_ASM_UNALIGNED_HI_OP
1400 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1401 #undef TARGET_ASM_UNALIGNED_SI_OP
1402 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1403 #undef TARGET_ASM_UNALIGNED_DI_OP
1404 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1405 #undef TARGET_ASM_ALIGNED_DI_OP
1406 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1410 /* This hook deals with fixups for relocatable code and DI-mode objects
1412 #undef TARGET_ASM_INTEGER
1413 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1415 #ifdef HAVE_GAS_HIDDEN
1416 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1417 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1420 #undef TARGET_HAVE_TLS
1421 #define TARGET_HAVE_TLS HAVE_AS_TLS
1423 #undef TARGET_CANNOT_FORCE_CONST_MEM
1424 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1426 #undef TARGET_DELEGITIMIZE_ADDRESS
1427 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1429 #undef TARGET_ASM_FUNCTION_PROLOGUE
1430 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1431 #undef TARGET_ASM_FUNCTION_EPILOGUE
1432 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1434 #undef TARGET_LEGITIMIZE_ADDRESS
1435 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1437 #undef TARGET_SCHED_VARIABLE_ISSUE
1438 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1440 #undef TARGET_SCHED_ISSUE_RATE
1441 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1442 #undef TARGET_SCHED_ADJUST_COST
1443 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1444 #undef TARGET_SCHED_ADJUST_PRIORITY
1445 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1446 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1447 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1448 #undef TARGET_SCHED_INIT
1449 #define TARGET_SCHED_INIT rs6000_sched_init
1450 #undef TARGET_SCHED_FINISH
1451 #define TARGET_SCHED_FINISH rs6000_sched_finish
1452 #undef TARGET_SCHED_REORDER
1453 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1454 #undef TARGET_SCHED_REORDER2
1455 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1457 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1458 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1460 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1461 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1463 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1464 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1465 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1466 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1467 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1468 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1469 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1470 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1472 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1473 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1474 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1475 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1476 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1477 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1478 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1479 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1480 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1481 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1482 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1483 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1484 rs6000_builtin_support_vector_misalignment
1485 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1486 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1487 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1488 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1489 rs6000_builtin_vectorization_cost
1490 #undef TARGET_VECTORIZE_UNITS_PER_SIMD_WORD
1491 #define TARGET_VECTORIZE_UNITS_PER_SIMD_WORD \
1492 rs6000_units_per_simd_word
1494 #undef TARGET_INIT_BUILTINS
1495 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1496 #undef TARGET_BUILTIN_DECL
1497 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1499 #undef TARGET_EXPAND_BUILTIN
1500 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1502 #undef TARGET_MANGLE_TYPE
1503 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1505 #undef TARGET_INIT_LIBFUNCS
1506 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1509 #undef TARGET_BINDS_LOCAL_P
1510 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1513 #undef TARGET_MS_BITFIELD_LAYOUT_P
1514 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1516 #undef TARGET_ASM_OUTPUT_MI_THUNK
1517 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1519 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1520 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1522 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1523 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1525 #undef TARGET_INVALID_WITHIN_DOLOOP
1526 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1528 #undef TARGET_REGISTER_MOVE_COST
1529 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1530 #undef TARGET_MEMORY_MOVE_COST
1531 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1532 #undef TARGET_RTX_COSTS
1533 #define TARGET_RTX_COSTS rs6000_rtx_costs
1534 #undef TARGET_ADDRESS_COST
1535 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1537 #undef TARGET_DWARF_REGISTER_SPAN
1538 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1540 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1541 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1543 /* On rs6000, function arguments are promoted, as are function return
1545 #undef TARGET_PROMOTE_FUNCTION_MODE
1546 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1548 #undef TARGET_RETURN_IN_MEMORY
1549 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1551 #undef TARGET_SETUP_INCOMING_VARARGS
1552 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1554 /* Always strict argument naming on rs6000. */
1555 #undef TARGET_STRICT_ARGUMENT_NAMING
1556 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1557 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1558 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1559 #undef TARGET_SPLIT_COMPLEX_ARG
1560 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1561 #undef TARGET_MUST_PASS_IN_STACK
1562 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1563 #undef TARGET_PASS_BY_REFERENCE
1564 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1565 #undef TARGET_ARG_PARTIAL_BYTES
1566 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1567 #undef TARGET_FUNCTION_ARG_ADVANCE
1568 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1569 #undef TARGET_FUNCTION_ARG
1570 #define TARGET_FUNCTION_ARG rs6000_function_arg
1572 #undef TARGET_BUILD_BUILTIN_VA_LIST
1573 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1575 #undef TARGET_EXPAND_BUILTIN_VA_START
1576 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1578 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1579 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1581 #undef TARGET_EH_RETURN_FILTER_MODE
1582 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1584 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1585 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1587 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1588 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1590 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1591 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1593 #undef TARGET_HANDLE_OPTION
1594 #define TARGET_HANDLE_OPTION rs6000_handle_option
1596 #undef TARGET_OPTION_OVERRIDE
1597 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1599 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1600 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1601 rs6000_builtin_vectorized_function
1603 #undef TARGET_DEFAULT_TARGET_FLAGS
1604 #define TARGET_DEFAULT_TARGET_FLAGS \
1607 #undef TARGET_STACK_PROTECT_FAIL
1608 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1610 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1611 The PowerPC architecture requires only weak consistency among
1612 processors--that is, memory accesses between processors need not be
1613 sequentially consistent and memory accesses among processors can occur
1614 in any order. The ability to order memory accesses weakly provides
1615 opportunities for more efficient use of the system bus. Unless a
1616 dependency exists, the 604e allows read operations to precede store
1618 #undef TARGET_RELAXED_ORDERING
1619 #define TARGET_RELAXED_ORDERING true
1622 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1623 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1626 /* Use a 32-bit anchor range. This leads to sequences like:
1628 addis tmp,anchor,high
1631 where tmp itself acts as an anchor, and can be shared between
1632 accesses to the same 64k page. */
1633 #undef TARGET_MIN_ANCHOR_OFFSET
1634 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1635 #undef TARGET_MAX_ANCHOR_OFFSET
1636 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1637 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1638 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1640 #undef TARGET_BUILTIN_RECIPROCAL
1641 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1643 #undef TARGET_EXPAND_TO_RTL_HOOK
1644 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1646 #undef TARGET_INSTANTIATE_DECLS
1647 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1649 #undef TARGET_SECONDARY_RELOAD
1650 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1652 #undef TARGET_IRA_COVER_CLASSES
1653 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1655 #undef TARGET_LEGITIMATE_ADDRESS_P
1656 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1658 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1659 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1661 #undef TARGET_CAN_ELIMINATE
1662 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1664 #undef TARGET_TRAMPOLINE_INIT
1665 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1667 #undef TARGET_FUNCTION_VALUE
1668 #define TARGET_FUNCTION_VALUE rs6000_function_value
1670 struct gcc_target targetm = TARGET_INITIALIZER;
1672 /* Return number of consecutive hard regs needed starting at reg REGNO
1673 to hold something of mode MODE.
1674 This is ordinarily the length in words of a value of mode MODE
1675 but can be less for certain modes in special long registers.
1677 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1678 scalar instructions. The upper 32 bits are only available to the
1681 POWER and PowerPC GPRs hold 32 bits worth;
1682 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1685 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1687 unsigned HOST_WIDE_INT reg_size;
1689 if (FP_REGNO_P (regno))
1690 reg_size = (VECTOR_MEM_VSX_P (mode)
1691 ? UNITS_PER_VSX_WORD
1692 : UNITS_PER_FP_WORD);
1694 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1695 reg_size = UNITS_PER_SPE_WORD;
1697 else if (ALTIVEC_REGNO_P (regno))
1698 reg_size = UNITS_PER_ALTIVEC_WORD;
1700 /* The value returned for SCmode in the E500 double case is 2 for
1701 ABI compatibility; storing an SCmode value in a single register
1702 would require function_arg and rs6000_spe_function_arg to handle
1703 SCmode so as to pass the value correctly in a pair of
1705 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1706 && !DECIMAL_FLOAT_MODE_P (mode))
1707 reg_size = UNITS_PER_FP_WORD;
1710 reg_size = UNITS_PER_WORD;
1712 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1715 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1718 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1720 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1722 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1723 implementations. Don't allow an item to be split between a FP register
1724 and an Altivec register. */
1725 if (VECTOR_MEM_VSX_P (mode))
1727 if (FP_REGNO_P (regno))
1728 return FP_REGNO_P (last_regno);
1730 if (ALTIVEC_REGNO_P (regno))
1731 return ALTIVEC_REGNO_P (last_regno);
1734 /* The GPRs can hold any mode, but values bigger than one register
1735 cannot go past R31. */
1736 if (INT_REGNO_P (regno))
1737 return INT_REGNO_P (last_regno);
1739 /* The float registers (except for VSX vector modes) can only hold floating
1740 modes and DImode. This excludes the 32-bit decimal float mode for
1742 if (FP_REGNO_P (regno))
1744 if (SCALAR_FLOAT_MODE_P (mode)
1745 && (mode != TDmode || (regno % 2) == 0)
1746 && FP_REGNO_P (last_regno))
1749 if (GET_MODE_CLASS (mode) == MODE_INT
1750 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1753 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1754 && PAIRED_VECTOR_MODE (mode))
1760 /* The CR register can only hold CC modes. */
1761 if (CR_REGNO_P (regno))
1762 return GET_MODE_CLASS (mode) == MODE_CC;
1764 if (CA_REGNO_P (regno))
1765 return mode == BImode;
1767 /* AltiVec only in AldyVec registers. */
1768 if (ALTIVEC_REGNO_P (regno))
1769 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1771 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1772 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1775 /* We cannot put TImode anywhere except general register and it must be able
1776 to fit within the register set. In the future, allow TImode in the
1777 Altivec or VSX registers. */
1779 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1782 /* Print interesting facts about registers. */
1784 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1788 for (r = first_regno; r <= last_regno; ++r)
1790 const char *comma = "";
1793 if (first_regno == last_regno)
1794 fprintf (stderr, "%s:\t", reg_name);
1796 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1799 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1800 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1804 fprintf (stderr, ",\n\t");
1809 if (rs6000_hard_regno_nregs[m][r] > 1)
1810 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1811 rs6000_hard_regno_nregs[m][r]);
1813 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1818 if (call_used_regs[r])
1822 fprintf (stderr, ",\n\t");
1827 len += fprintf (stderr, "%s%s", comma, "call-used");
1835 fprintf (stderr, ",\n\t");
1840 len += fprintf (stderr, "%s%s", comma, "fixed");
1846 fprintf (stderr, ",\n\t");
1850 fprintf (stderr, "%sregno = %d\n", comma, r);
1854 /* Print various interesting information with -mdebug=reg. */
1856 rs6000_debug_reg_global (void)
1858 const char *nl = (const char *)0;
1860 char costly_num[20];
1862 const char *costly_str;
1863 const char *nop_str;
1865 /* Map enum rs6000_vector to string. */
1866 static const char *rs6000_debug_vector_unit[] = {
1875 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1876 LAST_VIRTUAL_REGISTER);
1877 rs6000_debug_reg_print (0, 31, "gr");
1878 rs6000_debug_reg_print (32, 63, "fp");
1879 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1882 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1883 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1884 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1885 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1886 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1887 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1888 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1889 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1890 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1894 "d reg_class = %s\n"
1895 "f reg_class = %s\n"
1896 "v reg_class = %s\n"
1897 "wa reg_class = %s\n"
1898 "wd reg_class = %s\n"
1899 "wf reg_class = %s\n"
1900 "ws reg_class = %s\n\n",
1901 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1902 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1903 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1904 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1905 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1906 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1907 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1909 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1910 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1913 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1915 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1916 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1922 if (rs6000_recip_control)
1924 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1926 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1927 if (rs6000_recip_bits[m])
1930 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1932 (RS6000_RECIP_AUTO_RE_P (m)
1934 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1935 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1937 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1940 fputs ("\n", stderr);
1943 switch (rs6000_sched_costly_dep)
1945 case max_dep_latency:
1946 costly_str = "max_dep_latency";
1950 costly_str = "no_dep_costly";
1953 case all_deps_costly:
1954 costly_str = "all_deps_costly";
1957 case true_store_to_load_dep_costly:
1958 costly_str = "true_store_to_load_dep_costly";
1961 case store_to_load_dep_costly:
1962 costly_str = "store_to_load_dep_costly";
1966 costly_str = costly_num;
1967 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1971 switch (rs6000_sched_insert_nops)
1973 case sched_finish_regroup_exact:
1974 nop_str = "sched_finish_regroup_exact";
1977 case sched_finish_pad_groups:
1978 nop_str = "sched_finish_pad_groups";
1981 case sched_finish_none:
1982 nop_str = "sched_finish_none";
1987 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1992 "always_hint = %s\n"
1993 "align_branch_targets = %s\n"
1994 "sched_restricted_insns_priority = %d\n"
1995 "sched_costly_dep = %s\n"
1996 "sched_insert_nops = %s\n\n",
1997 rs6000_always_hint ? "true" : "false",
1998 rs6000_align_branch_targets ? "true" : "false",
1999 (int)rs6000_sched_restricted_insns_priority,
2000 costly_str, nop_str);
2003 /* Initialize the various global tables that are based on register size. */
2005 rs6000_init_hard_regno_mode_ok (void)
2011 /* Precalculate REGNO_REG_CLASS. */
2012 rs6000_regno_regclass[0] = GENERAL_REGS;
2013 for (r = 1; r < 32; ++r)
2014 rs6000_regno_regclass[r] = BASE_REGS;
2016 for (r = 32; r < 64; ++r)
2017 rs6000_regno_regclass[r] = FLOAT_REGS;
2019 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2020 rs6000_regno_regclass[r] = NO_REGS;
2022 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2023 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2025 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2026 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2027 rs6000_regno_regclass[r] = CR_REGS;
2029 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2030 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2031 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2032 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2033 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2034 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2035 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2036 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2037 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2038 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2040 /* Precalculate vector information, this must be set up before the
2041 rs6000_hard_regno_nregs_internal below. */
2042 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2044 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2045 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2046 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2049 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2050 rs6000_constraints[c] = NO_REGS;
2052 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2053 believes it can use native alignment or still uses 128-bit alignment. */
2054 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2065 /* V2DF mode, VSX only. */
2068 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2069 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2070 rs6000_vector_align[V2DFmode] = align64;
2073 /* V4SF mode, either VSX or Altivec. */
2076 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2077 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2078 rs6000_vector_align[V4SFmode] = align32;
2080 else if (TARGET_ALTIVEC)
2082 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2083 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2084 rs6000_vector_align[V4SFmode] = align32;
2087 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2091 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2092 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2093 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2094 rs6000_vector_align[V4SImode] = align32;
2095 rs6000_vector_align[V8HImode] = align32;
2096 rs6000_vector_align[V16QImode] = align32;
2100 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2101 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2102 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2106 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2107 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2108 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2112 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2113 Altivec doesn't have 64-bit support. */
2116 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2117 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2118 rs6000_vector_align[V2DImode] = align64;
2121 /* DFmode, see if we want to use the VSX unit. */
2122 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2124 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2125 rs6000_vector_mem[DFmode]
2126 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2127 rs6000_vector_align[DFmode] = align64;
2130 /* TODO add SPE and paired floating point vector support. */
2132 /* Register class constaints for the constraints that depend on compile
2134 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2135 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2137 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2138 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2142 /* At present, we just use VSX_REGS, but we have different constraints
2143 based on the use, in case we want to fine tune the default register
2144 class used. wa = any VSX register, wf = register class to use for
2145 V4SF, wd = register class to use for V2DF, and ws = register classs to
2146 use for DF scalars. */
2147 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2148 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2149 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2150 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2156 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2158 /* Set up the reload helper functions. */
2159 if (TARGET_VSX || TARGET_ALTIVEC)
2163 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2164 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2165 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2166 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2167 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2168 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2169 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2170 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2171 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2172 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2173 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2174 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2178 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2179 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2180 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2181 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2182 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2183 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2184 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2185 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2186 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2187 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2188 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2189 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2193 /* Precalculate HARD_REGNO_NREGS. */
2194 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2195 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2196 rs6000_hard_regno_nregs[m][r]
2197 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2199 /* Precalculate HARD_REGNO_MODE_OK. */
2200 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2201 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2202 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2203 rs6000_hard_regno_mode_ok_p[m][r] = true;
2205 /* Precalculate CLASS_MAX_NREGS sizes. */
2206 for (c = 0; c < LIM_REG_CLASSES; ++c)
2210 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2211 reg_size = UNITS_PER_VSX_WORD;
2213 else if (c == ALTIVEC_REGS)
2214 reg_size = UNITS_PER_ALTIVEC_WORD;
2216 else if (c == FLOAT_REGS)
2217 reg_size = UNITS_PER_FP_WORD;
2220 reg_size = UNITS_PER_WORD;
2222 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2223 rs6000_class_max_nregs[m][c]
2224 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2227 if (TARGET_E500_DOUBLE)
2228 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2230 /* Calculate which modes to automatically generate code to use a the
2231 reciprocal divide and square root instructions. In the future, possibly
2232 automatically generate the instructions even if the user did not specify
2233 -mrecip. The older machines double precision reciprocal sqrt estimate is
2234 not accurate enough. */
2235 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2237 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2239 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2240 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2241 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2242 if (VECTOR_UNIT_VSX_P (V2DFmode))
2243 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2245 if (TARGET_FRSQRTES)
2246 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2248 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2249 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2250 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2251 if (VECTOR_UNIT_VSX_P (V2DFmode))
2252 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2254 if (rs6000_recip_control)
2256 if (!TARGET_FUSED_MADD)
2257 warning (0, "-mrecip requires -mfused-madd");
2258 if (!flag_finite_math_only)
2259 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2260 if (flag_trapping_math)
2261 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2262 if (!flag_reciprocal_math)
2263 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2264 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2265 && flag_reciprocal_math)
2267 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2268 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2269 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2271 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2272 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2273 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2275 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2276 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2277 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2279 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2280 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2281 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2283 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2284 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2285 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2287 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2288 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2289 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2291 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2292 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2293 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2295 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2296 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2297 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2301 if (TARGET_DEBUG_REG)
2302 rs6000_debug_reg_global ();
2304 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2306 "SImode variable mult cost = %d\n"
2307 "SImode constant mult cost = %d\n"
2308 "SImode short constant mult cost = %d\n"
2309 "DImode multipliciation cost = %d\n"
2310 "SImode division cost = %d\n"
2311 "DImode division cost = %d\n"
2312 "Simple fp operation cost = %d\n"
2313 "DFmode multiplication cost = %d\n"
2314 "SFmode division cost = %d\n"
2315 "DFmode division cost = %d\n"
2316 "cache line size = %d\n"
2317 "l1 cache size = %d\n"
2318 "l2 cache size = %d\n"
2319 "simultaneous prefetches = %d\n"
2322 rs6000_cost->mulsi_const,
2323 rs6000_cost->mulsi_const9,
2331 rs6000_cost->cache_line_size,
2332 rs6000_cost->l1_cache_size,
2333 rs6000_cost->l2_cache_size,
2334 rs6000_cost->simultaneous_prefetches);
2338 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2341 darwin_rs6000_override_options (void)
2343 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2345 rs6000_altivec_abi = 1;
2346 TARGET_ALTIVEC_VRSAVE = 1;
2347 if (DEFAULT_ABI == ABI_DARWIN)
2349 if (MACHO_DYNAMIC_NO_PIC_P)
2352 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2355 else if (flag_pic == 1)
2360 darwin_one_byte_bool = 1;
2362 if (TARGET_64BIT && ! TARGET_POWERPC64)
2364 target_flags |= MASK_POWERPC64;
2365 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2369 rs6000_default_long_calls = 1;
2370 target_flags |= MASK_SOFT_FLOAT;
2373 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2375 if (!flag_mkernel && !flag_apple_kext
2377 && ! (target_flags_explicit & MASK_ALTIVEC))
2378 target_flags |= MASK_ALTIVEC;
2380 /* Unless the user (not the configurer) has explicitly overridden
2381 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2382 G4 unless targetting the kernel. */
2385 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2386 && ! (target_flags_explicit & MASK_ALTIVEC)
2387 && ! rs6000_select[1].string)
2389 target_flags |= MASK_ALTIVEC;
2394 /* If not otherwise specified by a target, make 'long double' equivalent to
2397 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2398 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2401 /* Override command line options. Mostly we process the processor
2402 type and sometimes adjust other TARGET_ options. */
2405 rs6000_option_override_internal (const char *default_cpu)
2408 struct rs6000_cpu_select *ptr;
2411 /* Simplifications for entries below. */
2414 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2415 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2418 /* This table occasionally claims that a processor does not support
2419 a particular feature even though it does, but the feature is slower
2420 than the alternative. Thus, it shouldn't be relied on as a
2421 complete description of the processor's support.
2423 Please keep this list in order, and don't forget to update the
2424 documentation in invoke.texi when adding a new processor or
2428 const char *const name; /* Canonical processor name. */
2429 const enum processor_type processor; /* Processor type enum value. */
2430 const int target_enable; /* Target flags to enable. */
2431 } const processor_target_table[]
2432 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2433 {"403", PROCESSOR_PPC403,
2434 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2435 {"405", PROCESSOR_PPC405,
2436 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2437 {"405fp", PROCESSOR_PPC405,
2438 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2439 {"440", PROCESSOR_PPC440,
2440 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2441 {"440fp", PROCESSOR_PPC440,
2442 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2443 {"464", PROCESSOR_PPC440,
2444 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2445 {"464fp", PROCESSOR_PPC440,
2446 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2447 {"476", PROCESSOR_PPC476,
2448 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2449 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2450 {"476fp", PROCESSOR_PPC476,
2451 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2452 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2453 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2454 {"601", PROCESSOR_PPC601,
2455 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2456 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2457 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2458 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2459 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2460 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2461 {"620", PROCESSOR_PPC620,
2462 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2463 {"630", PROCESSOR_PPC630,
2464 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2465 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2466 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2467 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2468 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2469 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2470 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2471 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2472 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2474 /* 8548 has a dummy entry for now. */
2475 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2477 {"a2", PROCESSOR_PPCA2,
2478 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2479 | MASK_CMPB | MASK_NO_UPDATE },
2480 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2481 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2482 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2484 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2485 | MASK_PPC_GFXOPT | MASK_ISEL},
2486 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2487 {"970", PROCESSOR_POWER4,
2488 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2489 {"cell", PROCESSOR_CELL,
2490 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2491 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2492 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2493 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2494 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2495 {"G5", PROCESSOR_POWER4,
2496 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2497 {"titan", PROCESSOR_TITAN,
2498 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2499 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2500 {"power2", PROCESSOR_POWER,
2501 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2502 {"power3", PROCESSOR_PPC630,
2503 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2504 {"power4", PROCESSOR_POWER4,
2505 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2507 {"power5", PROCESSOR_POWER5,
2508 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2509 | MASK_MFCRF | MASK_POPCNTB},
2510 {"power5+", PROCESSOR_POWER5,
2511 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2512 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2513 {"power6", PROCESSOR_POWER6,
2514 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2515 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2516 | MASK_RECIP_PRECISION},
2517 {"power6x", PROCESSOR_POWER6,
2518 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2519 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2520 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2521 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
2522 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2523 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2524 | MASK_VSX | MASK_RECIP_PRECISION},
2525 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2526 {"powerpc64", PROCESSOR_POWERPC64,
2527 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2528 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2529 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2530 {"rios2", PROCESSOR_RIOS2,
2531 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2532 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2533 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2534 {"rs64", PROCESSOR_RS64A,
2535 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2538 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2540 /* Some OSs don't support saving the high part of 64-bit registers on
2541 context switch. Other OSs don't support saving Altivec registers.
2542 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2543 settings; if the user wants either, the user must explicitly specify
2544 them and we won't interfere with the user's specification. */
2547 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2548 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2549 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2550 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2551 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2552 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2553 | MASK_RECIP_PRECISION)
2556 /* Masks for instructions set at various powerpc ISAs. */
2558 ISA_2_1_MASKS = MASK_MFCRF,
2559 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2561 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2562 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2563 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2564 masks by server and embedded. */
2565 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2566 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2567 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2569 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2570 altivec is a win so enable it. */
2571 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2572 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2576 /* Numerous experiment shows that IRA based loop pressure
2577 calculation works better for RTL loop invariant motion on targets
2578 with enough (>= 32) registers. It is an expensive optimization.
2579 So it is on only for peak performance. */
2581 flag_ira_loop_pressure = 1;
2583 /* Set the pointer size. */
2586 rs6000_pmode = (int)DImode;
2587 rs6000_pointer_size = 64;
2591 rs6000_pmode = (int)SImode;
2592 rs6000_pointer_size = 32;
2595 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2596 #ifdef OS_MISSING_POWERPC64
2597 if (OS_MISSING_POWERPC64)
2598 set_masks &= ~MASK_POWERPC64;
2600 #ifdef OS_MISSING_ALTIVEC
2601 if (OS_MISSING_ALTIVEC)
2602 set_masks &= ~MASK_ALTIVEC;
2605 /* Don't override by the processor default if given explicitly. */
2606 set_masks &= ~target_flags_explicit;
2608 /* Identify the processor type. */
2609 rs6000_select[0].string = default_cpu;
2610 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2612 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2614 ptr = &rs6000_select[i];
2615 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2617 for (j = 0; j < ptt_size; j++)
2618 if (! strcmp (ptr->string, processor_target_table[j].name))
2620 if (ptr->set_tune_p)
2621 rs6000_cpu = processor_target_table[j].processor;
2623 if (ptr->set_arch_p)
2625 target_flags &= ~set_masks;
2626 target_flags |= (processor_target_table[j].target_enable
2633 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2637 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2638 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2641 error ("AltiVec not supported in this target");
2643 error ("Spe not supported in this target");
2646 /* Disable Cell microcode if we are optimizing for the Cell
2647 and not optimizing for size. */
2648 if (rs6000_gen_cell_microcode == -1)
2649 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2652 /* If we are optimizing big endian systems for space and it's OK to
2653 use instructions that would be microcoded on the Cell, use the
2654 load/store multiple and string instructions. */
2655 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2656 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2658 /* Don't allow -mmultiple or -mstring on little endian systems
2659 unless the cpu is a 750, because the hardware doesn't support the
2660 instructions used in little endian mode, and causes an alignment
2661 trap. The 750 does not cause an alignment trap (except when the
2662 target is unaligned). */
2664 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2666 if (TARGET_MULTIPLE)
2668 target_flags &= ~MASK_MULTIPLE;
2669 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2670 warning (0, "-mmultiple is not supported on little endian systems");
2675 target_flags &= ~MASK_STRING;
2676 if ((target_flags_explicit & MASK_STRING) != 0)
2677 warning (0, "-mstring is not supported on little endian systems");
2681 /* Add some warnings for VSX. */
2684 const char *msg = NULL;
2685 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2686 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2688 if (target_flags_explicit & MASK_VSX)
2689 msg = N_("-mvsx requires hardware floating point");
2691 target_flags &= ~ MASK_VSX;
2693 else if (TARGET_PAIRED_FLOAT)
2694 msg = N_("-mvsx and -mpaired are incompatible");
2695 /* The hardware will allow VSX and little endian, but until we make sure
2696 things like vector select, etc. work don't allow VSX on little endian
2697 systems at this point. */
2698 else if (!BYTES_BIG_ENDIAN)
2699 msg = N_("-mvsx used with little endian code");
2700 else if (TARGET_AVOID_XFORM > 0)
2701 msg = N_("-mvsx needs indexed addressing");
2702 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2704 if (target_flags_explicit & MASK_VSX)
2705 msg = N_("-mvsx and -mno-altivec are incompatible");
2707 msg = N_("-mno-altivec disables vsx");
2713 target_flags &= ~ MASK_VSX;
2714 target_flags_explicit |= MASK_VSX;
2718 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2719 unless the user explicitly used the -mno-<option> to disable the code. */
2721 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2722 else if (TARGET_POPCNTD)
2723 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2724 else if (TARGET_DFP)
2725 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2726 else if (TARGET_CMPB)
2727 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2728 else if (TARGET_POPCNTB || TARGET_FPRND)
2729 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2730 else if (TARGET_ALTIVEC)
2731 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2733 /* E500mc does "better" if we inline more aggressively. Respect the
2734 user's opinion, though. */
2735 if (rs6000_block_move_inline_limit == 0
2736 && (rs6000_cpu == PROCESSOR_PPCE500MC
2737 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2738 rs6000_block_move_inline_limit = 128;
2740 /* store_one_arg depends on expand_block_move to handle at least the
2741 size of reg_parm_stack_space. */
2742 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2743 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2745 /* Set debug flags */
2746 if (rs6000_debug_name)
2748 if (! strcmp (rs6000_debug_name, "all"))
2749 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2750 = rs6000_debug_addr = rs6000_debug_cost = 1;
2751 else if (! strcmp (rs6000_debug_name, "stack"))
2752 rs6000_debug_stack = 1;
2753 else if (! strcmp (rs6000_debug_name, "arg"))
2754 rs6000_debug_arg = 1;
2755 else if (! strcmp (rs6000_debug_name, "reg"))
2756 rs6000_debug_reg = 1;
2757 else if (! strcmp (rs6000_debug_name, "addr"))
2758 rs6000_debug_addr = 1;
2759 else if (! strcmp (rs6000_debug_name, "cost"))
2760 rs6000_debug_cost = 1;
2762 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2764 /* If the appropriate debug option is enabled, replace the target hooks
2765 with debug versions that call the real version and then prints
2766 debugging information. */
2767 if (TARGET_DEBUG_COST)
2769 targetm.rtx_costs = rs6000_debug_rtx_costs;
2770 targetm.address_cost = rs6000_debug_address_cost;
2771 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2774 if (TARGET_DEBUG_ADDR)
2776 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2777 targetm.legitimize_address = rs6000_debug_legitimize_address;
2778 rs6000_secondary_reload_class_ptr
2779 = rs6000_debug_secondary_reload_class;
2780 rs6000_secondary_memory_needed_ptr
2781 = rs6000_debug_secondary_memory_needed;
2782 rs6000_cannot_change_mode_class_ptr
2783 = rs6000_debug_cannot_change_mode_class;
2784 rs6000_preferred_reload_class_ptr
2785 = rs6000_debug_preferred_reload_class;
2786 rs6000_legitimize_reload_address_ptr
2787 = rs6000_debug_legitimize_reload_address;
2788 rs6000_mode_dependent_address_ptr
2789 = rs6000_debug_mode_dependent_address;
2793 if (rs6000_traceback_name)
2795 if (! strncmp (rs6000_traceback_name, "full", 4))
2796 rs6000_traceback = traceback_full;
2797 else if (! strncmp (rs6000_traceback_name, "part", 4))
2798 rs6000_traceback = traceback_part;
2799 else if (! strncmp (rs6000_traceback_name, "no", 2))
2800 rs6000_traceback = traceback_none;
2802 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2803 rs6000_traceback_name);
2806 if (rs6000_veclibabi_name)
2808 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2809 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2811 error ("unknown vectorization library ABI type (%s) for "
2812 "-mveclibabi= switch", rs6000_veclibabi_name);
2815 if (!rs6000_explicit_options.long_double)
2816 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2818 #ifndef POWERPC_LINUX
2819 if (!rs6000_explicit_options.ieee)
2820 rs6000_ieeequad = 1;
2823 /* Enable Altivec ABI for AIX -maltivec. */
2824 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2825 rs6000_altivec_abi = 1;
2827 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2828 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2829 be explicitly overridden in either case. */
2832 if (!rs6000_explicit_options.altivec_abi
2833 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2834 rs6000_altivec_abi = 1;
2836 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2837 if (!rs6000_explicit_options.vrsave)
2838 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2841 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2842 So far, the only darwin64 targets are also MACH-O. */
2844 && DEFAULT_ABI == ABI_DARWIN
2847 rs6000_darwin64_abi = 1;
2848 /* Default to natural alignment, for better performance. */
2849 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2852 /* Place FP constants in the constant pool instead of TOC
2853 if section anchors enabled. */
2854 if (flag_section_anchors)
2855 TARGET_NO_FP_IN_TOC = 1;
2857 /* Handle -mtls-size option. */
2858 rs6000_parse_tls_size_option ();
2860 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2861 SUBTARGET_OVERRIDE_OPTIONS;
2863 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2864 SUBSUBTARGET_OVERRIDE_OPTIONS;
2866 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2867 SUB3TARGET_OVERRIDE_OPTIONS;
2870 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2871 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2873 /* The e500 and e500mc do not have string instructions, and we set
2874 MASK_STRING above when optimizing for size. */
2875 if ((target_flags & MASK_STRING) != 0)
2876 target_flags = target_flags & ~MASK_STRING;
2878 else if (rs6000_select[1].string != NULL)
2880 /* For the powerpc-eabispe configuration, we set all these by
2881 default, so let's unset them if we manually set another
2882 CPU that is not the E500. */
2883 if (!rs6000_explicit_options.spe_abi)
2885 if (!rs6000_explicit_options.spe)
2887 if (!rs6000_explicit_options.float_gprs)
2888 rs6000_float_gprs = 0;
2889 if (!(target_flags_explicit & MASK_ISEL))
2890 target_flags &= ~MASK_ISEL;
2893 /* Detect invalid option combinations with E500. */
2896 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2897 && rs6000_cpu != PROCESSOR_POWER5
2898 && rs6000_cpu != PROCESSOR_POWER6
2899 && rs6000_cpu != PROCESSOR_POWER7
2900 && rs6000_cpu != PROCESSOR_PPCA2
2901 && rs6000_cpu != PROCESSOR_CELL);
2902 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2903 || rs6000_cpu == PROCESSOR_POWER5
2904 || rs6000_cpu == PROCESSOR_POWER7);
2905 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2906 || rs6000_cpu == PROCESSOR_POWER5
2907 || rs6000_cpu == PROCESSOR_POWER6
2908 || rs6000_cpu == PROCESSOR_POWER7
2909 || rs6000_cpu == PROCESSOR_PPCE500MC
2910 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2912 /* Allow debug switches to override the above settings. */
2913 if (TARGET_ALWAYS_HINT > 0)
2914 rs6000_always_hint = TARGET_ALWAYS_HINT;
2916 if (TARGET_SCHED_GROUPS > 0)
2917 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2919 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2920 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2922 rs6000_sched_restricted_insns_priority
2923 = (rs6000_sched_groups ? 1 : 0);
2925 /* Handle -msched-costly-dep option. */
2926 rs6000_sched_costly_dep
2927 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2929 if (rs6000_sched_costly_dep_str)
2931 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2932 rs6000_sched_costly_dep = no_dep_costly;
2933 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2934 rs6000_sched_costly_dep = all_deps_costly;
2935 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2936 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2937 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2938 rs6000_sched_costly_dep = store_to_load_dep_costly;
2940 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2941 atoi (rs6000_sched_costly_dep_str));
2944 /* Handle -minsert-sched-nops option. */
2945 rs6000_sched_insert_nops
2946 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2948 if (rs6000_sched_insert_nops_str)
2950 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2951 rs6000_sched_insert_nops = sched_finish_none;
2952 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2953 rs6000_sched_insert_nops = sched_finish_pad_groups;
2954 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2955 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2957 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2958 atoi (rs6000_sched_insert_nops_str));
2961 #ifdef TARGET_REGNAMES
2962 /* If the user desires alternate register names, copy in the
2963 alternate names now. */
2964 if (TARGET_REGNAMES)
2965 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2968 /* Set aix_struct_return last, after the ABI is determined.
2969 If -maix-struct-return or -msvr4-struct-return was explicitly
2970 used, don't override with the ABI default. */
2971 if (!rs6000_explicit_options.aix_struct_ret)
2972 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2975 /* IBM XL compiler defaults to unsigned bitfields. */
2976 if (TARGET_XL_COMPAT)
2977 flag_signed_bitfields = 0;
2980 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2981 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2984 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2986 /* We can only guarantee the availability of DI pseudo-ops when
2987 assembling for 64-bit targets. */
2990 targetm.asm_out.aligned_op.di = NULL;
2991 targetm.asm_out.unaligned_op.di = NULL;
2994 /* Set branch target alignment, if not optimizing for size. */
2997 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2998 aligned 8byte to avoid misprediction by the branch predictor. */
2999 if (rs6000_cpu == PROCESSOR_TITAN
3000 || rs6000_cpu == PROCESSOR_CELL)
3002 if (align_functions <= 0)
3003 align_functions = 8;
3004 if (align_jumps <= 0)
3006 if (align_loops <= 0)
3009 if (rs6000_align_branch_targets)
3011 if (align_functions <= 0)
3012 align_functions = 16;
3013 if (align_jumps <= 0)
3015 if (align_loops <= 0)
3018 if (align_jumps_max_skip <= 0)
3019 align_jumps_max_skip = 15;
3020 if (align_loops_max_skip <= 0)
3021 align_loops_max_skip = 15;
3024 /* Arrange to save and restore machine status around nested functions. */
3025 init_machine_status = rs6000_init_machine_status;
3027 /* We should always be splitting complex arguments, but we can't break
3028 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3029 if (DEFAULT_ABI != ABI_AIX)
3030 targetm.calls.split_complex_arg = NULL;
3032 /* Initialize rs6000_cost with the appropriate target costs. */
3034 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3038 case PROCESSOR_RIOS1:
3039 rs6000_cost = &rios1_cost;
3042 case PROCESSOR_RIOS2:
3043 rs6000_cost = &rios2_cost;
3046 case PROCESSOR_RS64A:
3047 rs6000_cost = &rs64a_cost;
3050 case PROCESSOR_MPCCORE:
3051 rs6000_cost = &mpccore_cost;
3054 case PROCESSOR_PPC403:
3055 rs6000_cost = &ppc403_cost;
3058 case PROCESSOR_PPC405:
3059 rs6000_cost = &ppc405_cost;
3062 case PROCESSOR_PPC440:
3063 rs6000_cost = &ppc440_cost;
3066 case PROCESSOR_PPC476:
3067 rs6000_cost = &ppc476_cost;
3070 case PROCESSOR_PPC601:
3071 rs6000_cost = &ppc601_cost;
3074 case PROCESSOR_PPC603:
3075 rs6000_cost = &ppc603_cost;
3078 case PROCESSOR_PPC604:
3079 rs6000_cost = &ppc604_cost;
3082 case PROCESSOR_PPC604e:
3083 rs6000_cost = &ppc604e_cost;
3086 case PROCESSOR_PPC620:
3087 rs6000_cost = &ppc620_cost;
3090 case PROCESSOR_PPC630:
3091 rs6000_cost = &ppc630_cost;
3094 case PROCESSOR_CELL:
3095 rs6000_cost = &ppccell_cost;
3098 case PROCESSOR_PPC750:
3099 case PROCESSOR_PPC7400:
3100 rs6000_cost = &ppc750_cost;
3103 case PROCESSOR_PPC7450:
3104 rs6000_cost = &ppc7450_cost;
3107 case PROCESSOR_PPC8540:
3108 rs6000_cost = &ppc8540_cost;
3111 case PROCESSOR_PPCE300C2:
3112 case PROCESSOR_PPCE300C3:
3113 rs6000_cost = &ppce300c2c3_cost;
3116 case PROCESSOR_PPCE500MC:
3117 rs6000_cost = &ppce500mc_cost;
3120 case PROCESSOR_PPCE500MC64:
3121 rs6000_cost = &ppce500mc64_cost;
3124 case PROCESSOR_TITAN:
3125 rs6000_cost = &titan_cost;
3128 case PROCESSOR_POWER4:
3129 case PROCESSOR_POWER5:
3130 rs6000_cost = &power4_cost;
3133 case PROCESSOR_POWER6:
3134 rs6000_cost = &power6_cost;
3137 case PROCESSOR_POWER7:
3138 rs6000_cost = &power7_cost;
3141 case PROCESSOR_PPCA2:
3142 rs6000_cost = &ppca2_cost;
3149 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3150 set_param_value ("simultaneous-prefetches",
3151 rs6000_cost->simultaneous_prefetches);
3152 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3153 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3154 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3155 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3156 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3157 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3159 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3160 can be optimized to ap = __builtin_next_arg (0). */
3161 if (DEFAULT_ABI != ABI_V4)
3162 targetm.expand_builtin_va_start = NULL;
3164 /* Set up single/double float flags.
3165 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3166 then set both flags. */
3167 if (TARGET_HARD_FLOAT && TARGET_FPRS
3168 && rs6000_single_float == 0 && rs6000_double_float == 0)
3169 rs6000_single_float = rs6000_double_float = 1;
3171 /* Reset single and double FP flags if target is E500. */
3174 rs6000_single_float = rs6000_double_float = 0;
3175 if (TARGET_E500_SINGLE)
3176 rs6000_single_float = 1;
3177 if (TARGET_E500_DOUBLE)
3178 rs6000_single_float = rs6000_double_float = 1;
3181 /* If not explicitly specified via option, decide whether to generate indexed
3182 load/store instructions. */
3183 if (TARGET_AVOID_XFORM == -1)
3184 /* Avoid indexed addressing when targeting Power6 in order to avoid
3185 the DERAT mispredict penalty. */
3186 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3188 /* Set the -mrecip options. */
3189 if (rs6000_recip_name)
3191 char *p = ASTRDUP (rs6000_recip_name);
3193 unsigned int mask, i;
3196 while ((q = strtok (p, ",")) != NULL)
3207 if (!strcmp (q, "default"))
3208 mask = ((TARGET_RECIP_PRECISION)
3209 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3212 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3213 if (!strcmp (q, recip_options[i].string))
3215 mask = recip_options[i].mask;
3219 if (i == ARRAY_SIZE (recip_options))
3221 error ("Unknown option for -mrecip=%s", q);
3228 rs6000_recip_control &= ~mask;
3230 rs6000_recip_control |= mask;
3234 rs6000_init_hard_regno_mode_ok ();
3237 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3238 define the target cpu type. */
3241 rs6000_option_override (void)
3243 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT);
3246 /* Implement targetm.vectorize.builtin_mask_for_load. */
3248 rs6000_builtin_mask_for_load (void)
3250 if (TARGET_ALTIVEC || TARGET_VSX)
3251 return altivec_builtin_mask_for_load;
3256 /* Implement targetm.vectorize.builtin_conversion.
3257 Returns a decl of a function that implements conversion of an integer vector
3258 into a floating-point vector, or vice-versa. DEST_TYPE is the
3259 destination type and SRC_TYPE the source type of the conversion.
3260 Return NULL_TREE if it is not available. */
3262 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3264 enum tree_code code = (enum tree_code) tcode;
3268 case FIX_TRUNC_EXPR:
3269 switch (TYPE_MODE (dest_type))
3272 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3275 return TYPE_UNSIGNED (dest_type)
3276 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3277 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3280 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3283 return TYPE_UNSIGNED (dest_type)
3284 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3285 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3292 switch (TYPE_MODE (src_type))
3295 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3298 return TYPE_UNSIGNED (src_type)
3299 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3300 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3303 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3306 return TYPE_UNSIGNED (src_type)
3307 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3308 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3319 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3321 rs6000_builtin_mul_widen_even (tree type)
3323 if (!TARGET_ALTIVEC)
3326 switch (TYPE_MODE (type))
3329 return TYPE_UNSIGNED (type)
3330 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3331 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3334 return TYPE_UNSIGNED (type)
3335 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3336 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3342 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3344 rs6000_builtin_mul_widen_odd (tree type)
3346 if (!TARGET_ALTIVEC)
3349 switch (TYPE_MODE (type))
3352 return TYPE_UNSIGNED (type)
3353 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3354 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3357 return TYPE_UNSIGNED (type)
3358 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3359 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3366 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3367 after applying N number of iterations. This routine does not determine
3368 how may iterations are required to reach desired alignment. */
3371 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3378 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3381 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3391 /* Assuming that all other types are naturally aligned. CHECKME! */
3396 /* Return true if the vector misalignment factor is supported by the
3399 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3406 /* Return if movmisalign pattern is not supported for this mode. */
3407 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3410 if (misalignment == -1)
3412 /* Misalignment factor is unknown at compile time but we know
3413 it's word aligned. */
3414 if (rs6000_vector_alignment_reachable (type, is_packed))
3416 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3418 if (element_size == 64 || element_size == 32)
3425 /* VSX supports word-aligned vector. */
3426 if (misalignment % 4 == 0)
3432 /* Implement targetm.vectorize.builtin_vec_perm. */
3434 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3436 tree inner_type = TREE_TYPE (type);
3437 bool uns_p = TYPE_UNSIGNED (inner_type);
3440 *mask_element_type = unsigned_char_type_node;
3442 switch (TYPE_MODE (type))
3446 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3447 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3452 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3453 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3458 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3459 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3463 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3467 if (!TARGET_ALLOW_DF_PERMUTE)
3470 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3474 if (!TARGET_ALLOW_DF_PERMUTE)
3478 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3479 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3491 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3493 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3494 tree vectype, int misalign)
3498 switch (type_of_cost)
3508 case cond_branch_not_taken:
3512 case cond_branch_taken:
3515 case unaligned_load:
3516 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3518 elements = TYPE_VECTOR_SUBPARTS (vectype);
3520 /* Double word aligned. */
3528 /* Double word aligned. */
3532 /* Unknown misalignment. */
3545 /* Misaligned loads are not supported. */
3550 case unaligned_store:
3551 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3553 elements = TYPE_VECTOR_SUBPARTS (vectype);
3555 /* Double word aligned. */
3563 /* Double word aligned. */
3567 /* Unknown misalignment. */
3580 /* Misaligned stores are not supported. */
3590 /* Implement targetm.vectorize.units_per_simd_word. */
3593 rs6000_units_per_simd_word (enum machine_mode mode ATTRIBUTE_UNUSED)
3595 return (TARGET_VSX ? UNITS_PER_VSX_WORD
3596 : (TARGET_ALTIVEC ? UNITS_PER_ALTIVEC_WORD
3597 : (TARGET_SPE ? UNITS_PER_SPE_WORD
3598 : (TARGET_PAIRED_FLOAT ? UNITS_PER_PAIRED_WORD
3599 : UNITS_PER_WORD))));
3602 /* Handle generic options of the form -mfoo=yes/no.
3603 NAME is the option name.
3604 VALUE is the option value.
3605 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3606 whether the option value is 'yes' or 'no' respectively. */
3608 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3612 else if (!strcmp (value, "yes"))
3614 else if (!strcmp (value, "no"))
3617 error ("unknown -m%s= option specified: '%s'", name, value);
3620 /* Validate and record the size specified with the -mtls-size option. */
3623 rs6000_parse_tls_size_option (void)
3625 if (rs6000_tls_size_string == 0)
3627 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3628 rs6000_tls_size = 16;
3629 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3630 rs6000_tls_size = 32;
3631 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3632 rs6000_tls_size = 64;
3634 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3638 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3640 if (DEFAULT_ABI == ABI_DARWIN)
3641 /* The Darwin libraries never set errno, so we might as well
3642 avoid calling them when that's the only reason we would. */
3643 flag_errno_math = 0;
3645 /* Double growth factor to counter reduced min jump length. */
3646 set_param_value ("max-grow-copy-bb-insns", 16);
3648 /* Enable section anchors by default.
3649 Skip section anchors for Objective C and Objective C++
3650 until front-ends fixed. */
3651 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3652 flag_section_anchors = 2;
3655 static enum fpu_type_t
3656 rs6000_parse_fpu_option (const char *option)
3658 if (!strcmp("none", option)) return FPU_NONE;
3659 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3660 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3661 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3662 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3663 error("unknown value %s for -mfpu", option);
3668 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3669 library with vectorized intrinsics. */
3672 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3675 const char *suffix = NULL;
3676 tree fntype, new_fndecl, bdecl = NULL_TREE;
3679 enum machine_mode el_mode, in_mode;
3682 /* Libmass is suitable for unsafe math only as it does not correctly support
3683 parts of IEEE with the required precision such as denormals. Only support
3684 it if we have VSX to use the simd d2 or f4 functions.
3685 XXX: Add variable length support. */
3686 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3689 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3690 n = TYPE_VECTOR_SUBPARTS (type_out);
3691 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3692 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3693 if (el_mode != in_mode
3697 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3699 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3702 case BUILT_IN_ATAN2:
3703 case BUILT_IN_HYPOT:
3709 case BUILT_IN_ACOSH:
3711 case BUILT_IN_ASINH:
3713 case BUILT_IN_ATANH:
3721 case BUILT_IN_EXPM1:
3722 case BUILT_IN_LGAMMA:
3723 case BUILT_IN_LOG10:
3724 case BUILT_IN_LOG1P:
3732 bdecl = implicit_built_in_decls[fn];
3733 suffix = "d2"; /* pow -> powd2 */
3734 if (el_mode != DFmode
3739 case BUILT_IN_ATAN2F:
3740 case BUILT_IN_HYPOTF:
3745 case BUILT_IN_ACOSF:
3746 case BUILT_IN_ACOSHF:
3747 case BUILT_IN_ASINF:
3748 case BUILT_IN_ASINHF:
3749 case BUILT_IN_ATANF:
3750 case BUILT_IN_ATANHF:
3751 case BUILT_IN_CBRTF:
3753 case BUILT_IN_COSHF:
3755 case BUILT_IN_ERFCF:
3756 case BUILT_IN_EXP2F:
3758 case BUILT_IN_EXPM1F:
3759 case BUILT_IN_LGAMMAF:
3760 case BUILT_IN_LOG10F:
3761 case BUILT_IN_LOG1PF:
3762 case BUILT_IN_LOG2F:
3765 case BUILT_IN_SINHF:
3766 case BUILT_IN_SQRTF:
3768 case BUILT_IN_TANHF:
3769 bdecl = implicit_built_in_decls[fn];
3770 suffix = "4"; /* powf -> powf4 */
3771 if (el_mode != SFmode
3783 gcc_assert (suffix != NULL);
3784 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3785 strcpy (name, bname + sizeof ("__builtin_") - 1);
3786 strcat (name, suffix);
3789 fntype = build_function_type_list (type_out, type_in, NULL);
3790 else if (n_args == 2)
3791 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3795 /* Build a function declaration for the vectorized function. */
3796 new_fndecl = build_decl (BUILTINS_LOCATION,
3797 FUNCTION_DECL, get_identifier (name), fntype);
3798 TREE_PUBLIC (new_fndecl) = 1;
3799 DECL_EXTERNAL (new_fndecl) = 1;
3800 DECL_IS_NOVOPS (new_fndecl) = 1;
3801 TREE_READONLY (new_fndecl) = 1;
3806 /* Returns a function decl for a vectorized version of the builtin function
3807 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3808 if it is not available. */
3811 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3814 enum machine_mode in_mode, out_mode;
3817 if (TREE_CODE (type_out) != VECTOR_TYPE
3818 || TREE_CODE (type_in) != VECTOR_TYPE
3819 || !TARGET_VECTORIZE_BUILTINS)
3822 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3823 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3824 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3825 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3827 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3829 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3832 case BUILT_IN_COPYSIGN:
3833 if (VECTOR_UNIT_VSX_P (V2DFmode)
3834 && out_mode == DFmode && out_n == 2
3835 && in_mode == DFmode && in_n == 2)
3836 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3838 case BUILT_IN_COPYSIGNF:
3839 if (out_mode != SFmode || out_n != 4
3840 || in_mode != SFmode || in_n != 4)
3842 if (VECTOR_UNIT_VSX_P (V4SFmode))
3843 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3844 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3845 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3848 if (VECTOR_UNIT_VSX_P (V2DFmode)
3849 && out_mode == DFmode && out_n == 2
3850 && in_mode == DFmode && in_n == 2)
3851 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3853 case BUILT_IN_SQRTF:
3854 if (VECTOR_UNIT_VSX_P (V4SFmode)
3855 && out_mode == SFmode && out_n == 4
3856 && in_mode == SFmode && in_n == 4)
3857 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3860 if (VECTOR_UNIT_VSX_P (V2DFmode)
3861 && out_mode == DFmode && out_n == 2
3862 && in_mode == DFmode && in_n == 2)
3863 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3865 case BUILT_IN_CEILF:
3866 if (out_mode != SFmode || out_n != 4
3867 || in_mode != SFmode || in_n != 4)
3869 if (VECTOR_UNIT_VSX_P (V4SFmode))
3870 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3871 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3872 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3874 case BUILT_IN_FLOOR:
3875 if (VECTOR_UNIT_VSX_P (V2DFmode)
3876 && out_mode == DFmode && out_n == 2
3877 && in_mode == DFmode && in_n == 2)
3878 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3880 case BUILT_IN_FLOORF:
3881 if (out_mode != SFmode || out_n != 4
3882 || in_mode != SFmode || in_n != 4)
3884 if (VECTOR_UNIT_VSX_P (V4SFmode))
3885 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3886 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3887 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3889 case BUILT_IN_TRUNC:
3890 if (VECTOR_UNIT_VSX_P (V2DFmode)
3891 && out_mode == DFmode && out_n == 2
3892 && in_mode == DFmode && in_n == 2)
3893 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3895 case BUILT_IN_TRUNCF:
3896 if (out_mode != SFmode || out_n != 4
3897 || in_mode != SFmode || in_n != 4)
3899 if (VECTOR_UNIT_VSX_P (V4SFmode))
3900 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3901 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3902 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3904 case BUILT_IN_NEARBYINT:
3905 if (VECTOR_UNIT_VSX_P (V2DFmode)
3906 && flag_unsafe_math_optimizations
3907 && out_mode == DFmode && out_n == 2
3908 && in_mode == DFmode && in_n == 2)
3909 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3911 case BUILT_IN_NEARBYINTF:
3912 if (VECTOR_UNIT_VSX_P (V4SFmode)
3913 && flag_unsafe_math_optimizations
3914 && out_mode == SFmode && out_n == 4
3915 && in_mode == SFmode && in_n == 4)
3916 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3919 if (VECTOR_UNIT_VSX_P (V2DFmode)
3920 && !flag_trapping_math
3921 && out_mode == DFmode && out_n == 2
3922 && in_mode == DFmode && in_n == 2)
3923 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3925 case BUILT_IN_RINTF:
3926 if (VECTOR_UNIT_VSX_P (V4SFmode)
3927 && !flag_trapping_math
3928 && out_mode == SFmode && out_n == 4
3929 && in_mode == SFmode && in_n == 4)
3930 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3937 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3939 enum rs6000_builtins fn
3940 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3943 case RS6000_BUILTIN_RSQRTF:
3944 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3945 && out_mode == SFmode && out_n == 4
3946 && in_mode == SFmode && in_n == 4)
3947 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3949 case RS6000_BUILTIN_RSQRT:
3950 if (VECTOR_UNIT_VSX_P (V2DFmode)
3951 && out_mode == DFmode && out_n == 2
3952 && in_mode == DFmode && in_n == 2)
3953 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3955 case RS6000_BUILTIN_RECIPF:
3956 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3957 && out_mode == SFmode && out_n == 4
3958 && in_mode == SFmode && in_n == 4)
3959 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3961 case RS6000_BUILTIN_RECIP:
3962 if (VECTOR_UNIT_VSX_P (V2DFmode)
3963 && out_mode == DFmode && out_n == 2
3964 && in_mode == DFmode && in_n == 2)
3965 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3972 /* Generate calls to libmass if appropriate. */
3973 if (rs6000_veclib_handler)
3974 return rs6000_veclib_handler (fndecl, type_out, type_in);
3980 /* Implement TARGET_HANDLE_OPTION. */
3983 rs6000_handle_option (size_t code, const char *arg, int value)
3985 enum fpu_type_t fpu_type = FPU_NONE;
3991 g_switch_value = value;
3992 g_switch_set = true;
3996 target_flags &= ~(MASK_POWER | MASK_POWER2
3997 | MASK_MULTIPLE | MASK_STRING);
3998 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3999 | MASK_MULTIPLE | MASK_STRING);
4001 case OPT_mno_powerpc:
4002 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4003 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4004 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4005 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4008 target_flags &= ~MASK_MINIMAL_TOC;
4009 TARGET_NO_FP_IN_TOC = 0;
4010 TARGET_NO_SUM_IN_TOC = 0;
4011 target_flags_explicit |= MASK_MINIMAL_TOC;
4012 #ifdef TARGET_USES_SYSV4_OPT
4013 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4014 just the same as -mminimal-toc. */
4015 target_flags |= MASK_MINIMAL_TOC;
4016 target_flags_explicit |= MASK_MINIMAL_TOC;
4020 #ifdef TARGET_USES_SYSV4_OPT
4022 /* Make -mtoc behave like -mminimal-toc. */
4023 target_flags |= MASK_MINIMAL_TOC;
4024 target_flags_explicit |= MASK_MINIMAL_TOC;
4028 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4030 if (strcmp (arg, "small") == 0)
4031 cmodel = CMODEL_SMALL;
4032 else if (strcmp (arg, "medium") == 0)
4033 cmodel = CMODEL_MEDIUM;
4034 else if (strcmp (arg, "large") == 0)
4035 cmodel = CMODEL_LARGE;
4038 error ("invalid option for -mcmodel: '%s'", arg);
4041 rs6000_explicit_options.cmodel = true;
4044 #ifdef TARGET_USES_AIX64_OPT
4049 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4050 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4051 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4054 #ifdef TARGET_USES_AIX64_OPT
4059 target_flags &= ~MASK_POWERPC64;
4060 target_flags_explicit |= MASK_POWERPC64;
4063 case OPT_minsert_sched_nops_:
4064 rs6000_sched_insert_nops_str = arg;
4067 case OPT_mminimal_toc:
4070 TARGET_NO_FP_IN_TOC = 0;
4071 TARGET_NO_SUM_IN_TOC = 0;
4078 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4079 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4086 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4087 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4091 case OPT_mpowerpc_gpopt:
4092 case OPT_mpowerpc_gfxopt:
4095 target_flags |= MASK_POWERPC;
4096 target_flags_explicit |= MASK_POWERPC;
4100 case OPT_maix_struct_return:
4101 case OPT_msvr4_struct_return:
4102 rs6000_explicit_options.aix_struct_ret = true;
4106 rs6000_explicit_options.vrsave = true;
4107 TARGET_ALTIVEC_VRSAVE = value;
4111 rs6000_explicit_options.vrsave = true;
4112 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4116 target_flags_explicit |= MASK_ISEL;
4118 rs6000_parse_yes_no_option ("isel", arg, &isel);
4120 target_flags |= MASK_ISEL;
4122 target_flags &= ~MASK_ISEL;
4126 rs6000_explicit_options.spe = true;
4131 rs6000_explicit_options.spe = true;
4132 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4136 rs6000_debug_name = arg;
4139 #ifdef TARGET_USES_SYSV4_OPT
4141 rs6000_abi_name = arg;
4145 rs6000_sdata_name = arg;
4148 case OPT_mtls_size_:
4149 rs6000_tls_size_string = arg;
4152 case OPT_mrelocatable:
4155 target_flags |= MASK_MINIMAL_TOC;
4156 target_flags_explicit |= MASK_MINIMAL_TOC;
4157 TARGET_NO_FP_IN_TOC = 1;
4161 case OPT_mrelocatable_lib:
4164 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4165 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4166 TARGET_NO_FP_IN_TOC = 1;
4170 target_flags &= ~MASK_RELOCATABLE;
4171 target_flags_explicit |= MASK_RELOCATABLE;
4177 if (!strcmp (arg, "altivec"))
4179 rs6000_explicit_options.altivec_abi = true;
4180 rs6000_altivec_abi = 1;
4182 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4185 else if (! strcmp (arg, "no-altivec"))
4187 rs6000_explicit_options.altivec_abi = true;
4188 rs6000_altivec_abi = 0;
4190 else if (! strcmp (arg, "spe"))
4192 rs6000_explicit_options.spe_abi = true;
4194 rs6000_altivec_abi = 0;
4195 if (!TARGET_SPE_ABI)
4196 error ("not configured for ABI: '%s'", arg);
4198 else if (! strcmp (arg, "no-spe"))
4200 rs6000_explicit_options.spe_abi = true;
4204 /* These are here for testing during development only, do not
4205 document in the manual please. */
4206 else if (! strcmp (arg, "d64"))
4208 rs6000_darwin64_abi = 1;
4209 warning (0, "Using darwin64 ABI");
4211 else if (! strcmp (arg, "d32"))
4213 rs6000_darwin64_abi = 0;
4214 warning (0, "Using old darwin ABI");
4217 else if (! strcmp (arg, "ibmlongdouble"))
4219 rs6000_explicit_options.ieee = true;
4220 rs6000_ieeequad = 0;
4221 warning (0, "Using IBM extended precision long double");
4223 else if (! strcmp (arg, "ieeelongdouble"))
4225 rs6000_explicit_options.ieee = true;
4226 rs6000_ieeequad = 1;
4227 warning (0, "Using IEEE extended precision long double");
4232 error ("unknown ABI specified: '%s'", arg);
4238 rs6000_select[1].string = arg;
4242 rs6000_select[2].string = arg;
4245 case OPT_mtraceback_:
4246 rs6000_traceback_name = arg;
4249 case OPT_mfloat_gprs_:
4250 rs6000_explicit_options.float_gprs = true;
4251 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4252 rs6000_float_gprs = 1;
4253 else if (! strcmp (arg, "double"))
4254 rs6000_float_gprs = 2;
4255 else if (! strcmp (arg, "no"))
4256 rs6000_float_gprs = 0;
4259 error ("invalid option for -mfloat-gprs: '%s'", arg);
4264 case OPT_mlong_double_:
4265 rs6000_explicit_options.long_double = true;
4266 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4267 if (value != 64 && value != 128)
4269 error ("Unknown switch -mlong-double-%s", arg);
4270 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4274 rs6000_long_double_type_size = value;
4277 case OPT_msched_costly_dep_:
4278 rs6000_sched_costly_dep_str = arg;
4282 rs6000_explicit_options.alignment = true;
4283 if (! strcmp (arg, "power"))
4285 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4286 some C library functions, so warn about it. The flag may be
4287 useful for performance studies from time to time though, so
4288 don't disable it entirely. */
4289 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4290 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4291 " it is incompatible with the installed C and C++ libraries");
4292 rs6000_alignment_flags = MASK_ALIGN_POWER;
4294 else if (! strcmp (arg, "natural"))
4295 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4298 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4303 case OPT_msingle_float:
4304 if (!TARGET_SINGLE_FPU)
4305 warning (0, "-msingle-float option equivalent to -mhard-float");
4306 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4307 rs6000_double_float = 0;
4308 target_flags &= ~MASK_SOFT_FLOAT;
4309 target_flags_explicit |= MASK_SOFT_FLOAT;
4312 case OPT_mdouble_float:
4313 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4314 rs6000_single_float = 1;
4315 target_flags &= ~MASK_SOFT_FLOAT;
4316 target_flags_explicit |= MASK_SOFT_FLOAT;
4319 case OPT_msimple_fpu:
4320 if (!TARGET_SINGLE_FPU)
4321 warning (0, "-msimple-fpu option ignored");
4324 case OPT_mhard_float:
4325 /* -mhard_float implies -msingle-float and -mdouble-float. */
4326 rs6000_single_float = rs6000_double_float = 1;
4329 case OPT_msoft_float:
4330 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4331 rs6000_single_float = rs6000_double_float = 0;
4335 fpu_type = rs6000_parse_fpu_option(arg);
4336 if (fpu_type != FPU_NONE)
4337 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4339 target_flags &= ~MASK_SOFT_FLOAT;
4340 target_flags_explicit |= MASK_SOFT_FLOAT;
4341 rs6000_xilinx_fpu = 1;
4342 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4343 rs6000_single_float = 1;
4344 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4345 rs6000_single_float = rs6000_double_float = 1;
4346 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4347 rs6000_simple_fpu = 1;
4351 /* -mfpu=none is equivalent to -msoft-float */
4352 target_flags |= MASK_SOFT_FLOAT;
4353 target_flags_explicit |= MASK_SOFT_FLOAT;
4354 rs6000_single_float = rs6000_double_float = 0;
4358 rs6000_recip_name = (value) ? "default" : "none";
4362 rs6000_recip_name = arg;
4368 /* Do anything needed at the start of the asm file. */
4371 rs6000_file_start (void)
4375 const char *start = buffer;
4376 struct rs6000_cpu_select *ptr;
4377 const char *default_cpu = TARGET_CPU_DEFAULT;
4378 FILE *file = asm_out_file;
4380 default_file_start ();
4382 #ifdef TARGET_BI_ARCH
4383 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4387 if (flag_verbose_asm)
4389 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4390 rs6000_select[0].string = default_cpu;
4392 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4394 ptr = &rs6000_select[i];
4395 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4397 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4402 if (PPC405_ERRATUM77)
4404 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4408 #ifdef USING_ELFOS_H
4409 switch (rs6000_sdata)
4411 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4412 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4413 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4414 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4417 if (rs6000_sdata && g_switch_value)
4419 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4429 #ifdef HAVE_AS_GNU_ATTRIBUTE
4430 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4432 fprintf (file, "\t.gnu_attribute 4, %d\n",
4433 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4434 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4436 fprintf (file, "\t.gnu_attribute 8, %d\n",
4437 (TARGET_ALTIVEC_ABI ? 2
4438 : TARGET_SPE_ABI ? 3
4440 fprintf (file, "\t.gnu_attribute 12, %d\n",
4441 aix_struct_return ? 2 : 1);
4446 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4448 switch_to_section (toc_section);
4449 switch_to_section (text_section);
4454 /* Return nonzero if this function is known to have a null epilogue. */
4457 direct_return (void)
4459 if (reload_completed)
4461 rs6000_stack_t *info = rs6000_stack_info ();
4463 if (info->first_gp_reg_save == 32
4464 && info->first_fp_reg_save == 64
4465 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4466 && ! info->lr_save_p
4467 && ! info->cr_save_p
4468 && info->vrsave_mask == 0
4476 /* Return the number of instructions it takes to form a constant in an
4477 integer register. */
4480 num_insns_constant_wide (HOST_WIDE_INT value)
4482 /* signed constant loadable with {cal|addi} */
4483 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4486 /* constant loadable with {cau|addis} */
4487 else if ((value & 0xffff) == 0
4488 && (value >> 31 == -1 || value >> 31 == 0))
4491 #if HOST_BITS_PER_WIDE_INT == 64
4492 else if (TARGET_POWERPC64)
4494 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4495 HOST_WIDE_INT high = value >> 31;
4497 if (high == 0 || high == -1)
4503 return num_insns_constant_wide (high) + 1;
4505 return num_insns_constant_wide (low) + 1;
4507 return (num_insns_constant_wide (high)
4508 + num_insns_constant_wide (low) + 1);
4517 num_insns_constant (rtx op, enum machine_mode mode)
4519 HOST_WIDE_INT low, high;
4521 switch (GET_CODE (op))
4524 #if HOST_BITS_PER_WIDE_INT == 64
4525 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4526 && mask64_operand (op, mode))
4530 return num_insns_constant_wide (INTVAL (op));
4533 if (mode == SFmode || mode == SDmode)
4538 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4539 if (DECIMAL_FLOAT_MODE_P (mode))
4540 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4542 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4543 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4546 if (mode == VOIDmode || mode == DImode)
4548 high = CONST_DOUBLE_HIGH (op);
4549 low = CONST_DOUBLE_LOW (op);
4556 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4557 if (DECIMAL_FLOAT_MODE_P (mode))
4558 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4560 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4561 high = l[WORDS_BIG_ENDIAN == 0];
4562 low = l[WORDS_BIG_ENDIAN != 0];
4566 return (num_insns_constant_wide (low)
4567 + num_insns_constant_wide (high));
4570 if ((high == 0 && low >= 0)
4571 || (high == -1 && low < 0))
4572 return num_insns_constant_wide (low);
4574 else if (mask64_operand (op, mode))
4578 return num_insns_constant_wide (high) + 1;
4581 return (num_insns_constant_wide (high)
4582 + num_insns_constant_wide (low) + 1);
4590 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4591 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4592 corresponding element of the vector, but for V4SFmode and V2SFmode,
4593 the corresponding "float" is interpreted as an SImode integer. */
4596 const_vector_elt_as_int (rtx op, unsigned int elt)
4598 rtx tmp = CONST_VECTOR_ELT (op, elt);
4599 if (GET_MODE (op) == V4SFmode
4600 || GET_MODE (op) == V2SFmode)
4601 tmp = gen_lowpart (SImode, tmp);
4602 return INTVAL (tmp);
4605 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4606 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4607 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4608 all items are set to the same value and contain COPIES replicas of the
4609 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4610 operand and the others are set to the value of the operand's msb. */
4613 vspltis_constant (rtx op, unsigned step, unsigned copies)
4615 enum machine_mode mode = GET_MODE (op);
4616 enum machine_mode inner = GET_MODE_INNER (mode);
4619 unsigned nunits = GET_MODE_NUNITS (mode);
4620 unsigned bitsize = GET_MODE_BITSIZE (inner);
4621 unsigned mask = GET_MODE_MASK (inner);
4623 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4624 HOST_WIDE_INT splat_val = val;
4625 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4627 /* Construct the value to be splatted, if possible. If not, return 0. */
4628 for (i = 2; i <= copies; i *= 2)
4630 HOST_WIDE_INT small_val;
4632 small_val = splat_val >> bitsize;
4634 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4636 splat_val = small_val;
4639 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4640 if (EASY_VECTOR_15 (splat_val))
4643 /* Also check if we can splat, and then add the result to itself. Do so if
4644 the value is positive, of if the splat instruction is using OP's mode;
4645 for splat_val < 0, the splat and the add should use the same mode. */
4646 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4647 && (splat_val >= 0 || (step == 1 && copies == 1)))
4650 /* Also check if are loading up the most significant bit which can be done by
4651 loading up -1 and shifting the value left by -1. */
4652 else if (EASY_VECTOR_MSB (splat_val, inner))
4658 /* Check if VAL is present in every STEP-th element, and the
4659 other elements are filled with its most significant bit. */
4660 for (i = 0; i < nunits - 1; ++i)
4662 HOST_WIDE_INT desired_val;
4663 if (((i + 1) & (step - 1)) == 0)
4666 desired_val = msb_val;
4668 if (desired_val != const_vector_elt_as_int (op, i))
4676 /* Return true if OP is of the given MODE and can be synthesized
4677 with a vspltisb, vspltish or vspltisw. */
4680 easy_altivec_constant (rtx op, enum machine_mode mode)
4682 unsigned step, copies;
4684 if (mode == VOIDmode)
4685 mode = GET_MODE (op);
4686 else if (mode != GET_MODE (op))
4689 /* Start with a vspltisw. */
4690 step = GET_MODE_NUNITS (mode) / 4;
4693 if (vspltis_constant (op, step, copies))
4696 /* Then try with a vspltish. */
4702 if (vspltis_constant (op, step, copies))
4705 /* And finally a vspltisb. */
4711 if (vspltis_constant (op, step, copies))
4717 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4718 result is OP. Abort if it is not possible. */
4721 gen_easy_altivec_constant (rtx op)
4723 enum machine_mode mode = GET_MODE (op);
4724 int nunits = GET_MODE_NUNITS (mode);
4725 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4726 unsigned step = nunits / 4;
4727 unsigned copies = 1;
4729 /* Start with a vspltisw. */
4730 if (vspltis_constant (op, step, copies))
4731 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4733 /* Then try with a vspltish. */
4739 if (vspltis_constant (op, step, copies))
4740 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4742 /* And finally a vspltisb. */
4748 if (vspltis_constant (op, step, copies))
4749 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4755 output_vec_const_move (rtx *operands)
4758 enum machine_mode mode;
4763 mode = GET_MODE (dest);
4765 if (TARGET_VSX && zero_constant (vec, mode))
4766 return "xxlxor %x0,%x0,%x0";
4771 if (zero_constant (vec, mode))
4772 return "vxor %0,%0,%0";
4774 splat_vec = gen_easy_altivec_constant (vec);
4775 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4776 operands[1] = XEXP (splat_vec, 0);
4777 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4780 switch (GET_MODE (splat_vec))
4783 return "vspltisw %0,%1";
4786 return "vspltish %0,%1";
4789 return "vspltisb %0,%1";
4796 gcc_assert (TARGET_SPE);
4798 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4799 pattern of V1DI, V4HI, and V2SF.
4801 FIXME: We should probably return # and add post reload
4802 splitters for these, but this way is so easy ;-). */
4803 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4804 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4805 operands[1] = CONST_VECTOR_ELT (vec, 0);
4806 operands[2] = CONST_VECTOR_ELT (vec, 1);
4808 return "li %0,%1\n\tevmergelo %0,%0,%0";
4810 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4813 /* Initialize TARGET of vector PAIRED to VALS. */
4816 paired_expand_vector_init (rtx target, rtx vals)
4818 enum machine_mode mode = GET_MODE (target);
4819 int n_elts = GET_MODE_NUNITS (mode);
4821 rtx x, new_rtx, tmp, constant_op, op1, op2;
4824 for (i = 0; i < n_elts; ++i)
4826 x = XVECEXP (vals, 0, i);
4827 if (!CONSTANT_P (x))
4832 /* Load from constant pool. */
4833 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4839 /* The vector is initialized only with non-constants. */
4840 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4841 XVECEXP (vals, 0, 1));
4843 emit_move_insn (target, new_rtx);
4847 /* One field is non-constant and the other one is a constant. Load the
4848 constant from the constant pool and use ps_merge instruction to
4849 construct the whole vector. */
4850 op1 = XVECEXP (vals, 0, 0);
4851 op2 = XVECEXP (vals, 0, 1);
4853 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4855 tmp = gen_reg_rtx (GET_MODE (constant_op));
4856 emit_move_insn (tmp, constant_op);
4858 if (CONSTANT_P (op1))
4859 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4861 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4863 emit_move_insn (target, new_rtx);
4867 paired_expand_vector_move (rtx operands[])
4869 rtx op0 = operands[0], op1 = operands[1];
4871 emit_move_insn (op0, op1);
4874 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4875 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4876 operands for the relation operation COND. This is a recursive
4880 paired_emit_vector_compare (enum rtx_code rcode,
4881 rtx dest, rtx op0, rtx op1,
4882 rtx cc_op0, rtx cc_op1)
4884 rtx tmp = gen_reg_rtx (V2SFmode);
4887 gcc_assert (TARGET_PAIRED_FLOAT);
4888 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4894 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4898 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4899 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4903 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4906 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4909 tmp1 = gen_reg_rtx (V2SFmode);
4910 max = gen_reg_rtx (V2SFmode);
4911 min = gen_reg_rtx (V2SFmode);
4912 gen_reg_rtx (V2SFmode);
4914 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4915 emit_insn (gen_selv2sf4
4916 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4917 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4918 emit_insn (gen_selv2sf4
4919 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4920 emit_insn (gen_subv2sf3 (tmp1, min, max));
4921 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4924 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4927 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4930 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4933 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4936 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4945 /* Emit vector conditional expression.
4946 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4947 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4950 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4951 rtx cond, rtx cc_op0, rtx cc_op1)
4953 enum rtx_code rcode = GET_CODE (cond);
4955 if (!TARGET_PAIRED_FLOAT)
4958 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4963 /* Initialize vector TARGET to VALS. */
4966 rs6000_expand_vector_init (rtx target, rtx vals)
4968 enum machine_mode mode = GET_MODE (target);
4969 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4970 int n_elts = GET_MODE_NUNITS (mode);
4971 int n_var = 0, one_var = -1;
4972 bool all_same = true, all_const_zero = true;
4976 for (i = 0; i < n_elts; ++i)
4978 x = XVECEXP (vals, 0, i);
4979 if (!CONSTANT_P (x))
4980 ++n_var, one_var = i;
4981 else if (x != CONST0_RTX (inner_mode))
4982 all_const_zero = false;
4984 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4990 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4991 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4992 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4994 /* Zero register. */
4995 emit_insn (gen_rtx_SET (VOIDmode, target,
4996 gen_rtx_XOR (mode, target, target)));
4999 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5001 /* Splat immediate. */
5002 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5007 /* Load from constant pool. */
5008 emit_move_insn (target, const_vec);
5013 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5014 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5018 rtx element = XVECEXP (vals, 0, 0);
5019 if (mode == V2DFmode)
5020 emit_insn (gen_vsx_splat_v2df (target, element));
5022 emit_insn (gen_vsx_splat_v2di (target, element));
5026 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5027 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5028 if (mode == V2DFmode)
5029 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5031 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5036 /* With single precision floating point on VSX, know that internally single
5037 precision is actually represented as a double, and either make 2 V2DF
5038 vectors, and convert these vectors to single precision, or do one
5039 conversion, and splat the result to the other elements. */
5040 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5044 rtx freg = gen_reg_rtx (V4SFmode);
5045 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5047 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5048 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5052 rtx dbl_even = gen_reg_rtx (V2DFmode);
5053 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5054 rtx flt_even = gen_reg_rtx (V4SFmode);
5055 rtx flt_odd = gen_reg_rtx (V4SFmode);
5057 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5058 copy_to_reg (XVECEXP (vals, 0, 0)),
5059 copy_to_reg (XVECEXP (vals, 0, 1))));
5060 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5061 copy_to_reg (XVECEXP (vals, 0, 2)),
5062 copy_to_reg (XVECEXP (vals, 0, 3))));
5063 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5064 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5065 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5070 /* Store value to stack temp. Load vector element. Splat. However, splat
5071 of 64-bit items is not supported on Altivec. */
5072 if (all_same && GET_MODE_SIZE (mode) <= 4)
5074 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5075 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5076 XVECEXP (vals, 0, 0));
5077 x = gen_rtx_UNSPEC (VOIDmode,
5078 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5079 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5081 gen_rtx_SET (VOIDmode,
5084 x = gen_rtx_VEC_SELECT (inner_mode, target,
5085 gen_rtx_PARALLEL (VOIDmode,
5086 gen_rtvec (1, const0_rtx)));
5087 emit_insn (gen_rtx_SET (VOIDmode, target,
5088 gen_rtx_VEC_DUPLICATE (mode, x)));
5092 /* One field is non-constant. Load constant then overwrite
5096 rtx copy = copy_rtx (vals);
5098 /* Load constant part of vector, substitute neighboring value for
5100 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5101 rs6000_expand_vector_init (target, copy);
5103 /* Insert variable. */
5104 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5108 /* Construct the vector in memory one field at a time
5109 and load the whole vector. */
5110 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5111 for (i = 0; i < n_elts; i++)
5112 emit_move_insn (adjust_address_nv (mem, inner_mode,
5113 i * GET_MODE_SIZE (inner_mode)),
5114 XVECEXP (vals, 0, i));
5115 emit_move_insn (target, mem);
5118 /* Set field ELT of TARGET to VAL. */
5121 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5123 enum machine_mode mode = GET_MODE (target);
5124 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5125 rtx reg = gen_reg_rtx (mode);
5127 int width = GET_MODE_SIZE (inner_mode);
5130 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5132 rtx (*set_func) (rtx, rtx, rtx, rtx)
5133 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5134 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5138 /* Load single variable value. */
5139 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5140 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5141 x = gen_rtx_UNSPEC (VOIDmode,
5142 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5143 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5145 gen_rtx_SET (VOIDmode,
5149 /* Linear sequence. */
5150 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5151 for (i = 0; i < 16; ++i)
5152 XVECEXP (mask, 0, i) = GEN_INT (i);
5154 /* Set permute mask to insert element into target. */
5155 for (i = 0; i < width; ++i)
5156 XVECEXP (mask, 0, elt*width + i)
5157 = GEN_INT (i + 0x10);
5158 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5159 x = gen_rtx_UNSPEC (mode,
5160 gen_rtvec (3, target, reg,
5161 force_reg (V16QImode, x)),
5163 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5166 /* Extract field ELT from VEC into TARGET. */
5169 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5171 enum machine_mode mode = GET_MODE (vec);
5172 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5175 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5177 rtx (*extract_func) (rtx, rtx, rtx)
5178 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5179 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5183 /* Allocate mode-sized buffer. */
5184 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5186 /* Add offset to field within buffer matching vector element. */
5187 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5189 /* Store single field into mode-sized buffer. */
5190 x = gen_rtx_UNSPEC (VOIDmode,
5191 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5192 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5194 gen_rtx_SET (VOIDmode,
5197 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5200 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5201 implement ANDing by the mask IN. */
5203 build_mask64_2_operands (rtx in, rtx *out)
5205 #if HOST_BITS_PER_WIDE_INT >= 64
5206 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5209 gcc_assert (GET_CODE (in) == CONST_INT);
5214 /* Assume c initially something like 0x00fff000000fffff. The idea
5215 is to rotate the word so that the middle ^^^^^^ group of zeros
5216 is at the MS end and can be cleared with an rldicl mask. We then
5217 rotate back and clear off the MS ^^ group of zeros with a
5219 c = ~c; /* c == 0xff000ffffff00000 */
5220 lsb = c & -c; /* lsb == 0x0000000000100000 */
5221 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5222 c = ~c; /* c == 0x00fff000000fffff */
5223 c &= -lsb; /* c == 0x00fff00000000000 */
5224 lsb = c & -c; /* lsb == 0x0000100000000000 */
5225 c = ~c; /* c == 0xff000fffffffffff */
5226 c &= -lsb; /* c == 0xff00000000000000 */
5228 while ((lsb >>= 1) != 0)
5229 shift++; /* shift == 44 on exit from loop */
5230 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5231 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5232 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5236 /* Assume c initially something like 0xff000f0000000000. The idea
5237 is to rotate the word so that the ^^^ middle group of zeros
5238 is at the LS end and can be cleared with an rldicr mask. We then
5239 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5241 lsb = c & -c; /* lsb == 0x0000010000000000 */
5242 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5243 c = ~c; /* c == 0x00fff0ffffffffff */
5244 c &= -lsb; /* c == 0x00fff00000000000 */
5245 lsb = c & -c; /* lsb == 0x0000100000000000 */
5246 c = ~c; /* c == 0xff000fffffffffff */
5247 c &= -lsb; /* c == 0xff00000000000000 */
5249 while ((lsb >>= 1) != 0)
5250 shift++; /* shift == 44 on exit from loop */
5251 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5252 m1 >>= shift; /* m1 == 0x0000000000000fff */
5253 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5256 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5257 masks will be all 1's. We are guaranteed more than one transition. */
5258 out[0] = GEN_INT (64 - shift);
5259 out[1] = GEN_INT (m1);
5260 out[2] = GEN_INT (shift);
5261 out[3] = GEN_INT (m2);
5269 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5272 invalid_e500_subreg (rtx op, enum machine_mode mode)
5274 if (TARGET_E500_DOUBLE)
5276 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5277 subreg:TI and reg:TF. Decimal float modes are like integer
5278 modes (only low part of each register used) for this
5280 if (GET_CODE (op) == SUBREG
5281 && (mode == SImode || mode == DImode || mode == TImode
5282 || mode == DDmode || mode == TDmode)
5283 && REG_P (SUBREG_REG (op))
5284 && (GET_MODE (SUBREG_REG (op)) == DFmode
5285 || GET_MODE (SUBREG_REG (op)) == TFmode))
5288 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5290 if (GET_CODE (op) == SUBREG
5291 && (mode == DFmode || mode == TFmode)
5292 && REG_P (SUBREG_REG (op))
5293 && (GET_MODE (SUBREG_REG (op)) == DImode
5294 || GET_MODE (SUBREG_REG (op)) == TImode
5295 || GET_MODE (SUBREG_REG (op)) == DDmode
5296 || GET_MODE (SUBREG_REG (op)) == TDmode))
5301 && GET_CODE (op) == SUBREG
5303 && REG_P (SUBREG_REG (op))
5304 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5310 /* AIX increases natural record alignment to doubleword if the first
5311 field is an FP double while the FP fields remain word aligned. */
5314 rs6000_special_round_type_align (tree type, unsigned int computed,
5315 unsigned int specified)
5317 unsigned int align = MAX (computed, specified);
5318 tree field = TYPE_FIELDS (type);
5320 /* Skip all non field decls */
5321 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5322 field = DECL_CHAIN (field);
5324 if (field != NULL && field != type)
5326 type = TREE_TYPE (field);
5327 while (TREE_CODE (type) == ARRAY_TYPE)
5328 type = TREE_TYPE (type);
5330 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5331 align = MAX (align, 64);
5337 /* Darwin increases record alignment to the natural alignment of
5341 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5342 unsigned int specified)
5344 unsigned int align = MAX (computed, specified);
5346 if (TYPE_PACKED (type))
5349 /* Find the first field, looking down into aggregates. */
5351 tree field = TYPE_FIELDS (type);
5352 /* Skip all non field decls */
5353 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5354 field = DECL_CHAIN (field);
5357 /* A packed field does not contribute any extra alignment. */
5358 if (DECL_PACKED (field))
5360 type = TREE_TYPE (field);
5361 while (TREE_CODE (type) == ARRAY_TYPE)
5362 type = TREE_TYPE (type);
5363 } while (AGGREGATE_TYPE_P (type));
5365 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5366 align = MAX (align, TYPE_ALIGN (type));
5371 /* Return 1 for an operand in small memory on V.4/eabi. */
5374 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5375 enum machine_mode mode ATTRIBUTE_UNUSED)
5380 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5383 if (DEFAULT_ABI != ABI_V4)
5386 /* Vector and float memory instructions have a limited offset on the
5387 SPE, so using a vector or float variable directly as an operand is
5390 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5393 if (GET_CODE (op) == SYMBOL_REF)
5396 else if (GET_CODE (op) != CONST
5397 || GET_CODE (XEXP (op, 0)) != PLUS
5398 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5399 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5404 rtx sum = XEXP (op, 0);
5405 HOST_WIDE_INT summand;
5407 /* We have to be careful here, because it is the referenced address
5408 that must be 32k from _SDA_BASE_, not just the symbol. */
5409 summand = INTVAL (XEXP (sum, 1));
5410 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5413 sym_ref = XEXP (sum, 0);
5416 return SYMBOL_REF_SMALL_P (sym_ref);
5422 /* Return true if either operand is a general purpose register. */
5425 gpr_or_gpr_p (rtx op0, rtx op1)
5427 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5428 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5432 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5435 reg_offset_addressing_ok_p (enum machine_mode mode)
5445 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5446 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5454 /* Paired vector modes. Only reg+reg addressing is valid. */
5455 if (TARGET_PAIRED_FLOAT)
5467 virtual_stack_registers_memory_p (rtx op)
5471 if (GET_CODE (op) == REG)
5472 regnum = REGNO (op);
5474 else if (GET_CODE (op) == PLUS
5475 && GET_CODE (XEXP (op, 0)) == REG
5476 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5477 regnum = REGNO (XEXP (op, 0));
5482 return (regnum >= FIRST_VIRTUAL_REGISTER
5483 && regnum <= LAST_VIRTUAL_REGISTER);
5487 constant_pool_expr_p (rtx op)
5491 split_const (op, &base, &offset);
5492 return (GET_CODE (base) == SYMBOL_REF
5493 && CONSTANT_POOL_ADDRESS_P (base)
5494 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5497 static rtx tocrel_base, tocrel_offset;
5500 toc_relative_expr_p (rtx op)
5502 if (GET_CODE (op) != CONST)
5505 split_const (op, &tocrel_base, &tocrel_offset);
5506 return (GET_CODE (tocrel_base) == UNSPEC
5507 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5511 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5514 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5515 && GET_CODE (XEXP (x, 0)) == REG
5516 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5517 || ((TARGET_MINIMAL_TOC
5518 || TARGET_CMODEL != CMODEL_SMALL)
5519 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5520 && toc_relative_expr_p (XEXP (x, 1)));
5524 legitimate_small_data_p (enum machine_mode mode, rtx x)
5526 return (DEFAULT_ABI == ABI_V4
5527 && !flag_pic && !TARGET_TOC
5528 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5529 && small_data_operand (x, mode));
5532 /* SPE offset addressing is limited to 5-bits worth of double words. */
5533 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5536 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5538 unsigned HOST_WIDE_INT offset, extra;
5540 if (GET_CODE (x) != PLUS)
5542 if (GET_CODE (XEXP (x, 0)) != REG)
5544 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5546 if (!reg_offset_addressing_ok_p (mode))
5547 return virtual_stack_registers_memory_p (x);
5548 if (legitimate_constant_pool_address_p (x, strict))
5550 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5553 offset = INTVAL (XEXP (x, 1));
5561 /* SPE vector modes. */
5562 return SPE_CONST_OFFSET_OK (offset);
5565 if (TARGET_E500_DOUBLE)
5566 return SPE_CONST_OFFSET_OK (offset);
5568 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5570 if (VECTOR_MEM_VSX_P (DFmode))
5575 /* On e500v2, we may have:
5577 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5579 Which gets addressed with evldd instructions. */
5580 if (TARGET_E500_DOUBLE)
5581 return SPE_CONST_OFFSET_OK (offset);
5583 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5585 else if (offset & 3)
5590 if (TARGET_E500_DOUBLE)
5591 return (SPE_CONST_OFFSET_OK (offset)
5592 && SPE_CONST_OFFSET_OK (offset + 8));
5596 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5598 else if (offset & 3)
5609 return (offset < 0x10000) && (offset + extra < 0x10000);
5613 legitimate_indexed_address_p (rtx x, int strict)
5617 if (GET_CODE (x) != PLUS)
5623 /* Recognize the rtl generated by reload which we know will later be
5624 replaced with proper base and index regs. */
5626 && reload_in_progress
5627 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5631 return (REG_P (op0) && REG_P (op1)
5632 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5633 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5634 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5635 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5639 avoiding_indexed_address_p (enum machine_mode mode)
5641 /* Avoid indexed addressing for modes that have non-indexed
5642 load/store instruction forms. */
5643 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5647 legitimate_indirect_address_p (rtx x, int strict)
5649 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5653 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5655 if (!TARGET_MACHO || !flag_pic
5656 || mode != SImode || GET_CODE (x) != MEM)
5660 if (GET_CODE (x) != LO_SUM)
5662 if (GET_CODE (XEXP (x, 0)) != REG)
5664 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5668 return CONSTANT_P (x);
5672 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5674 if (GET_CODE (x) != LO_SUM)
5676 if (GET_CODE (XEXP (x, 0)) != REG)
5678 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5680 /* Restrict addressing for DI because of our SUBREG hackery. */
5681 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5682 || mode == DDmode || mode == TDmode
5687 if (TARGET_ELF || TARGET_MACHO)
5689 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5693 if (GET_MODE_NUNITS (mode) != 1)
5695 if (GET_MODE_BITSIZE (mode) > 64
5696 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5697 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5698 && (mode == DFmode || mode == DDmode))))
5701 return CONSTANT_P (x);
5708 /* Try machine-dependent ways of modifying an illegitimate address
5709 to be legitimate. If we find one, return the new, valid address.
5710 This is used from only one place: `memory_address' in explow.c.
5712 OLDX is the address as it was before break_out_memory_refs was
5713 called. In some cases it is useful to look at this to decide what
5716 It is always safe for this function to do nothing. It exists to
5717 recognize opportunities to optimize the output.
5719 On RS/6000, first check for the sum of a register with a constant
5720 integer that is out of range. If so, generate code to add the
5721 constant with the low-order 16 bits masked to the register and force
5722 this result into another register (this can be done with `cau').
5723 Then generate an address of REG+(CONST&0xffff), allowing for the
5724 possibility of bit 16 being a one.
5726 Then check for the sum of a register and something not constant, try to
5727 load the other things into a register and return the sum. */
5730 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5731 enum machine_mode mode)
5733 unsigned int extra = 0;
5735 if (!reg_offset_addressing_ok_p (mode))
5737 if (virtual_stack_registers_memory_p (x))
5740 /* In theory we should not be seeing addresses of the form reg+0,
5741 but just in case it is generated, optimize it away. */
5742 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5743 return force_reg (Pmode, XEXP (x, 0));
5745 /* Make sure both operands are registers. */
5746 else if (GET_CODE (x) == PLUS)
5747 return gen_rtx_PLUS (Pmode,
5748 force_reg (Pmode, XEXP (x, 0)),
5749 force_reg (Pmode, XEXP (x, 1)));
5751 return force_reg (Pmode, x);
5753 if (GET_CODE (x) == SYMBOL_REF)
5755 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5757 return rs6000_legitimize_tls_address (x, model);
5767 if (!TARGET_POWERPC64)
5775 extra = TARGET_POWERPC64 ? 8 : 12;
5781 if (GET_CODE (x) == PLUS
5782 && GET_CODE (XEXP (x, 0)) == REG
5783 && GET_CODE (XEXP (x, 1)) == CONST_INT
5784 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5786 && !((TARGET_POWERPC64
5787 && (mode == DImode || mode == TImode)
5788 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5789 || SPE_VECTOR_MODE (mode)
5790 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5791 || mode == DImode || mode == DDmode
5792 || mode == TDmode))))
5794 HOST_WIDE_INT high_int, low_int;
5796 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5797 if (low_int >= 0x8000 - extra)
5799 high_int = INTVAL (XEXP (x, 1)) - low_int;
5800 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5801 GEN_INT (high_int)), 0);
5802 return plus_constant (sum, low_int);
5804 else if (GET_CODE (x) == PLUS
5805 && GET_CODE (XEXP (x, 0)) == REG
5806 && GET_CODE (XEXP (x, 1)) != CONST_INT
5807 && GET_MODE_NUNITS (mode) == 1
5808 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5810 || ((mode != DImode && mode != DFmode && mode != DDmode)
5811 || (TARGET_E500_DOUBLE && mode != DDmode)))
5812 && (TARGET_POWERPC64 || mode != DImode)
5813 && !avoiding_indexed_address_p (mode)
5818 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5819 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5821 else if (SPE_VECTOR_MODE (mode)
5822 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5823 || mode == DDmode || mode == TDmode
5824 || mode == DImode)))
5828 /* We accept [reg + reg] and [reg + OFFSET]. */
5830 if (GET_CODE (x) == PLUS)
5832 rtx op1 = XEXP (x, 0);
5833 rtx op2 = XEXP (x, 1);
5836 op1 = force_reg (Pmode, op1);
5838 if (GET_CODE (op2) != REG
5839 && (GET_CODE (op2) != CONST_INT
5840 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5841 || (GET_MODE_SIZE (mode) > 8
5842 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5843 op2 = force_reg (Pmode, op2);
5845 /* We can't always do [reg + reg] for these, because [reg +
5846 reg + offset] is not a legitimate addressing mode. */
5847 y = gen_rtx_PLUS (Pmode, op1, op2);
5849 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5850 return force_reg (Pmode, y);
5855 return force_reg (Pmode, x);
5861 && GET_CODE (x) != CONST_INT
5862 && GET_CODE (x) != CONST_DOUBLE
5864 && GET_MODE_NUNITS (mode) == 1
5865 && (GET_MODE_BITSIZE (mode) <= 32
5866 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5867 && (mode == DFmode || mode == DDmode))))
5869 rtx reg = gen_reg_rtx (Pmode);
5870 emit_insn (gen_elf_high (reg, x));
5871 return gen_rtx_LO_SUM (Pmode, reg, x);
5873 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5876 && ! MACHO_DYNAMIC_NO_PIC_P
5878 && GET_CODE (x) != CONST_INT
5879 && GET_CODE (x) != CONST_DOUBLE
5881 && GET_MODE_NUNITS (mode) == 1
5882 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5883 || (mode != DFmode && mode != DDmode))
5887 rtx reg = gen_reg_rtx (Pmode);
5888 emit_insn (gen_macho_high (reg, x));
5889 return gen_rtx_LO_SUM (Pmode, reg, x);
5892 && GET_CODE (x) == SYMBOL_REF
5893 && constant_pool_expr_p (x)
5894 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5896 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5897 return create_TOC_reference (x, reg);
5903 /* Debug version of rs6000_legitimize_address. */
5905 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5911 ret = rs6000_legitimize_address (x, oldx, mode);
5912 insns = get_insns ();
5918 "\nrs6000_legitimize_address: mode %s, old code %s, "
5919 "new code %s, modified\n",
5920 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5921 GET_RTX_NAME (GET_CODE (ret)));
5923 fprintf (stderr, "Original address:\n");
5926 fprintf (stderr, "oldx:\n");
5929 fprintf (stderr, "New address:\n");
5934 fprintf (stderr, "Insns added:\n");
5935 debug_rtx_list (insns, 20);
5941 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5942 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5953 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5954 We need to emit DTP-relative relocations. */
5957 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5962 fputs ("\t.long\t", file);
5965 fputs (DOUBLE_INT_ASM_OP, file);
5970 output_addr_const (file, x);
5971 fputs ("@dtprel+0x8000", file);
5974 /* In the name of slightly smaller debug output, and to cater to
5975 general assembler lossage, recognize various UNSPEC sequences
5976 and turn them back into a direct symbol reference. */
5979 rs6000_delegitimize_address (rtx orig_x)
5983 orig_x = delegitimize_mem_from_attrs (orig_x);
5988 if ((GET_CODE (x) == PLUS
5989 || GET_CODE (x) == LO_SUM)
5990 && GET_CODE (XEXP (x, 0)) == REG
5991 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5992 || TARGET_MINIMAL_TOC
5993 || TARGET_CMODEL != CMODEL_SMALL)
5994 && GET_CODE (XEXP (x, 1)) == CONST)
5996 y = XEXP (XEXP (x, 1), 0);
5997 if (GET_CODE (y) == UNSPEC
5998 && XINT (y, 1) == UNSPEC_TOCREL)
6000 y = XVECEXP (y, 0, 0);
6001 if (!MEM_P (orig_x))
6004 return replace_equiv_address_nv (orig_x, y);
6009 && GET_CODE (orig_x) == LO_SUM
6010 && GET_CODE (XEXP (x, 1)) == CONST)
6012 y = XEXP (XEXP (x, 1), 0);
6013 if (GET_CODE (y) == UNSPEC
6014 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6015 return XVECEXP (y, 0, 0);
6021 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6023 static GTY(()) rtx rs6000_tls_symbol;
6025 rs6000_tls_get_addr (void)
6027 if (!rs6000_tls_symbol)
6028 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6030 return rs6000_tls_symbol;
6033 /* Construct the SYMBOL_REF for TLS GOT references. */
6035 static GTY(()) rtx rs6000_got_symbol;
6037 rs6000_got_sym (void)
6039 if (!rs6000_got_symbol)
6041 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6042 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6043 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6046 return rs6000_got_symbol;
6049 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6050 this (thread-local) address. */
6053 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6057 dest = gen_reg_rtx (Pmode);
6058 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6064 tlsreg = gen_rtx_REG (Pmode, 13);
6065 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6069 tlsreg = gen_rtx_REG (Pmode, 2);
6070 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6074 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6078 tmp = gen_reg_rtx (Pmode);
6081 tlsreg = gen_rtx_REG (Pmode, 13);
6082 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6086 tlsreg = gen_rtx_REG (Pmode, 2);
6087 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6091 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6093 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6098 rtx r3, got, tga, tmp1, tmp2, call_insn;
6100 /* We currently use relocations like @got@tlsgd for tls, which
6101 means the linker will handle allocation of tls entries, placing
6102 them in the .got section. So use a pointer to the .got section,
6103 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6104 or to secondary GOT sections used by 32-bit -fPIC. */
6106 got = gen_rtx_REG (Pmode, 2);
6110 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6113 rtx gsym = rs6000_got_sym ();
6114 got = gen_reg_rtx (Pmode);
6116 rs6000_emit_move (got, gsym, Pmode);
6121 tmp1 = gen_reg_rtx (Pmode);
6122 tmp2 = gen_reg_rtx (Pmode);
6123 mem = gen_const_mem (Pmode, tmp1);
6124 lab = gen_label_rtx ();
6125 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6126 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6127 emit_move_insn (tmp2, mem);
6128 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6129 set_unique_reg_note (last, REG_EQUAL, gsym);
6134 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6136 r3 = gen_rtx_REG (Pmode, 3);
6137 tga = rs6000_tls_get_addr ();
6138 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6140 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6141 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6142 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6143 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6144 else if (DEFAULT_ABI == ABI_V4)
6145 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6148 call_insn = last_call_insn ();
6149 PATTERN (call_insn) = insn;
6150 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6151 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6152 pic_offset_table_rtx);
6154 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6156 r3 = gen_rtx_REG (Pmode, 3);
6157 tga = rs6000_tls_get_addr ();
6158 tmp1 = gen_reg_rtx (Pmode);
6159 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6161 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6162 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6163 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6164 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6165 else if (DEFAULT_ABI == ABI_V4)
6166 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6169 call_insn = last_call_insn ();
6170 PATTERN (call_insn) = insn;
6171 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6172 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6173 pic_offset_table_rtx);
6175 if (rs6000_tls_size == 16)
6178 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6180 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6182 else if (rs6000_tls_size == 32)
6184 tmp2 = gen_reg_rtx (Pmode);
6186 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6188 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6191 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6193 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6197 tmp2 = gen_reg_rtx (Pmode);
6199 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6201 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6203 insn = gen_rtx_SET (Pmode, dest,
6204 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6210 /* IE, or 64-bit offset LE. */
6211 tmp2 = gen_reg_rtx (Pmode);
6213 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6215 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6218 insn = gen_tls_tls_64 (dest, tmp2, addr);
6220 insn = gen_tls_tls_32 (dest, tmp2, addr);
6228 /* Return 1 if X contains a thread-local symbol. */
6231 rs6000_tls_referenced_p (rtx x)
6233 if (! TARGET_HAVE_TLS)
6236 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6239 /* Return 1 if *X is a thread-local symbol. This is the same as
6240 rs6000_tls_symbol_ref except for the type of the unused argument. */
6243 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6245 return RS6000_SYMBOL_REF_TLS_P (*x);
6248 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6249 replace the input X, or the original X if no replacement is called for.
6250 The output parameter *WIN is 1 if the calling macro should goto WIN,
6253 For RS/6000, we wish to handle large displacements off a base
6254 register by splitting the addend across an addiu/addis and the mem insn.
6255 This cuts number of extra insns needed from 3 to 1.
6257 On Darwin, we use this to generate code for floating point constants.
6258 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6259 The Darwin code is inside #if TARGET_MACHO because only then are the
6260 machopic_* functions defined. */
6262 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6263 int opnum, int type,
6264 int ind_levels ATTRIBUTE_UNUSED, int *win)
6266 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6268 /* We must recognize output that we have already generated ourselves. */
6269 if (GET_CODE (x) == PLUS
6270 && GET_CODE (XEXP (x, 0)) == PLUS
6271 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6272 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6273 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6275 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6276 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6277 opnum, (enum reload_type)type);
6282 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6283 if (GET_CODE (x) == LO_SUM
6284 && GET_CODE (XEXP (x, 0)) == HIGH)
6286 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6287 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6288 opnum, (enum reload_type)type);
6294 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6295 && GET_CODE (x) == LO_SUM
6296 && GET_CODE (XEXP (x, 0)) == PLUS
6297 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6298 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6299 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6300 && machopic_operand_p (XEXP (x, 1)))
6302 /* Result of previous invocation of this function on Darwin
6303 floating point constant. */
6304 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6305 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6306 opnum, (enum reload_type)type);
6312 if (TARGET_CMODEL != CMODEL_SMALL
6313 && GET_CODE (x) == LO_SUM
6314 && GET_CODE (XEXP (x, 0)) == PLUS
6315 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6316 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6317 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6318 && GET_CODE (XEXP (x, 1)) == CONST
6319 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6320 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6321 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6323 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6324 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6325 opnum, (enum reload_type) type);
6330 /* Force ld/std non-word aligned offset into base register by wrapping
6332 if (GET_CODE (x) == PLUS
6333 && GET_CODE (XEXP (x, 0)) == REG
6334 && REGNO (XEXP (x, 0)) < 32
6335 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6336 && GET_CODE (XEXP (x, 1)) == CONST_INT
6338 && (INTVAL (XEXP (x, 1)) & 3) != 0
6339 && VECTOR_MEM_NONE_P (mode)
6340 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6341 && TARGET_POWERPC64)
6343 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6344 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6345 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6346 opnum, (enum reload_type) type);
6351 if (GET_CODE (x) == PLUS
6352 && GET_CODE (XEXP (x, 0)) == REG
6353 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6354 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6355 && GET_CODE (XEXP (x, 1)) == CONST_INT
6357 && !SPE_VECTOR_MODE (mode)
6358 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6359 || mode == DDmode || mode == TDmode
6361 && VECTOR_MEM_NONE_P (mode))
6363 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6364 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6366 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6368 /* Check for 32-bit overflow. */
6369 if (high + low != val)
6375 /* Reload the high part into a base reg; leave the low part
6376 in the mem directly. */
6378 x = gen_rtx_PLUS (GET_MODE (x),
6379 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6383 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6384 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6385 opnum, (enum reload_type)type);
6390 if (GET_CODE (x) == SYMBOL_REF
6392 && VECTOR_MEM_NONE_P (mode)
6393 && !SPE_VECTOR_MODE (mode)
6395 && DEFAULT_ABI == ABI_DARWIN
6396 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6398 && DEFAULT_ABI == ABI_V4
6401 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6402 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6406 && (mode != DImode || TARGET_POWERPC64)
6407 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6408 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6413 rtx offset = machopic_gen_offset (x);
6414 x = gen_rtx_LO_SUM (GET_MODE (x),
6415 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6416 gen_rtx_HIGH (Pmode, offset)), offset);
6420 x = gen_rtx_LO_SUM (GET_MODE (x),
6421 gen_rtx_HIGH (Pmode, x), x);
6423 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6424 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6425 opnum, (enum reload_type)type);
6430 /* Reload an offset address wrapped by an AND that represents the
6431 masking of the lower bits. Strip the outer AND and let reload
6432 convert the offset address into an indirect address. For VSX,
6433 force reload to create the address with an AND in a separate
6434 register, because we can't guarantee an altivec register will
6436 if (VECTOR_MEM_ALTIVEC_P (mode)
6437 && GET_CODE (x) == AND
6438 && GET_CODE (XEXP (x, 0)) == PLUS
6439 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6440 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6441 && GET_CODE (XEXP (x, 1)) == CONST_INT
6442 && INTVAL (XEXP (x, 1)) == -16)
6451 && GET_CODE (x) == SYMBOL_REF
6452 && constant_pool_expr_p (x)
6453 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6455 x = create_TOC_reference (x, NULL_RTX);
6456 if (TARGET_CMODEL != CMODEL_SMALL)
6457 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6458 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6459 opnum, (enum reload_type) type);
6467 /* Debug version of rs6000_legitimize_reload_address. */
6469 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6470 int opnum, int type,
6471 int ind_levels, int *win)
6473 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6476 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6477 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6478 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6482 fprintf (stderr, "Same address returned\n");
6484 fprintf (stderr, "NULL returned\n");
6487 fprintf (stderr, "New address:\n");
6494 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6495 that is a valid memory address for an instruction.
6496 The MODE argument is the machine mode for the MEM expression
6497 that wants to use this address.
6499 On the RS/6000, there are four valid address: a SYMBOL_REF that
6500 refers to a constant pool entry of an address (or the sum of it
6501 plus a constant), a short (16-bit signed) constant plus a register,
6502 the sum of two registers, or a register indirect, possibly with an
6503 auto-increment. For DFmode, DDmode and DImode with a constant plus
6504 register, we must ensure that both words are addressable or PowerPC64
6505 with offset word aligned.
6507 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6508 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6509 because adjacent memory cells are accessed by adding word-sized offsets
6510 during assembly output. */
6512 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6514 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6516 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6517 if (VECTOR_MEM_ALTIVEC_P (mode)
6518 && GET_CODE (x) == AND
6519 && GET_CODE (XEXP (x, 1)) == CONST_INT
6520 && INTVAL (XEXP (x, 1)) == -16)
6523 if (RS6000_SYMBOL_REF_TLS_P (x))
6525 if (legitimate_indirect_address_p (x, reg_ok_strict))
6527 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6528 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6529 && !SPE_VECTOR_MODE (mode)
6532 /* Restrict addressing for DI because of our SUBREG hackery. */
6533 && !(TARGET_E500_DOUBLE
6534 && (mode == DFmode || mode == DDmode || mode == DImode))
6536 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6538 if (virtual_stack_registers_memory_p (x))
6540 if (reg_offset_p && legitimate_small_data_p (mode, x))
6542 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6544 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6547 && GET_CODE (x) == PLUS
6548 && GET_CODE (XEXP (x, 0)) == REG
6549 && (XEXP (x, 0) == virtual_stack_vars_rtx
6550 || XEXP (x, 0) == arg_pointer_rtx)
6551 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6553 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6558 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6560 || (mode != DFmode && mode != DDmode)
6561 || (TARGET_E500_DOUBLE && mode != DDmode))
6562 && (TARGET_POWERPC64 || mode != DImode)
6563 && !avoiding_indexed_address_p (mode)
6564 && legitimate_indexed_address_p (x, reg_ok_strict))
6566 if (GET_CODE (x) == PRE_MODIFY
6570 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6572 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6573 && (TARGET_POWERPC64 || mode != DImode)
6574 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6575 && !SPE_VECTOR_MODE (mode)
6576 /* Restrict addressing for DI because of our SUBREG hackery. */
6577 && !(TARGET_E500_DOUBLE
6578 && (mode == DFmode || mode == DDmode || mode == DImode))
6580 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6581 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6582 || (!avoiding_indexed_address_p (mode)
6583 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6584 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6586 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6591 /* Debug version of rs6000_legitimate_address_p. */
6593 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6596 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6598 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6599 "strict = %d, code = %s\n",
6600 ret ? "true" : "false",
6601 GET_MODE_NAME (mode),
6603 GET_RTX_NAME (GET_CODE (x)));
6609 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6612 rs6000_mode_dependent_address_p (const_rtx addr)
6614 return rs6000_mode_dependent_address_ptr (addr);
6617 /* Go to LABEL if ADDR (a legitimate address expression)
6618 has an effect that depends on the machine mode it is used for.
6620 On the RS/6000 this is true of all integral offsets (since AltiVec
6621 and VSX modes don't allow them) or is a pre-increment or decrement.
6623 ??? Except that due to conceptual problems in offsettable_address_p
6624 we can't really report the problems of integral offsets. So leave
6625 this assuming that the adjustable offset must be valid for the
6626 sub-words of a TFmode operand, which is what we had before. */
6629 rs6000_mode_dependent_address (const_rtx addr)
6631 switch (GET_CODE (addr))
6634 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6635 is considered a legitimate address before reload, so there
6636 are no offset restrictions in that case. Note that this
6637 condition is safe in strict mode because any address involving
6638 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6639 been rejected as illegitimate. */
6640 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6641 && XEXP (addr, 0) != arg_pointer_rtx
6642 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6644 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6645 return val + 12 + 0x8000 >= 0x10000;
6650 /* Anything in the constant pool is sufficiently aligned that
6651 all bytes have the same high part address. */
6652 return !legitimate_constant_pool_address_p (addr, false);
6654 /* Auto-increment cases are now treated generically in recog.c. */
6656 return TARGET_UPDATE;
6658 /* AND is only allowed in Altivec loads. */
6669 /* Debug version of rs6000_mode_dependent_address. */
6671 rs6000_debug_mode_dependent_address (const_rtx addr)
6673 bool ret = rs6000_mode_dependent_address (addr);
6675 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6676 ret ? "true" : "false");
6682 /* Implement FIND_BASE_TERM. */
6685 rs6000_find_base_term (rtx op)
6689 split_const (op, &base, &offset);
6690 if (GET_CODE (base) == UNSPEC)
6691 switch (XINT (base, 1))
6694 case UNSPEC_MACHOPIC_OFFSET:
6695 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6696 for aliasing purposes. */
6697 return XVECEXP (base, 0, 0);
6703 /* More elaborate version of recog's offsettable_memref_p predicate
6704 that works around the ??? note of rs6000_mode_dependent_address.
6705 In particular it accepts
6707 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6709 in 32-bit mode, that the recog predicate rejects. */
6712 rs6000_offsettable_memref_p (rtx op)
6717 /* First mimic offsettable_memref_p. */
6718 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6721 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6722 the latter predicate knows nothing about the mode of the memory
6723 reference and, therefore, assumes that it is the largest supported
6724 mode (TFmode). As a consequence, legitimate offsettable memory
6725 references are rejected. rs6000_legitimate_offset_address_p contains
6726 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6727 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6730 /* Change register usage conditional on target flags. */
6732 rs6000_conditional_register_usage (void)
6736 /* Set MQ register fixed (already call_used) if not POWER
6737 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6742 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6744 fixed_regs[13] = call_used_regs[13]
6745 = call_really_used_regs[13] = 1;
6747 /* Conditionally disable FPRs. */
6748 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6749 for (i = 32; i < 64; i++)
6750 fixed_regs[i] = call_used_regs[i]
6751 = call_really_used_regs[i] = 1;
6753 /* The TOC register is not killed across calls in a way that is
6754 visible to the compiler. */
6755 if (DEFAULT_ABI == ABI_AIX)
6756 call_really_used_regs[2] = 0;
6758 if (DEFAULT_ABI == ABI_V4
6759 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6761 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6763 if (DEFAULT_ABI == ABI_V4
6764 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6766 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6767 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6768 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6770 if (DEFAULT_ABI == ABI_DARWIN
6771 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6772 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6773 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6774 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6776 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6777 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6778 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6782 global_regs[SPEFSCR_REGNO] = 1;
6783 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6784 registers in prologues and epilogues. We no longer use r14
6785 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6786 pool for link-compatibility with older versions of GCC. Once
6787 "old" code has died out, we can return r14 to the allocation
6790 = call_used_regs[14]
6791 = call_really_used_regs[14] = 1;
6794 if (!TARGET_ALTIVEC && !TARGET_VSX)
6796 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6797 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6798 call_really_used_regs[VRSAVE_REGNO] = 1;
6801 if (TARGET_ALTIVEC || TARGET_VSX)
6802 global_regs[VSCR_REGNO] = 1;
6804 if (TARGET_ALTIVEC_ABI)
6806 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6807 call_used_regs[i] = call_really_used_regs[i] = 1;
6809 /* AIX reserves VR20:31 in non-extended ABI mode. */
6811 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6812 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6816 /* Try to output insns to set TARGET equal to the constant C if it can
6817 be done in less than N insns. Do all computations in MODE.
6818 Returns the place where the output has been placed if it can be
6819 done and the insns have been emitted. If it would take more than N
6820 insns, zero is returned and no insns and emitted. */
6823 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6824 rtx source, int n ATTRIBUTE_UNUSED)
6826 rtx result, insn, set;
6827 HOST_WIDE_INT c0, c1;
6834 dest = gen_reg_rtx (mode);
6835 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6839 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6841 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6842 GEN_INT (INTVAL (source)
6843 & (~ (HOST_WIDE_INT) 0xffff))));
6844 emit_insn (gen_rtx_SET (VOIDmode, dest,
6845 gen_rtx_IOR (SImode, copy_rtx (result),
6846 GEN_INT (INTVAL (source) & 0xffff))));
6851 switch (GET_CODE (source))
6854 c0 = INTVAL (source);
6859 #if HOST_BITS_PER_WIDE_INT >= 64
6860 c0 = CONST_DOUBLE_LOW (source);
6863 c0 = CONST_DOUBLE_LOW (source);
6864 c1 = CONST_DOUBLE_HIGH (source);
6872 result = rs6000_emit_set_long_const (dest, c0, c1);
6879 insn = get_last_insn ();
6880 set = single_set (insn);
6881 if (! CONSTANT_P (SET_SRC (set)))
6882 set_unique_reg_note (insn, REG_EQUAL, source);
6887 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6888 fall back to a straight forward decomposition. We do this to avoid
6889 exponential run times encountered when looking for longer sequences
6890 with rs6000_emit_set_const. */
6892 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6894 if (!TARGET_POWERPC64)
6896 rtx operand1, operand2;
6898 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6900 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6902 emit_move_insn (operand1, GEN_INT (c1));
6903 emit_move_insn (operand2, GEN_INT (c2));
6907 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6910 ud2 = (c1 & 0xffff0000) >> 16;
6911 #if HOST_BITS_PER_WIDE_INT >= 64
6915 ud4 = (c2 & 0xffff0000) >> 16;
6917 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6918 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6921 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6923 emit_move_insn (dest, GEN_INT (ud1));
6926 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6927 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6930 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6933 emit_move_insn (dest, GEN_INT (ud2 << 16));
6935 emit_move_insn (copy_rtx (dest),
6936 gen_rtx_IOR (DImode, copy_rtx (dest),
6939 else if (ud3 == 0 && ud4 == 0)
6941 gcc_assert (ud2 & 0x8000);
6942 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6945 emit_move_insn (copy_rtx (dest),
6946 gen_rtx_IOR (DImode, copy_rtx (dest),
6948 emit_move_insn (copy_rtx (dest),
6949 gen_rtx_ZERO_EXTEND (DImode,
6950 gen_lowpart (SImode,
6953 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6954 || (ud4 == 0 && ! (ud3 & 0x8000)))
6957 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6960 emit_move_insn (dest, GEN_INT (ud3 << 16));
6963 emit_move_insn (copy_rtx (dest),
6964 gen_rtx_IOR (DImode, copy_rtx (dest),
6966 emit_move_insn (copy_rtx (dest),
6967 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6970 emit_move_insn (copy_rtx (dest),
6971 gen_rtx_IOR (DImode, copy_rtx (dest),
6977 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6980 emit_move_insn (dest, GEN_INT (ud4 << 16));
6983 emit_move_insn (copy_rtx (dest),
6984 gen_rtx_IOR (DImode, copy_rtx (dest),
6987 emit_move_insn (copy_rtx (dest),
6988 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6991 emit_move_insn (copy_rtx (dest),
6992 gen_rtx_IOR (DImode, copy_rtx (dest),
6993 GEN_INT (ud2 << 16)));
6995 emit_move_insn (copy_rtx (dest),
6996 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7002 /* Helper for the following. Get rid of [r+r] memory refs
7003 in cases where it won't work (TImode, TFmode, TDmode). */
7006 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7008 if (reload_in_progress)
7011 if (GET_CODE (operands[0]) == MEM
7012 && GET_CODE (XEXP (operands[0], 0)) != REG
7013 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7015 = replace_equiv_address (operands[0],
7016 copy_addr_to_reg (XEXP (operands[0], 0)));
7018 if (GET_CODE (operands[1]) == MEM
7019 && GET_CODE (XEXP (operands[1], 0)) != REG
7020 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7022 = replace_equiv_address (operands[1],
7023 copy_addr_to_reg (XEXP (operands[1], 0)));
7026 /* Return true if OP, a SYMBOL_REF, should be considered local when
7027 generating -mcmodel=medium code. */
7030 toc_relative_ok (rtx op)
7034 if (!SYMBOL_REF_LOCAL_P (op))
7037 /* This is a bit hard to explain. When building shared libraries,
7038 you are supposed to pass -fpic or -fPIC to the compiler.
7039 -fpic/-fPIC not only generate position independent code but also
7040 generate code that supports ELF shared library global function
7041 or variable overriding. ppc64 is always PIC and at least some of
7042 the ELF shared libaray semantics of global variables happen to be
7043 supported without -fpic/-fPIC. So people may not be careful
7044 about using -fPIC for shared libs.
7045 With -mcmodel=medium this situation changes. A shared library
7046 built without -fpic/-fPIC requires text relocs for global var
7047 access (and would fail to load since glibc ld.so doesn't support
7048 the required dynamic relocs). So avoid this potential
7049 problem by using -mcmodel=large access for global vars, unless
7050 we know we are compiling for an executable. */
7054 decl = SYMBOL_REF_DECL (op);
7055 if (!decl || !DECL_P (decl))
7057 if (!TREE_PUBLIC (decl))
7059 if (DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)
7062 /* If we get here we must have a global var. See binds_local_p. */
7063 return flag_whole_program;
7066 /* Return true if memory accesses to DECL are known to never straddle
7070 offsettable_ok_by_alignment (tree decl)
7072 unsigned HOST_WIDE_INT dsize, dalign;
7074 /* Presume any compiler generated symbol_ref is suitably aligned. */
7078 if (TREE_CODE (decl) != VAR_DECL
7079 && TREE_CODE (decl) != PARM_DECL
7080 && TREE_CODE (decl) != RESULT_DECL
7081 && TREE_CODE (decl) != FIELD_DECL)
7084 if (!DECL_SIZE_UNIT (decl))
7087 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7090 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7096 dalign = DECL_ALIGN_UNIT (decl);
7097 return dalign >= dsize;
7100 /* Emit a move from SOURCE to DEST in mode MODE. */
7102 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7106 operands[1] = source;
7108 if (TARGET_DEBUG_ADDR)
7111 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7112 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7113 GET_MODE_NAME (mode),
7116 can_create_pseudo_p ());
7118 fprintf (stderr, "source:\n");
7122 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7123 if (GET_CODE (operands[1]) == CONST_DOUBLE
7124 && ! FLOAT_MODE_P (mode)
7125 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7127 /* FIXME. This should never happen. */
7128 /* Since it seems that it does, do the safe thing and convert
7130 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7132 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7133 || FLOAT_MODE_P (mode)
7134 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7135 || CONST_DOUBLE_LOW (operands[1]) < 0)
7136 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7137 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7139 /* Check if GCC is setting up a block move that will end up using FP
7140 registers as temporaries. We must make sure this is acceptable. */
7141 if (GET_CODE (operands[0]) == MEM
7142 && GET_CODE (operands[1]) == MEM
7144 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7145 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7146 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7147 ? 32 : MEM_ALIGN (operands[0])))
7148 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7150 : MEM_ALIGN (operands[1]))))
7151 && ! MEM_VOLATILE_P (operands [0])
7152 && ! MEM_VOLATILE_P (operands [1]))
7154 emit_move_insn (adjust_address (operands[0], SImode, 0),
7155 adjust_address (operands[1], SImode, 0));
7156 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7157 adjust_address (copy_rtx (operands[1]), SImode, 4));
7161 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7162 && !gpc_reg_operand (operands[1], mode))
7163 operands[1] = force_reg (mode, operands[1]);
7165 if (mode == SFmode && ! TARGET_POWERPC
7166 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7167 && GET_CODE (operands[0]) == MEM)
7171 if (reload_in_progress || reload_completed)
7172 regnum = true_regnum (operands[1]);
7173 else if (GET_CODE (operands[1]) == REG)
7174 regnum = REGNO (operands[1]);
7178 /* If operands[1] is a register, on POWER it may have
7179 double-precision data in it, so truncate it to single
7181 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7184 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7185 : gen_reg_rtx (mode));
7186 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7187 operands[1] = newreg;
7191 /* Recognize the case where operand[1] is a reference to thread-local
7192 data and load its address to a register. */
7193 if (rs6000_tls_referenced_p (operands[1]))
7195 enum tls_model model;
7196 rtx tmp = operands[1];
7199 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7201 addend = XEXP (XEXP (tmp, 0), 1);
7202 tmp = XEXP (XEXP (tmp, 0), 0);
7205 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7206 model = SYMBOL_REF_TLS_MODEL (tmp);
7207 gcc_assert (model != 0);
7209 tmp = rs6000_legitimize_tls_address (tmp, model);
7212 tmp = gen_rtx_PLUS (mode, tmp, addend);
7213 tmp = force_operand (tmp, operands[0]);
7218 /* Handle the case where reload calls us with an invalid address. */
7219 if (reload_in_progress && mode == Pmode
7220 && (! general_operand (operands[1], mode)
7221 || ! nonimmediate_operand (operands[0], mode)))
7224 /* 128-bit constant floating-point values on Darwin should really be
7225 loaded as two parts. */
7226 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7227 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7229 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7230 know how to get a DFmode SUBREG of a TFmode. */
7231 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7232 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7233 simplify_gen_subreg (imode, operands[1], mode, 0),
7235 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7236 GET_MODE_SIZE (imode)),
7237 simplify_gen_subreg (imode, operands[1], mode,
7238 GET_MODE_SIZE (imode)),
7243 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7244 cfun->machine->sdmode_stack_slot =
7245 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7247 if (reload_in_progress
7249 && MEM_P (operands[0])
7250 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7251 && REG_P (operands[1]))
7253 if (FP_REGNO_P (REGNO (operands[1])))
7255 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7256 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7257 emit_insn (gen_movsd_store (mem, operands[1]));
7259 else if (INT_REGNO_P (REGNO (operands[1])))
7261 rtx mem = adjust_address_nv (operands[0], mode, 4);
7262 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7263 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7269 if (reload_in_progress
7271 && REG_P (operands[0])
7272 && MEM_P (operands[1])
7273 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7275 if (FP_REGNO_P (REGNO (operands[0])))
7277 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7278 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7279 emit_insn (gen_movsd_load (operands[0], mem));
7281 else if (INT_REGNO_P (REGNO (operands[0])))
7283 rtx mem = adjust_address_nv (operands[1], mode, 4);
7284 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7285 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7292 /* FIXME: In the long term, this switch statement should go away
7293 and be replaced by a sequence of tests based on things like
7299 if (CONSTANT_P (operands[1])
7300 && GET_CODE (operands[1]) != CONST_INT)
7301 operands[1] = force_const_mem (mode, operands[1]);
7306 rs6000_eliminate_indexed_memrefs (operands);
7313 if (CONSTANT_P (operands[1])
7314 && ! easy_fp_constant (operands[1], mode))
7315 operands[1] = force_const_mem (mode, operands[1]);
7328 if (CONSTANT_P (operands[1])
7329 && !easy_vector_constant (operands[1], mode))
7330 operands[1] = force_const_mem (mode, operands[1]);
7335 /* Use default pattern for address of ELF small data */
7338 && DEFAULT_ABI == ABI_V4
7339 && (GET_CODE (operands[1]) == SYMBOL_REF
7340 || GET_CODE (operands[1]) == CONST)
7341 && small_data_operand (operands[1], mode))
7343 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7347 if (DEFAULT_ABI == ABI_V4
7348 && mode == Pmode && mode == SImode
7349 && flag_pic == 1 && got_operand (operands[1], mode))
7351 emit_insn (gen_movsi_got (operands[0], operands[1]));
7355 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7359 && CONSTANT_P (operands[1])
7360 && GET_CODE (operands[1]) != HIGH
7361 && GET_CODE (operands[1]) != CONST_INT)
7363 rtx target = (!can_create_pseudo_p ()
7365 : gen_reg_rtx (mode));
7367 /* If this is a function address on -mcall-aixdesc,
7368 convert it to the address of the descriptor. */
7369 if (DEFAULT_ABI == ABI_AIX
7370 && GET_CODE (operands[1]) == SYMBOL_REF
7371 && XSTR (operands[1], 0)[0] == '.')
7373 const char *name = XSTR (operands[1], 0);
7375 while (*name == '.')
7377 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7378 CONSTANT_POOL_ADDRESS_P (new_ref)
7379 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7380 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7381 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7382 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7383 operands[1] = new_ref;
7386 if (DEFAULT_ABI == ABI_DARWIN)
7389 if (MACHO_DYNAMIC_NO_PIC_P)
7391 /* Take care of any required data indirection. */
7392 operands[1] = rs6000_machopic_legitimize_pic_address (
7393 operands[1], mode, operands[0]);
7394 if (operands[0] != operands[1])
7395 emit_insn (gen_rtx_SET (VOIDmode,
7396 operands[0], operands[1]));
7400 emit_insn (gen_macho_high (target, operands[1]));
7401 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7405 emit_insn (gen_elf_high (target, operands[1]));
7406 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7410 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7411 and we have put it in the TOC, we just need to make a TOC-relative
7414 && GET_CODE (operands[1]) == SYMBOL_REF
7415 && constant_pool_expr_p (operands[1])
7416 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7417 get_pool_mode (operands[1])))
7418 || (TARGET_CMODEL == CMODEL_MEDIUM
7419 && GET_CODE (operands[1]) == SYMBOL_REF
7420 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7421 && toc_relative_ok (operands[1])
7422 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7425 if (TARGET_CMODEL != CMODEL_SMALL)
7427 if (can_create_pseudo_p ())
7428 reg = gen_reg_rtx (Pmode);
7432 operands[1] = create_TOC_reference (operands[1], reg);
7434 else if (mode == Pmode
7435 && CONSTANT_P (operands[1])
7436 && ((GET_CODE (operands[1]) != CONST_INT
7437 && ! easy_fp_constant (operands[1], mode))
7438 || (GET_CODE (operands[1]) == CONST_INT
7439 && (num_insns_constant (operands[1], mode)
7440 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7441 || (GET_CODE (operands[0]) == REG
7442 && FP_REGNO_P (REGNO (operands[0]))))
7443 && GET_CODE (operands[1]) != HIGH
7444 && ! legitimate_constant_pool_address_p (operands[1], false)
7445 && ! toc_relative_expr_p (operands[1])
7446 && (TARGET_CMODEL == CMODEL_SMALL
7447 || can_create_pseudo_p ()
7448 || (REG_P (operands[0])
7449 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7453 /* Darwin uses a special PIC legitimizer. */
7454 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7457 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7459 if (operands[0] != operands[1])
7460 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7465 /* If we are to limit the number of things we put in the TOC and
7466 this is a symbol plus a constant we can add in one insn,
7467 just put the symbol in the TOC and add the constant. Don't do
7468 this if reload is in progress. */
7469 if (GET_CODE (operands[1]) == CONST
7470 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7471 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7472 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7473 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7474 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7475 && ! side_effects_p (operands[0]))
7478 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7479 rtx other = XEXP (XEXP (operands[1], 0), 1);
7481 sym = force_reg (mode, sym);
7482 emit_insn (gen_add3_insn (operands[0], sym, other));
7486 operands[1] = force_const_mem (mode, operands[1]);
7489 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7490 && constant_pool_expr_p (XEXP (operands[1], 0))
7491 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7492 get_pool_constant (XEXP (operands[1], 0)),
7493 get_pool_mode (XEXP (operands[1], 0))))
7497 if (TARGET_CMODEL != CMODEL_SMALL)
7499 if (can_create_pseudo_p ())
7500 reg = gen_reg_rtx (Pmode);
7504 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7505 operands[1] = gen_const_mem (mode, tocref);
7506 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7512 rs6000_eliminate_indexed_memrefs (operands);
7516 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7518 gen_rtx_SET (VOIDmode,
7519 operands[0], operands[1]),
7520 gen_rtx_CLOBBER (VOIDmode,
7521 gen_rtx_SCRATCH (SImode)))));
7527 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7530 /* Above, we may have called force_const_mem which may have returned
7531 an invalid address. If we can, fix this up; otherwise, reload will
7532 have to deal with it. */
7533 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7534 operands[1] = validize_mem (operands[1]);
7537 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7540 /* Nonzero if we can use a floating-point register to pass this arg. */
7541 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7542 (SCALAR_FLOAT_MODE_P (MODE) \
7543 && (CUM)->fregno <= FP_ARG_MAX_REG \
7544 && TARGET_HARD_FLOAT && TARGET_FPRS)
7546 /* Nonzero if we can use an AltiVec register to pass this arg. */
7547 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7548 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7549 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7550 && TARGET_ALTIVEC_ABI \
7553 /* Return a nonzero value to say to return the function value in
7554 memory, just as large structures are always returned. TYPE will be
7555 the data type of the value, and FNTYPE will be the type of the
7556 function doing the returning, or @code{NULL} for libcalls.
7558 The AIX ABI for the RS/6000 specifies that all structures are
7559 returned in memory. The Darwin ABI does the same.
7561 For the Darwin 64 Bit ABI, a function result can be returned in
7562 registers or in memory, depending on the size of the return data
7563 type. If it is returned in registers, the value occupies the same
7564 registers as it would if it were the first and only function
7565 argument. Otherwise, the function places its result in memory at
7566 the location pointed to by GPR3.
7568 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7569 but a draft put them in memory, and GCC used to implement the draft
7570 instead of the final standard. Therefore, aix_struct_return
7571 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7572 compatibility can change DRAFT_V4_STRUCT_RET to override the
7573 default, and -m switches get the final word. See
7574 rs6000_option_override_internal for more details.
7576 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7577 long double support is enabled. These values are returned in memory.
7579 int_size_in_bytes returns -1 for variable size objects, which go in
7580 memory always. The cast to unsigned makes -1 > 8. */
7583 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7585 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7587 && rs6000_darwin64_abi
7588 && TREE_CODE (type) == RECORD_TYPE
7589 && int_size_in_bytes (type) > 0)
7591 CUMULATIVE_ARGS valcum;
7595 valcum.fregno = FP_ARG_MIN_REG;
7596 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7597 /* Do a trial code generation as if this were going to be passed
7598 as an argument; if any part goes in memory, we return NULL. */
7599 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7602 /* Otherwise fall through to more conventional ABI rules. */
7605 if (AGGREGATE_TYPE_P (type)
7606 && (aix_struct_return
7607 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7610 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7611 modes only exist for GCC vector types if -maltivec. */
7612 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7613 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7616 /* Return synthetic vectors in memory. */
7617 if (TREE_CODE (type) == VECTOR_TYPE
7618 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7620 static bool warned_for_return_big_vectors = false;
7621 if (!warned_for_return_big_vectors)
7623 warning (0, "GCC vector returned by reference: "
7624 "non-standard ABI extension with no compatibility guarantee");
7625 warned_for_return_big_vectors = true;
7630 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7636 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7637 for a call to a function whose data type is FNTYPE.
7638 For a library call, FNTYPE is 0.
7640 For incoming args we set the number of arguments in the prototype large
7641 so we never return a PARALLEL. */
7644 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7645 rtx libname ATTRIBUTE_UNUSED, int incoming,
7646 int libcall, int n_named_args)
7648 static CUMULATIVE_ARGS zero_cumulative;
7650 *cum = zero_cumulative;
7652 cum->fregno = FP_ARG_MIN_REG;
7653 cum->vregno = ALTIVEC_ARG_MIN_REG;
7654 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7655 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7656 ? CALL_LIBCALL : CALL_NORMAL);
7657 cum->sysv_gregno = GP_ARG_MIN_REG;
7658 cum->stdarg = stdarg_p (fntype);
7660 cum->nargs_prototype = 0;
7661 if (incoming || cum->prototype)
7662 cum->nargs_prototype = n_named_args;
7664 /* Check for a longcall attribute. */
7665 if ((!fntype && rs6000_default_long_calls)
7667 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7668 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7669 cum->call_cookie |= CALL_LONG;
7671 if (TARGET_DEBUG_ARG)
7673 fprintf (stderr, "\ninit_cumulative_args:");
7676 tree ret_type = TREE_TYPE (fntype);
7677 fprintf (stderr, " ret code = %s,",
7678 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7681 if (cum->call_cookie & CALL_LONG)
7682 fprintf (stderr, " longcall,");
7684 fprintf (stderr, " proto = %d, nargs = %d\n",
7685 cum->prototype, cum->nargs_prototype);
7690 && TARGET_ALTIVEC_ABI
7691 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7693 error ("cannot return value in vector register because"
7694 " altivec instructions are disabled, use -maltivec"
7699 /* Return true if TYPE must be passed on the stack and not in registers. */
7702 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7704 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7705 return must_pass_in_stack_var_size (mode, type);
7707 return must_pass_in_stack_var_size_or_pad (mode, type);
7710 /* If defined, a C expression which determines whether, and in which
7711 direction, to pad out an argument with extra space. The value
7712 should be of type `enum direction': either `upward' to pad above
7713 the argument, `downward' to pad below, or `none' to inhibit
7716 For the AIX ABI structs are always stored left shifted in their
7720 function_arg_padding (enum machine_mode mode, const_tree type)
7722 #ifndef AGGREGATE_PADDING_FIXED
7723 #define AGGREGATE_PADDING_FIXED 0
7725 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7726 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7729 if (!AGGREGATE_PADDING_FIXED)
7731 /* GCC used to pass structures of the same size as integer types as
7732 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7733 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7734 passed padded downward, except that -mstrict-align further
7735 muddied the water in that multi-component structures of 2 and 4
7736 bytes in size were passed padded upward.
7738 The following arranges for best compatibility with previous
7739 versions of gcc, but removes the -mstrict-align dependency. */
7740 if (BYTES_BIG_ENDIAN)
7742 HOST_WIDE_INT size = 0;
7744 if (mode == BLKmode)
7746 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7747 size = int_size_in_bytes (type);
7750 size = GET_MODE_SIZE (mode);
7752 if (size == 1 || size == 2 || size == 4)
7758 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7760 if (type != 0 && AGGREGATE_TYPE_P (type))
7764 /* Fall back to the default. */
7765 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7768 /* If defined, a C expression that gives the alignment boundary, in bits,
7769 of an argument with the specified mode and type. If it is not defined,
7770 PARM_BOUNDARY is used for all arguments.
7772 V.4 wants long longs and doubles to be double word aligned. Just
7773 testing the mode size is a boneheaded way to do this as it means
7774 that other types such as complex int are also double word aligned.
7775 However, we're stuck with this because changing the ABI might break
7776 existing library interfaces.
7778 Doubleword align SPE vectors.
7779 Quadword align Altivec vectors.
7780 Quadword align large synthetic vector types. */
7783 function_arg_boundary (enum machine_mode mode, const_tree type)
7785 if (DEFAULT_ABI == ABI_V4
7786 && (GET_MODE_SIZE (mode) == 8
7787 || (TARGET_HARD_FLOAT
7789 && (mode == TFmode || mode == TDmode))))
7791 else if (SPE_VECTOR_MODE (mode)
7792 || (type && TREE_CODE (type) == VECTOR_TYPE
7793 && int_size_in_bytes (type) >= 8
7794 && int_size_in_bytes (type) < 16))
7796 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7797 || (type && TREE_CODE (type) == VECTOR_TYPE
7798 && int_size_in_bytes (type) >= 16))
7800 else if (TARGET_MACHO
7801 && rs6000_darwin64_abi
7803 && type && TYPE_ALIGN (type) > 64)
7806 return PARM_BOUNDARY;
7809 /* For a function parm of MODE and TYPE, return the starting word in
7810 the parameter area. NWORDS of the parameter area are already used. */
7813 rs6000_parm_start (enum machine_mode mode, const_tree type,
7814 unsigned int nwords)
7817 unsigned int parm_offset;
7819 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7820 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7821 return nwords + (-(parm_offset + nwords) & align);
7824 /* Compute the size (in words) of a function argument. */
7826 static unsigned long
7827 rs6000_arg_size (enum machine_mode mode, const_tree type)
7831 if (mode != BLKmode)
7832 size = GET_MODE_SIZE (mode);
7834 size = int_size_in_bytes (type);
7837 return (size + 3) >> 2;
7839 return (size + 7) >> 3;
7842 /* Use this to flush pending int fields. */
7845 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7846 HOST_WIDE_INT bitpos, int final)
7848 unsigned int startbit, endbit;
7849 int intregs, intoffset;
7850 enum machine_mode mode;
7852 /* Handle the situations where a float is taking up the first half
7853 of the GPR, and the other half is empty (typically due to
7854 alignment restrictions). We can detect this by a 8-byte-aligned
7855 int field, or by seeing that this is the final flush for this
7856 argument. Count the word and continue on. */
7857 if (cum->floats_in_gpr == 1
7858 && (cum->intoffset % 64 == 0
7859 || (cum->intoffset == -1 && final)))
7862 cum->floats_in_gpr = 0;
7865 if (cum->intoffset == -1)
7868 intoffset = cum->intoffset;
7869 cum->intoffset = -1;
7870 cum->floats_in_gpr = 0;
7872 if (intoffset % BITS_PER_WORD != 0)
7874 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7876 if (mode == BLKmode)
7878 /* We couldn't find an appropriate mode, which happens,
7879 e.g., in packed structs when there are 3 bytes to load.
7880 Back intoffset back to the beginning of the word in this
7882 intoffset = intoffset & -BITS_PER_WORD;
7886 startbit = intoffset & -BITS_PER_WORD;
7887 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7888 intregs = (endbit - startbit) / BITS_PER_WORD;
7889 cum->words += intregs;
7890 /* words should be unsigned. */
7891 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7893 int pad = (endbit/BITS_PER_WORD) - cum->words;
7898 /* The darwin64 ABI calls for us to recurse down through structs,
7899 looking for elements passed in registers. Unfortunately, we have
7900 to track int register count here also because of misalignments
7901 in powerpc alignment mode. */
7904 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7906 HOST_WIDE_INT startbitpos)
7910 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7911 if (TREE_CODE (f) == FIELD_DECL)
7913 HOST_WIDE_INT bitpos = startbitpos;
7914 tree ftype = TREE_TYPE (f);
7915 enum machine_mode mode;
7916 if (ftype == error_mark_node)
7918 mode = TYPE_MODE (ftype);
7920 if (DECL_SIZE (f) != 0
7921 && host_integerp (bit_position (f), 1))
7922 bitpos += int_bit_position (f);
7924 /* ??? FIXME: else assume zero offset. */
7926 if (TREE_CODE (ftype) == RECORD_TYPE)
7927 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7928 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7930 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7931 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7932 /* Single-precision floats present a special problem for
7933 us, because they are smaller than an 8-byte GPR, and so
7934 the structure-packing rules combined with the standard
7935 varargs behavior mean that we want to pack float/float
7936 and float/int combinations into a single register's
7937 space. This is complicated by the arg advance flushing,
7938 which works on arbitrarily large groups of int-type
7942 if (cum->floats_in_gpr == 1)
7944 /* Two floats in a word; count the word and reset
7947 cum->floats_in_gpr = 0;
7949 else if (bitpos % 64 == 0)
7951 /* A float at the beginning of an 8-byte word;
7952 count it and put off adjusting cum->words until
7953 we see if a arg advance flush is going to do it
7955 cum->floats_in_gpr++;
7959 /* The float is at the end of a word, preceded
7960 by integer fields, so the arg advance flush
7961 just above has already set cum->words and
7962 everything is taken care of. */
7966 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7968 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7970 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7974 else if (cum->intoffset == -1)
7975 cum->intoffset = bitpos;
7979 /* Check for an item that needs to be considered specially under the darwin 64
7980 bit ABI. These are record types where the mode is BLK or the structure is
7983 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7985 return rs6000_darwin64_abi
7986 && ((mode == BLKmode
7987 && TREE_CODE (type) == RECORD_TYPE
7988 && int_size_in_bytes (type) > 0)
7989 || (type && TREE_CODE (type) == RECORD_TYPE
7990 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7993 /* Update the data in CUM to advance over an argument
7994 of mode MODE and data type TYPE.
7995 (TYPE is null for libcalls where that information may not be available.)
7997 Note that for args passed by reference, function_arg will be called
7998 with MODE and TYPE set to that of the pointer to the arg, not the arg
8002 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8003 const_tree type, bool named, int depth)
8006 /* Only tick off an argument if we're not recursing. */
8008 cum->nargs_prototype--;
8010 if (TARGET_ALTIVEC_ABI
8011 && (ALTIVEC_VECTOR_MODE (mode)
8012 || VSX_VECTOR_MODE (mode)
8013 || (type && TREE_CODE (type) == VECTOR_TYPE
8014 && int_size_in_bytes (type) == 16)))
8018 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8021 if (!TARGET_ALTIVEC)
8022 error ("cannot pass argument in vector register because"
8023 " altivec instructions are disabled, use -maltivec"
8026 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8027 even if it is going to be passed in a vector register.
8028 Darwin does the same for variable-argument functions. */
8029 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8030 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8040 /* Vector parameters must be 16-byte aligned. This places
8041 them at 2 mod 4 in terms of words in 32-bit mode, since
8042 the parameter save area starts at offset 24 from the
8043 stack. In 64-bit mode, they just have to start on an
8044 even word, since the parameter save area is 16-byte
8045 aligned. Space for GPRs is reserved even if the argument
8046 will be passed in memory. */
8048 align = (2 - cum->words) & 3;
8050 align = cum->words & 1;
8051 cum->words += align + rs6000_arg_size (mode, type);
8053 if (TARGET_DEBUG_ARG)
8055 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8057 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8058 cum->nargs_prototype, cum->prototype,
8059 GET_MODE_NAME (mode));
8063 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8065 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8068 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8070 int size = int_size_in_bytes (type);
8071 /* Variable sized types have size == -1 and are
8072 treated as if consisting entirely of ints.
8073 Pad to 16 byte boundary if needed. */
8074 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8075 && (cum->words % 2) != 0)
8077 /* For varargs, we can just go up by the size of the struct. */
8079 cum->words += (size + 7) / 8;
8082 /* It is tempting to say int register count just goes up by
8083 sizeof(type)/8, but this is wrong in a case such as
8084 { int; double; int; } [powerpc alignment]. We have to
8085 grovel through the fields for these too. */
8087 cum->floats_in_gpr = 0;
8088 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8089 rs6000_darwin64_record_arg_advance_flush (cum,
8090 size * BITS_PER_UNIT, 1);
8092 if (TARGET_DEBUG_ARG)
8094 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8095 cum->words, TYPE_ALIGN (type), size);
8097 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8098 cum->nargs_prototype, cum->prototype,
8099 GET_MODE_NAME (mode));
8102 else if (DEFAULT_ABI == ABI_V4)
8104 if (TARGET_HARD_FLOAT && TARGET_FPRS
8105 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8106 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8107 || (mode == TFmode && !TARGET_IEEEQUAD)
8108 || mode == SDmode || mode == DDmode || mode == TDmode))
8110 /* _Decimal128 must use an even/odd register pair. This assumes
8111 that the register number is odd when fregno is odd. */
8112 if (mode == TDmode && (cum->fregno % 2) == 1)
8115 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8116 <= FP_ARG_V4_MAX_REG)
8117 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8120 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8121 if (mode == DFmode || mode == TFmode
8122 || mode == DDmode || mode == TDmode)
8123 cum->words += cum->words & 1;
8124 cum->words += rs6000_arg_size (mode, type);
8129 int n_words = rs6000_arg_size (mode, type);
8130 int gregno = cum->sysv_gregno;
8132 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8133 (r7,r8) or (r9,r10). As does any other 2 word item such
8134 as complex int due to a historical mistake. */
8136 gregno += (1 - gregno) & 1;
8138 /* Multi-reg args are not split between registers and stack. */
8139 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8141 /* Long long and SPE vectors are aligned on the stack.
8142 So are other 2 word items such as complex int due to
8143 a historical mistake. */
8145 cum->words += cum->words & 1;
8146 cum->words += n_words;
8149 /* Note: continuing to accumulate gregno past when we've started
8150 spilling to the stack indicates the fact that we've started
8151 spilling to the stack to expand_builtin_saveregs. */
8152 cum->sysv_gregno = gregno + n_words;
8155 if (TARGET_DEBUG_ARG)
8157 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8158 cum->words, cum->fregno);
8159 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8160 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8161 fprintf (stderr, "mode = %4s, named = %d\n",
8162 GET_MODE_NAME (mode), named);
8167 int n_words = rs6000_arg_size (mode, type);
8168 int start_words = cum->words;
8169 int align_words = rs6000_parm_start (mode, type, start_words);
8171 cum->words = align_words + n_words;
8173 if (SCALAR_FLOAT_MODE_P (mode)
8174 && TARGET_HARD_FLOAT && TARGET_FPRS)
8176 /* _Decimal128 must be passed in an even/odd float register pair.
8177 This assumes that the register number is odd when fregno is
8179 if (mode == TDmode && (cum->fregno % 2) == 1)
8181 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8184 if (TARGET_DEBUG_ARG)
8186 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8187 cum->words, cum->fregno);
8188 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8189 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8190 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8191 named, align_words - start_words, depth);
8197 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8198 const_tree type, bool named)
8200 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8204 spe_build_register_parallel (enum machine_mode mode, int gregno)
8211 r1 = gen_rtx_REG (DImode, gregno);
8212 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8213 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8217 r1 = gen_rtx_REG (DImode, gregno);
8218 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8219 r3 = gen_rtx_REG (DImode, gregno + 2);
8220 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8221 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8224 r1 = gen_rtx_REG (DImode, gregno);
8225 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8226 r3 = gen_rtx_REG (DImode, gregno + 2);
8227 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8228 r5 = gen_rtx_REG (DImode, gregno + 4);
8229 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8230 r7 = gen_rtx_REG (DImode, gregno + 6);
8231 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8232 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8239 /* Determine where to put a SIMD argument on the SPE. */
8241 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8244 int gregno = cum->sysv_gregno;
8246 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8247 are passed and returned in a pair of GPRs for ABI compatibility. */
8248 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8249 || mode == DCmode || mode == TCmode))
8251 int n_words = rs6000_arg_size (mode, type);
8253 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8255 gregno += (1 - gregno) & 1;
8257 /* Multi-reg args are not split between registers and stack. */
8258 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8261 return spe_build_register_parallel (mode, gregno);
8265 int n_words = rs6000_arg_size (mode, type);
8267 /* SPE vectors are put in odd registers. */
8268 if (n_words == 2 && (gregno & 1) == 0)
8271 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8274 enum machine_mode m = SImode;
8276 r1 = gen_rtx_REG (m, gregno);
8277 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8278 r2 = gen_rtx_REG (m, gregno + 1);
8279 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8280 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8287 if (gregno <= GP_ARG_MAX_REG)
8288 return gen_rtx_REG (mode, gregno);
8294 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8295 structure between cum->intoffset and bitpos to integer registers. */
8298 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8299 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8301 enum machine_mode mode;
8303 unsigned int startbit, endbit;
8304 int this_regno, intregs, intoffset;
8307 if (cum->intoffset == -1)
8310 intoffset = cum->intoffset;
8311 cum->intoffset = -1;
8313 /* If this is the trailing part of a word, try to only load that
8314 much into the register. Otherwise load the whole register. Note
8315 that in the latter case we may pick up unwanted bits. It's not a
8316 problem at the moment but may wish to revisit. */
8318 if (intoffset % BITS_PER_WORD != 0)
8320 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8322 if (mode == BLKmode)
8324 /* We couldn't find an appropriate mode, which happens,
8325 e.g., in packed structs when there are 3 bytes to load.
8326 Back intoffset back to the beginning of the word in this
8328 intoffset = intoffset & -BITS_PER_WORD;
8335 startbit = intoffset & -BITS_PER_WORD;
8336 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8337 intregs = (endbit - startbit) / BITS_PER_WORD;
8338 this_regno = cum->words + intoffset / BITS_PER_WORD;
8340 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8343 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8347 intoffset /= BITS_PER_UNIT;
8350 regno = GP_ARG_MIN_REG + this_regno;
8351 reg = gen_rtx_REG (mode, regno);
8353 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8356 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8360 while (intregs > 0);
8363 /* Recursive workhorse for the following. */
8366 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8367 HOST_WIDE_INT startbitpos, rtx rvec[],
8372 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8373 if (TREE_CODE (f) == FIELD_DECL)
8375 HOST_WIDE_INT bitpos = startbitpos;
8376 tree ftype = TREE_TYPE (f);
8377 enum machine_mode mode;
8378 if (ftype == error_mark_node)
8380 mode = TYPE_MODE (ftype);
8382 if (DECL_SIZE (f) != 0
8383 && host_integerp (bit_position (f), 1))
8384 bitpos += int_bit_position (f);
8386 /* ??? FIXME: else assume zero offset. */
8388 if (TREE_CODE (ftype) == RECORD_TYPE)
8389 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8390 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8395 case SCmode: mode = SFmode; break;
8396 case DCmode: mode = DFmode; break;
8397 case TCmode: mode = TFmode; break;
8401 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8403 = gen_rtx_EXPR_LIST (VOIDmode,
8404 gen_rtx_REG (mode, cum->fregno++),
8405 GEN_INT (bitpos / BITS_PER_UNIT));
8406 if (mode == TFmode || mode == TDmode)
8409 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8411 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8413 = gen_rtx_EXPR_LIST (VOIDmode,
8414 gen_rtx_REG (mode, cum->vregno++),
8415 GEN_INT (bitpos / BITS_PER_UNIT));
8417 else if (cum->intoffset == -1)
8418 cum->intoffset = bitpos;
8422 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8423 the register(s) to be used for each field and subfield of a struct
8424 being passed by value, along with the offset of where the
8425 register's value may be found in the block. FP fields go in FP
8426 register, vector fields go in vector registers, and everything
8427 else goes in int registers, packed as in memory.
8429 This code is also used for function return values. RETVAL indicates
8430 whether this is the case.
8432 Much of this is taken from the SPARC V9 port, which has a similar
8433 calling convention. */
8436 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8437 bool named, bool retval)
8439 rtx rvec[FIRST_PSEUDO_REGISTER];
8440 int k = 1, kbase = 1;
8441 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8442 /* This is a copy; modifications are not visible to our caller. */
8443 CUMULATIVE_ARGS copy_cum = *orig_cum;
8444 CUMULATIVE_ARGS *cum = ©_cum;
8446 /* Pad to 16 byte boundary if needed. */
8447 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8448 && (cum->words % 2) != 0)
8455 /* Put entries into rvec[] for individual FP and vector fields, and
8456 for the chunks of memory that go in int regs. Note we start at
8457 element 1; 0 is reserved for an indication of using memory, and
8458 may or may not be filled in below. */
8459 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8460 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8462 /* If any part of the struct went on the stack put all of it there.
8463 This hack is because the generic code for
8464 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8465 parts of the struct are not at the beginning. */
8469 return NULL_RTX; /* doesn't go in registers at all */
8471 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8473 if (k > 1 || cum->use_stack)
8474 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8479 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8482 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8487 rtx rvec[GP_ARG_NUM_REG + 1];
8489 if (align_words >= GP_ARG_NUM_REG)
8492 n_units = rs6000_arg_size (mode, type);
8494 /* Optimize the simple case where the arg fits in one gpr, except in
8495 the case of BLKmode due to assign_parms assuming that registers are
8496 BITS_PER_WORD wide. */
8498 || (n_units == 1 && mode != BLKmode))
8499 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8502 if (align_words + n_units > GP_ARG_NUM_REG)
8503 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8504 using a magic NULL_RTX component.
8505 This is not strictly correct. Only some of the arg belongs in
8506 memory, not all of it. However, the normal scheme using
8507 function_arg_partial_nregs can result in unusual subregs, eg.
8508 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8509 store the whole arg to memory is often more efficient than code
8510 to store pieces, and we know that space is available in the right
8511 place for the whole arg. */
8512 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8517 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8518 rtx off = GEN_INT (i++ * 4);
8519 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8521 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8523 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8526 /* Determine where to put an argument to a function.
8527 Value is zero to push the argument on the stack,
8528 or a hard register in which to store the argument.
8530 MODE is the argument's machine mode.
8531 TYPE is the data type of the argument (as a tree).
8532 This is null for libcalls where that information may
8534 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8535 the preceding args and about the function being called. It is
8536 not modified in this routine.
8537 NAMED is nonzero if this argument is a named parameter
8538 (otherwise it is an extra parameter matching an ellipsis).
8540 On RS/6000 the first eight words of non-FP are normally in registers
8541 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8542 Under V.4, the first 8 FP args are in registers.
8544 If this is floating-point and no prototype is specified, we use
8545 both an FP and integer register (or possibly FP reg and stack). Library
8546 functions (when CALL_LIBCALL is set) always have the proper types for args,
8547 so we can pass the FP value just in one register. emit_library_function
8548 doesn't support PARALLEL anyway.
8550 Note that for args passed by reference, function_arg will be called
8551 with MODE and TYPE set to that of the pointer to the arg, not the arg
8555 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8556 const_tree type, bool named)
8558 enum rs6000_abi abi = DEFAULT_ABI;
8560 /* Return a marker to indicate whether CR1 needs to set or clear the
8561 bit that V.4 uses to say fp args were passed in registers.
8562 Assume that we don't need the marker for software floating point,
8563 or compiler generated library calls. */
8564 if (mode == VOIDmode)
8567 && (cum->call_cookie & CALL_LIBCALL) == 0
8569 || (cum->nargs_prototype < 0
8570 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8572 /* For the SPE, we need to crxor CR6 always. */
8574 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8575 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8576 return GEN_INT (cum->call_cookie
8577 | ((cum->fregno == FP_ARG_MIN_REG)
8578 ? CALL_V4_SET_FP_ARGS
8579 : CALL_V4_CLEAR_FP_ARGS));
8582 return GEN_INT (cum->call_cookie);
8585 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8587 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8588 if (rslt != NULL_RTX)
8590 /* Else fall through to usual handling. */
8593 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8594 if (TARGET_64BIT && ! cum->prototype)
8596 /* Vector parameters get passed in vector register
8597 and also in GPRs or memory, in absence of prototype. */
8600 align_words = (cum->words + 1) & ~1;
8602 if (align_words >= GP_ARG_NUM_REG)
8608 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8610 return gen_rtx_PARALLEL (mode,
8612 gen_rtx_EXPR_LIST (VOIDmode,
8614 gen_rtx_EXPR_LIST (VOIDmode,
8615 gen_rtx_REG (mode, cum->vregno),
8619 return gen_rtx_REG (mode, cum->vregno);
8620 else if (TARGET_ALTIVEC_ABI
8621 && (ALTIVEC_VECTOR_MODE (mode)
8622 || VSX_VECTOR_MODE (mode)
8623 || (type && TREE_CODE (type) == VECTOR_TYPE
8624 && int_size_in_bytes (type) == 16)))
8626 if (named || abi == ABI_V4)
8630 /* Vector parameters to varargs functions under AIX or Darwin
8631 get passed in memory and possibly also in GPRs. */
8632 int align, align_words, n_words;
8633 enum machine_mode part_mode;
8635 /* Vector parameters must be 16-byte aligned. This places them at
8636 2 mod 4 in terms of words in 32-bit mode, since the parameter
8637 save area starts at offset 24 from the stack. In 64-bit mode,
8638 they just have to start on an even word, since the parameter
8639 save area is 16-byte aligned. */
8641 align = (2 - cum->words) & 3;
8643 align = cum->words & 1;
8644 align_words = cum->words + align;
8646 /* Out of registers? Memory, then. */
8647 if (align_words >= GP_ARG_NUM_REG)
8650 if (TARGET_32BIT && TARGET_POWERPC64)
8651 return rs6000_mixed_function_arg (mode, type, align_words);
8653 /* The vector value goes in GPRs. Only the part of the
8654 value in GPRs is reported here. */
8656 n_words = rs6000_arg_size (mode, type);
8657 if (align_words + n_words > GP_ARG_NUM_REG)
8658 /* Fortunately, there are only two possibilities, the value
8659 is either wholly in GPRs or half in GPRs and half not. */
8662 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8665 else if (TARGET_SPE_ABI && TARGET_SPE
8666 && (SPE_VECTOR_MODE (mode)
8667 || (TARGET_E500_DOUBLE && (mode == DFmode
8670 || mode == TCmode))))
8671 return rs6000_spe_function_arg (cum, mode, type);
8673 else if (abi == ABI_V4)
8675 if (TARGET_HARD_FLOAT && TARGET_FPRS
8676 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8677 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8678 || (mode == TFmode && !TARGET_IEEEQUAD)
8679 || mode == SDmode || mode == DDmode || mode == TDmode))
8681 /* _Decimal128 must use an even/odd register pair. This assumes
8682 that the register number is odd when fregno is odd. */
8683 if (mode == TDmode && (cum->fregno % 2) == 1)
8686 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8687 <= FP_ARG_V4_MAX_REG)
8688 return gen_rtx_REG (mode, cum->fregno);
8694 int n_words = rs6000_arg_size (mode, type);
8695 int gregno = cum->sysv_gregno;
8697 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8698 (r7,r8) or (r9,r10). As does any other 2 word item such
8699 as complex int due to a historical mistake. */
8701 gregno += (1 - gregno) & 1;
8703 /* Multi-reg args are not split between registers and stack. */
8704 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8707 if (TARGET_32BIT && TARGET_POWERPC64)
8708 return rs6000_mixed_function_arg (mode, type,
8709 gregno - GP_ARG_MIN_REG);
8710 return gen_rtx_REG (mode, gregno);
8715 int align_words = rs6000_parm_start (mode, type, cum->words);
8717 /* _Decimal128 must be passed in an even/odd float register pair.
8718 This assumes that the register number is odd when fregno is odd. */
8719 if (mode == TDmode && (cum->fregno % 2) == 1)
8722 if (USE_FP_FOR_ARG_P (cum, mode, type))
8724 rtx rvec[GP_ARG_NUM_REG + 1];
8728 enum machine_mode fmode = mode;
8729 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8731 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8733 /* Currently, we only ever need one reg here because complex
8734 doubles are split. */
8735 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8736 && (fmode == TFmode || fmode == TDmode));
8738 /* Long double or _Decimal128 split over regs and memory. */
8739 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8742 /* Do we also need to pass this arg in the parameter save
8745 && (cum->nargs_prototype <= 0
8746 || (DEFAULT_ABI == ABI_AIX
8748 && align_words >= GP_ARG_NUM_REG)));
8750 if (!needs_psave && mode == fmode)
8751 return gen_rtx_REG (fmode, cum->fregno);
8756 /* Describe the part that goes in gprs or the stack.
8757 This piece must come first, before the fprs. */
8758 if (align_words < GP_ARG_NUM_REG)
8760 unsigned long n_words = rs6000_arg_size (mode, type);
8762 if (align_words + n_words > GP_ARG_NUM_REG
8763 || (TARGET_32BIT && TARGET_POWERPC64))
8765 /* If this is partially on the stack, then we only
8766 include the portion actually in registers here. */
8767 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8770 if (align_words + n_words > GP_ARG_NUM_REG)
8771 /* Not all of the arg fits in gprs. Say that it
8772 goes in memory too, using a magic NULL_RTX
8773 component. Also see comment in
8774 rs6000_mixed_function_arg for why the normal
8775 function_arg_partial_nregs scheme doesn't work
8777 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8781 r = gen_rtx_REG (rmode,
8782 GP_ARG_MIN_REG + align_words);
8783 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8784 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8786 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8790 /* The whole arg fits in gprs. */
8791 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8792 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8796 /* It's entirely in memory. */
8797 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8800 /* Describe where this piece goes in the fprs. */
8801 r = gen_rtx_REG (fmode, cum->fregno);
8802 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8804 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8806 else if (align_words < GP_ARG_NUM_REG)
8808 if (TARGET_32BIT && TARGET_POWERPC64)
8809 return rs6000_mixed_function_arg (mode, type, align_words);
8811 if (mode == BLKmode)
8814 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8821 /* For an arg passed partly in registers and partly in memory, this is
8822 the number of bytes passed in registers. For args passed entirely in
8823 registers or entirely in memory, zero. When an arg is described by a
8824 PARALLEL, perhaps using more than one register type, this function
8825 returns the number of bytes used by the first element of the PARALLEL. */
8828 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8829 tree type, bool named)
8834 if (DEFAULT_ABI == ABI_V4)
8837 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8838 && cum->nargs_prototype >= 0)
8841 /* In this complicated case we just disable the partial_nregs code. */
8842 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8845 align_words = rs6000_parm_start (mode, type, cum->words);
8847 if (USE_FP_FOR_ARG_P (cum, mode, type))
8849 /* If we are passing this arg in the fixed parameter save area
8850 (gprs or memory) as well as fprs, then this function should
8851 return the number of partial bytes passed in the parameter
8852 save area rather than partial bytes passed in fprs. */
8854 && (cum->nargs_prototype <= 0
8855 || (DEFAULT_ABI == ABI_AIX
8857 && align_words >= GP_ARG_NUM_REG)))
8859 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8860 > FP_ARG_MAX_REG + 1)
8861 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8862 else if (cum->nargs_prototype >= 0)
8866 if (align_words < GP_ARG_NUM_REG
8867 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8868 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8870 if (ret != 0 && TARGET_DEBUG_ARG)
8871 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8876 /* A C expression that indicates when an argument must be passed by
8877 reference. If nonzero for an argument, a copy of that argument is
8878 made in memory and a pointer to the argument is passed instead of
8879 the argument itself. The pointer is passed in whatever way is
8880 appropriate for passing a pointer to that type.
8882 Under V.4, aggregates and long double are passed by reference.
8884 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8885 reference unless the AltiVec vector extension ABI is in force.
8887 As an extension to all ABIs, variable sized types are passed by
8891 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8892 enum machine_mode mode, const_tree type,
8893 bool named ATTRIBUTE_UNUSED)
8895 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8897 if (TARGET_DEBUG_ARG)
8898 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8905 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8907 if (TARGET_DEBUG_ARG)
8908 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8912 if (int_size_in_bytes (type) < 0)
8914 if (TARGET_DEBUG_ARG)
8915 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8919 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8920 modes only exist for GCC vector types if -maltivec. */
8921 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8923 if (TARGET_DEBUG_ARG)
8924 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8928 /* Pass synthetic vectors in memory. */
8929 if (TREE_CODE (type) == VECTOR_TYPE
8930 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8932 static bool warned_for_pass_big_vectors = false;
8933 if (TARGET_DEBUG_ARG)
8934 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8935 if (!warned_for_pass_big_vectors)
8937 warning (0, "GCC vector passed by reference: "
8938 "non-standard ABI extension with no compatibility guarantee");
8939 warned_for_pass_big_vectors = true;
8948 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8951 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8956 for (i = 0; i < nregs; i++)
8958 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8959 if (reload_completed)
8961 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8964 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8965 i * GET_MODE_SIZE (reg_mode));
8968 tem = replace_equiv_address (tem, XEXP (tem, 0));
8972 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8976 /* Perform any needed actions needed for a function that is receiving a
8977 variable number of arguments.
8981 MODE and TYPE are the mode and type of the current parameter.
8983 PRETEND_SIZE is a variable that should be set to the amount of stack
8984 that must be pushed by the prolog to pretend that our caller pushed
8987 Normally, this macro will push all remaining incoming registers on the
8988 stack and set PRETEND_SIZE to the length of the registers pushed. */
8991 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8992 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8995 CUMULATIVE_ARGS next_cum;
8996 int reg_size = TARGET_32BIT ? 4 : 8;
8997 rtx save_area = NULL_RTX, mem;
8998 int first_reg_offset;
9001 /* Skip the last named argument. */
9003 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9005 if (DEFAULT_ABI == ABI_V4)
9007 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9011 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9012 HOST_WIDE_INT offset = 0;
9014 /* Try to optimize the size of the varargs save area.
9015 The ABI requires that ap.reg_save_area is doubleword
9016 aligned, but we don't need to allocate space for all
9017 the bytes, only those to which we actually will save
9019 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9020 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9021 if (TARGET_HARD_FLOAT && TARGET_FPRS
9022 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9023 && cfun->va_list_fpr_size)
9026 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9027 * UNITS_PER_FP_WORD;
9028 if (cfun->va_list_fpr_size
9029 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9030 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9032 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9033 * UNITS_PER_FP_WORD;
9037 offset = -((first_reg_offset * reg_size) & ~7);
9038 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9040 gpr_reg_num = cfun->va_list_gpr_size;
9041 if (reg_size == 4 && (first_reg_offset & 1))
9044 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9047 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9049 - (int) (GP_ARG_NUM_REG * reg_size);
9051 if (gpr_size + fpr_size)
9054 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9055 gcc_assert (GET_CODE (reg_save_area) == MEM);
9056 reg_save_area = XEXP (reg_save_area, 0);
9057 if (GET_CODE (reg_save_area) == PLUS)
9059 gcc_assert (XEXP (reg_save_area, 0)
9060 == virtual_stack_vars_rtx);
9061 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9062 offset += INTVAL (XEXP (reg_save_area, 1));
9065 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9068 cfun->machine->varargs_save_offset = offset;
9069 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9074 first_reg_offset = next_cum.words;
9075 save_area = virtual_incoming_args_rtx;
9077 if (targetm.calls.must_pass_in_stack (mode, type))
9078 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9081 set = get_varargs_alias_set ();
9082 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9083 && cfun->va_list_gpr_size)
9085 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9087 if (va_list_gpr_counter_field)
9089 /* V4 va_list_gpr_size counts number of registers needed. */
9090 if (nregs > cfun->va_list_gpr_size)
9091 nregs = cfun->va_list_gpr_size;
9095 /* char * va_list instead counts number of bytes needed. */
9096 if (nregs > cfun->va_list_gpr_size / reg_size)
9097 nregs = cfun->va_list_gpr_size / reg_size;
9100 mem = gen_rtx_MEM (BLKmode,
9101 plus_constant (save_area,
9102 first_reg_offset * reg_size));
9103 MEM_NOTRAP_P (mem) = 1;
9104 set_mem_alias_set (mem, set);
9105 set_mem_align (mem, BITS_PER_WORD);
9107 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9111 /* Save FP registers if needed. */
9112 if (DEFAULT_ABI == ABI_V4
9113 && TARGET_HARD_FLOAT && TARGET_FPRS
9115 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9116 && cfun->va_list_fpr_size)
9118 int fregno = next_cum.fregno, nregs;
9119 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9120 rtx lab = gen_label_rtx ();
9121 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9122 * UNITS_PER_FP_WORD);
9125 (gen_rtx_SET (VOIDmode,
9127 gen_rtx_IF_THEN_ELSE (VOIDmode,
9128 gen_rtx_NE (VOIDmode, cr1,
9130 gen_rtx_LABEL_REF (VOIDmode, lab),
9134 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9135 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9137 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9139 plus_constant (save_area, off));
9140 MEM_NOTRAP_P (mem) = 1;
9141 set_mem_alias_set (mem, set);
9142 set_mem_align (mem, GET_MODE_ALIGNMENT (
9143 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9144 ? DFmode : SFmode));
9145 emit_move_insn (mem, gen_rtx_REG (
9146 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9147 ? DFmode : SFmode, fregno));
9154 /* Create the va_list data type. */
9157 rs6000_build_builtin_va_list (void)
9159 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9161 /* For AIX, prefer 'char *' because that's what the system
9162 header files like. */
9163 if (DEFAULT_ABI != ABI_V4)
9164 return build_pointer_type (char_type_node);
9166 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9167 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9168 get_identifier ("__va_list_tag"), record);
9170 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9171 unsigned_char_type_node);
9172 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9173 unsigned_char_type_node);
9174 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9176 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9177 get_identifier ("reserved"), short_unsigned_type_node);
9178 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9179 get_identifier ("overflow_arg_area"),
9181 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9182 get_identifier ("reg_save_area"),
9185 va_list_gpr_counter_field = f_gpr;
9186 va_list_fpr_counter_field = f_fpr;
9188 DECL_FIELD_CONTEXT (f_gpr) = record;
9189 DECL_FIELD_CONTEXT (f_fpr) = record;
9190 DECL_FIELD_CONTEXT (f_res) = record;
9191 DECL_FIELD_CONTEXT (f_ovf) = record;
9192 DECL_FIELD_CONTEXT (f_sav) = record;
9194 TREE_CHAIN (record) = type_decl;
9195 TYPE_NAME (record) = type_decl;
9196 TYPE_FIELDS (record) = f_gpr;
9197 DECL_CHAIN (f_gpr) = f_fpr;
9198 DECL_CHAIN (f_fpr) = f_res;
9199 DECL_CHAIN (f_res) = f_ovf;
9200 DECL_CHAIN (f_ovf) = f_sav;
9202 layout_type (record);
9204 /* The correct type is an array type of one element. */
9205 return build_array_type (record, build_index_type (size_zero_node));
9208 /* Implement va_start. */
9211 rs6000_va_start (tree valist, rtx nextarg)
9213 HOST_WIDE_INT words, n_gpr, n_fpr;
9214 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9215 tree gpr, fpr, ovf, sav, t;
9217 /* Only SVR4 needs something special. */
9218 if (DEFAULT_ABI != ABI_V4)
9220 std_expand_builtin_va_start (valist, nextarg);
9224 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9225 f_fpr = DECL_CHAIN (f_gpr);
9226 f_res = DECL_CHAIN (f_fpr);
9227 f_ovf = DECL_CHAIN (f_res);
9228 f_sav = DECL_CHAIN (f_ovf);
9230 valist = build_va_arg_indirect_ref (valist);
9231 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9232 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9234 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9236 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9239 /* Count number of gp and fp argument registers used. */
9240 words = crtl->args.info.words;
9241 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9243 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9246 if (TARGET_DEBUG_ARG)
9247 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9248 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9249 words, n_gpr, n_fpr);
9251 if (cfun->va_list_gpr_size)
9253 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9254 build_int_cst (NULL_TREE, n_gpr));
9255 TREE_SIDE_EFFECTS (t) = 1;
9256 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9259 if (cfun->va_list_fpr_size)
9261 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9262 build_int_cst (NULL_TREE, n_fpr));
9263 TREE_SIDE_EFFECTS (t) = 1;
9264 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9267 /* Find the overflow area. */
9268 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9270 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9271 size_int (words * UNITS_PER_WORD));
9272 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9273 TREE_SIDE_EFFECTS (t) = 1;
9274 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9276 /* If there were no va_arg invocations, don't set up the register
9278 if (!cfun->va_list_gpr_size
9279 && !cfun->va_list_fpr_size
9280 && n_gpr < GP_ARG_NUM_REG
9281 && n_fpr < FP_ARG_V4_MAX_REG)
9284 /* Find the register save area. */
9285 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9286 if (cfun->machine->varargs_save_offset)
9287 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9288 size_int (cfun->machine->varargs_save_offset));
9289 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9290 TREE_SIDE_EFFECTS (t) = 1;
9291 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9294 /* Implement va_arg. */
9297 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9300 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9301 tree gpr, fpr, ovf, sav, reg, t, u;
9302 int size, rsize, n_reg, sav_ofs, sav_scale;
9303 tree lab_false, lab_over, addr;
9305 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9309 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9311 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9312 return build_va_arg_indirect_ref (t);
9315 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9316 earlier version of gcc, with the property that it always applied alignment
9317 adjustments to the va-args (even for zero-sized types). The cheapest way
9318 to deal with this is to replicate the effect of the part of
9319 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9321 We don't need to check for pass-by-reference because of the test above.
9322 We can return a simplifed answer, since we know there's no offset to add. */
9325 && rs6000_darwin64_abi
9326 && integer_zerop (TYPE_SIZE (type)))
9328 unsigned HOST_WIDE_INT align, boundary;
9329 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9330 align = PARM_BOUNDARY / BITS_PER_UNIT;
9331 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9332 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9333 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9334 boundary /= BITS_PER_UNIT;
9335 if (boundary > align)
9338 /* This updates arg ptr by the amount that would be necessary
9339 to align the zero-sized (but not zero-alignment) item. */
9340 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9341 fold_build2 (POINTER_PLUS_EXPR,
9343 valist_tmp, size_int (boundary - 1)));
9344 gimplify_and_add (t, pre_p);
9346 t = fold_convert (sizetype, valist_tmp);
9347 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9348 fold_convert (TREE_TYPE (valist),
9349 fold_build2 (BIT_AND_EXPR, sizetype, t,
9350 size_int (-boundary))));
9351 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9352 gimplify_and_add (t, pre_p);
9354 /* Since it is zero-sized there's no increment for the item itself. */
9355 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9356 return build_va_arg_indirect_ref (valist_tmp);
9359 if (DEFAULT_ABI != ABI_V4)
9361 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9363 tree elem_type = TREE_TYPE (type);
9364 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9365 int elem_size = GET_MODE_SIZE (elem_mode);
9367 if (elem_size < UNITS_PER_WORD)
9369 tree real_part, imag_part;
9370 gimple_seq post = NULL;
9372 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9374 /* Copy the value into a temporary, lest the formal temporary
9375 be reused out from under us. */
9376 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9377 gimple_seq_add_seq (pre_p, post);
9379 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9382 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9386 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9389 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9390 f_fpr = DECL_CHAIN (f_gpr);
9391 f_res = DECL_CHAIN (f_fpr);
9392 f_ovf = DECL_CHAIN (f_res);
9393 f_sav = DECL_CHAIN (f_ovf);
9395 valist = build_va_arg_indirect_ref (valist);
9396 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9397 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9399 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9401 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9404 size = int_size_in_bytes (type);
9405 rsize = (size + 3) / 4;
9408 if (TARGET_HARD_FLOAT && TARGET_FPRS
9409 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9410 || (TARGET_DOUBLE_FLOAT
9411 && (TYPE_MODE (type) == DFmode
9412 || TYPE_MODE (type) == TFmode
9413 || TYPE_MODE (type) == SDmode
9414 || TYPE_MODE (type) == DDmode
9415 || TYPE_MODE (type) == TDmode))))
9417 /* FP args go in FP registers, if present. */
9419 n_reg = (size + 7) / 8;
9420 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9421 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9422 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9427 /* Otherwise into GP registers. */
9436 /* Pull the value out of the saved registers.... */
9439 addr = create_tmp_var (ptr_type_node, "addr");
9441 /* AltiVec vectors never go in registers when -mabi=altivec. */
9442 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9446 lab_false = create_artificial_label (input_location);
9447 lab_over = create_artificial_label (input_location);
9449 /* Long long and SPE vectors are aligned in the registers.
9450 As are any other 2 gpr item such as complex int due to a
9451 historical mistake. */
9453 if (n_reg == 2 && reg == gpr)
9456 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9457 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9458 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9459 unshare_expr (reg), u);
9461 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9462 reg number is 0 for f1, so we want to make it odd. */
9463 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9465 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9466 build_int_cst (TREE_TYPE (reg), 1));
9467 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9470 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9471 t = build2 (GE_EXPR, boolean_type_node, u, t);
9472 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9473 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9474 gimplify_and_add (t, pre_p);
9478 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9480 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9481 build_int_cst (TREE_TYPE (reg), n_reg));
9482 u = fold_convert (sizetype, u);
9483 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9484 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9486 /* _Decimal32 varargs are located in the second word of the 64-bit
9487 FP register for 32-bit binaries. */
9488 if (!TARGET_POWERPC64
9489 && TARGET_HARD_FLOAT && TARGET_FPRS
9490 && TYPE_MODE (type) == SDmode)
9491 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9493 gimplify_assign (addr, t, pre_p);
9495 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9497 stmt = gimple_build_label (lab_false);
9498 gimple_seq_add_stmt (pre_p, stmt);
9500 if ((n_reg == 2 && !regalign) || n_reg > 2)
9502 /* Ensure that we don't find any more args in regs.
9503 Alignment has taken care of for special cases. */
9504 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9508 /* ... otherwise out of the overflow area. */
9510 /* Care for on-stack alignment if needed. */
9514 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9515 t = fold_convert (sizetype, t);
9516 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9518 t = fold_convert (TREE_TYPE (ovf), t);
9520 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9522 gimplify_assign (unshare_expr (addr), t, pre_p);
9524 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9525 gimplify_assign (unshare_expr (ovf), t, pre_p);
9529 stmt = gimple_build_label (lab_over);
9530 gimple_seq_add_stmt (pre_p, stmt);
9533 if (STRICT_ALIGNMENT
9534 && (TYPE_ALIGN (type)
9535 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9537 /* The value (of type complex double, for example) may not be
9538 aligned in memory in the saved registers, so copy via a
9539 temporary. (This is the same code as used for SPARC.) */
9540 tree tmp = create_tmp_var (type, "va_arg_tmp");
9541 tree dest_addr = build_fold_addr_expr (tmp);
9543 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9544 3, dest_addr, addr, size_int (rsize * 4));
9546 gimplify_and_add (copy, pre_p);
9550 addr = fold_convert (ptrtype, addr);
9551 return build_va_arg_indirect_ref (addr);
9557 def_builtin (int mask, const char *name, tree type, int code)
9559 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9562 if (rs6000_builtin_decls[code])
9563 fatal_error ("internal error: builtin function to %s already processed.",
9566 rs6000_builtin_decls[code] = t =
9567 add_builtin_function (name, type, code, BUILT_IN_MD,
9570 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9571 switch (builtin_classify[code])
9576 /* assume builtin can do anything. */
9577 case RS6000_BTC_MISC:
9580 /* const function, function only depends on the inputs. */
9581 case RS6000_BTC_CONST:
9582 TREE_READONLY (t) = 1;
9583 TREE_NOTHROW (t) = 1;
9586 /* pure function, function can read global memory. */
9587 case RS6000_BTC_PURE:
9588 DECL_PURE_P (t) = 1;
9589 TREE_NOTHROW (t) = 1;
9592 /* Function is a math function. If rounding mode is on, then treat
9593 the function as not reading global memory, but it can have
9594 arbitrary side effects. If it is off, then assume the function is
9595 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9596 attribute in builtin-attribute.def that is used for the math
9598 case RS6000_BTC_FP_PURE:
9599 TREE_NOTHROW (t) = 1;
9600 if (flag_rounding_math)
9602 DECL_PURE_P (t) = 1;
9603 DECL_IS_NOVOPS (t) = 1;
9606 TREE_READONLY (t) = 1;
9612 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9614 static const struct builtin_description bdesc_3arg[] =
9616 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9617 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9618 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9619 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9620 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9621 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9622 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9623 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9624 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9633 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9634 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9635 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9636 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9637 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9638 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9639 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9640 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9641 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9642 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9643 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9644 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9645 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9646 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9647 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9648 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9649 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9650 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9652 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9653 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9654 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9655 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9656 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9657 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9658 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9659 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9660 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9663 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9664 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9665 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9666 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9668 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9669 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9670 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9671 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9673 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9674 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9675 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9676 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9678 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9679 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9681 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9682 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9683 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9684 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9685 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9686 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9687 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9688 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9689 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9690 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9692 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9693 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9694 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9695 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9696 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9697 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9698 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9699 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9700 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9701 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9703 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9704 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9705 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9706 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9707 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9708 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9709 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9710 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9711 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9713 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9714 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9715 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9716 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9717 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9718 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9719 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9721 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9722 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9723 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9724 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9725 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9726 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9727 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9728 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9729 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9732 /* DST operations: void foo (void *, const int, const char). */
9734 static const struct builtin_description bdesc_dst[] =
9736 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9737 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9738 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9739 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9747 /* Simple binary operations: VECc = foo (VECa, VECb). */
9749 static struct builtin_description bdesc_2arg[] =
9751 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9752 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9753 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9754 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9755 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9756 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9757 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9758 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9759 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9760 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9761 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9762 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9763 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9764 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9765 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9766 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9767 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9769 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9770 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9771 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9772 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9773 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9774 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9775 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9776 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9777 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9778 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9779 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9780 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9781 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9782 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9783 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9784 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9785 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9786 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9787 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9788 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9789 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9790 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9791 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9792 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9793 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9794 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9795 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9796 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9797 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9798 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9799 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9800 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9801 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9802 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9803 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9804 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9805 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9806 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9807 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9808 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9809 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9810 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9811 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9812 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9813 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9814 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9815 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9816 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9817 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9818 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9819 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9820 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9821 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9822 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9823 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9824 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9825 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9826 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9827 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9828 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9829 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9830 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9831 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9832 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9833 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9834 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9835 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9836 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9837 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9838 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9839 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9840 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9841 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9842 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9843 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9844 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9845 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9846 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9847 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9848 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9849 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9850 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9851 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9852 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9853 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9854 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9855 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9856 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9857 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9858 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9859 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9860 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9861 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9862 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9863 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9864 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9865 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9866 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9867 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9869 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9870 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9871 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9872 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9873 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9874 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9875 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9876 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9877 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9878 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9879 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9880 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9882 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9883 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9884 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9885 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9886 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9887 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9888 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9889 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9890 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9891 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9892 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9893 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9895 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9896 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9897 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9898 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9899 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9900 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9902 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9903 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9904 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9905 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9906 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9907 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9908 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9909 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9910 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9911 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9912 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9913 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9915 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9916 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9928 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9929 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9955 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9956 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9971 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9972 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9980 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9981 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9989 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9990 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10024 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10025 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10043 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10045 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10046 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10048 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10049 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10050 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10051 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10052 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10053 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10054 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10055 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10056 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10057 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10059 /* Place holder, leave as first spe builtin. */
10060 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10061 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10062 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10063 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10064 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10065 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10066 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10067 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10068 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10069 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10070 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10071 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10072 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10073 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10074 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10075 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10076 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10077 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10078 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10079 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10080 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10081 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10082 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10083 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10084 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10085 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10086 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10087 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10088 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10089 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10090 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10091 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10092 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10093 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10094 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10095 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10096 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10097 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10098 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10099 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10100 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10101 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10102 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10103 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10104 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10105 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10106 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10107 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10108 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10109 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10110 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10111 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10112 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10113 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10114 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10115 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10116 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10117 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10118 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10119 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10120 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10121 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10122 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10123 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10124 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10125 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10126 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10127 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10128 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10129 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10130 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10131 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10132 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10133 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10134 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10135 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10136 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10137 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10138 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10139 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10140 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10141 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10142 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10143 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10144 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10145 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10146 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10147 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10148 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10149 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10150 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10151 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10152 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10153 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10154 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10155 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10156 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10157 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10158 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10159 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10160 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10161 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10162 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10163 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10164 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10165 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10166 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10167 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10168 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10170 /* SPE binary operations expecting a 5-bit unsigned literal. */
10171 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10173 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10174 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10175 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10176 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10177 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10178 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10179 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10180 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10181 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10182 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10183 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10184 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10185 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10186 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10187 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10188 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10189 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10190 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10191 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10192 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10193 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10194 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10195 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10196 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10197 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10198 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10200 /* Place-holder. Leave as last binary SPE builtin. */
10201 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10204 /* AltiVec predicates. */
10206 struct builtin_description_predicates
10208 const unsigned int mask;
10209 const enum insn_code icode;
10210 const char *const name;
10211 const enum rs6000_builtins code;
10214 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10216 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10217 ALTIVEC_BUILTIN_VCMPBFP_P },
10218 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10219 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10220 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10221 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10222 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10223 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10224 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10225 ALTIVEC_BUILTIN_VCMPEQUW_P },
10226 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10227 ALTIVEC_BUILTIN_VCMPGTSW_P },
10228 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10229 ALTIVEC_BUILTIN_VCMPGTUW_P },
10230 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10231 ALTIVEC_BUILTIN_VCMPEQUH_P },
10232 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10233 ALTIVEC_BUILTIN_VCMPGTSH_P },
10234 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10235 ALTIVEC_BUILTIN_VCMPGTUH_P },
10236 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10237 ALTIVEC_BUILTIN_VCMPEQUB_P },
10238 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10239 ALTIVEC_BUILTIN_VCMPGTSB_P },
10240 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10241 ALTIVEC_BUILTIN_VCMPGTUB_P },
10243 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10244 VSX_BUILTIN_XVCMPEQSP_P },
10245 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10246 VSX_BUILTIN_XVCMPGESP_P },
10247 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10248 VSX_BUILTIN_XVCMPGTSP_P },
10249 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10250 VSX_BUILTIN_XVCMPEQDP_P },
10251 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10252 VSX_BUILTIN_XVCMPGEDP_P },
10253 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10254 VSX_BUILTIN_XVCMPGTDP_P },
10256 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10257 ALTIVEC_BUILTIN_VCMPEQ_P },
10258 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10259 ALTIVEC_BUILTIN_VCMPGT_P },
10260 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10261 ALTIVEC_BUILTIN_VCMPGE_P }
10264 /* SPE predicates. */
10265 static struct builtin_description bdesc_spe_predicates[] =
10267 /* Place-holder. Leave as first. */
10268 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10269 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10270 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10271 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10272 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10273 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10274 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10275 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10276 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10277 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10278 /* Place-holder. Leave as last. */
10279 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10282 /* SPE evsel predicates. */
10283 static struct builtin_description bdesc_spe_evsel[] =
10285 /* Place-holder. Leave as first. */
10286 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10287 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10288 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10289 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10290 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10291 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10292 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10293 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10294 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10295 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10296 /* Place-holder. Leave as last. */
10297 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10300 /* PAIRED predicates. */
10301 static const struct builtin_description bdesc_paired_preds[] =
10303 /* Place-holder. Leave as first. */
10304 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10305 /* Place-holder. Leave as last. */
10306 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10309 /* ABS* operations. */
10311 static const struct builtin_description bdesc_abs[] =
10313 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10314 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10315 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10316 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10317 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10318 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10319 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10320 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10321 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10322 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10323 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10326 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10329 static struct builtin_description bdesc_1arg[] =
10331 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10332 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10333 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10334 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10335 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10336 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10337 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10338 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10339 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10340 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10341 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10342 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10343 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10344 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10345 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10346 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10347 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10348 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10350 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10351 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10352 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10353 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10354 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10355 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10356 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10358 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10359 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10360 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10361 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10362 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10363 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10364 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10366 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10367 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10368 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10369 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10370 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10371 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10373 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10374 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10375 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10376 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10377 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10378 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10380 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10381 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10382 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10383 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10385 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10386 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10387 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10388 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10389 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10390 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10391 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10392 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10393 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10395 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10396 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10397 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10398 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10399 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10400 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10401 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10402 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10403 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10405 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10406 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10407 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10408 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10409 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10432 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10433 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10434 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10436 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10437 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10438 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10439 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10441 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10442 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10443 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10444 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10445 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10446 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10447 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10448 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10449 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10450 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10451 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10452 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10453 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10454 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10455 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10456 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10457 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10458 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10459 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10460 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10461 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10462 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10463 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10464 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10465 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10466 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10467 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10468 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10469 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10470 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10472 /* Place-holder. Leave as last unary SPE builtin. */
10473 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10475 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10476 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10477 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10478 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10479 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10483 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10486 tree arg0 = CALL_EXPR_ARG (exp, 0);
10487 rtx op0 = expand_normal (arg0);
10488 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10489 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10491 if (icode == CODE_FOR_nothing)
10492 /* Builtin not supported on this processor. */
10495 /* If we got invalid arguments bail out before generating bad rtl. */
10496 if (arg0 == error_mark_node)
10499 if (icode == CODE_FOR_altivec_vspltisb
10500 || icode == CODE_FOR_altivec_vspltish
10501 || icode == CODE_FOR_altivec_vspltisw
10502 || icode == CODE_FOR_spe_evsplatfi
10503 || icode == CODE_FOR_spe_evsplati)
10505 /* Only allow 5-bit *signed* literals. */
10506 if (GET_CODE (op0) != CONST_INT
10507 || INTVAL (op0) > 15
10508 || INTVAL (op0) < -16)
10510 error ("argument 1 must be a 5-bit signed literal");
10516 || GET_MODE (target) != tmode
10517 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10518 target = gen_reg_rtx (tmode);
10520 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10521 op0 = copy_to_mode_reg (mode0, op0);
10523 pat = GEN_FCN (icode) (target, op0);
10532 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10534 rtx pat, scratch1, scratch2;
10535 tree arg0 = CALL_EXPR_ARG (exp, 0);
10536 rtx op0 = expand_normal (arg0);
10537 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10538 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10540 /* If we have invalid arguments, bail out before generating bad rtl. */
10541 if (arg0 == error_mark_node)
10545 || GET_MODE (target) != tmode
10546 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10547 target = gen_reg_rtx (tmode);
10549 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10550 op0 = copy_to_mode_reg (mode0, op0);
10552 scratch1 = gen_reg_rtx (mode0);
10553 scratch2 = gen_reg_rtx (mode0);
10555 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10564 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10567 tree arg0 = CALL_EXPR_ARG (exp, 0);
10568 tree arg1 = CALL_EXPR_ARG (exp, 1);
10569 rtx op0 = expand_normal (arg0);
10570 rtx op1 = expand_normal (arg1);
10571 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10572 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10573 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10575 if (icode == CODE_FOR_nothing)
10576 /* Builtin not supported on this processor. */
10579 /* If we got invalid arguments bail out before generating bad rtl. */
10580 if (arg0 == error_mark_node || arg1 == error_mark_node)
10583 if (icode == CODE_FOR_altivec_vcfux
10584 || icode == CODE_FOR_altivec_vcfsx
10585 || icode == CODE_FOR_altivec_vctsxs
10586 || icode == CODE_FOR_altivec_vctuxs
10587 || icode == CODE_FOR_altivec_vspltb
10588 || icode == CODE_FOR_altivec_vsplth
10589 || icode == CODE_FOR_altivec_vspltw
10590 || icode == CODE_FOR_spe_evaddiw
10591 || icode == CODE_FOR_spe_evldd
10592 || icode == CODE_FOR_spe_evldh
10593 || icode == CODE_FOR_spe_evldw
10594 || icode == CODE_FOR_spe_evlhhesplat
10595 || icode == CODE_FOR_spe_evlhhossplat
10596 || icode == CODE_FOR_spe_evlhhousplat
10597 || icode == CODE_FOR_spe_evlwhe
10598 || icode == CODE_FOR_spe_evlwhos
10599 || icode == CODE_FOR_spe_evlwhou
10600 || icode == CODE_FOR_spe_evlwhsplat
10601 || icode == CODE_FOR_spe_evlwwsplat
10602 || icode == CODE_FOR_spe_evrlwi
10603 || icode == CODE_FOR_spe_evslwi
10604 || icode == CODE_FOR_spe_evsrwis
10605 || icode == CODE_FOR_spe_evsubifw
10606 || icode == CODE_FOR_spe_evsrwiu)
10608 /* Only allow 5-bit unsigned literals. */
10610 if (TREE_CODE (arg1) != INTEGER_CST
10611 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10613 error ("argument 2 must be a 5-bit unsigned literal");
10619 || GET_MODE (target) != tmode
10620 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10621 target = gen_reg_rtx (tmode);
10623 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10624 op0 = copy_to_mode_reg (mode0, op0);
10625 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10626 op1 = copy_to_mode_reg (mode1, op1);
10628 pat = GEN_FCN (icode) (target, op0, op1);
10637 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10640 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10641 tree arg0 = CALL_EXPR_ARG (exp, 1);
10642 tree arg1 = CALL_EXPR_ARG (exp, 2);
10643 rtx op0 = expand_normal (arg0);
10644 rtx op1 = expand_normal (arg1);
10645 enum machine_mode tmode = SImode;
10646 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10647 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10650 if (TREE_CODE (cr6_form) != INTEGER_CST)
10652 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10656 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10658 gcc_assert (mode0 == mode1);
10660 /* If we have invalid arguments, bail out before generating bad rtl. */
10661 if (arg0 == error_mark_node || arg1 == error_mark_node)
10665 || GET_MODE (target) != tmode
10666 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10667 target = gen_reg_rtx (tmode);
10669 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10670 op0 = copy_to_mode_reg (mode0, op0);
10671 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10672 op1 = copy_to_mode_reg (mode1, op1);
10674 scratch = gen_reg_rtx (mode0);
10676 pat = GEN_FCN (icode) (scratch, op0, op1);
10681 /* The vec_any* and vec_all* predicates use the same opcodes for two
10682 different operations, but the bits in CR6 will be different
10683 depending on what information we want. So we have to play tricks
10684 with CR6 to get the right bits out.
10686 If you think this is disgusting, look at the specs for the
10687 AltiVec predicates. */
10689 switch (cr6_form_int)
10692 emit_insn (gen_cr6_test_for_zero (target));
10695 emit_insn (gen_cr6_test_for_zero_reverse (target));
10698 emit_insn (gen_cr6_test_for_lt (target));
10701 emit_insn (gen_cr6_test_for_lt_reverse (target));
10704 error ("argument 1 of __builtin_altivec_predicate is out of range");
10712 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10715 tree arg0 = CALL_EXPR_ARG (exp, 0);
10716 tree arg1 = CALL_EXPR_ARG (exp, 1);
10717 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10718 enum machine_mode mode0 = Pmode;
10719 enum machine_mode mode1 = Pmode;
10720 rtx op0 = expand_normal (arg0);
10721 rtx op1 = expand_normal (arg1);
10723 if (icode == CODE_FOR_nothing)
10724 /* Builtin not supported on this processor. */
10727 /* If we got invalid arguments bail out before generating bad rtl. */
10728 if (arg0 == error_mark_node || arg1 == error_mark_node)
10732 || GET_MODE (target) != tmode
10733 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10734 target = gen_reg_rtx (tmode);
10736 op1 = copy_to_mode_reg (mode1, op1);
10738 if (op0 == const0_rtx)
10740 addr = gen_rtx_MEM (tmode, op1);
10744 op0 = copy_to_mode_reg (mode0, op0);
10745 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10748 pat = GEN_FCN (icode) (target, addr);
10758 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10761 tree arg0 = CALL_EXPR_ARG (exp, 0);
10762 tree arg1 = CALL_EXPR_ARG (exp, 1);
10763 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10764 enum machine_mode mode0 = Pmode;
10765 enum machine_mode mode1 = Pmode;
10766 rtx op0 = expand_normal (arg0);
10767 rtx op1 = expand_normal (arg1);
10769 if (icode == CODE_FOR_nothing)
10770 /* Builtin not supported on this processor. */
10773 /* If we got invalid arguments bail out before generating bad rtl. */
10774 if (arg0 == error_mark_node || arg1 == error_mark_node)
10778 || GET_MODE (target) != tmode
10779 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10780 target = gen_reg_rtx (tmode);
10782 op1 = copy_to_mode_reg (mode1, op1);
10784 if (op0 == const0_rtx)
10786 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10790 op0 = copy_to_mode_reg (mode0, op0);
10791 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10794 pat = GEN_FCN (icode) (target, addr);
10804 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10806 tree arg0 = CALL_EXPR_ARG (exp, 0);
10807 tree arg1 = CALL_EXPR_ARG (exp, 1);
10808 tree arg2 = CALL_EXPR_ARG (exp, 2);
10809 rtx op0 = expand_normal (arg0);
10810 rtx op1 = expand_normal (arg1);
10811 rtx op2 = expand_normal (arg2);
10813 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10814 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10815 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10817 /* Invalid arguments. Bail before doing anything stoopid! */
10818 if (arg0 == error_mark_node
10819 || arg1 == error_mark_node
10820 || arg2 == error_mark_node)
10823 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10824 op0 = copy_to_mode_reg (mode2, op0);
10825 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10826 op1 = copy_to_mode_reg (mode0, op1);
10827 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10828 op2 = copy_to_mode_reg (mode1, op2);
10830 pat = GEN_FCN (icode) (op1, op2, op0);
10837 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10839 tree arg0 = CALL_EXPR_ARG (exp, 0);
10840 tree arg1 = CALL_EXPR_ARG (exp, 1);
10841 tree arg2 = CALL_EXPR_ARG (exp, 2);
10842 rtx op0 = expand_normal (arg0);
10843 rtx op1 = expand_normal (arg1);
10844 rtx op2 = expand_normal (arg2);
10846 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10847 enum machine_mode mode1 = Pmode;
10848 enum machine_mode mode2 = Pmode;
10850 /* Invalid arguments. Bail before doing anything stoopid! */
10851 if (arg0 == error_mark_node
10852 || arg1 == error_mark_node
10853 || arg2 == error_mark_node)
10856 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10857 op0 = copy_to_mode_reg (tmode, op0);
10859 op2 = copy_to_mode_reg (mode2, op2);
10861 if (op1 == const0_rtx)
10863 addr = gen_rtx_MEM (tmode, op2);
10867 op1 = copy_to_mode_reg (mode1, op1);
10868 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10871 pat = GEN_FCN (icode) (addr, op0);
10878 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10880 tree arg0 = CALL_EXPR_ARG (exp, 0);
10881 tree arg1 = CALL_EXPR_ARG (exp, 1);
10882 tree arg2 = CALL_EXPR_ARG (exp, 2);
10883 rtx op0 = expand_normal (arg0);
10884 rtx op1 = expand_normal (arg1);
10885 rtx op2 = expand_normal (arg2);
10887 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10888 enum machine_mode mode1 = Pmode;
10889 enum machine_mode mode2 = Pmode;
10891 /* Invalid arguments. Bail before doing anything stoopid! */
10892 if (arg0 == error_mark_node
10893 || arg1 == error_mark_node
10894 || arg2 == error_mark_node)
10897 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10898 op0 = copy_to_mode_reg (tmode, op0);
10900 op2 = copy_to_mode_reg (mode2, op2);
10902 if (op1 == const0_rtx)
10904 addr = gen_rtx_MEM (tmode, op2);
10908 op1 = copy_to_mode_reg (mode1, op1);
10909 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10912 pat = GEN_FCN (icode) (addr, op0);
10919 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10922 tree arg0 = CALL_EXPR_ARG (exp, 0);
10923 tree arg1 = CALL_EXPR_ARG (exp, 1);
10924 tree arg2 = CALL_EXPR_ARG (exp, 2);
10925 rtx op0 = expand_normal (arg0);
10926 rtx op1 = expand_normal (arg1);
10927 rtx op2 = expand_normal (arg2);
10928 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10929 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10930 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10931 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10933 if (icode == CODE_FOR_nothing)
10934 /* Builtin not supported on this processor. */
10937 /* If we got invalid arguments bail out before generating bad rtl. */
10938 if (arg0 == error_mark_node
10939 || arg1 == error_mark_node
10940 || arg2 == error_mark_node)
10945 case CODE_FOR_altivec_vsldoi_v4sf:
10946 case CODE_FOR_altivec_vsldoi_v4si:
10947 case CODE_FOR_altivec_vsldoi_v8hi:
10948 case CODE_FOR_altivec_vsldoi_v16qi:
10949 /* Only allow 4-bit unsigned literals. */
10951 if (TREE_CODE (arg2) != INTEGER_CST
10952 || TREE_INT_CST_LOW (arg2) & ~0xf)
10954 error ("argument 3 must be a 4-bit unsigned literal");
10959 case CODE_FOR_vsx_xxpermdi_v2df:
10960 case CODE_FOR_vsx_xxpermdi_v2di:
10961 case CODE_FOR_vsx_xxsldwi_v16qi:
10962 case CODE_FOR_vsx_xxsldwi_v8hi:
10963 case CODE_FOR_vsx_xxsldwi_v4si:
10964 case CODE_FOR_vsx_xxsldwi_v4sf:
10965 case CODE_FOR_vsx_xxsldwi_v2di:
10966 case CODE_FOR_vsx_xxsldwi_v2df:
10967 /* Only allow 2-bit unsigned literals. */
10969 if (TREE_CODE (arg2) != INTEGER_CST
10970 || TREE_INT_CST_LOW (arg2) & ~0x3)
10972 error ("argument 3 must be a 2-bit unsigned literal");
10977 case CODE_FOR_vsx_set_v2df:
10978 case CODE_FOR_vsx_set_v2di:
10979 /* Only allow 1-bit unsigned literals. */
10981 if (TREE_CODE (arg2) != INTEGER_CST
10982 || TREE_INT_CST_LOW (arg2) & ~0x1)
10984 error ("argument 3 must be a 1-bit unsigned literal");
10994 || GET_MODE (target) != tmode
10995 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10996 target = gen_reg_rtx (tmode);
10998 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10999 op0 = copy_to_mode_reg (mode0, op0);
11000 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11001 op1 = copy_to_mode_reg (mode1, op1);
11002 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11003 op2 = copy_to_mode_reg (mode2, op2);
11005 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11006 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11008 pat = GEN_FCN (icode) (target, op0, op1, op2);
11016 /* Expand the lvx builtins. */
11018 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11020 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11021 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11023 enum machine_mode tmode, mode0;
11025 enum insn_code icode;
11029 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11030 icode = CODE_FOR_vector_load_v16qi;
11032 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11033 icode = CODE_FOR_vector_load_v8hi;
11035 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11036 icode = CODE_FOR_vector_load_v4si;
11038 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11039 icode = CODE_FOR_vector_load_v4sf;
11042 *expandedp = false;
11048 arg0 = CALL_EXPR_ARG (exp, 0);
11049 op0 = expand_normal (arg0);
11050 tmode = insn_data[icode].operand[0].mode;
11051 mode0 = insn_data[icode].operand[1].mode;
11054 || GET_MODE (target) != tmode
11055 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11056 target = gen_reg_rtx (tmode);
11058 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11059 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11061 pat = GEN_FCN (icode) (target, op0);
11068 /* Expand the stvx builtins. */
11070 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11073 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11074 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11076 enum machine_mode mode0, mode1;
11078 enum insn_code icode;
11082 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11083 icode = CODE_FOR_vector_store_v16qi;
11085 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11086 icode = CODE_FOR_vector_store_v8hi;
11088 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11089 icode = CODE_FOR_vector_store_v4si;
11091 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11092 icode = CODE_FOR_vector_store_v4sf;
11095 *expandedp = false;
11099 arg0 = CALL_EXPR_ARG (exp, 0);
11100 arg1 = CALL_EXPR_ARG (exp, 1);
11101 op0 = expand_normal (arg0);
11102 op1 = expand_normal (arg1);
11103 mode0 = insn_data[icode].operand[0].mode;
11104 mode1 = insn_data[icode].operand[1].mode;
11106 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11107 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11108 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11109 op1 = copy_to_mode_reg (mode1, op1);
11111 pat = GEN_FCN (icode) (op0, op1);
11119 /* Expand the dst builtins. */
11121 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11124 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11125 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11126 tree arg0, arg1, arg2;
11127 enum machine_mode mode0, mode1;
11128 rtx pat, op0, op1, op2;
11129 const struct builtin_description *d;
11132 *expandedp = false;
11134 /* Handle DST variants. */
11136 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11137 if (d->code == fcode)
11139 arg0 = CALL_EXPR_ARG (exp, 0);
11140 arg1 = CALL_EXPR_ARG (exp, 1);
11141 arg2 = CALL_EXPR_ARG (exp, 2);
11142 op0 = expand_normal (arg0);
11143 op1 = expand_normal (arg1);
11144 op2 = expand_normal (arg2);
11145 mode0 = insn_data[d->icode].operand[0].mode;
11146 mode1 = insn_data[d->icode].operand[1].mode;
11148 /* Invalid arguments, bail out before generating bad rtl. */
11149 if (arg0 == error_mark_node
11150 || arg1 == error_mark_node
11151 || arg2 == error_mark_node)
11156 if (TREE_CODE (arg2) != INTEGER_CST
11157 || TREE_INT_CST_LOW (arg2) & ~0x3)
11159 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11163 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11164 op0 = copy_to_mode_reg (Pmode, op0);
11165 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11166 op1 = copy_to_mode_reg (mode1, op1);
11168 pat = GEN_FCN (d->icode) (op0, op1, op2);
11178 /* Expand vec_init builtin. */
11180 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11182 enum machine_mode tmode = TYPE_MODE (type);
11183 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11184 int i, n_elt = GET_MODE_NUNITS (tmode);
11185 rtvec v = rtvec_alloc (n_elt);
11187 gcc_assert (VECTOR_MODE_P (tmode));
11188 gcc_assert (n_elt == call_expr_nargs (exp));
11190 for (i = 0; i < n_elt; ++i)
11192 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11193 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11196 if (!target || !register_operand (target, tmode))
11197 target = gen_reg_rtx (tmode);
11199 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11203 /* Return the integer constant in ARG. Constrain it to be in the range
11204 of the subparts of VEC_TYPE; issue an error if not. */
11207 get_element_number (tree vec_type, tree arg)
11209 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11211 if (!host_integerp (arg, 1)
11212 || (elt = tree_low_cst (arg, 1), elt > max))
11214 error ("selector must be an integer constant in the range 0..%wi", max);
11221 /* Expand vec_set builtin. */
11223 altivec_expand_vec_set_builtin (tree exp)
11225 enum machine_mode tmode, mode1;
11226 tree arg0, arg1, arg2;
11230 arg0 = CALL_EXPR_ARG (exp, 0);
11231 arg1 = CALL_EXPR_ARG (exp, 1);
11232 arg2 = CALL_EXPR_ARG (exp, 2);
11234 tmode = TYPE_MODE (TREE_TYPE (arg0));
11235 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11236 gcc_assert (VECTOR_MODE_P (tmode));
11238 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11239 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11240 elt = get_element_number (TREE_TYPE (arg0), arg2);
11242 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11243 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11245 op0 = force_reg (tmode, op0);
11246 op1 = force_reg (mode1, op1);
11248 rs6000_expand_vector_set (op0, op1, elt);
11253 /* Expand vec_ext builtin. */
11255 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11257 enum machine_mode tmode, mode0;
11262 arg0 = CALL_EXPR_ARG (exp, 0);
11263 arg1 = CALL_EXPR_ARG (exp, 1);
11265 op0 = expand_normal (arg0);
11266 elt = get_element_number (TREE_TYPE (arg0), arg1);
11268 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11269 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11270 gcc_assert (VECTOR_MODE_P (mode0));
11272 op0 = force_reg (mode0, op0);
11274 if (optimize || !target || !register_operand (target, tmode))
11275 target = gen_reg_rtx (tmode);
11277 rs6000_expand_vector_extract (target, op0, elt);
11282 /* Expand the builtin in EXP and store the result in TARGET. Store
11283 true in *EXPANDEDP if we found a builtin to expand. */
11285 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11287 const struct builtin_description *d;
11288 const struct builtin_description_predicates *dp;
11290 enum insn_code icode;
11291 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11294 enum machine_mode tmode, mode0;
11295 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11297 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11298 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11299 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11300 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11303 error ("unresolved overload for Altivec builtin %qF", fndecl);
11307 target = altivec_expand_ld_builtin (exp, target, expandedp);
11311 target = altivec_expand_st_builtin (exp, target, expandedp);
11315 target = altivec_expand_dst_builtin (exp, target, expandedp);
11323 case ALTIVEC_BUILTIN_STVX:
11324 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11325 case ALTIVEC_BUILTIN_STVEBX:
11326 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11327 case ALTIVEC_BUILTIN_STVEHX:
11328 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11329 case ALTIVEC_BUILTIN_STVEWX:
11330 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11331 case ALTIVEC_BUILTIN_STVXL:
11332 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11334 case ALTIVEC_BUILTIN_STVLX:
11335 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11336 case ALTIVEC_BUILTIN_STVLXL:
11337 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11338 case ALTIVEC_BUILTIN_STVRX:
11339 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11340 case ALTIVEC_BUILTIN_STVRXL:
11341 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11343 case ALTIVEC_BUILTIN_MFVSCR:
11344 icode = CODE_FOR_altivec_mfvscr;
11345 tmode = insn_data[icode].operand[0].mode;
11348 || GET_MODE (target) != tmode
11349 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11350 target = gen_reg_rtx (tmode);
11352 pat = GEN_FCN (icode) (target);
11358 case ALTIVEC_BUILTIN_MTVSCR:
11359 icode = CODE_FOR_altivec_mtvscr;
11360 arg0 = CALL_EXPR_ARG (exp, 0);
11361 op0 = expand_normal (arg0);
11362 mode0 = insn_data[icode].operand[0].mode;
11364 /* If we got invalid arguments bail out before generating bad rtl. */
11365 if (arg0 == error_mark_node)
11368 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11369 op0 = copy_to_mode_reg (mode0, op0);
11371 pat = GEN_FCN (icode) (op0);
11376 case ALTIVEC_BUILTIN_DSSALL:
11377 emit_insn (gen_altivec_dssall ());
11380 case ALTIVEC_BUILTIN_DSS:
11381 icode = CODE_FOR_altivec_dss;
11382 arg0 = CALL_EXPR_ARG (exp, 0);
11384 op0 = expand_normal (arg0);
11385 mode0 = insn_data[icode].operand[0].mode;
11387 /* If we got invalid arguments bail out before generating bad rtl. */
11388 if (arg0 == error_mark_node)
11391 if (TREE_CODE (arg0) != INTEGER_CST
11392 || TREE_INT_CST_LOW (arg0) & ~0x3)
11394 error ("argument to dss must be a 2-bit unsigned literal");
11398 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11399 op0 = copy_to_mode_reg (mode0, op0);
11401 emit_insn (gen_altivec_dss (op0));
11404 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11405 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11406 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11407 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11408 case VSX_BUILTIN_VEC_INIT_V2DF:
11409 case VSX_BUILTIN_VEC_INIT_V2DI:
11410 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11412 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11413 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11414 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11415 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11416 case VSX_BUILTIN_VEC_SET_V2DF:
11417 case VSX_BUILTIN_VEC_SET_V2DI:
11418 return altivec_expand_vec_set_builtin (exp);
11420 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11421 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11422 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11423 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11424 case VSX_BUILTIN_VEC_EXT_V2DF:
11425 case VSX_BUILTIN_VEC_EXT_V2DI:
11426 return altivec_expand_vec_ext_builtin (exp, target);
11430 /* Fall through. */
11433 /* Expand abs* operations. */
11435 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11436 if (d->code == fcode)
11437 return altivec_expand_abs_builtin (d->icode, exp, target);
11439 /* Expand the AltiVec predicates. */
11440 dp = bdesc_altivec_preds;
11441 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11442 if (dp->code == fcode)
11443 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11445 /* LV* are funky. We initialized them differently. */
11448 case ALTIVEC_BUILTIN_LVSL:
11449 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11450 exp, target, false);
11451 case ALTIVEC_BUILTIN_LVSR:
11452 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11453 exp, target, false);
11454 case ALTIVEC_BUILTIN_LVEBX:
11455 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11456 exp, target, false);
11457 case ALTIVEC_BUILTIN_LVEHX:
11458 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11459 exp, target, false);
11460 case ALTIVEC_BUILTIN_LVEWX:
11461 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11462 exp, target, false);
11463 case ALTIVEC_BUILTIN_LVXL:
11464 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11465 exp, target, false);
11466 case ALTIVEC_BUILTIN_LVX:
11467 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11468 exp, target, false);
11469 case ALTIVEC_BUILTIN_LVLX:
11470 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11471 exp, target, true);
11472 case ALTIVEC_BUILTIN_LVLXL:
11473 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11474 exp, target, true);
11475 case ALTIVEC_BUILTIN_LVRX:
11476 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11477 exp, target, true);
11478 case ALTIVEC_BUILTIN_LVRXL:
11479 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11480 exp, target, true);
11483 /* Fall through. */
11486 *expandedp = false;
11490 /* Expand the builtin in EXP and store the result in TARGET. Store
11491 true in *EXPANDEDP if we found a builtin to expand. */
11493 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11495 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11496 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11497 const struct builtin_description *d;
11504 case PAIRED_BUILTIN_STX:
11505 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11506 case PAIRED_BUILTIN_LX:
11507 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11510 /* Fall through. */
11513 /* Expand the paired predicates. */
11514 d = bdesc_paired_preds;
11515 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11516 if (d->code == fcode)
11517 return paired_expand_predicate_builtin (d->icode, exp, target);
11519 *expandedp = false;
11523 /* Binops that need to be initialized manually, but can be expanded
11524 automagically by rs6000_expand_binop_builtin. */
11525 static struct builtin_description bdesc_2arg_spe[] =
11527 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11528 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11529 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11530 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11531 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11532 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11533 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11534 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11535 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11536 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11537 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11538 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11539 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11540 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11541 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11542 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11543 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11544 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11545 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11546 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11547 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11548 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11551 /* Expand the builtin in EXP and store the result in TARGET. Store
11552 true in *EXPANDEDP if we found a builtin to expand.
11554 This expands the SPE builtins that are not simple unary and binary
11557 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11559 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11561 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11562 enum insn_code icode;
11563 enum machine_mode tmode, mode0;
11565 struct builtin_description *d;
11570 /* Syntax check for a 5-bit unsigned immediate. */
11573 case SPE_BUILTIN_EVSTDD:
11574 case SPE_BUILTIN_EVSTDH:
11575 case SPE_BUILTIN_EVSTDW:
11576 case SPE_BUILTIN_EVSTWHE:
11577 case SPE_BUILTIN_EVSTWHO:
11578 case SPE_BUILTIN_EVSTWWE:
11579 case SPE_BUILTIN_EVSTWWO:
11580 arg1 = CALL_EXPR_ARG (exp, 2);
11581 if (TREE_CODE (arg1) != INTEGER_CST
11582 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11584 error ("argument 2 must be a 5-bit unsigned literal");
11592 /* The evsplat*i instructions are not quite generic. */
11595 case SPE_BUILTIN_EVSPLATFI:
11596 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11598 case SPE_BUILTIN_EVSPLATI:
11599 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11605 d = (struct builtin_description *) bdesc_2arg_spe;
11606 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11607 if (d->code == fcode)
11608 return rs6000_expand_binop_builtin (d->icode, exp, target);
11610 d = (struct builtin_description *) bdesc_spe_predicates;
11611 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11612 if (d->code == fcode)
11613 return spe_expand_predicate_builtin (d->icode, exp, target);
11615 d = (struct builtin_description *) bdesc_spe_evsel;
11616 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11617 if (d->code == fcode)
11618 return spe_expand_evsel_builtin (d->icode, exp, target);
11622 case SPE_BUILTIN_EVSTDDX:
11623 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11624 case SPE_BUILTIN_EVSTDHX:
11625 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11626 case SPE_BUILTIN_EVSTDWX:
11627 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11628 case SPE_BUILTIN_EVSTWHEX:
11629 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11630 case SPE_BUILTIN_EVSTWHOX:
11631 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11632 case SPE_BUILTIN_EVSTWWEX:
11633 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11634 case SPE_BUILTIN_EVSTWWOX:
11635 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11636 case SPE_BUILTIN_EVSTDD:
11637 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11638 case SPE_BUILTIN_EVSTDH:
11639 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11640 case SPE_BUILTIN_EVSTDW:
11641 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11642 case SPE_BUILTIN_EVSTWHE:
11643 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11644 case SPE_BUILTIN_EVSTWHO:
11645 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11646 case SPE_BUILTIN_EVSTWWE:
11647 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11648 case SPE_BUILTIN_EVSTWWO:
11649 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11650 case SPE_BUILTIN_MFSPEFSCR:
11651 icode = CODE_FOR_spe_mfspefscr;
11652 tmode = insn_data[icode].operand[0].mode;
11655 || GET_MODE (target) != tmode
11656 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11657 target = gen_reg_rtx (tmode);
11659 pat = GEN_FCN (icode) (target);
11664 case SPE_BUILTIN_MTSPEFSCR:
11665 icode = CODE_FOR_spe_mtspefscr;
11666 arg0 = CALL_EXPR_ARG (exp, 0);
11667 op0 = expand_normal (arg0);
11668 mode0 = insn_data[icode].operand[0].mode;
11670 if (arg0 == error_mark_node)
11673 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11674 op0 = copy_to_mode_reg (mode0, op0);
11676 pat = GEN_FCN (icode) (op0);
11684 *expandedp = false;
11689 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11691 rtx pat, scratch, tmp;
11692 tree form = CALL_EXPR_ARG (exp, 0);
11693 tree arg0 = CALL_EXPR_ARG (exp, 1);
11694 tree arg1 = CALL_EXPR_ARG (exp, 2);
11695 rtx op0 = expand_normal (arg0);
11696 rtx op1 = expand_normal (arg1);
11697 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11698 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11700 enum rtx_code code;
11702 if (TREE_CODE (form) != INTEGER_CST)
11704 error ("argument 1 of __builtin_paired_predicate must be a constant");
11708 form_int = TREE_INT_CST_LOW (form);
11710 gcc_assert (mode0 == mode1);
11712 if (arg0 == error_mark_node || arg1 == error_mark_node)
11716 || GET_MODE (target) != SImode
11717 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11718 target = gen_reg_rtx (SImode);
11719 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11720 op0 = copy_to_mode_reg (mode0, op0);
11721 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11722 op1 = copy_to_mode_reg (mode1, op1);
11724 scratch = gen_reg_rtx (CCFPmode);
11726 pat = GEN_FCN (icode) (scratch, op0, op1);
11748 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11751 error ("argument 1 of __builtin_paired_predicate is out of range");
11755 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11756 emit_move_insn (target, tmp);
11761 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11763 rtx pat, scratch, tmp;
11764 tree form = CALL_EXPR_ARG (exp, 0);
11765 tree arg0 = CALL_EXPR_ARG (exp, 1);
11766 tree arg1 = CALL_EXPR_ARG (exp, 2);
11767 rtx op0 = expand_normal (arg0);
11768 rtx op1 = expand_normal (arg1);
11769 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11770 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11772 enum rtx_code code;
11774 if (TREE_CODE (form) != INTEGER_CST)
11776 error ("argument 1 of __builtin_spe_predicate must be a constant");
11780 form_int = TREE_INT_CST_LOW (form);
11782 gcc_assert (mode0 == mode1);
11784 if (arg0 == error_mark_node || arg1 == error_mark_node)
11788 || GET_MODE (target) != SImode
11789 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11790 target = gen_reg_rtx (SImode);
11792 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11793 op0 = copy_to_mode_reg (mode0, op0);
11794 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11795 op1 = copy_to_mode_reg (mode1, op1);
11797 scratch = gen_reg_rtx (CCmode);
11799 pat = GEN_FCN (icode) (scratch, op0, op1);
11804 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11805 _lower_. We use one compare, but look in different bits of the
11806 CR for each variant.
11808 There are 2 elements in each SPE simd type (upper/lower). The CR
11809 bits are set as follows:
11811 BIT0 | BIT 1 | BIT 2 | BIT 3
11812 U | L | (U | L) | (U & L)
11814 So, for an "all" relationship, BIT 3 would be set.
11815 For an "any" relationship, BIT 2 would be set. Etc.
11817 Following traditional nomenclature, these bits map to:
11819 BIT0 | BIT 1 | BIT 2 | BIT 3
11822 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11827 /* All variant. OV bit. */
11829 /* We need to get to the OV bit, which is the ORDERED bit. We
11830 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11831 that's ugly and will make validate_condition_mode die.
11832 So let's just use another pattern. */
11833 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11835 /* Any variant. EQ bit. */
11839 /* Upper variant. LT bit. */
11843 /* Lower variant. GT bit. */
11848 error ("argument 1 of __builtin_spe_predicate is out of range");
11852 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11853 emit_move_insn (target, tmp);
11858 /* The evsel builtins look like this:
11860 e = __builtin_spe_evsel_OP (a, b, c, d);
11862 and work like this:
11864 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11865 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11869 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11872 tree arg0 = CALL_EXPR_ARG (exp, 0);
11873 tree arg1 = CALL_EXPR_ARG (exp, 1);
11874 tree arg2 = CALL_EXPR_ARG (exp, 2);
11875 tree arg3 = CALL_EXPR_ARG (exp, 3);
11876 rtx op0 = expand_normal (arg0);
11877 rtx op1 = expand_normal (arg1);
11878 rtx op2 = expand_normal (arg2);
11879 rtx op3 = expand_normal (arg3);
11880 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11881 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11883 gcc_assert (mode0 == mode1);
11885 if (arg0 == error_mark_node || arg1 == error_mark_node
11886 || arg2 == error_mark_node || arg3 == error_mark_node)
11890 || GET_MODE (target) != mode0
11891 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11892 target = gen_reg_rtx (mode0);
11894 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11895 op0 = copy_to_mode_reg (mode0, op0);
11896 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11897 op1 = copy_to_mode_reg (mode0, op1);
11898 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11899 op2 = copy_to_mode_reg (mode0, op2);
11900 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11901 op3 = copy_to_mode_reg (mode0, op3);
11903 /* Generate the compare. */
11904 scratch = gen_reg_rtx (CCmode);
11905 pat = GEN_FCN (icode) (scratch, op0, op1);
11910 if (mode0 == V2SImode)
11911 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11913 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11918 /* Expand an expression EXP that calls a built-in function,
11919 with result going to TARGET if that's convenient
11920 (and in mode MODE if that's convenient).
11921 SUBTARGET may be used as the target for computing one of EXP's operands.
11922 IGNORE is nonzero if the value is to be ignored. */
11925 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11926 enum machine_mode mode ATTRIBUTE_UNUSED,
11927 int ignore ATTRIBUTE_UNUSED)
11929 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11930 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11931 const struct builtin_description *d;
11938 case RS6000_BUILTIN_RECIP:
11939 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11941 case RS6000_BUILTIN_RECIPF:
11942 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11944 case RS6000_BUILTIN_RSQRTF:
11945 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11947 case RS6000_BUILTIN_RSQRT:
11948 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11950 case RS6000_BUILTIN_BSWAP_HI:
11951 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11953 case POWER7_BUILTIN_BPERMD:
11954 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11955 ? CODE_FOR_bpermd_di
11956 : CODE_FOR_bpermd_si), exp, target);
11958 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11959 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11961 int icode = (int) CODE_FOR_altivec_lvsr;
11962 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11963 enum machine_mode mode = insn_data[icode].operand[1].mode;
11967 gcc_assert (TARGET_ALTIVEC);
11969 arg = CALL_EXPR_ARG (exp, 0);
11970 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11971 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11972 addr = memory_address (mode, op);
11973 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11977 /* For the load case need to negate the address. */
11978 op = gen_reg_rtx (GET_MODE (addr));
11979 emit_insn (gen_rtx_SET (VOIDmode, op,
11980 gen_rtx_NEG (GET_MODE (addr), addr)));
11982 op = gen_rtx_MEM (mode, op);
11985 || GET_MODE (target) != tmode
11986 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11987 target = gen_reg_rtx (tmode);
11989 /*pat = gen_altivec_lvsr (target, op);*/
11990 pat = GEN_FCN (icode) (target, op);
11998 case ALTIVEC_BUILTIN_VCFUX:
11999 case ALTIVEC_BUILTIN_VCFSX:
12000 case ALTIVEC_BUILTIN_VCTUXS:
12001 case ALTIVEC_BUILTIN_VCTSXS:
12002 /* FIXME: There's got to be a nicer way to handle this case than
12003 constructing a new CALL_EXPR. */
12004 if (call_expr_nargs (exp) == 1)
12006 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12007 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12015 if (TARGET_ALTIVEC)
12017 ret = altivec_expand_builtin (exp, target, &success);
12024 ret = spe_expand_builtin (exp, target, &success);
12029 if (TARGET_PAIRED_FLOAT)
12031 ret = paired_expand_builtin (exp, target, &success);
12037 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12039 /* Handle simple unary operations. */
12040 d = (struct builtin_description *) bdesc_1arg;
12041 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12042 if (d->code == fcode)
12043 return rs6000_expand_unop_builtin (d->icode, exp, target);
12045 /* Handle simple binary operations. */
12046 d = (struct builtin_description *) bdesc_2arg;
12047 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12048 if (d->code == fcode)
12049 return rs6000_expand_binop_builtin (d->icode, exp, target);
12051 /* Handle simple ternary operations. */
12053 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12054 if (d->code == fcode)
12055 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12057 gcc_unreachable ();
12061 rs6000_init_builtins (void)
12066 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12067 V2SF_type_node = build_vector_type (float_type_node, 2);
12068 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12069 V2DF_type_node = build_vector_type (double_type_node, 2);
12070 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12071 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12072 V4SF_type_node = build_vector_type (float_type_node, 4);
12073 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12074 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12076 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12077 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12078 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12079 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12081 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12082 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12083 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12084 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12086 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12087 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12088 'vector unsigned short'. */
12090 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12091 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12092 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12093 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12094 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12096 long_integer_type_internal_node = long_integer_type_node;
12097 long_unsigned_type_internal_node = long_unsigned_type_node;
12098 intQI_type_internal_node = intQI_type_node;
12099 uintQI_type_internal_node = unsigned_intQI_type_node;
12100 intHI_type_internal_node = intHI_type_node;
12101 uintHI_type_internal_node = unsigned_intHI_type_node;
12102 intSI_type_internal_node = intSI_type_node;
12103 uintSI_type_internal_node = unsigned_intSI_type_node;
12104 intDI_type_internal_node = intDI_type_node;
12105 uintDI_type_internal_node = unsigned_intDI_type_node;
12106 float_type_internal_node = float_type_node;
12107 double_type_internal_node = float_type_node;
12108 void_type_internal_node = void_type_node;
12110 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12112 builtin_mode_to_type[QImode][0] = integer_type_node;
12113 builtin_mode_to_type[HImode][0] = integer_type_node;
12114 builtin_mode_to_type[SImode][0] = intSI_type_node;
12115 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12116 builtin_mode_to_type[DImode][0] = intDI_type_node;
12117 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12118 builtin_mode_to_type[SFmode][0] = float_type_node;
12119 builtin_mode_to_type[DFmode][0] = double_type_node;
12120 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12121 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12122 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12123 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12124 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12125 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12126 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12127 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12128 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12129 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12130 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12131 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12132 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12134 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12135 get_identifier ("__bool char"),
12136 bool_char_type_node);
12137 TYPE_NAME (bool_char_type_node) = tdecl;
12138 (*lang_hooks.decls.pushdecl) (tdecl);
12139 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12140 get_identifier ("__bool short"),
12141 bool_short_type_node);
12142 TYPE_NAME (bool_short_type_node) = tdecl;
12143 (*lang_hooks.decls.pushdecl) (tdecl);
12144 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12145 get_identifier ("__bool int"),
12146 bool_int_type_node);
12147 TYPE_NAME (bool_int_type_node) = tdecl;
12148 (*lang_hooks.decls.pushdecl) (tdecl);
12149 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12151 TYPE_NAME (pixel_type_node) = tdecl;
12152 (*lang_hooks.decls.pushdecl) (tdecl);
12154 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12155 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12156 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12157 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12158 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12160 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12161 get_identifier ("__vector unsigned char"),
12162 unsigned_V16QI_type_node);
12163 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12164 (*lang_hooks.decls.pushdecl) (tdecl);
12165 tdecl = build_decl (BUILTINS_LOCATION,
12166 TYPE_DECL, get_identifier ("__vector signed char"),
12168 TYPE_NAME (V16QI_type_node) = tdecl;
12169 (*lang_hooks.decls.pushdecl) (tdecl);
12170 tdecl = build_decl (BUILTINS_LOCATION,
12171 TYPE_DECL, get_identifier ("__vector __bool char"),
12172 bool_V16QI_type_node);
12173 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12174 (*lang_hooks.decls.pushdecl) (tdecl);
12176 tdecl = build_decl (BUILTINS_LOCATION,
12177 TYPE_DECL, get_identifier ("__vector unsigned short"),
12178 unsigned_V8HI_type_node);
12179 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12180 (*lang_hooks.decls.pushdecl) (tdecl);
12181 tdecl = build_decl (BUILTINS_LOCATION,
12182 TYPE_DECL, get_identifier ("__vector signed short"),
12184 TYPE_NAME (V8HI_type_node) = tdecl;
12185 (*lang_hooks.decls.pushdecl) (tdecl);
12186 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12187 get_identifier ("__vector __bool short"),
12188 bool_V8HI_type_node);
12189 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12190 (*lang_hooks.decls.pushdecl) (tdecl);
12192 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12193 get_identifier ("__vector unsigned int"),
12194 unsigned_V4SI_type_node);
12195 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12196 (*lang_hooks.decls.pushdecl) (tdecl);
12197 tdecl = build_decl (BUILTINS_LOCATION,
12198 TYPE_DECL, get_identifier ("__vector signed int"),
12200 TYPE_NAME (V4SI_type_node) = tdecl;
12201 (*lang_hooks.decls.pushdecl) (tdecl);
12202 tdecl = build_decl (BUILTINS_LOCATION,
12203 TYPE_DECL, get_identifier ("__vector __bool int"),
12204 bool_V4SI_type_node);
12205 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12206 (*lang_hooks.decls.pushdecl) (tdecl);
12208 tdecl = build_decl (BUILTINS_LOCATION,
12209 TYPE_DECL, get_identifier ("__vector float"),
12211 TYPE_NAME (V4SF_type_node) = tdecl;
12212 (*lang_hooks.decls.pushdecl) (tdecl);
12213 tdecl = build_decl (BUILTINS_LOCATION,
12214 TYPE_DECL, get_identifier ("__vector __pixel"),
12215 pixel_V8HI_type_node);
12216 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12217 (*lang_hooks.decls.pushdecl) (tdecl);
12221 tdecl = build_decl (BUILTINS_LOCATION,
12222 TYPE_DECL, get_identifier ("__vector double"),
12224 TYPE_NAME (V2DF_type_node) = tdecl;
12225 (*lang_hooks.decls.pushdecl) (tdecl);
12227 tdecl = build_decl (BUILTINS_LOCATION,
12228 TYPE_DECL, get_identifier ("__vector long"),
12230 TYPE_NAME (V2DI_type_node) = tdecl;
12231 (*lang_hooks.decls.pushdecl) (tdecl);
12233 tdecl = build_decl (BUILTINS_LOCATION,
12234 TYPE_DECL, get_identifier ("__vector unsigned long"),
12235 unsigned_V2DI_type_node);
12236 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12237 (*lang_hooks.decls.pushdecl) (tdecl);
12239 tdecl = build_decl (BUILTINS_LOCATION,
12240 TYPE_DECL, get_identifier ("__vector __bool long"),
12241 bool_V2DI_type_node);
12242 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12243 (*lang_hooks.decls.pushdecl) (tdecl);
12246 if (TARGET_PAIRED_FLOAT)
12247 paired_init_builtins ();
12249 spe_init_builtins ();
12250 if (TARGET_ALTIVEC)
12251 altivec_init_builtins ();
12252 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12253 rs6000_common_init_builtins ();
12256 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12257 RS6000_BUILTIN_RECIP,
12258 "__builtin_recipdiv");
12259 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12260 RS6000_BUILTIN_RECIP);
12264 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12265 RS6000_BUILTIN_RECIPF,
12266 "__builtin_recipdivf");
12267 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12268 RS6000_BUILTIN_RECIPF);
12270 if (TARGET_FRSQRTE)
12272 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12273 RS6000_BUILTIN_RSQRT,
12274 "__builtin_rsqrt");
12275 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12276 RS6000_BUILTIN_RSQRT);
12278 if (TARGET_FRSQRTES)
12280 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12281 RS6000_BUILTIN_RSQRTF,
12282 "__builtin_rsqrtf");
12283 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12284 RS6000_BUILTIN_RSQRTF);
12286 if (TARGET_POPCNTD)
12288 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12289 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12290 POWER7_BUILTIN_BPERMD,
12291 "__builtin_bpermd");
12292 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12293 POWER7_BUILTIN_BPERMD);
12295 if (TARGET_POWERPC)
12297 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12298 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12299 unsigned_intHI_type_node,
12301 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12302 RS6000_BUILTIN_BSWAP_HI);
12306 /* AIX libm provides clog as __clog. */
12307 if (built_in_decls [BUILT_IN_CLOG])
12308 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12311 #ifdef SUBTARGET_INIT_BUILTINS
12312 SUBTARGET_INIT_BUILTINS;
12316 /* Returns the rs6000 builtin decl for CODE. */
12319 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12321 if (code >= RS6000_BUILTIN_COUNT)
12322 return error_mark_node;
12324 return rs6000_builtin_decls[code];
12327 /* Search through a set of builtins and enable the mask bits.
12328 DESC is an array of builtins.
12329 SIZE is the total number of builtins.
12330 START is the builtin enum at which to start.
12331 END is the builtin enum at which to end. */
12333 enable_mask_for_builtins (struct builtin_description *desc, int size,
12334 enum rs6000_builtins start,
12335 enum rs6000_builtins end)
12339 for (i = 0; i < size; ++i)
12340 if (desc[i].code == start)
12346 for (; i < size; ++i)
12348 /* Flip all the bits on. */
12349 desc[i].mask = target_flags;
12350 if (desc[i].code == end)
12356 spe_init_builtins (void)
12358 tree endlink = void_list_node;
12359 tree puint_type_node = build_pointer_type (unsigned_type_node);
12360 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12361 struct builtin_description *d;
12364 tree v2si_ftype_4_v2si
12365 = build_function_type
12366 (opaque_V2SI_type_node,
12367 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12368 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12369 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12370 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12373 tree v2sf_ftype_4_v2sf
12374 = build_function_type
12375 (opaque_V2SF_type_node,
12376 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12377 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12378 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12379 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12382 tree int_ftype_int_v2si_v2si
12383 = build_function_type
12384 (integer_type_node,
12385 tree_cons (NULL_TREE, integer_type_node,
12386 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12387 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12390 tree int_ftype_int_v2sf_v2sf
12391 = build_function_type
12392 (integer_type_node,
12393 tree_cons (NULL_TREE, integer_type_node,
12394 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12395 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12398 tree void_ftype_v2si_puint_int
12399 = build_function_type (void_type_node,
12400 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12401 tree_cons (NULL_TREE, puint_type_node,
12402 tree_cons (NULL_TREE,
12406 tree void_ftype_v2si_puint_char
12407 = build_function_type (void_type_node,
12408 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12409 tree_cons (NULL_TREE, puint_type_node,
12410 tree_cons (NULL_TREE,
12414 tree void_ftype_v2si_pv2si_int
12415 = build_function_type (void_type_node,
12416 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12417 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12418 tree_cons (NULL_TREE,
12422 tree void_ftype_v2si_pv2si_char
12423 = build_function_type (void_type_node,
12424 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12425 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12426 tree_cons (NULL_TREE,
12430 tree void_ftype_int
12431 = build_function_type (void_type_node,
12432 tree_cons (NULL_TREE, integer_type_node, endlink));
12434 tree int_ftype_void
12435 = build_function_type (integer_type_node, endlink);
12437 tree v2si_ftype_pv2si_int
12438 = build_function_type (opaque_V2SI_type_node,
12439 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12440 tree_cons (NULL_TREE, integer_type_node,
12443 tree v2si_ftype_puint_int
12444 = build_function_type (opaque_V2SI_type_node,
12445 tree_cons (NULL_TREE, puint_type_node,
12446 tree_cons (NULL_TREE, integer_type_node,
12449 tree v2si_ftype_pushort_int
12450 = build_function_type (opaque_V2SI_type_node,
12451 tree_cons (NULL_TREE, pushort_type_node,
12452 tree_cons (NULL_TREE, integer_type_node,
12455 tree v2si_ftype_signed_char
12456 = build_function_type (opaque_V2SI_type_node,
12457 tree_cons (NULL_TREE, signed_char_type_node,
12460 /* The initialization of the simple binary and unary builtins is
12461 done in rs6000_common_init_builtins, but we have to enable the
12462 mask bits here manually because we have run out of `target_flags'
12463 bits. We really need to redesign this mask business. */
12465 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12466 ARRAY_SIZE (bdesc_2arg),
12467 SPE_BUILTIN_EVADDW,
12468 SPE_BUILTIN_EVXOR);
12469 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12470 ARRAY_SIZE (bdesc_1arg),
12472 SPE_BUILTIN_EVSUBFUSIAAW);
12473 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12474 ARRAY_SIZE (bdesc_spe_predicates),
12475 SPE_BUILTIN_EVCMPEQ,
12476 SPE_BUILTIN_EVFSTSTLT);
12477 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12478 ARRAY_SIZE (bdesc_spe_evsel),
12479 SPE_BUILTIN_EVSEL_CMPGTS,
12480 SPE_BUILTIN_EVSEL_FSTSTEQ);
12482 (*lang_hooks.decls.pushdecl)
12483 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12484 get_identifier ("__ev64_opaque__"),
12485 opaque_V2SI_type_node));
12487 /* Initialize irregular SPE builtins. */
12489 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12490 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12491 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12492 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12493 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12494 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12495 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12496 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12497 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12498 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12499 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12500 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12501 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12502 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12503 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12504 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12505 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12506 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12509 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12510 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12511 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12512 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12513 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12514 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12515 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12516 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12517 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12518 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12519 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12520 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12521 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12522 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12523 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12524 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12525 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12526 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12527 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12528 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12529 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12530 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12533 d = (struct builtin_description *) bdesc_spe_predicates;
12534 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12538 switch (insn_data[d->icode].operand[1].mode)
12541 type = int_ftype_int_v2si_v2si;
12544 type = int_ftype_int_v2sf_v2sf;
12547 gcc_unreachable ();
12550 def_builtin (d->mask, d->name, type, d->code);
12553 /* Evsel predicates. */
12554 d = (struct builtin_description *) bdesc_spe_evsel;
12555 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12559 switch (insn_data[d->icode].operand[1].mode)
12562 type = v2si_ftype_4_v2si;
12565 type = v2sf_ftype_4_v2sf;
12568 gcc_unreachable ();
12571 def_builtin (d->mask, d->name, type, d->code);
12576 paired_init_builtins (void)
12578 const struct builtin_description *d;
12580 tree endlink = void_list_node;
12582 tree int_ftype_int_v2sf_v2sf
12583 = build_function_type
12584 (integer_type_node,
12585 tree_cons (NULL_TREE, integer_type_node,
12586 tree_cons (NULL_TREE, V2SF_type_node,
12587 tree_cons (NULL_TREE, V2SF_type_node,
12589 tree pcfloat_type_node =
12590 build_pointer_type (build_qualified_type
12591 (float_type_node, TYPE_QUAL_CONST));
12593 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12594 long_integer_type_node,
12597 tree void_ftype_v2sf_long_pcfloat =
12598 build_function_type_list (void_type_node,
12600 long_integer_type_node,
12605 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12606 PAIRED_BUILTIN_LX);
12609 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12610 PAIRED_BUILTIN_STX);
12613 d = bdesc_paired_preds;
12614 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12618 switch (insn_data[d->icode].operand[1].mode)
12621 type = int_ftype_int_v2sf_v2sf;
12624 gcc_unreachable ();
12627 def_builtin (d->mask, d->name, type, d->code);
12632 altivec_init_builtins (void)
12634 const struct builtin_description *d;
12635 const struct builtin_description_predicates *dp;
12639 tree pfloat_type_node = build_pointer_type (float_type_node);
12640 tree pint_type_node = build_pointer_type (integer_type_node);
12641 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12642 tree pchar_type_node = build_pointer_type (char_type_node);
12644 tree pvoid_type_node = build_pointer_type (void_type_node);
12646 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12647 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12648 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12649 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12651 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12653 tree int_ftype_opaque
12654 = build_function_type_list (integer_type_node,
12655 opaque_V4SI_type_node, NULL_TREE);
12656 tree opaque_ftype_opaque
12657 = build_function_type (integer_type_node,
12659 tree opaque_ftype_opaque_int
12660 = build_function_type_list (opaque_V4SI_type_node,
12661 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12662 tree opaque_ftype_opaque_opaque_int
12663 = build_function_type_list (opaque_V4SI_type_node,
12664 opaque_V4SI_type_node, opaque_V4SI_type_node,
12665 integer_type_node, NULL_TREE);
12666 tree int_ftype_int_opaque_opaque
12667 = build_function_type_list (integer_type_node,
12668 integer_type_node, opaque_V4SI_type_node,
12669 opaque_V4SI_type_node, NULL_TREE);
12670 tree int_ftype_int_v4si_v4si
12671 = build_function_type_list (integer_type_node,
12672 integer_type_node, V4SI_type_node,
12673 V4SI_type_node, NULL_TREE);
12674 tree v4sf_ftype_pcfloat
12675 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12676 tree void_ftype_pfloat_v4sf
12677 = build_function_type_list (void_type_node,
12678 pfloat_type_node, V4SF_type_node, NULL_TREE);
12679 tree v4si_ftype_pcint
12680 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12681 tree void_ftype_pint_v4si
12682 = build_function_type_list (void_type_node,
12683 pint_type_node, V4SI_type_node, NULL_TREE);
12684 tree v8hi_ftype_pcshort
12685 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12686 tree void_ftype_pshort_v8hi
12687 = build_function_type_list (void_type_node,
12688 pshort_type_node, V8HI_type_node, NULL_TREE);
12689 tree v16qi_ftype_pcchar
12690 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12691 tree void_ftype_pchar_v16qi
12692 = build_function_type_list (void_type_node,
12693 pchar_type_node, V16QI_type_node, NULL_TREE);
12694 tree void_ftype_v4si
12695 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12696 tree v8hi_ftype_void
12697 = build_function_type (V8HI_type_node, void_list_node);
12698 tree void_ftype_void
12699 = build_function_type (void_type_node, void_list_node);
12700 tree void_ftype_int
12701 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12703 tree opaque_ftype_long_pcvoid
12704 = build_function_type_list (opaque_V4SI_type_node,
12705 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12706 tree v16qi_ftype_long_pcvoid
12707 = build_function_type_list (V16QI_type_node,
12708 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12709 tree v8hi_ftype_long_pcvoid
12710 = build_function_type_list (V8HI_type_node,
12711 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12712 tree v4si_ftype_long_pcvoid
12713 = build_function_type_list (V4SI_type_node,
12714 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12716 tree void_ftype_opaque_long_pvoid
12717 = build_function_type_list (void_type_node,
12718 opaque_V4SI_type_node, long_integer_type_node,
12719 pvoid_type_node, NULL_TREE);
12720 tree void_ftype_v4si_long_pvoid
12721 = build_function_type_list (void_type_node,
12722 V4SI_type_node, long_integer_type_node,
12723 pvoid_type_node, NULL_TREE);
12724 tree void_ftype_v16qi_long_pvoid
12725 = build_function_type_list (void_type_node,
12726 V16QI_type_node, long_integer_type_node,
12727 pvoid_type_node, NULL_TREE);
12728 tree void_ftype_v8hi_long_pvoid
12729 = build_function_type_list (void_type_node,
12730 V8HI_type_node, long_integer_type_node,
12731 pvoid_type_node, NULL_TREE);
12732 tree int_ftype_int_v8hi_v8hi
12733 = build_function_type_list (integer_type_node,
12734 integer_type_node, V8HI_type_node,
12735 V8HI_type_node, NULL_TREE);
12736 tree int_ftype_int_v16qi_v16qi
12737 = build_function_type_list (integer_type_node,
12738 integer_type_node, V16QI_type_node,
12739 V16QI_type_node, NULL_TREE);
12740 tree int_ftype_int_v4sf_v4sf
12741 = build_function_type_list (integer_type_node,
12742 integer_type_node, V4SF_type_node,
12743 V4SF_type_node, NULL_TREE);
12744 tree int_ftype_int_v2df_v2df
12745 = build_function_type_list (integer_type_node,
12746 integer_type_node, V2DF_type_node,
12747 V2DF_type_node, NULL_TREE);
12748 tree v4si_ftype_v4si
12749 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12750 tree v8hi_ftype_v8hi
12751 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12752 tree v16qi_ftype_v16qi
12753 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12754 tree v4sf_ftype_v4sf
12755 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12756 tree v2df_ftype_v2df
12757 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12758 tree void_ftype_pcvoid_int_int
12759 = build_function_type_list (void_type_node,
12760 pcvoid_type_node, integer_type_node,
12761 integer_type_node, NULL_TREE);
12763 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12764 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12765 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12766 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12767 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12768 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12769 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12770 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12771 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12772 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12773 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12774 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12775 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12776 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12777 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12778 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12779 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12781 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12783 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12785 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12787 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12789 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12795 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12796 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12797 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12798 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12799 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12800 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12801 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12802 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12803 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12804 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12805 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12806 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12807 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12808 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12810 if (rs6000_cpu == PROCESSOR_CELL)
12812 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12813 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12814 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12815 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12817 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12818 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12819 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12820 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12822 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12823 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12824 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12825 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12827 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12828 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12829 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12830 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12832 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12833 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12834 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12836 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12837 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12838 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12839 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12840 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12841 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12842 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12843 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12844 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12845 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12846 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12847 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12849 /* Add the DST variants. */
12851 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12852 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12854 /* Initialize the predicates. */
12855 dp = bdesc_altivec_preds;
12856 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12858 enum machine_mode mode1;
12860 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12861 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12862 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12863 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12868 mode1 = insn_data[dp->icode].operand[1].mode;
12873 type = int_ftype_int_opaque_opaque;
12876 type = int_ftype_int_v4si_v4si;
12879 type = int_ftype_int_v8hi_v8hi;
12882 type = int_ftype_int_v16qi_v16qi;
12885 type = int_ftype_int_v4sf_v4sf;
12888 type = int_ftype_int_v2df_v2df;
12891 gcc_unreachable ();
12894 def_builtin (dp->mask, dp->name, type, dp->code);
12897 /* Initialize the abs* operators. */
12899 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12901 enum machine_mode mode0;
12904 mode0 = insn_data[d->icode].operand[0].mode;
12909 type = v4si_ftype_v4si;
12912 type = v8hi_ftype_v8hi;
12915 type = v16qi_ftype_v16qi;
12918 type = v4sf_ftype_v4sf;
12921 type = v2df_ftype_v2df;
12924 gcc_unreachable ();
12927 def_builtin (d->mask, d->name, type, d->code);
12930 if (TARGET_ALTIVEC)
12934 /* Initialize target builtin that implements
12935 targetm.vectorize.builtin_mask_for_load. */
12937 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12938 v16qi_ftype_long_pcvoid,
12939 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12940 BUILT_IN_MD, NULL, NULL_TREE);
12941 TREE_READONLY (decl) = 1;
12942 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12943 altivec_builtin_mask_for_load = decl;
12946 /* Access to the vec_init patterns. */
12947 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12948 integer_type_node, integer_type_node,
12949 integer_type_node, NULL_TREE);
12950 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12951 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12953 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12954 short_integer_type_node,
12955 short_integer_type_node,
12956 short_integer_type_node,
12957 short_integer_type_node,
12958 short_integer_type_node,
12959 short_integer_type_node,
12960 short_integer_type_node, NULL_TREE);
12961 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12962 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12964 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12965 char_type_node, char_type_node,
12966 char_type_node, char_type_node,
12967 char_type_node, char_type_node,
12968 char_type_node, char_type_node,
12969 char_type_node, char_type_node,
12970 char_type_node, char_type_node,
12971 char_type_node, char_type_node,
12972 char_type_node, NULL_TREE);
12973 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12974 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12976 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12977 float_type_node, float_type_node,
12978 float_type_node, NULL_TREE);
12979 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12980 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12984 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12985 double_type_node, NULL_TREE);
12986 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12987 VSX_BUILTIN_VEC_INIT_V2DF);
12989 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12990 intDI_type_node, NULL_TREE);
12991 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12992 VSX_BUILTIN_VEC_INIT_V2DI);
12995 /* Access to the vec_set patterns. */
12996 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12998 integer_type_node, NULL_TREE);
12999 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13000 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13002 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13004 integer_type_node, NULL_TREE);
13005 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13006 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13008 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13010 integer_type_node, NULL_TREE);
13011 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13012 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13014 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13016 integer_type_node, NULL_TREE);
13017 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13018 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13022 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13024 integer_type_node, NULL_TREE);
13025 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13026 VSX_BUILTIN_VEC_SET_V2DF);
13028 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13030 integer_type_node, NULL_TREE);
13031 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13032 VSX_BUILTIN_VEC_SET_V2DI);
13035 /* Access to the vec_extract patterns. */
13036 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13037 integer_type_node, NULL_TREE);
13038 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13039 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13041 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13042 integer_type_node, NULL_TREE);
13043 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13044 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13046 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13047 integer_type_node, NULL_TREE);
13048 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13049 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13051 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13052 integer_type_node, NULL_TREE);
13053 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13054 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13058 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13059 integer_type_node, NULL_TREE);
13060 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13061 VSX_BUILTIN_VEC_EXT_V2DF);
13063 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13064 integer_type_node, NULL_TREE);
13065 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13066 VSX_BUILTIN_VEC_EXT_V2DI);
13070 /* Hash function for builtin functions with up to 3 arguments and a return
13073 builtin_hash_function (const void *hash_entry)
13077 const struct builtin_hash_struct *bh =
13078 (const struct builtin_hash_struct *) hash_entry;
13080 for (i = 0; i < 4; i++)
13082 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13083 ret = (ret * 2) + bh->uns_p[i];
13089 /* Compare builtin hash entries H1 and H2 for equivalence. */
13091 builtin_hash_eq (const void *h1, const void *h2)
13093 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13094 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13096 return ((p1->mode[0] == p2->mode[0])
13097 && (p1->mode[1] == p2->mode[1])
13098 && (p1->mode[2] == p2->mode[2])
13099 && (p1->mode[3] == p2->mode[3])
13100 && (p1->uns_p[0] == p2->uns_p[0])
13101 && (p1->uns_p[1] == p2->uns_p[1])
13102 && (p1->uns_p[2] == p2->uns_p[2])
13103 && (p1->uns_p[3] == p2->uns_p[3]));
13106 /* Map types for builtin functions with an explicit return type and up to 3
13107 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13108 of the argument. */
13110 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13111 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13112 enum rs6000_builtins builtin, const char *name)
13114 struct builtin_hash_struct h;
13115 struct builtin_hash_struct *h2;
13119 tree ret_type = NULL_TREE;
13120 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13123 /* Create builtin_hash_table. */
13124 if (builtin_hash_table == NULL)
13125 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13126 builtin_hash_eq, NULL);
13128 h.type = NULL_TREE;
13129 h.mode[0] = mode_ret;
13130 h.mode[1] = mode_arg0;
13131 h.mode[2] = mode_arg1;
13132 h.mode[3] = mode_arg2;
13138 /* If the builtin is a type that produces unsigned results or takes unsigned
13139 arguments, and it is returned as a decl for the vectorizer (such as
13140 widening multiplies, permute), make sure the arguments and return value
13141 are type correct. */
13144 /* unsigned 2 argument functions. */
13145 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13146 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13147 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13148 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13154 /* unsigned 3 argument functions. */
13155 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13156 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13157 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13158 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13159 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13160 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13161 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13162 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13163 case VSX_BUILTIN_VPERM_16QI_UNS:
13164 case VSX_BUILTIN_VPERM_8HI_UNS:
13165 case VSX_BUILTIN_VPERM_4SI_UNS:
13166 case VSX_BUILTIN_VPERM_2DI_UNS:
13167 case VSX_BUILTIN_XXSEL_16QI_UNS:
13168 case VSX_BUILTIN_XXSEL_8HI_UNS:
13169 case VSX_BUILTIN_XXSEL_4SI_UNS:
13170 case VSX_BUILTIN_XXSEL_2DI_UNS:
13177 /* signed permute functions with unsigned char mask. */
13178 case ALTIVEC_BUILTIN_VPERM_16QI:
13179 case ALTIVEC_BUILTIN_VPERM_8HI:
13180 case ALTIVEC_BUILTIN_VPERM_4SI:
13181 case ALTIVEC_BUILTIN_VPERM_4SF:
13182 case ALTIVEC_BUILTIN_VPERM_2DI:
13183 case ALTIVEC_BUILTIN_VPERM_2DF:
13184 case VSX_BUILTIN_VPERM_16QI:
13185 case VSX_BUILTIN_VPERM_8HI:
13186 case VSX_BUILTIN_VPERM_4SI:
13187 case VSX_BUILTIN_VPERM_4SF:
13188 case VSX_BUILTIN_VPERM_2DI:
13189 case VSX_BUILTIN_VPERM_2DF:
13193 /* unsigned args, signed return. */
13194 case VSX_BUILTIN_XVCVUXDDP_UNS:
13195 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13199 /* signed args, unsigned return. */
13200 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13201 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13209 /* Figure out how many args are present. */
13210 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13214 fatal_error ("internal error: builtin function %s had no type", name);
13216 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13217 if (!ret_type && h.uns_p[0])
13218 ret_type = builtin_mode_to_type[h.mode[0]][0];
13221 fatal_error ("internal error: builtin function %s had an unexpected "
13222 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13224 for (i = 0; i < num_args; i++)
13226 int m = (int) h.mode[i+1];
13227 int uns_p = h.uns_p[i+1];
13229 arg_type[i] = builtin_mode_to_type[m][uns_p];
13230 if (!arg_type[i] && uns_p)
13231 arg_type[i] = builtin_mode_to_type[m][0];
13234 fatal_error ("internal error: builtin function %s, argument %d "
13235 "had unexpected argument type %s", name, i,
13236 GET_MODE_NAME (m));
13239 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13240 if (*found == NULL)
13242 h2 = ggc_alloc_builtin_hash_struct ();
13244 *found = (void *)h2;
13245 args = void_list_node;
13247 for (i = num_args - 1; i >= 0; i--)
13248 args = tree_cons (NULL_TREE, arg_type[i], args);
13250 h2->type = build_function_type (ret_type, args);
13253 return ((struct builtin_hash_struct *)(*found))->type;
13257 rs6000_common_init_builtins (void)
13259 const struct builtin_description *d;
13262 tree opaque_ftype_opaque = NULL_TREE;
13263 tree opaque_ftype_opaque_opaque = NULL_TREE;
13264 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13265 tree v2si_ftype_qi = NULL_TREE;
13266 tree v2si_ftype_v2si_qi = NULL_TREE;
13267 tree v2si_ftype_int_qi = NULL_TREE;
13269 if (!TARGET_PAIRED_FLOAT)
13271 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13272 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13275 /* Add the ternary operators. */
13277 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13280 int mask = d->mask;
13282 if ((mask != 0 && (mask & target_flags) == 0)
13283 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13286 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13287 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13288 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13289 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13291 if (! (type = opaque_ftype_opaque_opaque_opaque))
13292 type = opaque_ftype_opaque_opaque_opaque
13293 = build_function_type_list (opaque_V4SI_type_node,
13294 opaque_V4SI_type_node,
13295 opaque_V4SI_type_node,
13296 opaque_V4SI_type_node,
13301 enum insn_code icode = d->icode;
13302 if (d->name == 0 || icode == CODE_FOR_nothing)
13305 type = builtin_function_type (insn_data[icode].operand[0].mode,
13306 insn_data[icode].operand[1].mode,
13307 insn_data[icode].operand[2].mode,
13308 insn_data[icode].operand[3].mode,
13312 def_builtin (d->mask, d->name, type, d->code);
13315 /* Add the binary operators. */
13317 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13319 enum machine_mode mode0, mode1, mode2;
13321 int mask = d->mask;
13323 if ((mask != 0 && (mask & target_flags) == 0)
13324 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13327 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13328 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13329 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13330 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13332 if (! (type = opaque_ftype_opaque_opaque))
13333 type = opaque_ftype_opaque_opaque
13334 = build_function_type_list (opaque_V4SI_type_node,
13335 opaque_V4SI_type_node,
13336 opaque_V4SI_type_node,
13341 enum insn_code icode = d->icode;
13342 if (d->name == 0 || icode == CODE_FOR_nothing)
13345 mode0 = insn_data[icode].operand[0].mode;
13346 mode1 = insn_data[icode].operand[1].mode;
13347 mode2 = insn_data[icode].operand[2].mode;
13349 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13351 if (! (type = v2si_ftype_v2si_qi))
13352 type = v2si_ftype_v2si_qi
13353 = build_function_type_list (opaque_V2SI_type_node,
13354 opaque_V2SI_type_node,
13359 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13360 && mode2 == QImode)
13362 if (! (type = v2si_ftype_int_qi))
13363 type = v2si_ftype_int_qi
13364 = build_function_type_list (opaque_V2SI_type_node,
13371 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13375 def_builtin (d->mask, d->name, type, d->code);
13378 /* Add the simple unary operators. */
13379 d = (struct builtin_description *) bdesc_1arg;
13380 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13382 enum machine_mode mode0, mode1;
13384 int mask = d->mask;
13386 if ((mask != 0 && (mask & target_flags) == 0)
13387 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13390 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13391 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13392 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13393 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13395 if (! (type = opaque_ftype_opaque))
13396 type = opaque_ftype_opaque
13397 = build_function_type_list (opaque_V4SI_type_node,
13398 opaque_V4SI_type_node,
13403 enum insn_code icode = d->icode;
13404 if (d->name == 0 || icode == CODE_FOR_nothing)
13407 mode0 = insn_data[icode].operand[0].mode;
13408 mode1 = insn_data[icode].operand[1].mode;
13410 if (mode0 == V2SImode && mode1 == QImode)
13412 if (! (type = v2si_ftype_qi))
13413 type = v2si_ftype_qi
13414 = build_function_type_list (opaque_V2SI_type_node,
13420 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13424 def_builtin (d->mask, d->name, type, d->code);
13429 rs6000_init_libfuncs (void)
13431 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13432 && !TARGET_POWER2 && !TARGET_POWERPC)
13434 /* AIX library routines for float->int conversion. */
13435 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13436 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13437 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13438 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13441 if (!TARGET_IEEEQUAD)
13442 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13443 if (!TARGET_XL_COMPAT)
13445 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13446 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13447 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13448 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13450 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13452 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13453 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13454 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13455 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13456 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13457 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13458 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13460 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13461 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13462 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13463 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13464 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13465 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13466 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13467 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13470 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13471 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13475 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13476 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13477 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13478 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13482 /* 32-bit SVR4 quad floating point routines. */
13484 set_optab_libfunc (add_optab, TFmode, "_q_add");
13485 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13486 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13487 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13488 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13489 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13490 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13492 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13493 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13494 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13495 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13496 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13497 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13499 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13500 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13501 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13502 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13503 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13504 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13505 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13506 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13511 /* Expand a block clear operation, and return 1 if successful. Return 0
13512 if we should let the compiler generate normal code.
13514 operands[0] is the destination
13515 operands[1] is the length
13516 operands[3] is the alignment */
13519 expand_block_clear (rtx operands[])
13521 rtx orig_dest = operands[0];
13522 rtx bytes_rtx = operands[1];
13523 rtx align_rtx = operands[3];
13524 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13525 HOST_WIDE_INT align;
13526 HOST_WIDE_INT bytes;
13531 /* If this is not a fixed size move, just call memcpy */
13535 /* This must be a fixed size alignment */
13536 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13537 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13539 /* Anything to clear? */
13540 bytes = INTVAL (bytes_rtx);
13544 /* Use the builtin memset after a point, to avoid huge code bloat.
13545 When optimize_size, avoid any significant code bloat; calling
13546 memset is about 4 instructions, so allow for one instruction to
13547 load zero and three to do clearing. */
13548 if (TARGET_ALTIVEC && align >= 128)
13550 else if (TARGET_POWERPC64 && align >= 32)
13552 else if (TARGET_SPE && align >= 64)
13557 if (optimize_size && bytes > 3 * clear_step)
13559 if (! optimize_size && bytes > 8 * clear_step)
13562 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13564 enum machine_mode mode = BLKmode;
13567 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13572 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13577 else if (bytes >= 8 && TARGET_POWERPC64
13578 /* 64-bit loads and stores require word-aligned
13580 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13585 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13586 { /* move 4 bytes */
13590 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13591 { /* move 2 bytes */
13595 else /* move 1 byte at a time */
13601 dest = adjust_address (orig_dest, mode, offset);
13603 emit_move_insn (dest, CONST0_RTX (mode));
13610 /* Expand a block move operation, and return 1 if successful. Return 0
13611 if we should let the compiler generate normal code.
13613 operands[0] is the destination
13614 operands[1] is the source
13615 operands[2] is the length
13616 operands[3] is the alignment */
13618 #define MAX_MOVE_REG 4
13621 expand_block_move (rtx operands[])
13623 rtx orig_dest = operands[0];
13624 rtx orig_src = operands[1];
13625 rtx bytes_rtx = operands[2];
13626 rtx align_rtx = operands[3];
13627 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13632 rtx stores[MAX_MOVE_REG];
13635 /* If this is not a fixed size move, just call memcpy */
13639 /* This must be a fixed size alignment */
13640 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13641 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13643 /* Anything to move? */
13644 bytes = INTVAL (bytes_rtx);
13648 if (bytes > rs6000_block_move_inline_limit)
13651 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13654 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13655 rtx (*mov) (rtx, rtx);
13657 enum machine_mode mode = BLKmode;
13660 /* Altivec first, since it will be faster than a string move
13661 when it applies, and usually not significantly larger. */
13662 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13666 gen_func.mov = gen_movv4si;
13668 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13672 gen_func.mov = gen_movv2si;
13674 else if (TARGET_STRING
13675 && bytes > 24 /* move up to 32 bytes at a time */
13681 && ! fixed_regs[10]
13682 && ! fixed_regs[11]
13683 && ! fixed_regs[12])
13685 move_bytes = (bytes > 32) ? 32 : bytes;
13686 gen_func.movmemsi = gen_movmemsi_8reg;
13688 else if (TARGET_STRING
13689 && bytes > 16 /* move up to 24 bytes at a time */
13695 && ! fixed_regs[10])
13697 move_bytes = (bytes > 24) ? 24 : bytes;
13698 gen_func.movmemsi = gen_movmemsi_6reg;
13700 else if (TARGET_STRING
13701 && bytes > 8 /* move up to 16 bytes at a time */
13705 && ! fixed_regs[8])
13707 move_bytes = (bytes > 16) ? 16 : bytes;
13708 gen_func.movmemsi = gen_movmemsi_4reg;
13710 else if (bytes >= 8 && TARGET_POWERPC64
13711 /* 64-bit loads and stores require word-aligned
13713 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13717 gen_func.mov = gen_movdi;
13719 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13720 { /* move up to 8 bytes at a time */
13721 move_bytes = (bytes > 8) ? 8 : bytes;
13722 gen_func.movmemsi = gen_movmemsi_2reg;
13724 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13725 { /* move 4 bytes */
13728 gen_func.mov = gen_movsi;
13730 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13731 { /* move 2 bytes */
13734 gen_func.mov = gen_movhi;
13736 else if (TARGET_STRING && bytes > 1)
13737 { /* move up to 4 bytes at a time */
13738 move_bytes = (bytes > 4) ? 4 : bytes;
13739 gen_func.movmemsi = gen_movmemsi_1reg;
13741 else /* move 1 byte at a time */
13745 gen_func.mov = gen_movqi;
13748 src = adjust_address (orig_src, mode, offset);
13749 dest = adjust_address (orig_dest, mode, offset);
13751 if (mode != BLKmode)
13753 rtx tmp_reg = gen_reg_rtx (mode);
13755 emit_insn ((*gen_func.mov) (tmp_reg, src));
13756 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13759 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13762 for (i = 0; i < num_reg; i++)
13763 emit_insn (stores[i]);
13767 if (mode == BLKmode)
13769 /* Move the address into scratch registers. The movmemsi
13770 patterns require zero offset. */
13771 if (!REG_P (XEXP (src, 0)))
13773 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13774 src = replace_equiv_address (src, src_reg);
13776 set_mem_size (src, GEN_INT (move_bytes));
13778 if (!REG_P (XEXP (dest, 0)))
13780 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13781 dest = replace_equiv_address (dest, dest_reg);
13783 set_mem_size (dest, GEN_INT (move_bytes));
13785 emit_insn ((*gen_func.movmemsi) (dest, src,
13786 GEN_INT (move_bytes & 31),
13795 /* Return a string to perform a load_multiple operation.
13796 operands[0] is the vector.
13797 operands[1] is the source address.
13798 operands[2] is the first destination register. */
13801 rs6000_output_load_multiple (rtx operands[3])
13803 /* We have to handle the case where the pseudo used to contain the address
13804 is assigned to one of the output registers. */
13806 int words = XVECLEN (operands[0], 0);
13809 if (XVECLEN (operands[0], 0) == 1)
13810 return "{l|lwz} %2,0(%1)";
13812 for (i = 0; i < words; i++)
13813 if (refers_to_regno_p (REGNO (operands[2]) + i,
13814 REGNO (operands[2]) + i + 1, operands[1], 0))
13818 xop[0] = GEN_INT (4 * (words-1));
13819 xop[1] = operands[1];
13820 xop[2] = operands[2];
13821 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13826 xop[0] = GEN_INT (4 * (words-1));
13827 xop[1] = operands[1];
13828 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13829 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);
13834 for (j = 0; j < words; j++)
13837 xop[0] = GEN_INT (j * 4);
13838 xop[1] = operands[1];
13839 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13840 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13842 xop[0] = GEN_INT (i * 4);
13843 xop[1] = operands[1];
13844 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13849 return "{lsi|lswi} %2,%1,%N0";
13853 /* A validation routine: say whether CODE, a condition code, and MODE
13854 match. The other alternatives either don't make sense or should
13855 never be generated. */
13858 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13860 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13861 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13862 && GET_MODE_CLASS (mode) == MODE_CC);
13864 /* These don't make sense. */
13865 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13866 || mode != CCUNSmode);
13868 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13869 || mode == CCUNSmode);
13871 gcc_assert (mode == CCFPmode
13872 || (code != ORDERED && code != UNORDERED
13873 && code != UNEQ && code != LTGT
13874 && code != UNGT && code != UNLT
13875 && code != UNGE && code != UNLE));
13877 /* These should never be generated except for
13878 flag_finite_math_only. */
13879 gcc_assert (mode != CCFPmode
13880 || flag_finite_math_only
13881 || (code != LE && code != GE
13882 && code != UNEQ && code != LTGT
13883 && code != UNGT && code != UNLT));
13885 /* These are invalid; the information is not there. */
13886 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13890 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13891 mask required to convert the result of a rotate insn into a shift
13892 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13895 includes_lshift_p (rtx shiftop, rtx andop)
13897 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13899 shift_mask <<= INTVAL (shiftop);
13901 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13904 /* Similar, but for right shift. */
13907 includes_rshift_p (rtx shiftop, rtx andop)
13909 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13911 shift_mask >>= INTVAL (shiftop);
13913 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13916 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13917 to perform a left shift. It must have exactly SHIFTOP least
13918 significant 0's, then one or more 1's, then zero or more 0's. */
13921 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13923 if (GET_CODE (andop) == CONST_INT)
13925 HOST_WIDE_INT c, lsb, shift_mask;
13927 c = INTVAL (andop);
13928 if (c == 0 || c == ~0)
13932 shift_mask <<= INTVAL (shiftop);
13934 /* Find the least significant one bit. */
13937 /* It must coincide with the LSB of the shift mask. */
13938 if (-lsb != shift_mask)
13941 /* Invert to look for the next transition (if any). */
13944 /* Remove the low group of ones (originally low group of zeros). */
13947 /* Again find the lsb, and check we have all 1's above. */
13951 else if (GET_CODE (andop) == CONST_DOUBLE
13952 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13954 HOST_WIDE_INT low, high, lsb;
13955 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13957 low = CONST_DOUBLE_LOW (andop);
13958 if (HOST_BITS_PER_WIDE_INT < 64)
13959 high = CONST_DOUBLE_HIGH (andop);
13961 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13962 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13965 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13967 shift_mask_high = ~0;
13968 if (INTVAL (shiftop) > 32)
13969 shift_mask_high <<= INTVAL (shiftop) - 32;
13971 lsb = high & -high;
13973 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13979 lsb = high & -high;
13980 return high == -lsb;
13983 shift_mask_low = ~0;
13984 shift_mask_low <<= INTVAL (shiftop);
13988 if (-lsb != shift_mask_low)
13991 if (HOST_BITS_PER_WIDE_INT < 64)
13996 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13998 lsb = high & -high;
13999 return high == -lsb;
14003 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14009 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14010 to perform a left shift. It must have SHIFTOP or more least
14011 significant 0's, with the remainder of the word 1's. */
14014 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14016 if (GET_CODE (andop) == CONST_INT)
14018 HOST_WIDE_INT c, lsb, shift_mask;
14021 shift_mask <<= INTVAL (shiftop);
14022 c = INTVAL (andop);
14024 /* Find the least significant one bit. */
14027 /* It must be covered by the shift mask.
14028 This test also rejects c == 0. */
14029 if ((lsb & shift_mask) == 0)
14032 /* Check we have all 1's above the transition, and reject all 1's. */
14033 return c == -lsb && lsb != 1;
14035 else if (GET_CODE (andop) == CONST_DOUBLE
14036 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14038 HOST_WIDE_INT low, lsb, shift_mask_low;
14040 low = CONST_DOUBLE_LOW (andop);
14042 if (HOST_BITS_PER_WIDE_INT < 64)
14044 HOST_WIDE_INT high, shift_mask_high;
14046 high = CONST_DOUBLE_HIGH (andop);
14050 shift_mask_high = ~0;
14051 if (INTVAL (shiftop) > 32)
14052 shift_mask_high <<= INTVAL (shiftop) - 32;
14054 lsb = high & -high;
14056 if ((lsb & shift_mask_high) == 0)
14059 return high == -lsb;
14065 shift_mask_low = ~0;
14066 shift_mask_low <<= INTVAL (shiftop);
14070 if ((lsb & shift_mask_low) == 0)
14073 return low == -lsb && lsb != 1;
14079 /* Return 1 if operands will generate a valid arguments to rlwimi
14080 instruction for insert with right shift in 64-bit mode. The mask may
14081 not start on the first bit or stop on the last bit because wrap-around
14082 effects of instruction do not correspond to semantics of RTL insn. */
14085 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14087 if (INTVAL (startop) > 32
14088 && INTVAL (startop) < 64
14089 && INTVAL (sizeop) > 1
14090 && INTVAL (sizeop) + INTVAL (startop) < 64
14091 && INTVAL (shiftop) > 0
14092 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14093 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14099 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14100 for lfq and stfq insns iff the registers are hard registers. */
14103 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14105 /* We might have been passed a SUBREG. */
14106 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14109 /* We might have been passed non floating point registers. */
14110 if (!FP_REGNO_P (REGNO (reg1))
14111 || !FP_REGNO_P (REGNO (reg2)))
14114 return (REGNO (reg1) == REGNO (reg2) - 1);
14117 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14118 addr1 and addr2 must be in consecutive memory locations
14119 (addr2 == addr1 + 8). */
14122 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14125 unsigned int reg1, reg2;
14126 int offset1, offset2;
14128 /* The mems cannot be volatile. */
14129 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14132 addr1 = XEXP (mem1, 0);
14133 addr2 = XEXP (mem2, 0);
14135 /* Extract an offset (if used) from the first addr. */
14136 if (GET_CODE (addr1) == PLUS)
14138 /* If not a REG, return zero. */
14139 if (GET_CODE (XEXP (addr1, 0)) != REG)
14143 reg1 = REGNO (XEXP (addr1, 0));
14144 /* The offset must be constant! */
14145 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14147 offset1 = INTVAL (XEXP (addr1, 1));
14150 else if (GET_CODE (addr1) != REG)
14154 reg1 = REGNO (addr1);
14155 /* This was a simple (mem (reg)) expression. Offset is 0. */
14159 /* And now for the second addr. */
14160 if (GET_CODE (addr2) == PLUS)
14162 /* If not a REG, return zero. */
14163 if (GET_CODE (XEXP (addr2, 0)) != REG)
14167 reg2 = REGNO (XEXP (addr2, 0));
14168 /* The offset must be constant. */
14169 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14171 offset2 = INTVAL (XEXP (addr2, 1));
14174 else if (GET_CODE (addr2) != REG)
14178 reg2 = REGNO (addr2);
14179 /* This was a simple (mem (reg)) expression. Offset is 0. */
14183 /* Both of these must have the same base register. */
14187 /* The offset for the second addr must be 8 more than the first addr. */
14188 if (offset2 != offset1 + 8)
14191 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14198 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14200 static bool eliminated = false;
14203 if (mode != SDmode)
14204 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14207 rtx mem = cfun->machine->sdmode_stack_slot;
14208 gcc_assert (mem != NULL_RTX);
14212 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14213 cfun->machine->sdmode_stack_slot = mem;
14219 if (TARGET_DEBUG_ADDR)
14221 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14222 GET_MODE_NAME (mode));
14224 fprintf (stderr, "\tNULL_RTX\n");
14233 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14235 /* Don't walk into types. */
14236 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14238 *walk_subtrees = 0;
14242 switch (TREE_CODE (*tp))
14251 case VIEW_CONVERT_EXPR:
14252 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14262 enum reload_reg_type {
14264 VECTOR_REGISTER_TYPE,
14265 OTHER_REGISTER_TYPE
14268 static enum reload_reg_type
14269 rs6000_reload_register_type (enum reg_class rclass)
14275 return GPR_REGISTER_TYPE;
14280 return VECTOR_REGISTER_TYPE;
14283 return OTHER_REGISTER_TYPE;
14287 /* Inform reload about cases where moving X with a mode MODE to a register in
14288 RCLASS requires an extra scratch or immediate register. Return the class
14289 needed for the immediate register.
14291 For VSX and Altivec, we may need a register to convert sp+offset into
14295 rs6000_secondary_reload (bool in_p,
14297 reg_class_t rclass_i,
14298 enum machine_mode mode,
14299 secondary_reload_info *sri)
14301 enum reg_class rclass = (enum reg_class) rclass_i;
14302 reg_class_t ret = ALL_REGS;
14303 enum insn_code icode;
14304 bool default_p = false;
14306 sri->icode = CODE_FOR_nothing;
14308 /* Convert vector loads and stores into gprs to use an additional base
14310 icode = rs6000_vector_reload[mode][in_p != false];
14311 if (icode != CODE_FOR_nothing)
14314 sri->icode = CODE_FOR_nothing;
14315 sri->extra_cost = 0;
14317 if (GET_CODE (x) == MEM)
14319 rtx addr = XEXP (x, 0);
14321 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14322 an extra register in that case, but it would need an extra
14323 register if the addressing is reg+reg or (reg+reg)&(-16). */
14324 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14326 if (!legitimate_indirect_address_p (addr, false)
14327 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14329 sri->icode = icode;
14330 /* account for splitting the loads, and converting the
14331 address from reg+reg to reg. */
14332 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14333 + ((GET_CODE (addr) == AND) ? 1 : 0));
14336 /* Loads to and stores from vector registers can only do reg+reg
14337 addressing. Altivec registers can also do (reg+reg)&(-16). */
14338 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14339 || rclass == FLOAT_REGS || rclass == NO_REGS)
14341 if (!VECTOR_MEM_ALTIVEC_P (mode)
14342 && GET_CODE (addr) == AND
14343 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14344 && INTVAL (XEXP (addr, 1)) == -16
14345 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14346 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14348 sri->icode = icode;
14349 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14352 else if (!legitimate_indirect_address_p (addr, false)
14353 && (rclass == NO_REGS
14354 || !legitimate_indexed_address_p (addr, false)))
14356 sri->icode = icode;
14357 sri->extra_cost = 1;
14360 icode = CODE_FOR_nothing;
14362 /* Any other loads, including to pseudo registers which haven't been
14363 assigned to a register yet, default to require a scratch
14367 sri->icode = icode;
14368 sri->extra_cost = 2;
14371 else if (REG_P (x))
14373 int regno = true_regnum (x);
14375 icode = CODE_FOR_nothing;
14376 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14380 enum reg_class xclass = REGNO_REG_CLASS (regno);
14381 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14382 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14384 /* If memory is needed, use default_secondary_reload to create the
14386 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14399 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14401 gcc_assert (ret != ALL_REGS);
14403 if (TARGET_DEBUG_ADDR)
14406 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14408 reg_class_names[ret],
14409 in_p ? "true" : "false",
14410 reg_class_names[rclass],
14411 GET_MODE_NAME (mode));
14414 fprintf (stderr, ", default secondary reload");
14416 if (sri->icode != CODE_FOR_nothing)
14417 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14418 insn_data[sri->icode].name, sri->extra_cost);
14420 fprintf (stderr, "\n");
14428 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14429 to SP+reg addressing. */
14432 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14434 int regno = true_regnum (reg);
14435 enum machine_mode mode = GET_MODE (reg);
14436 enum reg_class rclass;
14438 rtx and_op2 = NULL_RTX;
14441 rtx scratch_or_premodify = scratch;
14445 if (TARGET_DEBUG_ADDR)
14447 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14448 store_p ? "store" : "load");
14449 fprintf (stderr, "reg:\n");
14451 fprintf (stderr, "mem:\n");
14453 fprintf (stderr, "scratch:\n");
14454 debug_rtx (scratch);
14457 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14458 gcc_assert (GET_CODE (mem) == MEM);
14459 rclass = REGNO_REG_CLASS (regno);
14460 addr = XEXP (mem, 0);
14464 /* GPRs can handle reg + small constant, all other addresses need to use
14465 the scratch register. */
14468 if (GET_CODE (addr) == AND)
14470 and_op2 = XEXP (addr, 1);
14471 addr = XEXP (addr, 0);
14474 if (GET_CODE (addr) == PRE_MODIFY)
14476 scratch_or_premodify = XEXP (addr, 0);
14477 gcc_assert (REG_P (scratch_or_premodify));
14478 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14479 addr = XEXP (addr, 1);
14482 if (GET_CODE (addr) == PLUS
14483 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14484 || and_op2 != NULL_RTX))
14486 addr_op1 = XEXP (addr, 0);
14487 addr_op2 = XEXP (addr, 1);
14488 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14490 if (!REG_P (addr_op2)
14491 && (GET_CODE (addr_op2) != CONST_INT
14492 || !satisfies_constraint_I (addr_op2)))
14494 if (TARGET_DEBUG_ADDR)
14497 "\nMove plus addr to register %s, mode = %s: ",
14498 rs6000_reg_names[REGNO (scratch)],
14499 GET_MODE_NAME (mode));
14500 debug_rtx (addr_op2);
14502 rs6000_emit_move (scratch, addr_op2, Pmode);
14503 addr_op2 = scratch;
14506 emit_insn (gen_rtx_SET (VOIDmode,
14507 scratch_or_premodify,
14508 gen_rtx_PLUS (Pmode,
14512 addr = scratch_or_premodify;
14513 scratch_or_premodify = scratch;
14515 else if (!legitimate_indirect_address_p (addr, false)
14516 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14518 if (TARGET_DEBUG_ADDR)
14520 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14521 rs6000_reg_names[REGNO (scratch_or_premodify)],
14522 GET_MODE_NAME (mode));
14525 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14526 addr = scratch_or_premodify;
14527 scratch_or_premodify = scratch;
14531 /* Float/Altivec registers can only handle reg+reg addressing. Move
14532 other addresses into a scratch register. */
14537 /* With float regs, we need to handle the AND ourselves, since we can't
14538 use the Altivec instruction with an implicit AND -16. Allow scalar
14539 loads to float registers to use reg+offset even if VSX. */
14540 if (GET_CODE (addr) == AND
14541 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14542 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14543 || INTVAL (XEXP (addr, 1)) != -16
14544 || !VECTOR_MEM_ALTIVEC_P (mode)))
14546 and_op2 = XEXP (addr, 1);
14547 addr = XEXP (addr, 0);
14550 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14551 as the address later. */
14552 if (GET_CODE (addr) == PRE_MODIFY
14553 && (!VECTOR_MEM_VSX_P (mode)
14554 || and_op2 != NULL_RTX
14555 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14557 scratch_or_premodify = XEXP (addr, 0);
14558 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14560 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14561 addr = XEXP (addr, 1);
14564 if (legitimate_indirect_address_p (addr, false) /* reg */
14565 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14566 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14567 || (GET_CODE (addr) == AND /* Altivec memory */
14568 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14569 && INTVAL (XEXP (addr, 1)) == -16
14570 && VECTOR_MEM_ALTIVEC_P (mode))
14571 || (rclass == FLOAT_REGS /* legacy float mem */
14572 && GET_MODE_SIZE (mode) == 8
14573 && and_op2 == NULL_RTX
14574 && scratch_or_premodify == scratch
14575 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14578 else if (GET_CODE (addr) == PLUS)
14580 addr_op1 = XEXP (addr, 0);
14581 addr_op2 = XEXP (addr, 1);
14582 gcc_assert (REG_P (addr_op1));
14584 if (TARGET_DEBUG_ADDR)
14586 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14587 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14588 debug_rtx (addr_op2);
14590 rs6000_emit_move (scratch, addr_op2, Pmode);
14591 emit_insn (gen_rtx_SET (VOIDmode,
14592 scratch_or_premodify,
14593 gen_rtx_PLUS (Pmode,
14596 addr = scratch_or_premodify;
14597 scratch_or_premodify = scratch;
14600 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14601 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14603 if (TARGET_DEBUG_ADDR)
14605 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14606 rs6000_reg_names[REGNO (scratch_or_premodify)],
14607 GET_MODE_NAME (mode));
14611 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14612 addr = scratch_or_premodify;
14613 scratch_or_premodify = scratch;
14617 gcc_unreachable ();
14622 gcc_unreachable ();
14625 /* If the original address involved a pre-modify that we couldn't use the VSX
14626 memory instruction with update, and we haven't taken care of already,
14627 store the address in the pre-modify register and use that as the
14629 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14631 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14632 addr = scratch_or_premodify;
14635 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14636 memory instruction, recreate the AND now, including the clobber which is
14637 generated by the general ANDSI3/ANDDI3 patterns for the
14638 andi. instruction. */
14639 if (and_op2 != NULL_RTX)
14641 if (! legitimate_indirect_address_p (addr, false))
14643 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14647 if (TARGET_DEBUG_ADDR)
14649 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14650 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14651 debug_rtx (and_op2);
14654 and_rtx = gen_rtx_SET (VOIDmode,
14656 gen_rtx_AND (Pmode,
14660 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14661 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14662 gen_rtvec (2, and_rtx, cc_clobber)));
14666 /* Adjust the address if it changed. */
14667 if (addr != XEXP (mem, 0))
14669 mem = change_address (mem, mode, addr);
14670 if (TARGET_DEBUG_ADDR)
14671 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14674 /* Now create the move. */
14676 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14678 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14683 /* Target hook to return the cover classes for Integrated Register Allocator.
14684 Cover classes is a set of non-intersected register classes covering all hard
14685 registers used for register allocation purpose. Any move between two
14686 registers of a cover class should be cheaper than load or store of the
14687 registers. The value is array of register classes with LIM_REG_CLASSES used
14690 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14691 account for the Altivec and Floating registers being subsets of the VSX
14692 register set under VSX, but distinct register sets on pre-VSX machines. */
14694 static const reg_class_t *
14695 rs6000_ira_cover_classes (void)
14697 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14698 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14700 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14703 /* Allocate a 64-bit stack slot to be used for copying SDmode
14704 values through if this function has any SDmode references. */
14707 rs6000_alloc_sdmode_stack_slot (void)
14711 gimple_stmt_iterator gsi;
14713 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14716 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14718 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14721 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14722 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14728 /* Check for any SDmode parameters of the function. */
14729 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14731 if (TREE_TYPE (t) == error_mark_node)
14734 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14735 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14737 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14738 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14746 rs6000_instantiate_decls (void)
14748 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14749 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14752 /* Given an rtx X being reloaded into a reg required to be
14753 in class CLASS, return the class of reg to actually use.
14754 In general this is just CLASS; but on some machines
14755 in some cases it is preferable to use a more restrictive class.
14757 On the RS/6000, we have to return NO_REGS when we want to reload a
14758 floating-point CONST_DOUBLE to force it to be copied to memory.
14760 We also don't want to reload integer values into floating-point
14761 registers if we can at all help it. In fact, this can
14762 cause reload to die, if it tries to generate a reload of CTR
14763 into a FP register and discovers it doesn't have the memory location
14766 ??? Would it be a good idea to have reload do the converse, that is
14767 try to reload floating modes into FP registers if possible?
14770 static enum reg_class
14771 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14773 enum machine_mode mode = GET_MODE (x);
14775 if (VECTOR_UNIT_VSX_P (mode)
14776 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14779 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14780 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14781 && easy_vector_constant (x, mode))
14782 return ALTIVEC_REGS;
14784 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14787 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14788 return GENERAL_REGS;
14790 /* For VSX, prefer the traditional registers for 64-bit values because we can
14791 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14792 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14793 prefer Altivec loads.. */
14794 if (rclass == VSX_REGS)
14796 if (GET_MODE_SIZE (mode) <= 8)
14799 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14800 return ALTIVEC_REGS;
14808 /* Debug version of rs6000_preferred_reload_class. */
14809 static enum reg_class
14810 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14812 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14815 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14817 reg_class_names[ret], reg_class_names[rclass],
14818 GET_MODE_NAME (GET_MODE (x)));
14824 /* If we are copying between FP or AltiVec registers and anything else, we need
14825 a memory location. The exception is when we are targeting ppc64 and the
14826 move to/from fpr to gpr instructions are available. Also, under VSX, you
14827 can copy vector registers from the FP register set to the Altivec register
14828 set and vice versa. */
14831 rs6000_secondary_memory_needed (enum reg_class class1,
14832 enum reg_class class2,
14833 enum machine_mode mode)
14835 if (class1 == class2)
14838 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14839 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14840 between these classes. But we need memory for other things that can go in
14841 FLOAT_REGS like SFmode. */
14843 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14844 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14845 || class1 == FLOAT_REGS))
14846 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14847 && class2 != FLOAT_REGS);
14849 if (class1 == VSX_REGS || class2 == VSX_REGS)
14852 if (class1 == FLOAT_REGS
14853 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14854 || ((mode != DFmode)
14855 && (mode != DDmode)
14856 && (mode != DImode))))
14859 if (class2 == FLOAT_REGS
14860 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14861 || ((mode != DFmode)
14862 && (mode != DDmode)
14863 && (mode != DImode))))
14866 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14872 /* Debug version of rs6000_secondary_memory_needed. */
14874 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14875 enum reg_class class2,
14876 enum machine_mode mode)
14878 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14881 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14882 "class2 = %s, mode = %s\n",
14883 ret ? "true" : "false", reg_class_names[class1],
14884 reg_class_names[class2], GET_MODE_NAME (mode));
14889 /* Return the register class of a scratch register needed to copy IN into
14890 or out of a register in RCLASS in MODE. If it can be done directly,
14891 NO_REGS is returned. */
14893 static enum reg_class
14894 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14899 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14901 && MACHOPIC_INDIRECT
14905 /* We cannot copy a symbolic operand directly into anything
14906 other than BASE_REGS for TARGET_ELF. So indicate that a
14907 register from BASE_REGS is needed as an intermediate
14910 On Darwin, pic addresses require a load from memory, which
14911 needs a base register. */
14912 if (rclass != BASE_REGS
14913 && (GET_CODE (in) == SYMBOL_REF
14914 || GET_CODE (in) == HIGH
14915 || GET_CODE (in) == LABEL_REF
14916 || GET_CODE (in) == CONST))
14920 if (GET_CODE (in) == REG)
14922 regno = REGNO (in);
14923 if (regno >= FIRST_PSEUDO_REGISTER)
14925 regno = true_regnum (in);
14926 if (regno >= FIRST_PSEUDO_REGISTER)
14930 else if (GET_CODE (in) == SUBREG)
14932 regno = true_regnum (in);
14933 if (regno >= FIRST_PSEUDO_REGISTER)
14939 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14941 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14942 || (regno >= 0 && INT_REGNO_P (regno)))
14945 /* Constants, memory, and FP registers can go into FP registers. */
14946 if ((regno == -1 || FP_REGNO_P (regno))
14947 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14948 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14950 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14953 && (regno == -1 || VSX_REGNO_P (regno))
14954 && VSX_REG_CLASS_P (rclass))
14957 /* Memory, and AltiVec registers can go into AltiVec registers. */
14958 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14959 && rclass == ALTIVEC_REGS)
14962 /* We can copy among the CR registers. */
14963 if ((rclass == CR_REGS || rclass == CR0_REGS)
14964 && regno >= 0 && CR_REGNO_P (regno))
14967 /* Otherwise, we need GENERAL_REGS. */
14968 return GENERAL_REGS;
14971 /* Debug version of rs6000_secondary_reload_class. */
14972 static enum reg_class
14973 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14974 enum machine_mode mode, rtx in)
14976 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14978 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14979 "mode = %s, input rtx:\n",
14980 reg_class_names[ret], reg_class_names[rclass],
14981 GET_MODE_NAME (mode));
14987 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14990 rs6000_cannot_change_mode_class (enum machine_mode from,
14991 enum machine_mode to,
14992 enum reg_class rclass)
14994 unsigned from_size = GET_MODE_SIZE (from);
14995 unsigned to_size = GET_MODE_SIZE (to);
14997 if (from_size != to_size)
14999 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15000 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15001 && reg_classes_intersect_p (xclass, rclass));
15004 if (TARGET_E500_DOUBLE
15005 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15006 || (((to) == TFmode) + ((from) == TFmode)) == 1
15007 || (((to) == DDmode) + ((from) == DDmode)) == 1
15008 || (((to) == TDmode) + ((from) == TDmode)) == 1
15009 || (((to) == DImode) + ((from) == DImode)) == 1))
15012 /* Since the VSX register set includes traditional floating point registers
15013 and altivec registers, just check for the size being different instead of
15014 trying to check whether the modes are vector modes. Otherwise it won't
15015 allow say DF and DI to change classes. */
15016 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15017 return (from_size != 8 && from_size != 16);
15019 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15020 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15023 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15024 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15030 /* Debug version of rs6000_cannot_change_mode_class. */
15032 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15033 enum machine_mode to,
15034 enum reg_class rclass)
15036 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15039 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15040 "to = %s, rclass = %s\n",
15041 ret ? "true" : "false",
15042 GET_MODE_NAME (from), GET_MODE_NAME (to),
15043 reg_class_names[rclass]);
15048 /* Given a comparison operation, return the bit number in CCR to test. We
15049 know this is a valid comparison.
15051 SCC_P is 1 if this is for an scc. That means that %D will have been
15052 used instead of %C, so the bits will be in different places.
15054 Return -1 if OP isn't a valid comparison for some reason. */
15057 ccr_bit (rtx op, int scc_p)
15059 enum rtx_code code = GET_CODE (op);
15060 enum machine_mode cc_mode;
15065 if (!COMPARISON_P (op))
15068 reg = XEXP (op, 0);
15070 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15072 cc_mode = GET_MODE (reg);
15073 cc_regnum = REGNO (reg);
15074 base_bit = 4 * (cc_regnum - CR0_REGNO);
15076 validate_condition_mode (code, cc_mode);
15078 /* When generating a sCOND operation, only positive conditions are
15081 || code == EQ || code == GT || code == LT || code == UNORDERED
15082 || code == GTU || code == LTU);
15087 return scc_p ? base_bit + 3 : base_bit + 2;
15089 return base_bit + 2;
15090 case GT: case GTU: case UNLE:
15091 return base_bit + 1;
15092 case LT: case LTU: case UNGE:
15094 case ORDERED: case UNORDERED:
15095 return base_bit + 3;
15098 /* If scc, we will have done a cror to put the bit in the
15099 unordered position. So test that bit. For integer, this is ! LT
15100 unless this is an scc insn. */
15101 return scc_p ? base_bit + 3 : base_bit;
15104 return scc_p ? base_bit + 3 : base_bit + 1;
15107 gcc_unreachable ();
15111 /* Return the GOT register. */
15114 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15116 /* The second flow pass currently (June 1999) can't update
15117 regs_ever_live without disturbing other parts of the compiler, so
15118 update it here to make the prolog/epilogue code happy. */
15119 if (!can_create_pseudo_p ()
15120 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15121 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15123 crtl->uses_pic_offset_table = 1;
15125 return pic_offset_table_rtx;
15128 /* Function to init struct machine_function.
15129 This will be called, via a pointer variable,
15130 from push_function_context. */
15132 static struct machine_function *
15133 rs6000_init_machine_status (void)
15135 return ggc_alloc_cleared_machine_function ();
15138 /* These macros test for integers and extract the low-order bits. */
15140 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15141 && GET_MODE (X) == VOIDmode)
15143 #define INT_LOWPART(X) \
15144 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15147 extract_MB (rtx op)
15150 unsigned long val = INT_LOWPART (op);
15152 /* If the high bit is zero, the value is the first 1 bit we find
15154 if ((val & 0x80000000) == 0)
15156 gcc_assert (val & 0xffffffff);
15159 while (((val <<= 1) & 0x80000000) == 0)
15164 /* If the high bit is set and the low bit is not, or the mask is all
15165 1's, the value is zero. */
15166 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15169 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15172 while (((val >>= 1) & 1) != 0)
15179 extract_ME (rtx op)
15182 unsigned long val = INT_LOWPART (op);
15184 /* If the low bit is zero, the value is the first 1 bit we find from
15186 if ((val & 1) == 0)
15188 gcc_assert (val & 0xffffffff);
15191 while (((val >>= 1) & 1) == 0)
15197 /* If the low bit is set and the high bit is not, or the mask is all
15198 1's, the value is 31. */
15199 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15202 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15205 while (((val <<= 1) & 0x80000000) != 0)
15211 /* Locate some local-dynamic symbol still in use by this function
15212 so that we can print its name in some tls_ld pattern. */
15214 static const char *
15215 rs6000_get_some_local_dynamic_name (void)
15219 if (cfun->machine->some_ld_name)
15220 return cfun->machine->some_ld_name;
15222 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15224 && for_each_rtx (&PATTERN (insn),
15225 rs6000_get_some_local_dynamic_name_1, 0))
15226 return cfun->machine->some_ld_name;
15228 gcc_unreachable ();
15231 /* Helper function for rs6000_get_some_local_dynamic_name. */
15234 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15238 if (GET_CODE (x) == SYMBOL_REF)
15240 const char *str = XSTR (x, 0);
15241 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15243 cfun->machine->some_ld_name = str;
15251 /* Write out a function code label. */
15254 rs6000_output_function_entry (FILE *file, const char *fname)
15256 if (fname[0] != '.')
15258 switch (DEFAULT_ABI)
15261 gcc_unreachable ();
15267 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15276 RS6000_OUTPUT_BASENAME (file, fname);
15279 /* Print an operand. Recognize special options, documented below. */
15282 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15283 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15285 #define SMALL_DATA_RELOC "sda21"
15286 #define SMALL_DATA_REG 0
15290 print_operand (FILE *file, rtx x, int code)
15294 unsigned HOST_WIDE_INT uval;
15299 /* Write out an instruction after the call which may be replaced
15300 with glue code by the loader. This depends on the AIX version. */
15301 asm_fprintf (file, RS6000_CALL_GLUE);
15304 /* %a is output_address. */
15307 /* If X is a constant integer whose low-order 5 bits are zero,
15308 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15309 in the AIX assembler where "sri" with a zero shift count
15310 writes a trash instruction. */
15311 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15318 /* If constant, low-order 16 bits of constant, unsigned.
15319 Otherwise, write normally. */
15321 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15323 print_operand (file, x, 0);
15327 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15328 for 64-bit mask direction. */
15329 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15332 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15336 /* X is a CR register. Print the number of the GT bit of the CR. */
15337 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15338 output_operand_lossage ("invalid %%c value");
15340 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15344 /* Like 'J' but get to the GT bit only. */
15345 gcc_assert (GET_CODE (x) == REG);
15347 /* Bit 1 is GT bit. */
15348 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15350 /* Add one for shift count in rlinm for scc. */
15351 fprintf (file, "%d", i + 1);
15355 /* X is a CR register. Print the number of the EQ bit of the CR */
15356 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15357 output_operand_lossage ("invalid %%E value");
15359 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15363 /* X is a CR register. Print the shift count needed to move it
15364 to the high-order four bits. */
15365 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15366 output_operand_lossage ("invalid %%f value");
15368 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15372 /* Similar, but print the count for the rotate in the opposite
15374 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15375 output_operand_lossage ("invalid %%F value");
15377 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15381 /* X is a constant integer. If it is negative, print "m",
15382 otherwise print "z". This is to make an aze or ame insn. */
15383 if (GET_CODE (x) != CONST_INT)
15384 output_operand_lossage ("invalid %%G value");
15385 else if (INTVAL (x) >= 0)
15392 /* If constant, output low-order five bits. Otherwise, write
15395 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15397 print_operand (file, x, 0);
15401 /* If constant, output low-order six bits. Otherwise, write
15404 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15406 print_operand (file, x, 0);
15410 /* Print `i' if this is a constant, else nothing. */
15416 /* Write the bit number in CCR for jump. */
15417 i = ccr_bit (x, 0);
15419 output_operand_lossage ("invalid %%j code");
15421 fprintf (file, "%d", i);
15425 /* Similar, but add one for shift count in rlinm for scc and pass
15426 scc flag to `ccr_bit'. */
15427 i = ccr_bit (x, 1);
15429 output_operand_lossage ("invalid %%J code");
15431 /* If we want bit 31, write a shift count of zero, not 32. */
15432 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15436 /* X must be a constant. Write the 1's complement of the
15439 output_operand_lossage ("invalid %%k value");
15441 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15445 /* X must be a symbolic constant on ELF. Write an
15446 expression suitable for an 'addi' that adds in the low 16
15447 bits of the MEM. */
15448 if (GET_CODE (x) == CONST)
15450 if (GET_CODE (XEXP (x, 0)) != PLUS
15451 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15452 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15453 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15454 output_operand_lossage ("invalid %%K value");
15456 print_operand_address (file, x);
15457 fputs ("@l", file);
15460 /* %l is output_asm_label. */
15463 /* Write second word of DImode or DFmode reference. Works on register
15464 or non-indexed memory only. */
15465 if (GET_CODE (x) == REG)
15466 fputs (reg_names[REGNO (x) + 1], file);
15467 else if (GET_CODE (x) == MEM)
15469 /* Handle possible auto-increment. Since it is pre-increment and
15470 we have already done it, we can just use an offset of word. */
15471 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15472 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15473 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15475 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15476 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15479 output_address (XEXP (adjust_address_nv (x, SImode,
15483 if (small_data_operand (x, GET_MODE (x)))
15484 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15485 reg_names[SMALL_DATA_REG]);
15490 /* MB value for a mask operand. */
15491 if (! mask_operand (x, SImode))
15492 output_operand_lossage ("invalid %%m value");
15494 fprintf (file, "%d", extract_MB (x));
15498 /* ME value for a mask operand. */
15499 if (! mask_operand (x, SImode))
15500 output_operand_lossage ("invalid %%M value");
15502 fprintf (file, "%d", extract_ME (x));
15505 /* %n outputs the negative of its operand. */
15508 /* Write the number of elements in the vector times 4. */
15509 if (GET_CODE (x) != PARALLEL)
15510 output_operand_lossage ("invalid %%N value");
15512 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15516 /* Similar, but subtract 1 first. */
15517 if (GET_CODE (x) != PARALLEL)
15518 output_operand_lossage ("invalid %%O value");
15520 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15524 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15526 || INT_LOWPART (x) < 0
15527 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15528 output_operand_lossage ("invalid %%p value");
15530 fprintf (file, "%d", i);
15534 /* The operand must be an indirect memory reference. The result
15535 is the register name. */
15536 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15537 || REGNO (XEXP (x, 0)) >= 32)
15538 output_operand_lossage ("invalid %%P value");
15540 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15544 /* This outputs the logical code corresponding to a boolean
15545 expression. The expression may have one or both operands
15546 negated (if one, only the first one). For condition register
15547 logical operations, it will also treat the negated
15548 CR codes as NOTs, but not handle NOTs of them. */
15550 const char *const *t = 0;
15552 enum rtx_code code = GET_CODE (x);
15553 static const char * const tbl[3][3] = {
15554 { "and", "andc", "nor" },
15555 { "or", "orc", "nand" },
15556 { "xor", "eqv", "xor" } };
15560 else if (code == IOR)
15562 else if (code == XOR)
15565 output_operand_lossage ("invalid %%q value");
15567 if (GET_CODE (XEXP (x, 0)) != NOT)
15571 if (GET_CODE (XEXP (x, 1)) == NOT)
15589 /* X is a CR register. Print the mask for `mtcrf'. */
15590 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15591 output_operand_lossage ("invalid %%R value");
15593 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15597 /* Low 5 bits of 32 - value */
15599 output_operand_lossage ("invalid %%s value");
15601 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15605 /* PowerPC64 mask position. All 0's is excluded.
15606 CONST_INT 32-bit mask is considered sign-extended so any
15607 transition must occur within the CONST_INT, not on the boundary. */
15608 if (! mask64_operand (x, DImode))
15609 output_operand_lossage ("invalid %%S value");
15611 uval = INT_LOWPART (x);
15613 if (uval & 1) /* Clear Left */
15615 #if HOST_BITS_PER_WIDE_INT > 64
15616 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15620 else /* Clear Right */
15623 #if HOST_BITS_PER_WIDE_INT > 64
15624 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15630 gcc_assert (i >= 0);
15631 fprintf (file, "%d", i);
15635 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15636 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15638 /* Bit 3 is OV bit. */
15639 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15641 /* If we want bit 31, write a shift count of zero, not 32. */
15642 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15646 /* Print the symbolic name of a branch target register. */
15647 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15648 && REGNO (x) != CTR_REGNO))
15649 output_operand_lossage ("invalid %%T value");
15650 else if (REGNO (x) == LR_REGNO)
15651 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15653 fputs ("ctr", file);
15657 /* High-order 16 bits of constant for use in unsigned operand. */
15659 output_operand_lossage ("invalid %%u value");
15661 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15662 (INT_LOWPART (x) >> 16) & 0xffff);
15666 /* High-order 16 bits of constant for use in signed operand. */
15668 output_operand_lossage ("invalid %%v value");
15670 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15671 (INT_LOWPART (x) >> 16) & 0xffff);
15675 /* Print `u' if this has an auto-increment or auto-decrement. */
15676 if (GET_CODE (x) == MEM
15677 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15678 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15679 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15684 /* Print the trap code for this operand. */
15685 switch (GET_CODE (x))
15688 fputs ("eq", file); /* 4 */
15691 fputs ("ne", file); /* 24 */
15694 fputs ("lt", file); /* 16 */
15697 fputs ("le", file); /* 20 */
15700 fputs ("gt", file); /* 8 */
15703 fputs ("ge", file); /* 12 */
15706 fputs ("llt", file); /* 2 */
15709 fputs ("lle", file); /* 6 */
15712 fputs ("lgt", file); /* 1 */
15715 fputs ("lge", file); /* 5 */
15718 gcc_unreachable ();
15723 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15726 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15727 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15729 print_operand (file, x, 0);
15733 /* MB value for a PowerPC64 rldic operand. */
15734 val = (GET_CODE (x) == CONST_INT
15735 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15740 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15741 if ((val <<= 1) < 0)
15744 #if HOST_BITS_PER_WIDE_INT == 32
15745 if (GET_CODE (x) == CONST_INT && i >= 0)
15746 i += 32; /* zero-extend high-part was all 0's */
15747 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15749 val = CONST_DOUBLE_LOW (x);
15755 for ( ; i < 64; i++)
15756 if ((val <<= 1) < 0)
15761 fprintf (file, "%d", i + 1);
15765 /* X is a FPR or Altivec register used in a VSX context. */
15766 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15767 output_operand_lossage ("invalid %%x value");
15770 int reg = REGNO (x);
15771 int vsx_reg = (FP_REGNO_P (reg)
15773 : reg - FIRST_ALTIVEC_REGNO + 32);
15775 #ifdef TARGET_REGNAMES
15776 if (TARGET_REGNAMES)
15777 fprintf (file, "%%vs%d", vsx_reg);
15780 fprintf (file, "%d", vsx_reg);
15785 if (GET_CODE (x) == MEM
15786 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15787 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15788 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15793 /* Like 'L', for third word of TImode */
15794 if (GET_CODE (x) == REG)
15795 fputs (reg_names[REGNO (x) + 2], file);
15796 else if (GET_CODE (x) == MEM)
15798 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15799 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15800 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15801 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15802 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15804 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15805 if (small_data_operand (x, GET_MODE (x)))
15806 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15807 reg_names[SMALL_DATA_REG]);
15812 /* X is a SYMBOL_REF. Write out the name preceded by a
15813 period and without any trailing data in brackets. Used for function
15814 names. If we are configured for System V (or the embedded ABI) on
15815 the PowerPC, do not emit the period, since those systems do not use
15816 TOCs and the like. */
15817 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15819 /* Mark the decl as referenced so that cgraph will output the
15821 if (SYMBOL_REF_DECL (x))
15822 mark_decl_referenced (SYMBOL_REF_DECL (x));
15824 /* For macho, check to see if we need a stub. */
15827 const char *name = XSTR (x, 0);
15829 if (darwin_emit_branch_islands
15830 && MACHOPIC_INDIRECT
15831 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15832 name = machopic_indirection_name (x, /*stub_p=*/true);
15834 assemble_name (file, name);
15836 else if (!DOT_SYMBOLS)
15837 assemble_name (file, XSTR (x, 0));
15839 rs6000_output_function_entry (file, XSTR (x, 0));
15843 /* Like 'L', for last word of TImode. */
15844 if (GET_CODE (x) == REG)
15845 fputs (reg_names[REGNO (x) + 3], file);
15846 else if (GET_CODE (x) == MEM)
15848 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15849 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15850 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15851 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15852 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15854 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15855 if (small_data_operand (x, GET_MODE (x)))
15856 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15857 reg_names[SMALL_DATA_REG]);
15861 /* Print AltiVec or SPE memory operand. */
15866 gcc_assert (GET_CODE (x) == MEM);
15870 /* Ugly hack because %y is overloaded. */
15871 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15872 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15873 || GET_MODE (x) == TFmode
15874 || GET_MODE (x) == TImode))
15876 /* Handle [reg]. */
15877 if (GET_CODE (tmp) == REG)
15879 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15882 /* Handle [reg+UIMM]. */
15883 else if (GET_CODE (tmp) == PLUS &&
15884 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15888 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15890 x = INTVAL (XEXP (tmp, 1));
15891 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15895 /* Fall through. Must be [reg+reg]. */
15897 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15898 && GET_CODE (tmp) == AND
15899 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15900 && INTVAL (XEXP (tmp, 1)) == -16)
15901 tmp = XEXP (tmp, 0);
15902 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15903 && GET_CODE (tmp) == PRE_MODIFY)
15904 tmp = XEXP (tmp, 1);
15905 if (GET_CODE (tmp) == REG)
15906 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15909 if (!GET_CODE (tmp) == PLUS
15910 || !REG_P (XEXP (tmp, 0))
15911 || !REG_P (XEXP (tmp, 1)))
15913 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15917 if (REGNO (XEXP (tmp, 0)) == 0)
15918 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15919 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15921 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15922 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15928 if (GET_CODE (x) == REG)
15929 fprintf (file, "%s", reg_names[REGNO (x)]);
15930 else if (GET_CODE (x) == MEM)
15932 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15933 know the width from the mode. */
15934 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15935 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15936 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15937 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15938 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15939 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15940 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15941 output_address (XEXP (XEXP (x, 0), 1));
15943 output_address (XEXP (x, 0));
15946 output_addr_const (file, x);
15950 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15954 output_operand_lossage ("invalid %%xn code");
15958 /* Print the address of an operand. */
15961 print_operand_address (FILE *file, rtx x)
15963 if (GET_CODE (x) == REG)
15964 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15965 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15966 || GET_CODE (x) == LABEL_REF)
15968 output_addr_const (file, x);
15969 if (small_data_operand (x, GET_MODE (x)))
15970 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15971 reg_names[SMALL_DATA_REG]);
15973 gcc_assert (!TARGET_TOC);
15975 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15977 gcc_assert (REG_P (XEXP (x, 0)));
15978 if (REGNO (XEXP (x, 0)) == 0)
15979 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15980 reg_names[ REGNO (XEXP (x, 0)) ]);
15982 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15983 reg_names[ REGNO (XEXP (x, 1)) ]);
15985 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15986 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15987 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15989 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15990 && CONSTANT_P (XEXP (x, 1)))
15992 fprintf (file, "lo16(");
15993 output_addr_const (file, XEXP (x, 1));
15994 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15997 else if (legitimate_constant_pool_address_p (x, true))
15999 /* This hack along with a corresponding hack in
16000 rs6000_output_addr_const_extra arranges to output addends
16001 where the assembler expects to find them. eg.
16003 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16004 without this hack would be output as "x@toc+8@l(9)". We
16005 want "x+8@toc@l(9)". */
16006 output_addr_const (file, tocrel_base);
16007 if (GET_CODE (x) == LO_SUM)
16008 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16010 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16013 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16014 && CONSTANT_P (XEXP (x, 1)))
16016 output_addr_const (file, XEXP (x, 1));
16017 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16021 gcc_unreachable ();
16024 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
16027 rs6000_output_addr_const_extra (FILE *file, rtx x)
16029 if (GET_CODE (x) == UNSPEC)
16030 switch (XINT (x, 1))
16032 case UNSPEC_TOCREL:
16033 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16034 output_addr_const (file, XVECEXP (x, 0, 0));
16035 if (x == tocrel_base && tocrel_offset != const0_rtx)
16037 if (INTVAL (tocrel_offset) >= 0)
16038 fprintf (file, "+");
16039 output_addr_const (file, tocrel_offset);
16041 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16044 assemble_name (file, toc_label_name);
16046 else if (TARGET_ELF)
16047 fputs ("@toc", file);
16051 case UNSPEC_MACHOPIC_OFFSET:
16052 output_addr_const (file, XVECEXP (x, 0, 0));
16054 machopic_output_function_base_name (file);
16061 /* Target hook for assembling integer objects. The PowerPC version has
16062 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16063 is defined. It also needs to handle DI-mode objects on 64-bit
16067 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16069 #ifdef RELOCATABLE_NEEDS_FIXUP
16070 /* Special handling for SI values. */
16071 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16073 static int recurse = 0;
16075 /* For -mrelocatable, we mark all addresses that need to be fixed up
16076 in the .fixup section. */
16077 if (TARGET_RELOCATABLE
16078 && in_section != toc_section
16079 && in_section != text_section
16080 && !unlikely_text_section_p (in_section)
16082 && GET_CODE (x) != CONST_INT
16083 && GET_CODE (x) != CONST_DOUBLE
16089 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16091 ASM_OUTPUT_LABEL (asm_out_file, buf);
16092 fprintf (asm_out_file, "\t.long\t(");
16093 output_addr_const (asm_out_file, x);
16094 fprintf (asm_out_file, ")@fixup\n");
16095 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16096 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16097 fprintf (asm_out_file, "\t.long\t");
16098 assemble_name (asm_out_file, buf);
16099 fprintf (asm_out_file, "\n\t.previous\n");
16103 /* Remove initial .'s to turn a -mcall-aixdesc function
16104 address into the address of the descriptor, not the function
16106 else if (GET_CODE (x) == SYMBOL_REF
16107 && XSTR (x, 0)[0] == '.'
16108 && DEFAULT_ABI == ABI_AIX)
16110 const char *name = XSTR (x, 0);
16111 while (*name == '.')
16114 fprintf (asm_out_file, "\t.long\t%s\n", name);
16118 #endif /* RELOCATABLE_NEEDS_FIXUP */
16119 return default_assemble_integer (x, size, aligned_p);
16122 #ifdef HAVE_GAS_HIDDEN
16123 /* Emit an assembler directive to set symbol visibility for DECL to
16124 VISIBILITY_TYPE. */
16127 rs6000_assemble_visibility (tree decl, int vis)
16129 /* Functions need to have their entry point symbol visibility set as
16130 well as their descriptor symbol visibility. */
16131 if (DEFAULT_ABI == ABI_AIX
16133 && TREE_CODE (decl) == FUNCTION_DECL)
16135 static const char * const visibility_types[] = {
16136 NULL, "internal", "hidden", "protected"
16139 const char *name, *type;
16141 name = ((* targetm.strip_name_encoding)
16142 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16143 type = visibility_types[vis];
16145 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16146 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16149 default_assemble_visibility (decl, vis);
16154 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16156 /* Reversal of FP compares takes care -- an ordered compare
16157 becomes an unordered compare and vice versa. */
16158 if (mode == CCFPmode
16159 && (!flag_finite_math_only
16160 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16161 || code == UNEQ || code == LTGT))
16162 return reverse_condition_maybe_unordered (code);
16164 return reverse_condition (code);
16167 /* Generate a compare for CODE. Return a brand-new rtx that
16168 represents the result of the compare. */
16171 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16173 enum machine_mode comp_mode;
16174 rtx compare_result;
16175 enum rtx_code code = GET_CODE (cmp);
16176 rtx op0 = XEXP (cmp, 0);
16177 rtx op1 = XEXP (cmp, 1);
16179 if (FLOAT_MODE_P (mode))
16180 comp_mode = CCFPmode;
16181 else if (code == GTU || code == LTU
16182 || code == GEU || code == LEU)
16183 comp_mode = CCUNSmode;
16184 else if ((code == EQ || code == NE)
16185 && GET_CODE (op0) == SUBREG
16186 && GET_CODE (op1) == SUBREG
16187 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16188 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16189 /* These are unsigned values, perhaps there will be a later
16190 ordering compare that can be shared with this one.
16191 Unfortunately we cannot detect the signedness of the operands
16192 for non-subregs. */
16193 comp_mode = CCUNSmode;
16195 comp_mode = CCmode;
16197 /* First, the compare. */
16198 compare_result = gen_reg_rtx (comp_mode);
16200 /* E500 FP compare instructions on the GPRs. Yuck! */
16201 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16202 && FLOAT_MODE_P (mode))
16204 rtx cmp, or_result, compare_result2;
16205 enum machine_mode op_mode = GET_MODE (op0);
16207 if (op_mode == VOIDmode)
16208 op_mode = GET_MODE (op1);
16210 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16211 This explains the following mess. */
16215 case EQ: case UNEQ: case NE: case LTGT:
16219 cmp = (flag_finite_math_only && !flag_trapping_math)
16220 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16221 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16225 cmp = (flag_finite_math_only && !flag_trapping_math)
16226 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16227 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16231 cmp = (flag_finite_math_only && !flag_trapping_math)
16232 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16233 : gen_cmptfeq_gpr (compare_result, op0, op1);
16237 gcc_unreachable ();
16241 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16245 cmp = (flag_finite_math_only && !flag_trapping_math)
16246 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16247 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16251 cmp = (flag_finite_math_only && !flag_trapping_math)
16252 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16253 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16257 cmp = (flag_finite_math_only && !flag_trapping_math)
16258 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16259 : gen_cmptfgt_gpr (compare_result, op0, op1);
16263 gcc_unreachable ();
16267 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16271 cmp = (flag_finite_math_only && !flag_trapping_math)
16272 ? gen_tstsflt_gpr (compare_result, op0, op1)
16273 : gen_cmpsflt_gpr (compare_result, op0, op1);
16277 cmp = (flag_finite_math_only && !flag_trapping_math)
16278 ? gen_tstdflt_gpr (compare_result, op0, op1)
16279 : gen_cmpdflt_gpr (compare_result, op0, op1);
16283 cmp = (flag_finite_math_only && !flag_trapping_math)
16284 ? gen_tsttflt_gpr (compare_result, op0, op1)
16285 : gen_cmptflt_gpr (compare_result, op0, op1);
16289 gcc_unreachable ();
16293 gcc_unreachable ();
16296 /* Synthesize LE and GE from LT/GT || EQ. */
16297 if (code == LE || code == GE || code == LEU || code == GEU)
16303 case LE: code = LT; break;
16304 case GE: code = GT; break;
16305 case LEU: code = LT; break;
16306 case GEU: code = GT; break;
16307 default: gcc_unreachable ();
16310 compare_result2 = gen_reg_rtx (CCFPmode);
16316 cmp = (flag_finite_math_only && !flag_trapping_math)
16317 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16318 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16322 cmp = (flag_finite_math_only && !flag_trapping_math)
16323 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16324 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16328 cmp = (flag_finite_math_only && !flag_trapping_math)
16329 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16330 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16334 gcc_unreachable ();
16338 /* OR them together. */
16339 or_result = gen_reg_rtx (CCFPmode);
16340 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16342 compare_result = or_result;
16347 if (code == NE || code == LTGT)
16357 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16358 CLOBBERs to match cmptf_internal2 pattern. */
16359 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16360 && GET_MODE (op0) == TFmode
16361 && !TARGET_IEEEQUAD
16362 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16363 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16365 gen_rtx_SET (VOIDmode,
16367 gen_rtx_COMPARE (comp_mode, op0, op1)),
16368 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16369 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16370 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16371 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16372 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16373 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16374 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16375 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16376 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16377 else if (GET_CODE (op1) == UNSPEC
16378 && XINT (op1, 1) == UNSPEC_SP_TEST)
16380 rtx op1b = XVECEXP (op1, 0, 0);
16381 comp_mode = CCEQmode;
16382 compare_result = gen_reg_rtx (CCEQmode);
16384 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16386 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16389 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16390 gen_rtx_COMPARE (comp_mode, op0, op1)));
16393 /* Some kinds of FP comparisons need an OR operation;
16394 under flag_finite_math_only we don't bother. */
16395 if (FLOAT_MODE_P (mode)
16396 && !flag_finite_math_only
16397 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16398 && (code == LE || code == GE
16399 || code == UNEQ || code == LTGT
16400 || code == UNGT || code == UNLT))
16402 enum rtx_code or1, or2;
16403 rtx or1_rtx, or2_rtx, compare2_rtx;
16404 rtx or_result = gen_reg_rtx (CCEQmode);
16408 case LE: or1 = LT; or2 = EQ; break;
16409 case GE: or1 = GT; or2 = EQ; break;
16410 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16411 case LTGT: or1 = LT; or2 = GT; break;
16412 case UNGT: or1 = UNORDERED; or2 = GT; break;
16413 case UNLT: or1 = UNORDERED; or2 = LT; break;
16414 default: gcc_unreachable ();
16416 validate_condition_mode (or1, comp_mode);
16417 validate_condition_mode (or2, comp_mode);
16418 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16419 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16420 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16421 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16423 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16425 compare_result = or_result;
16429 validate_condition_mode (code, GET_MODE (compare_result));
16431 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16435 /* Emit the RTL for an sISEL pattern. */
16438 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16440 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16444 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16447 enum machine_mode op_mode;
16448 enum rtx_code cond_code;
16449 rtx result = operands[0];
16451 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16453 rs6000_emit_sISEL (mode, operands);
16457 condition_rtx = rs6000_generate_compare (operands[1], mode);
16458 cond_code = GET_CODE (condition_rtx);
16460 if (FLOAT_MODE_P (mode)
16461 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16465 PUT_MODE (condition_rtx, SImode);
16466 t = XEXP (condition_rtx, 0);
16468 gcc_assert (cond_code == NE || cond_code == EQ);
16470 if (cond_code == NE)
16471 emit_insn (gen_e500_flip_gt_bit (t, t));
16473 emit_insn (gen_move_from_CR_gt_bit (result, t));
16477 if (cond_code == NE
16478 || cond_code == GE || cond_code == LE
16479 || cond_code == GEU || cond_code == LEU
16480 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16482 rtx not_result = gen_reg_rtx (CCEQmode);
16483 rtx not_op, rev_cond_rtx;
16484 enum machine_mode cc_mode;
16486 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16488 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16489 SImode, XEXP (condition_rtx, 0), const0_rtx);
16490 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16491 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16492 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16495 op_mode = GET_MODE (XEXP (operands[1], 0));
16496 if (op_mode == VOIDmode)
16497 op_mode = GET_MODE (XEXP (operands[1], 1));
16499 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16501 PUT_MODE (condition_rtx, DImode);
16502 convert_move (result, condition_rtx, 0);
16506 PUT_MODE (condition_rtx, SImode);
16507 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16511 /* Emit a branch of kind CODE to location LOC. */
16514 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16516 rtx condition_rtx, loc_ref;
16518 condition_rtx = rs6000_generate_compare (operands[0], mode);
16519 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16520 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16521 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16522 loc_ref, pc_rtx)));
16525 /* Return the string to output a conditional branch to LABEL, which is
16526 the operand number of the label, or -1 if the branch is really a
16527 conditional return.
16529 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16530 condition code register and its mode specifies what kind of
16531 comparison we made.
16533 REVERSED is nonzero if we should reverse the sense of the comparison.
16535 INSN is the insn. */
16538 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16540 static char string[64];
16541 enum rtx_code code = GET_CODE (op);
16542 rtx cc_reg = XEXP (op, 0);
16543 enum machine_mode mode = GET_MODE (cc_reg);
16544 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16545 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16546 int really_reversed = reversed ^ need_longbranch;
16552 validate_condition_mode (code, mode);
16554 /* Work out which way this really branches. We could use
16555 reverse_condition_maybe_unordered here always but this
16556 makes the resulting assembler clearer. */
16557 if (really_reversed)
16559 /* Reversal of FP compares takes care -- an ordered compare
16560 becomes an unordered compare and vice versa. */
16561 if (mode == CCFPmode)
16562 code = reverse_condition_maybe_unordered (code);
16564 code = reverse_condition (code);
16567 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16569 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16574 /* Opposite of GT. */
16583 gcc_unreachable ();
16589 /* Not all of these are actually distinct opcodes, but
16590 we distinguish them for clarity of the resulting assembler. */
16591 case NE: case LTGT:
16592 ccode = "ne"; break;
16593 case EQ: case UNEQ:
16594 ccode = "eq"; break;
16596 ccode = "ge"; break;
16597 case GT: case GTU: case UNGT:
16598 ccode = "gt"; break;
16600 ccode = "le"; break;
16601 case LT: case LTU: case UNLT:
16602 ccode = "lt"; break;
16603 case UNORDERED: ccode = "un"; break;
16604 case ORDERED: ccode = "nu"; break;
16605 case UNGE: ccode = "nl"; break;
16606 case UNLE: ccode = "ng"; break;
16608 gcc_unreachable ();
16611 /* Maybe we have a guess as to how likely the branch is.
16612 The old mnemonics don't have a way to specify this information. */
16614 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16615 if (note != NULL_RTX)
16617 /* PROB is the difference from 50%. */
16618 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16620 /* Only hint for highly probable/improbable branches on newer
16621 cpus as static prediction overrides processor dynamic
16622 prediction. For older cpus we may as well always hint, but
16623 assume not taken for branches that are very close to 50% as a
16624 mispredicted taken branch is more expensive than a
16625 mispredicted not-taken branch. */
16626 if (rs6000_always_hint
16627 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16628 && br_prob_note_reliable_p (note)))
16630 if (abs (prob) > REG_BR_PROB_BASE / 20
16631 && ((prob > 0) ^ need_longbranch))
16639 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16641 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16643 /* We need to escape any '%' characters in the reg_names string.
16644 Assume they'd only be the first character.... */
16645 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16647 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16651 /* If the branch distance was too far, we may have to use an
16652 unconditional branch to go the distance. */
16653 if (need_longbranch)
16654 s += sprintf (s, ",$+8\n\tb %s", label);
16656 s += sprintf (s, ",%s", label);
16662 /* Return the string to flip the GT bit on a CR. */
16664 output_e500_flip_gt_bit (rtx dst, rtx src)
16666 static char string[64];
16669 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16670 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16673 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16674 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16676 sprintf (string, "crnot %d,%d", a, b);
16680 /* Return insn for VSX or Altivec comparisons. */
16683 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16686 enum machine_mode mode = GET_MODE (op0);
16694 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16700 mask = gen_reg_rtx (mode);
16701 emit_insn (gen_rtx_SET (VOIDmode,
16703 gen_rtx_fmt_ee (code, mode, op0, op1)));
16710 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16711 DMODE is expected destination mode. This is a recursive function. */
16714 rs6000_emit_vector_compare (enum rtx_code rcode,
16716 enum machine_mode dmode)
16719 bool swap_operands = false;
16720 bool try_again = false;
16722 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16723 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16725 /* See if the comparison works as is. */
16726 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16734 swap_operands = true;
16739 swap_operands = true;
16747 /* Invert condition and try again.
16748 e.g., A != B becomes ~(A==B). */
16750 enum rtx_code rev_code;
16751 enum insn_code nor_code;
16754 rev_code = reverse_condition_maybe_unordered (rcode);
16755 if (rev_code == UNKNOWN)
16758 nor_code = optab_handler (one_cmpl_optab, dmode);
16759 if (nor_code == CODE_FOR_nothing)
16762 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16766 mask = gen_reg_rtx (dmode);
16767 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16775 /* Try GT/GTU/LT/LTU OR EQ */
16778 enum insn_code ior_code;
16779 enum rtx_code new_code;
16800 gcc_unreachable ();
16803 ior_code = optab_handler (ior_optab, dmode);
16804 if (ior_code == CODE_FOR_nothing)
16807 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16811 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16815 mask = gen_reg_rtx (dmode);
16816 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16834 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16839 /* You only get two chances. */
16843 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16844 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16845 operands for the relation operation COND. */
16848 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16849 rtx cond, rtx cc_op0, rtx cc_op1)
16851 enum machine_mode dest_mode = GET_MODE (dest);
16852 enum rtx_code rcode = GET_CODE (cond);
16853 enum machine_mode cc_mode = CCmode;
16857 bool invert_move = false;
16859 if (VECTOR_UNIT_NONE_P (dest_mode))
16864 /* Swap operands if we can, and fall back to doing the operation as
16865 specified, and doing a NOR to invert the test. */
16871 /* Invert condition and try again.
16872 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16873 invert_move = true;
16874 rcode = reverse_condition_maybe_unordered (rcode);
16875 if (rcode == UNKNOWN)
16879 /* Mark unsigned tests with CCUNSmode. */
16884 cc_mode = CCUNSmode;
16891 /* Get the vector mask for the given relational operations. */
16892 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16900 op_true = op_false;
16904 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16905 emit_insn (gen_rtx_SET (VOIDmode,
16907 gen_rtx_IF_THEN_ELSE (dest_mode,
16914 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16915 operands of the last comparison is nonzero/true, FALSE_COND if it
16916 is zero/false. Return 0 if the hardware has no such operation. */
16919 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16921 enum rtx_code code = GET_CODE (op);
16922 rtx op0 = XEXP (op, 0);
16923 rtx op1 = XEXP (op, 1);
16924 REAL_VALUE_TYPE c1;
16925 enum machine_mode compare_mode = GET_MODE (op0);
16926 enum machine_mode result_mode = GET_MODE (dest);
16928 bool is_against_zero;
16930 /* These modes should always match. */
16931 if (GET_MODE (op1) != compare_mode
16932 /* In the isel case however, we can use a compare immediate, so
16933 op1 may be a small constant. */
16934 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16936 if (GET_MODE (true_cond) != result_mode)
16938 if (GET_MODE (false_cond) != result_mode)
16941 /* First, work out if the hardware can do this at all, or
16942 if it's too slow.... */
16943 if (!FLOAT_MODE_P (compare_mode))
16946 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16949 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16950 && SCALAR_FLOAT_MODE_P (compare_mode))
16953 is_against_zero = op1 == CONST0_RTX (compare_mode);
16955 /* A floating-point subtract might overflow, underflow, or produce
16956 an inexact result, thus changing the floating-point flags, so it
16957 can't be generated if we care about that. It's safe if one side
16958 of the construct is zero, since then no subtract will be
16960 if (SCALAR_FLOAT_MODE_P (compare_mode)
16961 && flag_trapping_math && ! is_against_zero)
16964 /* Eliminate half of the comparisons by switching operands, this
16965 makes the remaining code simpler. */
16966 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16967 || code == LTGT || code == LT || code == UNLE)
16969 code = reverse_condition_maybe_unordered (code);
16971 true_cond = false_cond;
16975 /* UNEQ and LTGT take four instructions for a comparison with zero,
16976 it'll probably be faster to use a branch here too. */
16977 if (code == UNEQ && HONOR_NANS (compare_mode))
16980 if (GET_CODE (op1) == CONST_DOUBLE)
16981 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16983 /* We're going to try to implement comparisons by performing
16984 a subtract, then comparing against zero. Unfortunately,
16985 Inf - Inf is NaN which is not zero, and so if we don't
16986 know that the operand is finite and the comparison
16987 would treat EQ different to UNORDERED, we can't do it. */
16988 if (HONOR_INFINITIES (compare_mode)
16989 && code != GT && code != UNGE
16990 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16991 /* Constructs of the form (a OP b ? a : b) are safe. */
16992 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16993 || (! rtx_equal_p (op0, true_cond)
16994 && ! rtx_equal_p (op1, true_cond))))
16997 /* At this point we know we can use fsel. */
16999 /* Reduce the comparison to a comparison against zero. */
17000 if (! is_against_zero)
17002 temp = gen_reg_rtx (compare_mode);
17003 emit_insn (gen_rtx_SET (VOIDmode, temp,
17004 gen_rtx_MINUS (compare_mode, op0, op1)));
17006 op1 = CONST0_RTX (compare_mode);
17009 /* If we don't care about NaNs we can reduce some of the comparisons
17010 down to faster ones. */
17011 if (! HONOR_NANS (compare_mode))
17017 true_cond = false_cond;
17030 /* Now, reduce everything down to a GE. */
17037 temp = gen_reg_rtx (compare_mode);
17038 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17043 temp = gen_reg_rtx (compare_mode);
17044 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17049 temp = gen_reg_rtx (compare_mode);
17050 emit_insn (gen_rtx_SET (VOIDmode, temp,
17051 gen_rtx_NEG (compare_mode,
17052 gen_rtx_ABS (compare_mode, op0))));
17057 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17058 temp = gen_reg_rtx (result_mode);
17059 emit_insn (gen_rtx_SET (VOIDmode, temp,
17060 gen_rtx_IF_THEN_ELSE (result_mode,
17061 gen_rtx_GE (VOIDmode,
17063 true_cond, false_cond)));
17064 false_cond = true_cond;
17067 temp = gen_reg_rtx (compare_mode);
17068 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17073 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17074 temp = gen_reg_rtx (result_mode);
17075 emit_insn (gen_rtx_SET (VOIDmode, temp,
17076 gen_rtx_IF_THEN_ELSE (result_mode,
17077 gen_rtx_GE (VOIDmode,
17079 true_cond, false_cond)));
17080 true_cond = false_cond;
17083 temp = gen_reg_rtx (compare_mode);
17084 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17089 gcc_unreachable ();
17092 emit_insn (gen_rtx_SET (VOIDmode, dest,
17093 gen_rtx_IF_THEN_ELSE (result_mode,
17094 gen_rtx_GE (VOIDmode,
17096 true_cond, false_cond)));
17100 /* Same as above, but for ints (isel). */
17103 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17105 rtx condition_rtx, cr;
17106 enum machine_mode mode = GET_MODE (dest);
17107 enum rtx_code cond_code;
17108 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17111 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17114 /* We still have to do the compare, because isel doesn't do a
17115 compare, it just looks at the CRx bits set by a previous compare
17117 condition_rtx = rs6000_generate_compare (op, mode);
17118 cond_code = GET_CODE (condition_rtx);
17119 cr = XEXP (condition_rtx, 0);
17120 signedp = GET_MODE (cr) == CCmode;
17122 isel_func = (mode == SImode
17123 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17124 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17128 case LT: case GT: case LTU: case GTU: case EQ:
17129 /* isel handles these directly. */
17133 /* We need to swap the sense of the comparison. */
17136 true_cond = false_cond;
17138 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17143 false_cond = force_reg (mode, false_cond);
17144 if (true_cond != const0_rtx)
17145 true_cond = force_reg (mode, true_cond);
17147 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17153 output_isel (rtx *operands)
17155 enum rtx_code code;
17157 code = GET_CODE (operands[1]);
17159 gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
17161 return "isel %0,%2,%3,%j1";
17165 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17167 enum machine_mode mode = GET_MODE (op0);
17171 /* VSX/altivec have direct min/max insns. */
17172 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
17174 emit_insn (gen_rtx_SET (VOIDmode,
17176 gen_rtx_fmt_ee (code, mode, op0, op1)));
17180 if (code == SMAX || code == SMIN)
17185 if (code == SMAX || code == UMAX)
17186 target = emit_conditional_move (dest, c, op0, op1, mode,
17187 op0, op1, mode, 0);
17189 target = emit_conditional_move (dest, c, op0, op1, mode,
17190 op1, op0, mode, 0);
17191 gcc_assert (target);
17192 if (target != dest)
17193 emit_move_insn (dest, target);
17196 /* Emit instructions to perform a load-reserved/store-conditional operation.
17197 The operation performed is an atomic
17198 (set M (CODE:MODE M OP))
17199 If not NULL, BEFORE is atomically set to M before the operation, and
17200 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17201 If SYNC_P then a memory barrier is emitted before the operation.
17202 Either OP or M may be wrapped in a NOT operation. */
17205 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17206 rtx m, rtx op, rtx before_param, rtx after_param,
17209 enum machine_mode used_mode;
17210 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17213 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17214 rtx shift = NULL_RTX;
17217 emit_insn (gen_lwsync ());
17221 /* If this is smaller than SImode, we'll have to use SImode with
17223 if (mode == QImode || mode == HImode)
17227 if (MEM_ALIGN (used_m) >= 32)
17230 if (BYTES_BIG_ENDIAN)
17231 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17233 shift = GEN_INT (ishift);
17234 used_m = change_address (used_m, SImode, 0);
17238 rtx addrSI, aligned_addr;
17239 int shift_mask = mode == QImode ? 0x18 : 0x10;
17241 addrSI = gen_lowpart_common (SImode,
17242 force_reg (Pmode, XEXP (used_m, 0)));
17243 addrSI = force_reg (SImode, addrSI);
17244 shift = gen_reg_rtx (SImode);
17246 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17247 GEN_INT (shift_mask)));
17248 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17250 aligned_addr = expand_binop (Pmode, and_optab,
17252 GEN_INT (-4), NULL_RTX,
17253 1, OPTAB_LIB_WIDEN);
17254 used_m = change_address (used_m, SImode, aligned_addr);
17255 set_mem_align (used_m, 32);
17257 /* It's safe to keep the old alias set of USED_M, because
17258 the operation is atomic and only affects the original
17262 if (GET_CODE (op) == NOT)
17264 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17265 oldop = gen_rtx_NOT (SImode, oldop);
17268 oldop = lowpart_subreg (SImode, op, mode);
17274 newop = expand_binop (SImode, and_optab,
17275 oldop, GEN_INT (imask), NULL_RTX,
17276 1, OPTAB_LIB_WIDEN);
17277 emit_insn (gen_ashlsi3 (newop, newop, shift));
17280 case NOT: /* NAND */
17281 newop = expand_binop (SImode, ior_optab,
17282 oldop, GEN_INT (~imask), NULL_RTX,
17283 1, OPTAB_LIB_WIDEN);
17284 emit_insn (gen_rotlsi3 (newop, newop, shift));
17288 newop = expand_binop (SImode, ior_optab,
17289 oldop, GEN_INT (~imask), NULL_RTX,
17290 1, OPTAB_LIB_WIDEN);
17291 emit_insn (gen_rotlsi3 (newop, newop, shift));
17299 newop = expand_binop (SImode, and_optab,
17300 oldop, GEN_INT (imask), NULL_RTX,
17301 1, OPTAB_LIB_WIDEN);
17302 emit_insn (gen_ashlsi3 (newop, newop, shift));
17304 mask = gen_reg_rtx (SImode);
17305 emit_move_insn (mask, GEN_INT (imask));
17306 emit_insn (gen_ashlsi3 (mask, mask, shift));
17309 newop = gen_rtx_PLUS (SImode, m, newop);
17311 newop = gen_rtx_MINUS (SImode, m, newop);
17312 newop = gen_rtx_AND (SImode, newop, mask);
17313 newop = gen_rtx_IOR (SImode, newop,
17314 gen_rtx_AND (SImode,
17315 gen_rtx_NOT (SImode, mask),
17321 gcc_unreachable ();
17325 used_mode = SImode;
17326 before = gen_reg_rtx (used_mode);
17327 after = gen_reg_rtx (used_mode);
17332 before = before_param;
17333 after = after_param;
17335 if (before == NULL_RTX)
17336 before = gen_reg_rtx (used_mode);
17337 if (after == NULL_RTX)
17338 after = gen_reg_rtx (used_mode);
17341 if ((code == PLUS || code == MINUS)
17342 && used_mode != mode)
17343 the_op = op; /* Computed above. */
17344 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17345 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17346 else if (code == NOT)
17347 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17348 gen_rtx_NOT (used_mode, m),
17349 gen_rtx_NOT (used_mode, op));
17351 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17353 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17354 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17355 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17356 gen_rtx_UNSPEC (used_mode,
17357 gen_rtvec (1, the_op),
17359 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17361 if ((code == PLUS || code == MINUS) && used_mode != mode)
17362 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17363 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17365 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17366 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17368 /* Shift and mask the return values properly. */
17369 if (used_mode != mode && before_param)
17371 emit_insn (gen_lshrsi3 (before, before, shift));
17372 convert_move (before_param, before, 1);
17375 if (used_mode != mode && after_param)
17377 emit_insn (gen_lshrsi3 (after, after, shift));
17378 convert_move (after_param, after, 1);
17381 /* The previous sequence will end with a branch that's dependent on
17382 the conditional store, so placing an isync will ensure that no
17383 other instructions (especially, no load or store instructions)
17384 can start before the atomic operation completes. */
17386 emit_insn (gen_isync ());
17389 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17390 COND is true. Mark the jump as unlikely to be taken. */
17393 emit_unlikely_jump (rtx cond, rtx label)
17395 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17398 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17399 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17400 add_reg_note (x, REG_BR_PROB, very_unlikely);
17403 /* A subroutine of the atomic operation splitters. Emit a load-locked
17404 instruction in MODE. */
17407 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17409 rtx (*fn) (rtx, rtx) = NULL;
17410 if (mode == SImode)
17411 fn = gen_load_locked_si;
17412 else if (mode == DImode)
17413 fn = gen_load_locked_di;
17414 emit_insn (fn (reg, mem));
17417 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17418 instruction in MODE. */
17421 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17423 rtx (*fn) (rtx, rtx, rtx) = NULL;
17424 if (mode == SImode)
17425 fn = gen_store_conditional_si;
17426 else if (mode == DImode)
17427 fn = gen_store_conditional_di;
17429 /* Emit sync before stwcx. to address PPC405 Erratum. */
17430 if (PPC405_ERRATUM77)
17431 emit_insn (gen_memory_barrier ());
17433 emit_insn (fn (res, mem, val));
17436 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17437 to perform. MEM is the memory on which to operate. VAL is the second
17438 operand of the binary operator. BEFORE and AFTER are optional locations to
17439 return the value of MEM either before of after the operation. SCRATCH is
17440 a scratch register. */
17443 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17444 rtx before, rtx after, rtx scratch)
17446 enum machine_mode mode = GET_MODE (mem);
17447 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17449 emit_insn (gen_lwsync ());
17451 label = gen_label_rtx ();
17452 emit_label (label);
17453 label = gen_rtx_LABEL_REF (VOIDmode, label);
17455 if (before == NULL_RTX)
17457 emit_load_locked (mode, before, mem);
17460 x = gen_rtx_IOR (mode,
17461 gen_rtx_NOT (mode, before),
17462 gen_rtx_NOT (mode, val));
17463 else if (code == AND)
17464 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17466 x = gen_rtx_fmt_ee (code, mode, before, val);
17468 if (after != NULL_RTX)
17469 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17470 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17472 emit_store_conditional (mode, cond, mem, scratch);
17474 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17475 emit_unlikely_jump (x, label);
17477 emit_insn (gen_isync ());
17480 /* Expand an atomic compare and swap operation. MEM is the memory on which
17481 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17482 value to be stored. SCRATCH is a scratch GPR. */
17485 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17488 enum machine_mode mode = GET_MODE (mem);
17489 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17491 emit_insn (gen_lwsync ());
17493 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17494 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17495 emit_label (XEXP (label1, 0));
17497 emit_load_locked (mode, retval, mem);
17499 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17500 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17502 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17503 emit_unlikely_jump (x, label2);
17505 emit_move_insn (scratch, newval);
17506 emit_store_conditional (mode, cond, mem, scratch);
17508 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17509 emit_unlikely_jump (x, label1);
17511 emit_insn (gen_isync ());
17512 emit_label (XEXP (label2, 0));
17515 /* Expand an atomic test and set operation. MEM is the memory on which
17516 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17519 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17521 enum machine_mode mode = GET_MODE (mem);
17522 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17524 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17525 emit_label (XEXP (label, 0));
17527 emit_load_locked (mode, retval, mem);
17528 emit_move_insn (scratch, val);
17529 emit_store_conditional (mode, cond, mem, scratch);
17531 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17532 emit_unlikely_jump (x, label);
17534 emit_insn (gen_isync ());
17538 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17540 enum machine_mode mode = GET_MODE (mem);
17541 rtx addrSI, align, wdst, shift, mask;
17542 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17543 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17545 /* Shift amount for subword relative to aligned word. */
17546 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17547 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17548 shift = gen_reg_rtx (SImode);
17549 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17550 GEN_INT (shift_mask)));
17551 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17553 /* Shift and mask old value into position within word. */
17554 oldval = convert_modes (SImode, mode, oldval, 1);
17555 oldval = expand_binop (SImode, and_optab,
17556 oldval, GEN_INT (imask), NULL_RTX,
17557 1, OPTAB_LIB_WIDEN);
17558 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17560 /* Shift and mask new value into position within word. */
17561 newval = convert_modes (SImode, mode, newval, 1);
17562 newval = expand_binop (SImode, and_optab,
17563 newval, GEN_INT (imask), NULL_RTX,
17564 1, OPTAB_LIB_WIDEN);
17565 emit_insn (gen_ashlsi3 (newval, newval, shift));
17567 /* Mask for insertion. */
17568 mask = gen_reg_rtx (SImode);
17569 emit_move_insn (mask, GEN_INT (imask));
17570 emit_insn (gen_ashlsi3 (mask, mask, shift));
17572 /* Address of aligned word containing subword. */
17573 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17574 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17575 mem = change_address (mem, SImode, align);
17576 set_mem_align (mem, 32);
17577 MEM_VOLATILE_P (mem) = 1;
17579 wdst = gen_reg_rtx (SImode);
17580 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17581 oldval, newval, mem));
17583 /* Shift the result back. */
17584 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17586 emit_move_insn (dst, gen_lowpart (mode, wdst));
17590 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17591 rtx oldval, rtx newval, rtx mem,
17594 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17596 emit_insn (gen_lwsync ());
17597 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17598 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17599 emit_label (XEXP (label1, 0));
17601 emit_load_locked (SImode, scratch, mem);
17603 /* Mask subword within loaded value for comparison with oldval.
17604 Use UNSPEC_AND to avoid clobber.*/
17605 emit_insn (gen_rtx_SET (SImode, dest,
17606 gen_rtx_UNSPEC (SImode,
17607 gen_rtvec (2, scratch, mask),
17610 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17611 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17613 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17614 emit_unlikely_jump (x, label2);
17616 /* Clear subword within loaded value for insertion of new value. */
17617 emit_insn (gen_rtx_SET (SImode, scratch,
17618 gen_rtx_AND (SImode,
17619 gen_rtx_NOT (SImode, mask), scratch)));
17620 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17621 emit_store_conditional (SImode, cond, mem, scratch);
17623 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17624 emit_unlikely_jump (x, label1);
17626 emit_insn (gen_isync ());
17627 emit_label (XEXP (label2, 0));
17631 /* Emit instructions to move SRC to DST. Called by splitters for
17632 multi-register moves. It will emit at most one instruction for
17633 each register that is accessed; that is, it won't emit li/lis pairs
17634 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17638 rs6000_split_multireg_move (rtx dst, rtx src)
17640 /* The register number of the first register being moved. */
17642 /* The mode that is to be moved. */
17643 enum machine_mode mode;
17644 /* The mode that the move is being done in, and its size. */
17645 enum machine_mode reg_mode;
17647 /* The number of registers that will be moved. */
17650 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17651 mode = GET_MODE (dst);
17652 nregs = hard_regno_nregs[reg][mode];
17653 if (FP_REGNO_P (reg))
17654 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17655 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17656 else if (ALTIVEC_REGNO_P (reg))
17657 reg_mode = V16QImode;
17658 else if (TARGET_E500_DOUBLE && mode == TFmode)
17661 reg_mode = word_mode;
17662 reg_mode_size = GET_MODE_SIZE (reg_mode);
17664 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17666 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17668 /* Move register range backwards, if we might have destructive
17671 for (i = nregs - 1; i >= 0; i--)
17672 emit_insn (gen_rtx_SET (VOIDmode,
17673 simplify_gen_subreg (reg_mode, dst, mode,
17674 i * reg_mode_size),
17675 simplify_gen_subreg (reg_mode, src, mode,
17676 i * reg_mode_size)));
17682 bool used_update = false;
17683 rtx restore_basereg = NULL_RTX;
17685 if (MEM_P (src) && INT_REGNO_P (reg))
17689 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17690 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17693 breg = XEXP (XEXP (src, 0), 0);
17694 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17695 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17696 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17697 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17698 src = replace_equiv_address (src, breg);
17700 else if (! rs6000_offsettable_memref_p (src))
17702 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17704 rtx basereg = XEXP (XEXP (src, 0), 0);
17707 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17708 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17709 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17710 used_update = true;
17713 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17714 XEXP (XEXP (src, 0), 1)));
17715 src = replace_equiv_address (src, basereg);
17719 rtx basereg = gen_rtx_REG (Pmode, reg);
17720 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17721 src = replace_equiv_address (src, basereg);
17725 breg = XEXP (src, 0);
17726 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17727 breg = XEXP (breg, 0);
17729 /* If the base register we are using to address memory is
17730 also a destination reg, then change that register last. */
17732 && REGNO (breg) >= REGNO (dst)
17733 && REGNO (breg) < REGNO (dst) + nregs)
17734 j = REGNO (breg) - REGNO (dst);
17736 else if (MEM_P (dst) && INT_REGNO_P (reg))
17740 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17741 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17744 breg = XEXP (XEXP (dst, 0), 0);
17745 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17746 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17747 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17749 /* We have to update the breg before doing the store.
17750 Use store with update, if available. */
17754 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17755 emit_insn (TARGET_32BIT
17756 ? (TARGET_POWERPC64
17757 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17758 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17759 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17760 used_update = true;
17763 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17764 dst = replace_equiv_address (dst, breg);
17766 else if (!rs6000_offsettable_memref_p (dst)
17767 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17769 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17771 rtx basereg = XEXP (XEXP (dst, 0), 0);
17774 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17775 emit_insn (gen_rtx_SET (VOIDmode,
17776 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17777 used_update = true;
17780 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17781 XEXP (XEXP (dst, 0), 1)));
17782 dst = replace_equiv_address (dst, basereg);
17786 rtx basereg = XEXP (XEXP (dst, 0), 0);
17787 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17788 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17790 && REG_P (offsetreg)
17791 && REGNO (basereg) != REGNO (offsetreg));
17792 if (REGNO (basereg) == 0)
17794 rtx tmp = offsetreg;
17795 offsetreg = basereg;
17798 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17799 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17800 dst = replace_equiv_address (dst, basereg);
17803 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17804 gcc_assert (rs6000_offsettable_memref_p (dst));
17807 for (i = 0; i < nregs; i++)
17809 /* Calculate index to next subword. */
17814 /* If compiler already emitted move of first word by
17815 store with update, no need to do anything. */
17816 if (j == 0 && used_update)
17819 emit_insn (gen_rtx_SET (VOIDmode,
17820 simplify_gen_subreg (reg_mode, dst, mode,
17821 j * reg_mode_size),
17822 simplify_gen_subreg (reg_mode, src, mode,
17823 j * reg_mode_size)));
17825 if (restore_basereg != NULL_RTX)
17826 emit_insn (restore_basereg);
17831 /* This page contains routines that are used to determine what the
17832 function prologue and epilogue code will do and write them out. */
17834 /* Return the first fixed-point register that is required to be
17835 saved. 32 if none. */
17838 first_reg_to_save (void)
17842 /* Find lowest numbered live register. */
17843 for (first_reg = 13; first_reg <= 31; first_reg++)
17844 if (df_regs_ever_live_p (first_reg)
17845 && (! call_used_regs[first_reg]
17846 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17847 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17848 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17849 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17854 && crtl->uses_pic_offset_table
17855 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17856 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17862 /* Similar, for FP regs. */
17865 first_fp_reg_to_save (void)
17869 /* Find lowest numbered live register. */
17870 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17871 if (df_regs_ever_live_p (first_reg))
17877 /* Similar, for AltiVec regs. */
17880 first_altivec_reg_to_save (void)
17884 /* Stack frame remains as is unless we are in AltiVec ABI. */
17885 if (! TARGET_ALTIVEC_ABI)
17886 return LAST_ALTIVEC_REGNO + 1;
17888 /* On Darwin, the unwind routines are compiled without
17889 TARGET_ALTIVEC, and use save_world to save/restore the
17890 altivec registers when necessary. */
17891 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17892 && ! TARGET_ALTIVEC)
17893 return FIRST_ALTIVEC_REGNO + 20;
17895 /* Find lowest numbered live register. */
17896 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17897 if (df_regs_ever_live_p (i))
17903 /* Return a 32-bit mask of the AltiVec registers we need to set in
17904 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17905 the 32-bit word is 0. */
17907 static unsigned int
17908 compute_vrsave_mask (void)
17910 unsigned int i, mask = 0;
17912 /* On Darwin, the unwind routines are compiled without
17913 TARGET_ALTIVEC, and use save_world to save/restore the
17914 call-saved altivec registers when necessary. */
17915 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17916 && ! TARGET_ALTIVEC)
17919 /* First, find out if we use _any_ altivec registers. */
17920 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17921 if (df_regs_ever_live_p (i))
17922 mask |= ALTIVEC_REG_BIT (i);
17927 /* Next, remove the argument registers from the set. These must
17928 be in the VRSAVE mask set by the caller, so we don't need to add
17929 them in again. More importantly, the mask we compute here is
17930 used to generate CLOBBERs in the set_vrsave insn, and we do not
17931 wish the argument registers to die. */
17932 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17933 mask &= ~ALTIVEC_REG_BIT (i);
17935 /* Similarly, remove the return value from the set. */
17938 diddle_return_value (is_altivec_return_reg, &yes);
17940 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17946 /* For a very restricted set of circumstances, we can cut down the
17947 size of prologues/epilogues by calling our own save/restore-the-world
17951 compute_save_world_info (rs6000_stack_t *info_ptr)
17953 info_ptr->world_save_p = 1;
17954 info_ptr->world_save_p
17955 = (WORLD_SAVE_P (info_ptr)
17956 && DEFAULT_ABI == ABI_DARWIN
17957 && ! (cfun->calls_setjmp && flag_exceptions)
17958 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17959 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17960 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17961 && info_ptr->cr_save_p);
17963 /* This will not work in conjunction with sibcalls. Make sure there
17964 are none. (This check is expensive, but seldom executed.) */
17965 if (WORLD_SAVE_P (info_ptr))
17968 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17969 if ( GET_CODE (insn) == CALL_INSN
17970 && SIBLING_CALL_P (insn))
17972 info_ptr->world_save_p = 0;
17977 if (WORLD_SAVE_P (info_ptr))
17979 /* Even if we're not touching VRsave, make sure there's room on the
17980 stack for it, if it looks like we're calling SAVE_WORLD, which
17981 will attempt to save it. */
17982 info_ptr->vrsave_size = 4;
17984 /* If we are going to save the world, we need to save the link register too. */
17985 info_ptr->lr_save_p = 1;
17987 /* "Save" the VRsave register too if we're saving the world. */
17988 if (info_ptr->vrsave_mask == 0)
17989 info_ptr->vrsave_mask = compute_vrsave_mask ();
17991 /* Because the Darwin register save/restore routines only handle
17992 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17994 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17995 && (info_ptr->first_altivec_reg_save
17996 >= FIRST_SAVED_ALTIVEC_REGNO));
18003 is_altivec_return_reg (rtx reg, void *xyes)
18005 bool *yes = (bool *) xyes;
18006 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18011 /* Calculate the stack information for the current function. This is
18012 complicated by having two separate calling sequences, the AIX calling
18013 sequence and the V.4 calling sequence.
18015 AIX (and Darwin/Mac OS X) stack frames look like:
18017 SP----> +---------------------------------------+
18018 | back chain to caller | 0 0
18019 +---------------------------------------+
18020 | saved CR | 4 8 (8-11)
18021 +---------------------------------------+
18023 +---------------------------------------+
18024 | reserved for compilers | 12 24
18025 +---------------------------------------+
18026 | reserved for binders | 16 32
18027 +---------------------------------------+
18028 | saved TOC pointer | 20 40
18029 +---------------------------------------+
18030 | Parameter save area (P) | 24 48
18031 +---------------------------------------+
18032 | Alloca space (A) | 24+P etc.
18033 +---------------------------------------+
18034 | Local variable space (L) | 24+P+A
18035 +---------------------------------------+
18036 | Float/int conversion temporary (X) | 24+P+A+L
18037 +---------------------------------------+
18038 | Save area for AltiVec registers (W) | 24+P+A+L+X
18039 +---------------------------------------+
18040 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18041 +---------------------------------------+
18042 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18043 +---------------------------------------+
18044 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18045 +---------------------------------------+
18046 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18047 +---------------------------------------+
18048 old SP->| back chain to caller's caller |
18049 +---------------------------------------+
18051 The required alignment for AIX configurations is two words (i.e., 8
18055 V.4 stack frames look like:
18057 SP----> +---------------------------------------+
18058 | back chain to caller | 0
18059 +---------------------------------------+
18060 | caller's saved LR | 4
18061 +---------------------------------------+
18062 | Parameter save area (P) | 8
18063 +---------------------------------------+
18064 | Alloca space (A) | 8+P
18065 +---------------------------------------+
18066 | Varargs save area (V) | 8+P+A
18067 +---------------------------------------+
18068 | Local variable space (L) | 8+P+A+V
18069 +---------------------------------------+
18070 | Float/int conversion temporary (X) | 8+P+A+V+L
18071 +---------------------------------------+
18072 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18073 +---------------------------------------+
18074 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18075 +---------------------------------------+
18076 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18077 +---------------------------------------+
18078 | SPE: area for 64-bit GP registers |
18079 +---------------------------------------+
18080 | SPE alignment padding |
18081 +---------------------------------------+
18082 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18083 +---------------------------------------+
18084 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18085 +---------------------------------------+
18086 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18087 +---------------------------------------+
18088 old SP->| back chain to caller's caller |
18089 +---------------------------------------+
18091 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18092 given. (But note below and in sysv4.h that we require only 8 and
18093 may round up the size of our stack frame anyways. The historical
18094 reason is early versions of powerpc-linux which didn't properly
18095 align the stack at program startup. A happy side-effect is that
18096 -mno-eabi libraries can be used with -meabi programs.)
18098 The EABI configuration defaults to the V.4 layout. However,
18099 the stack alignment requirements may differ. If -mno-eabi is not
18100 given, the required stack alignment is 8 bytes; if -mno-eabi is
18101 given, the required alignment is 16 bytes. (But see V.4 comment
18104 #ifndef ABI_STACK_BOUNDARY
18105 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18108 static rs6000_stack_t *
18109 rs6000_stack_info (void)
18111 static rs6000_stack_t info;
18112 rs6000_stack_t *info_ptr = &info;
18113 int reg_size = TARGET_32BIT ? 4 : 8;
18117 HOST_WIDE_INT non_fixed_size;
18119 memset (&info, 0, sizeof (info));
18123 /* Cache value so we don't rescan instruction chain over and over. */
18124 if (cfun->machine->insn_chain_scanned_p == 0)
18125 cfun->machine->insn_chain_scanned_p
18126 = spe_func_has_64bit_regs_p () + 1;
18127 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18130 /* Select which calling sequence. */
18131 info_ptr->abi = DEFAULT_ABI;
18133 /* Calculate which registers need to be saved & save area size. */
18134 info_ptr->first_gp_reg_save = first_reg_to_save ();
18135 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18136 even if it currently looks like we won't. Reload may need it to
18137 get at a constant; if so, it will have already created a constant
18138 pool entry for it. */
18139 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18140 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18141 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18142 && crtl->uses_const_pool
18143 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18144 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18146 first_gp = info_ptr->first_gp_reg_save;
18148 info_ptr->gp_size = reg_size * (32 - first_gp);
18150 /* For the SPE, we have an additional upper 32-bits on each GPR.
18151 Ideally we should save the entire 64-bits only when the upper
18152 half is used in SIMD instructions. Since we only record
18153 registers live (not the size they are used in), this proves
18154 difficult because we'd have to traverse the instruction chain at
18155 the right time, taking reload into account. This is a real pain,
18156 so we opt to save the GPRs in 64-bits always if but one register
18157 gets used in 64-bits. Otherwise, all the registers in the frame
18158 get saved in 32-bits.
18160 So... since when we save all GPRs (except the SP) in 64-bits, the
18161 traditional GP save area will be empty. */
18162 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18163 info_ptr->gp_size = 0;
18165 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18166 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18168 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18169 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18170 - info_ptr->first_altivec_reg_save);
18172 /* Does this function call anything? */
18173 info_ptr->calls_p = (! current_function_is_leaf
18174 || cfun->machine->ra_needs_full_frame);
18176 /* Determine if we need to save the link register. */
18177 if ((DEFAULT_ABI == ABI_AIX
18179 && !TARGET_PROFILE_KERNEL)
18180 #ifdef TARGET_RELOCATABLE
18181 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18183 || (info_ptr->first_fp_reg_save != 64
18184 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
18185 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18186 || info_ptr->calls_p
18187 || rs6000_ra_ever_killed ())
18189 info_ptr->lr_save_p = 1;
18190 df_set_regs_ever_live (LR_REGNO, true);
18193 /* Determine if we need to save the condition code registers. */
18194 if (df_regs_ever_live_p (CR2_REGNO)
18195 || df_regs_ever_live_p (CR3_REGNO)
18196 || df_regs_ever_live_p (CR4_REGNO))
18198 info_ptr->cr_save_p = 1;
18199 if (DEFAULT_ABI == ABI_V4)
18200 info_ptr->cr_size = reg_size;
18203 /* If the current function calls __builtin_eh_return, then we need
18204 to allocate stack space for registers that will hold data for
18205 the exception handler. */
18206 if (crtl->calls_eh_return)
18209 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18212 /* SPE saves EH registers in 64-bits. */
18213 ehrd_size = i * (TARGET_SPE_ABI
18214 && info_ptr->spe_64bit_regs_used != 0
18215 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18220 /* Determine various sizes. */
18221 info_ptr->reg_size = reg_size;
18222 info_ptr->fixed_size = RS6000_SAVE_AREA;
18223 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18224 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18225 TARGET_ALTIVEC ? 16 : 8);
18226 if (FRAME_GROWS_DOWNWARD)
18227 info_ptr->vars_size
18228 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18229 + info_ptr->parm_size,
18230 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18231 - (info_ptr->fixed_size + info_ptr->vars_size
18232 + info_ptr->parm_size);
18234 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18235 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18237 info_ptr->spe_gp_size = 0;
18239 if (TARGET_ALTIVEC_ABI)
18240 info_ptr->vrsave_mask = compute_vrsave_mask ();
18242 info_ptr->vrsave_mask = 0;
18244 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18245 info_ptr->vrsave_size = 4;
18247 info_ptr->vrsave_size = 0;
18249 compute_save_world_info (info_ptr);
18251 /* Calculate the offsets. */
18252 switch (DEFAULT_ABI)
18256 gcc_unreachable ();
18260 info_ptr->fp_save_offset = - info_ptr->fp_size;
18261 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18263 if (TARGET_ALTIVEC_ABI)
18265 info_ptr->vrsave_save_offset
18266 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18268 /* Align stack so vector save area is on a quadword boundary.
18269 The padding goes above the vectors. */
18270 if (info_ptr->altivec_size != 0)
18271 info_ptr->altivec_padding_size
18272 = info_ptr->vrsave_save_offset & 0xF;
18274 info_ptr->altivec_padding_size = 0;
18276 info_ptr->altivec_save_offset
18277 = info_ptr->vrsave_save_offset
18278 - info_ptr->altivec_padding_size
18279 - info_ptr->altivec_size;
18280 gcc_assert (info_ptr->altivec_size == 0
18281 || info_ptr->altivec_save_offset % 16 == 0);
18283 /* Adjust for AltiVec case. */
18284 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18287 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18288 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18289 info_ptr->lr_save_offset = 2*reg_size;
18293 info_ptr->fp_save_offset = - info_ptr->fp_size;
18294 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18295 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18297 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18299 /* Align stack so SPE GPR save area is aligned on a
18300 double-word boundary. */
18301 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18302 info_ptr->spe_padding_size
18303 = 8 - (-info_ptr->cr_save_offset % 8);
18305 info_ptr->spe_padding_size = 0;
18307 info_ptr->spe_gp_save_offset
18308 = info_ptr->cr_save_offset
18309 - info_ptr->spe_padding_size
18310 - info_ptr->spe_gp_size;
18312 /* Adjust for SPE case. */
18313 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18315 else if (TARGET_ALTIVEC_ABI)
18317 info_ptr->vrsave_save_offset
18318 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18320 /* Align stack so vector save area is on a quadword boundary. */
18321 if (info_ptr->altivec_size != 0)
18322 info_ptr->altivec_padding_size
18323 = 16 - (-info_ptr->vrsave_save_offset % 16);
18325 info_ptr->altivec_padding_size = 0;
18327 info_ptr->altivec_save_offset
18328 = info_ptr->vrsave_save_offset
18329 - info_ptr->altivec_padding_size
18330 - info_ptr->altivec_size;
18332 /* Adjust for AltiVec case. */
18333 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18336 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18337 info_ptr->ehrd_offset -= ehrd_size;
18338 info_ptr->lr_save_offset = reg_size;
18342 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18343 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18344 + info_ptr->gp_size
18345 + info_ptr->altivec_size
18346 + info_ptr->altivec_padding_size
18347 + info_ptr->spe_gp_size
18348 + info_ptr->spe_padding_size
18350 + info_ptr->cr_size
18351 + info_ptr->vrsave_size,
18354 non_fixed_size = (info_ptr->vars_size
18355 + info_ptr->parm_size
18356 + info_ptr->save_size);
18358 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18359 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18361 /* Determine if we need to allocate any stack frame:
18363 For AIX we need to push the stack if a frame pointer is needed
18364 (because the stack might be dynamically adjusted), if we are
18365 debugging, if we make calls, or if the sum of fp_save, gp_save,
18366 and local variables are more than the space needed to save all
18367 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18368 + 18*8 = 288 (GPR13 reserved).
18370 For V.4 we don't have the stack cushion that AIX uses, but assume
18371 that the debugger can handle stackless frames. */
18373 if (info_ptr->calls_p)
18374 info_ptr->push_p = 1;
18376 else if (DEFAULT_ABI == ABI_V4)
18377 info_ptr->push_p = non_fixed_size != 0;
18379 else if (frame_pointer_needed)
18380 info_ptr->push_p = 1;
18382 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18383 info_ptr->push_p = 1;
18386 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18388 /* Zero offsets if we're not saving those registers. */
18389 if (info_ptr->fp_size == 0)
18390 info_ptr->fp_save_offset = 0;
18392 if (info_ptr->gp_size == 0)
18393 info_ptr->gp_save_offset = 0;
18395 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18396 info_ptr->altivec_save_offset = 0;
18398 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18399 info_ptr->vrsave_save_offset = 0;
18401 if (! TARGET_SPE_ABI
18402 || info_ptr->spe_64bit_regs_used == 0
18403 || info_ptr->spe_gp_size == 0)
18404 info_ptr->spe_gp_save_offset = 0;
18406 if (! info_ptr->lr_save_p)
18407 info_ptr->lr_save_offset = 0;
18409 if (! info_ptr->cr_save_p)
18410 info_ptr->cr_save_offset = 0;
18415 /* Return true if the current function uses any GPRs in 64-bit SIMD
18419 spe_func_has_64bit_regs_p (void)
18423 /* Functions that save and restore all the call-saved registers will
18424 need to save/restore the registers in 64-bits. */
18425 if (crtl->calls_eh_return
18426 || cfun->calls_setjmp
18427 || crtl->has_nonlocal_goto)
18430 insns = get_insns ();
18432 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18438 /* FIXME: This should be implemented with attributes...
18440 (set_attr "spe64" "true")....then,
18441 if (get_spe64(insn)) return true;
18443 It's the only reliable way to do the stuff below. */
18445 i = PATTERN (insn);
18446 if (GET_CODE (i) == SET)
18448 enum machine_mode mode = GET_MODE (SET_SRC (i));
18450 if (SPE_VECTOR_MODE (mode))
18452 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18462 debug_stack_info (rs6000_stack_t *info)
18464 const char *abi_string;
18467 info = rs6000_stack_info ();
18469 fprintf (stderr, "\nStack information for function %s:\n",
18470 ((current_function_decl && DECL_NAME (current_function_decl))
18471 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18476 default: abi_string = "Unknown"; break;
18477 case ABI_NONE: abi_string = "NONE"; break;
18478 case ABI_AIX: abi_string = "AIX"; break;
18479 case ABI_DARWIN: abi_string = "Darwin"; break;
18480 case ABI_V4: abi_string = "V.4"; break;
18483 fprintf (stderr, "\tABI = %5s\n", abi_string);
18485 if (TARGET_ALTIVEC_ABI)
18486 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18488 if (TARGET_SPE_ABI)
18489 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18491 if (info->first_gp_reg_save != 32)
18492 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18494 if (info->first_fp_reg_save != 64)
18495 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18497 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18498 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18499 info->first_altivec_reg_save);
18501 if (info->lr_save_p)
18502 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18504 if (info->cr_save_p)
18505 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18507 if (info->vrsave_mask)
18508 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18511 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18514 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18516 if (info->gp_save_offset)
18517 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18519 if (info->fp_save_offset)
18520 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18522 if (info->altivec_save_offset)
18523 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18524 info->altivec_save_offset);
18526 if (info->spe_gp_save_offset)
18527 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18528 info->spe_gp_save_offset);
18530 if (info->vrsave_save_offset)
18531 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18532 info->vrsave_save_offset);
18534 if (info->lr_save_offset)
18535 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18537 if (info->cr_save_offset)
18538 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18540 if (info->varargs_save_offset)
18541 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18543 if (info->total_size)
18544 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18547 if (info->vars_size)
18548 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18551 if (info->parm_size)
18552 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18554 if (info->fixed_size)
18555 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18558 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18560 if (info->spe_gp_size)
18561 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18564 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18566 if (info->altivec_size)
18567 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18569 if (info->vrsave_size)
18570 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18572 if (info->altivec_padding_size)
18573 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18574 info->altivec_padding_size);
18576 if (info->spe_padding_size)
18577 fprintf (stderr, "\tspe_padding_size = %5d\n",
18578 info->spe_padding_size);
18581 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18583 if (info->save_size)
18584 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18586 if (info->reg_size != 4)
18587 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18589 fprintf (stderr, "\n");
18593 rs6000_return_addr (int count, rtx frame)
18595 /* Currently we don't optimize very well between prolog and body
18596 code and for PIC code the code can be actually quite bad, so
18597 don't try to be too clever here. */
18598 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18600 cfun->machine->ra_needs_full_frame = 1;
18607 plus_constant (copy_to_reg
18608 (gen_rtx_MEM (Pmode,
18609 memory_address (Pmode, frame))),
18610 RETURN_ADDRESS_OFFSET)));
18613 cfun->machine->ra_need_lr = 1;
18614 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18617 /* Say whether a function is a candidate for sibcall handling or not.
18618 We do not allow indirect calls to be optimized into sibling calls.
18619 Also, we can't do it if there are any vector parameters; there's
18620 nowhere to put the VRsave code so it works; note that functions with
18621 vector parameters are required to have a prototype, so the argument
18622 type info must be available here. (The tail recursion case can work
18623 with vector parameters, but there's no way to distinguish here.) */
18625 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18630 if (TARGET_ALTIVEC_VRSAVE)
18632 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18633 type; type = TREE_CHAIN (type))
18635 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18639 if (DEFAULT_ABI == ABI_DARWIN
18640 || ((*targetm.binds_local_p) (decl)
18641 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18643 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18645 if (!lookup_attribute ("longcall", attr_list)
18646 || lookup_attribute ("shortcall", attr_list))
18653 /* NULL if INSN insn is valid within a low-overhead loop.
18654 Otherwise return why doloop cannot be applied.
18655 PowerPC uses the COUNT register for branch on table instructions. */
18657 static const char *
18658 rs6000_invalid_within_doloop (const_rtx insn)
18661 return "Function call in the loop.";
18664 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18665 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18666 return "Computed branch in the loop.";
18672 rs6000_ra_ever_killed (void)
18678 if (cfun->is_thunk)
18681 if (cfun->machine->lr_save_state)
18682 return cfun->machine->lr_save_state - 1;
18684 /* regs_ever_live has LR marked as used if any sibcalls are present,
18685 but this should not force saving and restoring in the
18686 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18687 clobbers LR, so that is inappropriate. */
18689 /* Also, the prologue can generate a store into LR that
18690 doesn't really count, like this:
18693 bcl to set PIC register
18697 When we're called from the epilogue, we need to avoid counting
18698 this as a store. */
18700 push_topmost_sequence ();
18701 top = get_insns ();
18702 pop_topmost_sequence ();
18703 reg = gen_rtx_REG (Pmode, LR_REGNO);
18705 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18711 if (!SIBLING_CALL_P (insn))
18714 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18716 else if (set_of (reg, insn) != NULL_RTX
18717 && !prologue_epilogue_contains (insn))
18724 /* Emit instructions needed to load the TOC register.
18725 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18726 a constant pool; or for SVR4 -fpic. */
18729 rs6000_emit_load_toc_table (int fromprolog)
18732 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18734 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18737 rtx lab, tmp1, tmp2, got;
18739 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18740 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18742 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18744 got = rs6000_got_sym ();
18745 tmp1 = tmp2 = dest;
18748 tmp1 = gen_reg_rtx (Pmode);
18749 tmp2 = gen_reg_rtx (Pmode);
18751 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18752 emit_move_insn (tmp1,
18753 gen_rtx_REG (Pmode, LR_REGNO));
18754 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18755 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18757 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18759 emit_insn (gen_load_toc_v4_pic_si ());
18760 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18762 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18765 rtx temp0 = (fromprolog
18766 ? gen_rtx_REG (Pmode, 0)
18767 : gen_reg_rtx (Pmode));
18773 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18774 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18776 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18777 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18779 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18780 emit_move_insn (dest,
18781 gen_rtx_REG (Pmode, LR_REGNO));
18782 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18788 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18789 lab = gen_label_rtx ();
18790 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18791 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18792 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18794 emit_insn (gen_addsi3 (dest, temp0, dest));
18796 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18798 /* This is for AIX code running in non-PIC ELF32. */
18801 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18802 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18804 emit_insn (gen_elf_high (dest, realsym));
18805 emit_insn (gen_elf_low (dest, dest, realsym));
18809 gcc_assert (DEFAULT_ABI == ABI_AIX);
18812 emit_insn (gen_load_toc_aix_si (dest));
18814 emit_insn (gen_load_toc_aix_di (dest));
18818 /* Emit instructions to restore the link register after determining where
18819 its value has been stored. */
18822 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18824 rs6000_stack_t *info = rs6000_stack_info ();
18827 operands[0] = source;
18828 operands[1] = scratch;
18830 if (info->lr_save_p)
18832 rtx frame_rtx = stack_pointer_rtx;
18833 HOST_WIDE_INT sp_offset = 0;
18836 if (frame_pointer_needed
18837 || cfun->calls_alloca
18838 || info->total_size > 32767)
18840 tmp = gen_frame_mem (Pmode, frame_rtx);
18841 emit_move_insn (operands[1], tmp);
18842 frame_rtx = operands[1];
18844 else if (info->push_p)
18845 sp_offset = info->total_size;
18847 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18848 tmp = gen_frame_mem (Pmode, tmp);
18849 emit_move_insn (tmp, operands[0]);
18852 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18854 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18855 state of lr_save_p so any change from here on would be a bug. In
18856 particular, stop rs6000_ra_ever_killed from considering the SET
18857 of lr we may have added just above. */
18858 cfun->machine->lr_save_state = info->lr_save_p + 1;
18861 static GTY(()) alias_set_type set = -1;
18864 get_TOC_alias_set (void)
18867 set = new_alias_set ();
18871 /* This returns nonzero if the current function uses the TOC. This is
18872 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18873 is generated by the ABI_V4 load_toc_* patterns. */
18880 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18883 rtx pat = PATTERN (insn);
18886 if (GET_CODE (pat) == PARALLEL)
18887 for (i = 0; i < XVECLEN (pat, 0); i++)
18889 rtx sub = XVECEXP (pat, 0, i);
18890 if (GET_CODE (sub) == USE)
18892 sub = XEXP (sub, 0);
18893 if (GET_CODE (sub) == UNSPEC
18894 && XINT (sub, 1) == UNSPEC_TOC)
18904 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18906 rtx tocrel, tocreg;
18908 if (TARGET_DEBUG_ADDR)
18910 if (GET_CODE (symbol) == SYMBOL_REF)
18911 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18915 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18916 GET_RTX_NAME (GET_CODE (symbol)));
18917 debug_rtx (symbol);
18921 if (!can_create_pseudo_p ())
18922 df_set_regs_ever_live (TOC_REGISTER, true);
18924 tocrel = gen_rtx_CONST (Pmode,
18925 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18927 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18928 if (TARGET_CMODEL != CMODEL_SMALL)
18930 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18931 if (largetoc_reg != NULL)
18933 emit_move_insn (largetoc_reg, hi);
18936 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18939 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18942 /* Issue assembly directives that create a reference to the given DWARF
18943 FRAME_TABLE_LABEL from the current function section. */
18945 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18947 fprintf (asm_out_file, "\t.ref %s\n",
18948 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18951 /* If _Unwind_* has been called from within the same module,
18952 toc register is not guaranteed to be saved to 40(1) on function
18953 entry. Save it there in that case. */
18956 rs6000_aix_emit_builtin_unwind_init (void)
18959 rtx stack_top = gen_reg_rtx (Pmode);
18960 rtx opcode_addr = gen_reg_rtx (Pmode);
18961 rtx opcode = gen_reg_rtx (SImode);
18962 rtx tocompare = gen_reg_rtx (SImode);
18963 rtx no_toc_save_needed = gen_label_rtx ();
18965 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18966 emit_move_insn (stack_top, mem);
18968 mem = gen_frame_mem (Pmode,
18969 gen_rtx_PLUS (Pmode, stack_top,
18970 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18971 emit_move_insn (opcode_addr, mem);
18972 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18973 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18974 : 0xE8410028, SImode));
18976 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18977 SImode, NULL_RTX, NULL_RTX,
18978 no_toc_save_needed, -1);
18980 mem = gen_frame_mem (Pmode,
18981 gen_rtx_PLUS (Pmode, stack_top,
18982 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18983 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18984 emit_label (no_toc_save_needed);
18987 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18988 and the change to the stack pointer. */
18991 rs6000_emit_stack_tie (void)
18993 rtx mem = gen_frame_mem (BLKmode,
18994 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18996 emit_insn (gen_stack_tie (mem));
18999 /* Emit the correct code for allocating stack space, as insns.
19000 If COPY_REG, make sure a copy of the old frame is left there.
19001 The generated code may use hard register 0 as a temporary. */
19004 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19007 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19008 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19009 rtx todec = gen_int_mode (-size, Pmode);
19012 if (INTVAL (todec) != -size)
19014 warning (0, "stack frame too large");
19015 emit_insn (gen_trap ());
19019 if (crtl->limit_stack)
19021 if (REG_P (stack_limit_rtx)
19022 && REGNO (stack_limit_rtx) > 1
19023 && REGNO (stack_limit_rtx) <= 31)
19025 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19026 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19029 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19031 && DEFAULT_ABI == ABI_V4)
19033 rtx toload = gen_rtx_CONST (VOIDmode,
19034 gen_rtx_PLUS (Pmode,
19038 emit_insn (gen_elf_high (tmp_reg, toload));
19039 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19040 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19044 warning (0, "stack limit expression is not supported");
19048 emit_move_insn (copy_reg, stack_reg);
19052 /* Need a note here so that try_split doesn't get confused. */
19053 if (get_last_insn () == NULL_RTX)
19054 emit_note (NOTE_INSN_DELETED);
19055 insn = emit_move_insn (tmp_reg, todec);
19056 try_split (PATTERN (insn), insn, 0);
19060 insn = emit_insn (TARGET_32BIT
19061 ? gen_movsi_update_stack (stack_reg, stack_reg,
19063 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19064 todec, stack_reg));
19065 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19066 it now and set the alias set/attributes. The above gen_*_update
19067 calls will generate a PARALLEL with the MEM set being the first
19069 par = PATTERN (insn);
19070 gcc_assert (GET_CODE (par) == PARALLEL);
19071 set = XVECEXP (par, 0, 0);
19072 gcc_assert (GET_CODE (set) == SET);
19073 mem = SET_DEST (set);
19074 gcc_assert (MEM_P (mem));
19075 MEM_NOTRAP_P (mem) = 1;
19076 set_mem_alias_set (mem, get_frame_alias_set ());
19078 RTX_FRAME_RELATED_P (insn) = 1;
19079 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19080 gen_rtx_SET (VOIDmode, stack_reg,
19081 gen_rtx_PLUS (Pmode, stack_reg,
19082 GEN_INT (-size))));
19085 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19087 #if PROBE_INTERVAL > 32768
19088 #error Cannot use indexed addressing mode for stack probing
19091 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19092 inclusive. These are offsets from the current stack pointer. */
19095 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19097 /* See if we have a constant small number of probes to generate. If so,
19098 that's the easy case. */
19099 if (first + size <= 32768)
19103 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19104 it exceeds SIZE. If only one probe is needed, this will not
19105 generate any code. Then probe at FIRST + SIZE. */
19106 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19107 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19109 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19112 /* Otherwise, do the same as above, but in a loop. Note that we must be
19113 extra careful with variables wrapping around because we might be at
19114 the very top (or the very bottom) of the address space and we have
19115 to be able to handle this case properly; in particular, we use an
19116 equality test for the loop condition. */
19119 HOST_WIDE_INT rounded_size;
19120 rtx r12 = gen_rtx_REG (Pmode, 12);
19121 rtx r0 = gen_rtx_REG (Pmode, 0);
19123 /* Sanity check for the addressing mode we're going to use. */
19124 gcc_assert (first <= 32768);
19126 /* Step 1: round SIZE to the previous multiple of the interval. */
19128 rounded_size = size & -PROBE_INTERVAL;
19131 /* Step 2: compute initial and final value of the loop counter. */
19133 /* TEST_ADDR = SP + FIRST. */
19134 emit_insn (gen_rtx_SET (VOIDmode, r12,
19135 plus_constant (stack_pointer_rtx, -first)));
19137 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19138 if (rounded_size > 32768)
19140 emit_move_insn (r0, GEN_INT (-rounded_size));
19141 emit_insn (gen_rtx_SET (VOIDmode, r0,
19142 gen_rtx_PLUS (Pmode, r12, r0)));
19145 emit_insn (gen_rtx_SET (VOIDmode, r0,
19146 plus_constant (r12, -rounded_size)));
19149 /* Step 3: the loop
19151 while (TEST_ADDR != LAST_ADDR)
19153 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19157 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19158 until it is equal to ROUNDED_SIZE. */
19161 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19163 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19166 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19167 that SIZE is equal to ROUNDED_SIZE. */
19169 if (size != rounded_size)
19170 emit_stack_probe (plus_constant (r12, rounded_size - size));
19174 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19175 absolute addresses. */
19178 output_probe_stack_range (rtx reg1, rtx reg2)
19180 static int labelno = 0;
19181 char loop_lab[32], end_lab[32];
19184 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19185 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19187 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19189 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19193 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19195 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19197 fputs ("\tbeq 0,", asm_out_file);
19198 assemble_name_raw (asm_out_file, end_lab);
19199 fputc ('\n', asm_out_file);
19201 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19202 xops[1] = GEN_INT (-PROBE_INTERVAL);
19203 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19205 /* Probe at TEST_ADDR and branch. */
19206 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19207 fprintf (asm_out_file, "\tb ");
19208 assemble_name_raw (asm_out_file, loop_lab);
19209 fputc ('\n', asm_out_file);
19211 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19216 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19217 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19218 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19219 deduce these equivalences by itself so it wasn't necessary to hold
19220 its hand so much. */
19223 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19224 rtx reg2, rtx rreg)
19228 /* copy_rtx will not make unique copies of registers, so we need to
19229 ensure we don't have unwanted sharing here. */
19231 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19234 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19236 real = copy_rtx (PATTERN (insn));
19238 if (reg2 != NULL_RTX)
19239 real = replace_rtx (real, reg2, rreg);
19241 real = replace_rtx (real, reg,
19242 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19243 STACK_POINTER_REGNUM),
19246 /* We expect that 'real' is either a SET or a PARALLEL containing
19247 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19248 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19250 if (GET_CODE (real) == SET)
19254 temp = simplify_rtx (SET_SRC (set));
19256 SET_SRC (set) = temp;
19257 temp = simplify_rtx (SET_DEST (set));
19259 SET_DEST (set) = temp;
19260 if (GET_CODE (SET_DEST (set)) == MEM)
19262 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19264 XEXP (SET_DEST (set), 0) = temp;
19271 gcc_assert (GET_CODE (real) == PARALLEL);
19272 for (i = 0; i < XVECLEN (real, 0); i++)
19273 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19275 rtx set = XVECEXP (real, 0, i);
19277 temp = simplify_rtx (SET_SRC (set));
19279 SET_SRC (set) = temp;
19280 temp = simplify_rtx (SET_DEST (set));
19282 SET_DEST (set) = temp;
19283 if (GET_CODE (SET_DEST (set)) == MEM)
19285 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19287 XEXP (SET_DEST (set), 0) = temp;
19289 RTX_FRAME_RELATED_P (set) = 1;
19293 RTX_FRAME_RELATED_P (insn) = 1;
19294 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19297 /* Returns an insn that has a vrsave set operation with the
19298 appropriate CLOBBERs. */
19301 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19304 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19305 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19308 = gen_rtx_SET (VOIDmode,
19310 gen_rtx_UNSPEC_VOLATILE (SImode,
19311 gen_rtvec (2, reg, vrsave),
19312 UNSPECV_SET_VRSAVE));
19316 /* We need to clobber the registers in the mask so the scheduler
19317 does not move sets to VRSAVE before sets of AltiVec registers.
19319 However, if the function receives nonlocal gotos, reload will set
19320 all call saved registers live. We will end up with:
19322 (set (reg 999) (mem))
19323 (parallel [ (set (reg vrsave) (unspec blah))
19324 (clobber (reg 999))])
19326 The clobber will cause the store into reg 999 to be dead, and
19327 flow will attempt to delete an epilogue insn. In this case, we
19328 need an unspec use/set of the register. */
19330 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19331 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19333 if (!epiloguep || call_used_regs [i])
19334 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19335 gen_rtx_REG (V4SImode, i));
19338 rtx reg = gen_rtx_REG (V4SImode, i);
19341 = gen_rtx_SET (VOIDmode,
19343 gen_rtx_UNSPEC (V4SImode,
19344 gen_rtvec (1, reg), 27));
19348 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19350 for (i = 0; i < nclobs; ++i)
19351 XVECEXP (insn, 0, i) = clobs[i];
19356 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19357 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19360 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19361 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19363 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19364 rtx replacea, replaceb;
19366 int_rtx = GEN_INT (offset);
19368 /* Some cases that need register indexed addressing. */
19369 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19370 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19371 || (TARGET_E500_DOUBLE && mode == DFmode)
19373 && SPE_VECTOR_MODE (mode)
19374 && !SPE_CONST_OFFSET_OK (offset)))
19376 /* Whomever calls us must make sure r11 is available in the
19377 flow path of instructions in the prologue. */
19378 offset_rtx = gen_rtx_REG (Pmode, 11);
19379 emit_move_insn (offset_rtx, int_rtx);
19381 replacea = offset_rtx;
19382 replaceb = int_rtx;
19386 offset_rtx = int_rtx;
19387 replacea = NULL_RTX;
19388 replaceb = NULL_RTX;
19391 reg = gen_rtx_REG (mode, regno);
19392 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19393 mem = gen_frame_mem (mode, addr);
19395 insn = emit_move_insn (mem, reg);
19397 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19400 /* Emit an offset memory reference suitable for a frame store, while
19401 converting to a valid addressing mode. */
19404 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19406 rtx int_rtx, offset_rtx;
19408 int_rtx = GEN_INT (offset);
19410 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19411 || (TARGET_E500_DOUBLE && mode == DFmode))
19413 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19414 emit_move_insn (offset_rtx, int_rtx);
19417 offset_rtx = int_rtx;
19419 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19422 /* Look for user-defined global regs. We should not save and restore these,
19423 and cannot use stmw/lmw if there are any in its range. */
19426 no_global_regs_above (int first, bool gpr)
19429 int last = gpr ? 32 : 64;
19430 for (i = first; i < last; i++)
19431 if (global_regs[i])
19436 #ifndef TARGET_FIX_AND_CONTINUE
19437 #define TARGET_FIX_AND_CONTINUE 0
19440 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19441 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19442 #define LAST_SAVRES_REGISTER 31
19443 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19445 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19447 /* Temporary holding space for an out-of-line register save/restore
19449 static char savres_routine_name[30];
19451 /* Return the name for an out-of-line register save/restore routine.
19452 We are saving/restoring GPRs if GPR is true. */
19455 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19456 bool savep, bool gpr, bool lr)
19458 const char *prefix = "";
19459 const char *suffix = "";
19461 /* Different targets are supposed to define
19462 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19463 routine name could be defined with:
19465 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19467 This is a nice idea in practice, but in reality, things are
19468 complicated in several ways:
19470 - ELF targets have save/restore routines for GPRs.
19472 - SPE targets use different prefixes for 32/64-bit registers, and
19473 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19475 - PPC64 ELF targets have routines for save/restore of GPRs that
19476 differ in what they do with the link register, so having a set
19477 prefix doesn't work. (We only use one of the save routines at
19478 the moment, though.)
19480 - PPC32 elf targets have "exit" versions of the restore routines
19481 that restore the link register and can save some extra space.
19482 These require an extra suffix. (There are also "tail" versions
19483 of the restore routines and "GOT" versions of the save routines,
19484 but we don't generate those at present. Same problems apply,
19487 We deal with all this by synthesizing our own prefix/suffix and
19488 using that for the simple sprintf call shown above. */
19491 /* No floating point saves on the SPE. */
19495 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19497 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19502 else if (DEFAULT_ABI == ABI_V4)
19508 prefix = savep ? "_savegpr_" : "_restgpr_";
19510 prefix = savep ? "_savefpr_" : "_restfpr_";
19515 else if (DEFAULT_ABI == ABI_AIX)
19517 #ifndef POWERPC_LINUX
19518 /* No out-of-line save/restore routines for GPRs on AIX. */
19519 gcc_assert (!TARGET_AIX || !gpr);
19525 ? (lr ? "_savegpr0_" : "_savegpr1_")
19526 : (lr ? "_restgpr0_" : "_restgpr1_"));
19527 #ifdef POWERPC_LINUX
19529 prefix = (savep ? "_savefpr_" : "_restfpr_");
19533 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19534 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19537 else if (DEFAULT_ABI == ABI_DARWIN)
19538 sorry ("Out-of-line save/restore routines not supported on Darwin");
19540 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19542 return savres_routine_name;
19545 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19546 We are saving/restoring GPRs if GPR is true. */
19549 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19552 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19554 int select = ((savep ? 1 : 0) << 2
19556 /* On the SPE, we never have any FPRs, but we do have
19557 32/64-bit versions of the routines. */
19558 ? (info->spe_64bit_regs_used ? 1 : 0)
19559 : (gpr ? 1 : 0)) << 1)
19562 /* Don't generate bogus routine names. */
19563 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19564 && regno <= LAST_SAVRES_REGISTER);
19566 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19572 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19574 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19575 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19576 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19582 /* Emit a sequence of insns, including a stack tie if needed, for
19583 resetting the stack pointer. If SAVRES is true, then don't reset the
19584 stack pointer, but move the base of the frame into r11 for use by
19585 out-of-line register restore routines. */
19588 rs6000_emit_stack_reset (rs6000_stack_t *info,
19589 rtx sp_reg_rtx, rtx frame_reg_rtx,
19590 int sp_offset, bool savres)
19592 /* This blockage is needed so that sched doesn't decide to move
19593 the sp change before the register restores. */
19594 if (frame_reg_rtx != sp_reg_rtx
19596 && info->spe_64bit_regs_used != 0
19597 && info->first_gp_reg_save != 32))
19598 rs6000_emit_stack_tie ();
19600 if (frame_reg_rtx != sp_reg_rtx)
19602 if (sp_offset != 0)
19604 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19605 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19606 GEN_INT (sp_offset)));
19609 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19611 else if (sp_offset != 0)
19613 /* If we are restoring registers out-of-line, we will be using the
19614 "exit" variants of the restore routines, which will reset the
19615 stack for us. But we do need to point r11 into the right place
19616 for those routines. */
19617 rtx dest_reg = (savres
19618 ? gen_rtx_REG (Pmode, 11)
19621 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19622 GEN_INT (sp_offset)));
19629 /* Construct a parallel rtx describing the effect of a call to an
19630 out-of-line register save/restore routine. */
19633 rs6000_make_savres_rtx (rs6000_stack_t *info,
19634 rtx frame_reg_rtx, int save_area_offset,
19635 enum machine_mode reg_mode,
19636 bool savep, bool gpr, bool lr)
19639 int offset, start_reg, end_reg, n_regs;
19640 int reg_size = GET_MODE_SIZE (reg_mode);
19646 ? info->first_gp_reg_save
19647 : info->first_fp_reg_save);
19648 end_reg = gpr ? 32 : 64;
19649 n_regs = end_reg - start_reg;
19650 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19653 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19655 RTVEC_ELT (p, offset++)
19656 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19658 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19659 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19660 RTVEC_ELT (p, offset++)
19661 = gen_rtx_USE (VOIDmode,
19662 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19666 for (i = 0; i < end_reg - start_reg; i++)
19668 rtx addr, reg, mem;
19669 reg = gen_rtx_REG (reg_mode, start_reg + i);
19670 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19671 GEN_INT (save_area_offset + reg_size*i));
19672 mem = gen_frame_mem (reg_mode, addr);
19674 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19676 savep ? reg : mem);
19681 rtx addr, reg, mem;
19682 reg = gen_rtx_REG (Pmode, 0);
19683 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19684 GEN_INT (info->lr_save_offset));
19685 mem = gen_frame_mem (Pmode, addr);
19686 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19689 return gen_rtx_PARALLEL (VOIDmode, p);
19692 /* Determine whether the gp REG is really used. */
19695 rs6000_reg_live_or_pic_offset_p (int reg)
19697 return ((df_regs_ever_live_p (reg)
19698 && (!call_used_regs[reg]
19699 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19700 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19701 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19702 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19703 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19707 SAVRES_MULTIPLE = 0x1,
19708 SAVRES_INLINE_FPRS = 0x2,
19709 SAVRES_INLINE_GPRS = 0x4,
19710 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19711 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19712 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19715 /* Determine the strategy for savings/restoring registers. */
19718 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19719 int using_static_chain_p, int sibcall)
19721 bool using_multiple_p;
19723 bool savres_fprs_inline;
19724 bool savres_gprs_inline;
19725 bool noclobber_global_gprs
19726 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19729 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19730 && (!TARGET_SPE_ABI
19731 || info->spe_64bit_regs_used == 0)
19732 && info->first_gp_reg_save < 31
19733 && noclobber_global_gprs);
19734 /* Don't bother to try to save things out-of-line if r11 is occupied
19735 by the static chain. It would require too much fiddling and the
19736 static chain is rarely used anyway. */
19737 common = (using_static_chain_p
19739 || crtl->calls_eh_return
19740 || !info->lr_save_p
19741 || cfun->machine->ra_need_lr
19742 || info->total_size > 32767);
19743 savres_fprs_inline = (common
19744 || info->first_fp_reg_save == 64
19745 || !no_global_regs_above (info->first_fp_reg_save,
19747 /* The out-of-line FP routines use
19748 double-precision stores; we can't use those
19749 routines if we don't have such stores. */
19750 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19751 || FP_SAVE_INLINE (info->first_fp_reg_save));
19752 savres_gprs_inline = (common
19753 /* Saving CR interferes with the exit routines
19754 used on the SPE, so just punt here. */
19757 && info->spe_64bit_regs_used != 0
19758 && info->cr_save_p != 0)
19759 || info->first_gp_reg_save == 32
19760 || !noclobber_global_gprs
19761 || GP_SAVE_INLINE (info->first_gp_reg_save));
19764 /* If we are going to use store multiple, then don't even bother
19765 with the out-of-line routines, since the store-multiple instruction
19766 will always be smaller. */
19767 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19770 /* The situation is more complicated with load multiple. We'd
19771 prefer to use the out-of-line routines for restores, since the
19772 "exit" out-of-line routines can handle the restore of LR and
19773 the frame teardown. But we can only use the out-of-line
19774 routines if we know that we've used store multiple or
19775 out-of-line routines in the prologue, i.e. if we've saved all
19776 the registers from first_gp_reg_save. Otherwise, we risk
19777 loading garbage from the stack. Furthermore, we can only use
19778 the "exit" out-of-line gpr restore if we haven't saved any
19780 bool saved_all = !savres_gprs_inline || using_multiple_p;
19782 if (saved_all && info->first_fp_reg_save != 64)
19783 /* We can't use the exit routine; use load multiple if it's
19785 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19788 strategy = (using_multiple_p
19789 | (savres_fprs_inline << 1)
19790 | (savres_gprs_inline << 2));
19791 #ifdef POWERPC_LINUX
19794 if (!savres_fprs_inline)
19795 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19796 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19797 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19800 if (TARGET_AIX && !savres_fprs_inline)
19801 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19806 /* Emit function prologue as insns. */
19809 rs6000_emit_prologue (void)
19811 rs6000_stack_t *info = rs6000_stack_info ();
19812 enum machine_mode reg_mode = Pmode;
19813 int reg_size = TARGET_32BIT ? 4 : 8;
19814 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19815 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19816 rtx frame_reg_rtx = sp_reg_rtx;
19817 rtx cr_save_rtx = NULL_RTX;
19820 int saving_FPRs_inline;
19821 int saving_GPRs_inline;
19822 int using_store_multiple;
19823 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19824 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19825 && call_used_regs[STATIC_CHAIN_REGNUM]);
19826 HOST_WIDE_INT sp_offset = 0;
19828 if (flag_stack_usage)
19829 current_function_static_stack_size = info->total_size;
19831 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19832 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19834 if (TARGET_FIX_AND_CONTINUE)
19836 /* gdb on darwin arranges to forward a function from the old
19837 address by modifying the first 5 instructions of the function
19838 to branch to the overriding function. This is necessary to
19839 permit function pointers that point to the old function to
19840 actually forward to the new function. */
19841 emit_insn (gen_nop ());
19842 emit_insn (gen_nop ());
19843 emit_insn (gen_nop ());
19844 emit_insn (gen_nop ());
19845 emit_insn (gen_nop ());
19848 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19850 reg_mode = V2SImode;
19854 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19855 /*static_chain_p=*/using_static_chain_p,
19857 using_store_multiple = strategy & SAVRES_MULTIPLE;
19858 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19859 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19861 /* For V.4, update stack before we do any saving and set back pointer. */
19862 if (! WORLD_SAVE_P (info)
19864 && (DEFAULT_ABI == ABI_V4
19865 || crtl->calls_eh_return))
19867 bool need_r11 = (TARGET_SPE
19868 ? (!saving_GPRs_inline
19869 && info->spe_64bit_regs_used == 0)
19870 : (!saving_FPRs_inline || !saving_GPRs_inline));
19871 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19873 if (info->total_size < 32767)
19874 sp_offset = info->total_size;
19876 frame_reg_rtx = copy_reg;
19877 else if (info->cr_save_p
19879 || info->first_fp_reg_save < 64
19880 || info->first_gp_reg_save < 32
19881 || info->altivec_size != 0
19882 || info->vrsave_mask != 0
19883 || crtl->calls_eh_return)
19885 copy_reg = frame_ptr_rtx;
19886 frame_reg_rtx = copy_reg;
19890 /* The prologue won't be saving any regs so there is no need
19891 to set up a frame register to access any frame save area.
19892 We also won't be using sp_offset anywhere below, but set
19893 the correct value anyway to protect against future
19894 changes to this function. */
19895 sp_offset = info->total_size;
19897 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19898 if (frame_reg_rtx != sp_reg_rtx)
19899 rs6000_emit_stack_tie ();
19902 /* Handle world saves specially here. */
19903 if (WORLD_SAVE_P (info))
19910 /* save_world expects lr in r0. */
19911 reg0 = gen_rtx_REG (Pmode, 0);
19912 if (info->lr_save_p)
19914 insn = emit_move_insn (reg0,
19915 gen_rtx_REG (Pmode, LR_REGNO));
19916 RTX_FRAME_RELATED_P (insn) = 1;
19919 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19920 assumptions about the offsets of various bits of the stack
19922 gcc_assert (info->gp_save_offset == -220
19923 && info->fp_save_offset == -144
19924 && info->lr_save_offset == 8
19925 && info->cr_save_offset == 4
19928 && (!crtl->calls_eh_return
19929 || info->ehrd_offset == -432)
19930 && info->vrsave_save_offset == -224
19931 && info->altivec_save_offset == -416);
19933 treg = gen_rtx_REG (SImode, 11);
19934 emit_move_insn (treg, GEN_INT (-info->total_size));
19936 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19937 in R11. It also clobbers R12, so beware! */
19939 /* Preserve CR2 for save_world prologues */
19941 sz += 32 - info->first_gp_reg_save;
19942 sz += 64 - info->first_fp_reg_save;
19943 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19944 p = rtvec_alloc (sz);
19946 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19947 gen_rtx_REG (SImode,
19949 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19950 gen_rtx_SYMBOL_REF (Pmode,
19952 /* We do floats first so that the instruction pattern matches
19954 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19956 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19957 ? DFmode : SFmode),
19958 info->first_fp_reg_save + i);
19959 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19960 GEN_INT (info->fp_save_offset
19961 + sp_offset + 8 * i));
19962 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19963 ? DFmode : SFmode), addr);
19965 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19967 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19969 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19970 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19971 GEN_INT (info->altivec_save_offset
19972 + sp_offset + 16 * i));
19973 rtx mem = gen_frame_mem (V4SImode, addr);
19975 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19977 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19979 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19980 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19981 GEN_INT (info->gp_save_offset
19982 + sp_offset + reg_size * i));
19983 rtx mem = gen_frame_mem (reg_mode, addr);
19985 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19989 /* CR register traditionally saved as CR2. */
19990 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19991 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19992 GEN_INT (info->cr_save_offset
19994 rtx mem = gen_frame_mem (reg_mode, addr);
19996 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19998 /* Explain about use of R0. */
19999 if (info->lr_save_p)
20001 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20002 GEN_INT (info->lr_save_offset
20004 rtx mem = gen_frame_mem (reg_mode, addr);
20006 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20008 /* Explain what happens to the stack pointer. */
20010 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20011 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20014 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20015 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20016 treg, GEN_INT (-info->total_size));
20017 sp_offset = info->total_size;
20020 /* If we use the link register, get it into r0. */
20021 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20023 rtx addr, reg, mem;
20025 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20026 gen_rtx_REG (Pmode, LR_REGNO));
20027 RTX_FRAME_RELATED_P (insn) = 1;
20029 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
20030 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
20032 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20033 GEN_INT (info->lr_save_offset + sp_offset));
20034 reg = gen_rtx_REG (Pmode, 0);
20035 mem = gen_rtx_MEM (Pmode, addr);
20036 /* This should not be of rs6000_sr_alias_set, because of
20037 __builtin_return_address. */
20039 insn = emit_move_insn (mem, reg);
20040 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20041 NULL_RTX, NULL_RTX);
20045 /* If we need to save CR, put it into r12 or r11. */
20046 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20051 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20053 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20054 RTX_FRAME_RELATED_P (insn) = 1;
20055 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20056 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20057 But that's OK. All we have to do is specify that _one_ condition
20058 code register is saved in this stack slot. The thrower's epilogue
20059 will then restore all the call-saved registers.
20060 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20061 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20062 gen_rtx_REG (SImode, CR2_REGNO));
20063 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20066 /* Do any required saving of fpr's. If only one or two to save, do
20067 it ourselves. Otherwise, call function. */
20068 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20071 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20072 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20073 && ! call_used_regs[info->first_fp_reg_save+i]))
20074 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20075 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20077 info->first_fp_reg_save + i,
20078 info->fp_save_offset + sp_offset + 8 * i,
20081 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20085 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20086 info->fp_save_offset + sp_offset,
20088 /*savep=*/true, /*gpr=*/false,
20090 & SAVRES_NOINLINE_FPRS_SAVES_LR)
20092 insn = emit_insn (par);
20093 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20094 NULL_RTX, NULL_RTX);
20097 /* Save GPRs. This is done as a PARALLEL if we are using
20098 the store-multiple instructions. */
20099 if (!WORLD_SAVE_P (info)
20101 && info->spe_64bit_regs_used != 0
20102 && info->first_gp_reg_save != 32)
20105 rtx spe_save_area_ptr;
20107 /* Determine whether we can address all of the registers that need
20108 to be saved with an offset from the stack pointer that fits in
20109 the small const field for SPE memory instructions. */
20110 int spe_regs_addressable_via_sp
20111 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20112 + (32 - info->first_gp_reg_save - 1) * reg_size)
20113 && saving_GPRs_inline);
20116 if (spe_regs_addressable_via_sp)
20118 spe_save_area_ptr = frame_reg_rtx;
20119 spe_offset = info->spe_gp_save_offset + sp_offset;
20123 /* Make r11 point to the start of the SPE save area. We need
20124 to be careful here if r11 is holding the static chain. If
20125 it is, then temporarily save it in r0. We would use r0 as
20126 our base register here, but using r0 as a base register in
20127 loads and stores means something different from what we
20129 int ool_adjust = (saving_GPRs_inline
20131 : (info->first_gp_reg_save
20132 - (FIRST_SAVRES_REGISTER+1))*8);
20133 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20134 + sp_offset - ool_adjust);
20136 if (using_static_chain_p)
20138 rtx r0 = gen_rtx_REG (Pmode, 0);
20139 gcc_assert (info->first_gp_reg_save > 11);
20141 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20144 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20145 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20147 GEN_INT (offset)));
20148 /* We need to make sure the move to r11 gets noted for
20149 properly outputting unwind information. */
20150 if (!saving_GPRs_inline)
20151 rs6000_frame_related (insn, frame_reg_rtx, offset,
20152 NULL_RTX, NULL_RTX);
20156 if (saving_GPRs_inline)
20158 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20159 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20161 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20162 rtx offset, addr, mem;
20164 /* We're doing all this to ensure that the offset fits into
20165 the immediate offset of 'evstdd'. */
20166 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20168 offset = GEN_INT (reg_size * i + spe_offset);
20169 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20170 mem = gen_rtx_MEM (V2SImode, addr);
20172 insn = emit_move_insn (mem, reg);
20174 rs6000_frame_related (insn, spe_save_area_ptr,
20175 info->spe_gp_save_offset
20176 + sp_offset + reg_size * i,
20177 offset, const0_rtx);
20184 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20186 /*savep=*/true, /*gpr=*/true,
20188 insn = emit_insn (par);
20189 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20190 NULL_RTX, NULL_RTX);
20194 /* Move the static chain pointer back. */
20195 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20196 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20198 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20202 /* Need to adjust r11 (r12) if we saved any FPRs. */
20203 if (info->first_fp_reg_save != 64)
20205 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20207 rtx offset = GEN_INT (sp_offset
20208 + (-8 * (64-info->first_fp_reg_save)));
20209 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20212 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20213 info->gp_save_offset + sp_offset,
20215 /*savep=*/true, /*gpr=*/true,
20217 & SAVRES_NOINLINE_GPRS_SAVES_LR)
20219 insn = emit_insn (par);
20220 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20221 NULL_RTX, NULL_RTX);
20223 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20227 p = rtvec_alloc (32 - info->first_gp_reg_save);
20228 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20230 rtx addr, reg, mem;
20231 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20232 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20233 GEN_INT (info->gp_save_offset
20236 mem = gen_frame_mem (reg_mode, addr);
20238 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20240 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20241 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20242 NULL_RTX, NULL_RTX);
20244 else if (!WORLD_SAVE_P (info))
20247 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20248 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20250 rtx addr, reg, mem;
20251 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20253 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20254 GEN_INT (info->gp_save_offset
20257 mem = gen_frame_mem (reg_mode, addr);
20259 insn = emit_move_insn (mem, reg);
20260 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20261 NULL_RTX, NULL_RTX);
20265 /* ??? There's no need to emit actual instructions here, but it's the
20266 easiest way to get the frame unwind information emitted. */
20267 if (crtl->calls_eh_return)
20269 unsigned int i, regno;
20271 /* In AIX ABI we need to pretend we save r2 here. */
20274 rtx addr, reg, mem;
20276 reg = gen_rtx_REG (reg_mode, 2);
20277 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20278 GEN_INT (sp_offset + 5 * reg_size));
20279 mem = gen_frame_mem (reg_mode, addr);
20281 insn = emit_move_insn (mem, reg);
20282 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20283 NULL_RTX, NULL_RTX);
20284 PATTERN (insn) = gen_blockage ();
20289 regno = EH_RETURN_DATA_REGNO (i);
20290 if (regno == INVALID_REGNUM)
20293 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20294 info->ehrd_offset + sp_offset
20295 + reg_size * (int) i,
20300 /* Save CR if we use any that must be preserved. */
20301 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20303 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20304 GEN_INT (info->cr_save_offset + sp_offset));
20305 rtx mem = gen_frame_mem (SImode, addr);
20306 /* See the large comment above about why CR2_REGNO is used. */
20307 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20309 /* If r12 was used to hold the original sp, copy cr into r0 now
20311 if (REGNO (frame_reg_rtx) == 12)
20315 cr_save_rtx = gen_rtx_REG (SImode, 0);
20316 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20317 RTX_FRAME_RELATED_P (insn) = 1;
20318 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20319 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20321 insn = emit_move_insn (mem, cr_save_rtx);
20323 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20324 NULL_RTX, NULL_RTX);
20327 /* Update stack and set back pointer unless this is V.4,
20328 for which it was done previously. */
20329 if (!WORLD_SAVE_P (info) && info->push_p
20330 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20332 rtx copy_reg = NULL;
20334 if (info->total_size < 32767)
20335 sp_offset = info->total_size;
20336 else if (info->altivec_size != 0
20337 || info->vrsave_mask != 0)
20339 copy_reg = frame_ptr_rtx;
20340 frame_reg_rtx = copy_reg;
20343 sp_offset = info->total_size;
20344 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20345 if (frame_reg_rtx != sp_reg_rtx)
20346 rs6000_emit_stack_tie ();
20349 /* Set frame pointer, if needed. */
20350 if (frame_pointer_needed)
20352 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20354 RTX_FRAME_RELATED_P (insn) = 1;
20357 /* Save AltiVec registers if needed. Save here because the red zone does
20358 not include AltiVec registers. */
20359 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20363 /* There should be a non inline version of this, for when we
20364 are saving lots of vector registers. */
20365 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20366 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20368 rtx areg, savereg, mem;
20371 offset = info->altivec_save_offset + sp_offset
20372 + 16 * (i - info->first_altivec_reg_save);
20374 savereg = gen_rtx_REG (V4SImode, i);
20376 areg = gen_rtx_REG (Pmode, 0);
20377 emit_move_insn (areg, GEN_INT (offset));
20379 /* AltiVec addressing mode is [reg+reg]. */
20380 mem = gen_frame_mem (V4SImode,
20381 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20383 insn = emit_move_insn (mem, savereg);
20385 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20386 areg, GEN_INT (offset));
20390 /* VRSAVE is a bit vector representing which AltiVec registers
20391 are used. The OS uses this to determine which vector
20392 registers to save on a context switch. We need to save
20393 VRSAVE on the stack frame, add whatever AltiVec registers we
20394 used in this function, and do the corresponding magic in the
20397 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20398 && info->vrsave_mask != 0)
20400 rtx reg, mem, vrsave;
20403 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20404 as frame_reg_rtx and r11 as the static chain pointer for
20405 nested functions. */
20406 reg = gen_rtx_REG (SImode, 0);
20407 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20409 emit_insn (gen_get_vrsave_internal (reg));
20411 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20413 if (!WORLD_SAVE_P (info))
20416 offset = info->vrsave_save_offset + sp_offset;
20417 mem = gen_frame_mem (SImode,
20418 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20419 GEN_INT (offset)));
20420 insn = emit_move_insn (mem, reg);
20423 /* Include the registers in the mask. */
20424 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20426 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20429 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20430 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20431 || (DEFAULT_ABI == ABI_V4
20432 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20433 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20435 /* If emit_load_toc_table will use the link register, we need to save
20436 it. We use R12 for this purpose because emit_load_toc_table
20437 can use register 0. This allows us to use a plain 'blr' to return
20438 from the procedure more often. */
20439 int save_LR_around_toc_setup = (TARGET_ELF
20440 && DEFAULT_ABI != ABI_AIX
20442 && ! info->lr_save_p
20443 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20444 if (save_LR_around_toc_setup)
20446 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20448 insn = emit_move_insn (frame_ptr_rtx, lr);
20449 RTX_FRAME_RELATED_P (insn) = 1;
20451 rs6000_emit_load_toc_table (TRUE);
20453 insn = emit_move_insn (lr, frame_ptr_rtx);
20454 RTX_FRAME_RELATED_P (insn) = 1;
20457 rs6000_emit_load_toc_table (TRUE);
20461 if (DEFAULT_ABI == ABI_DARWIN
20462 && flag_pic && crtl->uses_pic_offset_table)
20464 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20465 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20467 /* Save and restore LR locally around this call (in R0). */
20468 if (!info->lr_save_p)
20469 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20471 emit_insn (gen_load_macho_picbase (src));
20473 emit_move_insn (gen_rtx_REG (Pmode,
20474 RS6000_PIC_OFFSET_TABLE_REGNUM),
20477 if (!info->lr_save_p)
20478 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20483 /* Write function prologue. */
20486 rs6000_output_function_prologue (FILE *file,
20487 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20489 rs6000_stack_t *info = rs6000_stack_info ();
20491 if (TARGET_DEBUG_STACK)
20492 debug_stack_info (info);
20494 /* Write .extern for any function we will call to save and restore
20496 if (info->first_fp_reg_save < 64
20497 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20500 int regno = info->first_fp_reg_save - 32;
20502 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20503 /*gpr=*/false, /*lr=*/false);
20504 fprintf (file, "\t.extern %s\n", name);
20506 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20507 /*gpr=*/false, /*lr=*/true);
20508 fprintf (file, "\t.extern %s\n", name);
20511 /* Write .extern for AIX common mode routines, if needed. */
20512 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20514 fputs ("\t.extern __mulh\n", file);
20515 fputs ("\t.extern __mull\n", file);
20516 fputs ("\t.extern __divss\n", file);
20517 fputs ("\t.extern __divus\n", file);
20518 fputs ("\t.extern __quoss\n", file);
20519 fputs ("\t.extern __quous\n", file);
20520 common_mode_defined = 1;
20523 if (! HAVE_prologue)
20529 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20530 the "toplevel" insn chain. */
20531 emit_note (NOTE_INSN_DELETED);
20532 rs6000_emit_prologue ();
20533 emit_note (NOTE_INSN_DELETED);
20535 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20539 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20541 INSN_ADDRESSES_NEW (insn, addr);
20546 prologue = get_insns ();
20549 if (TARGET_DEBUG_STACK)
20550 debug_rtx_list (prologue, 100);
20552 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20556 rs6000_pic_labelno++;
20559 /* Non-zero if vmx regs are restored before the frame pop, zero if
20560 we restore after the pop when possible. */
20561 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20563 /* Reload CR from REG. */
20566 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20571 if (using_mfcr_multiple)
20573 for (i = 0; i < 8; i++)
20574 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20576 gcc_assert (count);
20579 if (using_mfcr_multiple && count > 1)
20584 p = rtvec_alloc (count);
20587 for (i = 0; i < 8; i++)
20588 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20590 rtvec r = rtvec_alloc (2);
20591 RTVEC_ELT (r, 0) = reg;
20592 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20593 RTVEC_ELT (p, ndx) =
20594 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20595 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20598 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20599 gcc_assert (ndx == count);
20602 for (i = 0; i < 8; i++)
20603 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20605 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20611 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20612 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20613 below stack pointer not cloberred by signals. */
20616 offset_below_red_zone_p (HOST_WIDE_INT offset)
20618 return offset < (DEFAULT_ABI == ABI_V4
20620 : TARGET_32BIT ? -220 : -288);
20623 /* Emit function epilogue as insns. */
20626 rs6000_emit_epilogue (int sibcall)
20628 rs6000_stack_t *info;
20629 int restoring_GPRs_inline;
20630 int restoring_FPRs_inline;
20631 int using_load_multiple;
20632 int using_mtcr_multiple;
20633 int use_backchain_to_restore_sp;
20637 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20638 rtx frame_reg_rtx = sp_reg_rtx;
20639 rtx cfa_restores = NULL_RTX;
20641 rtx cr_save_reg = NULL_RTX;
20642 enum machine_mode reg_mode = Pmode;
20643 int reg_size = TARGET_32BIT ? 4 : 8;
20646 info = rs6000_stack_info ();
20648 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20650 reg_mode = V2SImode;
20654 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20655 /*static_chain_p=*/0, sibcall);
20656 using_load_multiple = strategy & SAVRES_MULTIPLE;
20657 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20658 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20659 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20660 || rs6000_cpu == PROCESSOR_PPC603
20661 || rs6000_cpu == PROCESSOR_PPC750
20663 /* Restore via the backchain when we have a large frame, since this
20664 is more efficient than an addis, addi pair. The second condition
20665 here will not trigger at the moment; We don't actually need a
20666 frame pointer for alloca, but the generic parts of the compiler
20667 give us one anyway. */
20668 use_backchain_to_restore_sp = (info->total_size > 32767
20669 || info->total_size
20670 + (info->lr_save_p ? info->lr_save_offset : 0)
20672 || (cfun->calls_alloca
20673 && !frame_pointer_needed));
20674 restore_lr = (info->lr_save_p
20675 && (restoring_FPRs_inline
20676 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20677 && (restoring_GPRs_inline
20678 || info->first_fp_reg_save < 64));
20680 if (WORLD_SAVE_P (info))
20684 const char *alloc_rname;
20687 /* eh_rest_world_r10 will return to the location saved in the LR
20688 stack slot (which is not likely to be our caller.)
20689 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20690 rest_world is similar, except any R10 parameter is ignored.
20691 The exception-handling stuff that was here in 2.95 is no
20692 longer necessary. */
20696 + 32 - info->first_gp_reg_save
20697 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20698 + 63 + 1 - info->first_fp_reg_save);
20700 strcpy (rname, ((crtl->calls_eh_return) ?
20701 "*eh_rest_world_r10" : "*rest_world"));
20702 alloc_rname = ggc_strdup (rname);
20705 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20706 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20707 gen_rtx_REG (Pmode,
20710 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20711 /* The instruction pattern requires a clobber here;
20712 it is shared with the restVEC helper. */
20714 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20717 /* CR register traditionally saved as CR2. */
20718 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20719 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20720 GEN_INT (info->cr_save_offset));
20721 rtx mem = gen_frame_mem (reg_mode, addr);
20723 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20726 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20728 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20729 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20730 GEN_INT (info->gp_save_offset
20732 rtx mem = gen_frame_mem (reg_mode, addr);
20734 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20736 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20738 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20739 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20740 GEN_INT (info->altivec_save_offset
20742 rtx mem = gen_frame_mem (V4SImode, addr);
20744 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20746 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20748 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20749 ? DFmode : SFmode),
20750 info->first_fp_reg_save + i);
20751 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20752 GEN_INT (info->fp_save_offset
20754 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20755 ? DFmode : SFmode), addr);
20757 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20760 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20762 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20764 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20766 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20768 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20769 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20774 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20776 sp_offset = info->total_size;
20778 /* Restore AltiVec registers if we must do so before adjusting the
20780 if (TARGET_ALTIVEC_ABI
20781 && info->altivec_size != 0
20782 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20783 || (DEFAULT_ABI != ABI_V4
20784 && offset_below_red_zone_p (info->altivec_save_offset))))
20788 if (use_backchain_to_restore_sp)
20790 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20791 emit_move_insn (frame_reg_rtx,
20792 gen_rtx_MEM (Pmode, sp_reg_rtx));
20795 else if (frame_pointer_needed)
20796 frame_reg_rtx = hard_frame_pointer_rtx;
20798 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20799 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20801 rtx addr, areg, mem, reg;
20803 areg = gen_rtx_REG (Pmode, 0);
20805 (areg, GEN_INT (info->altivec_save_offset
20807 + 16 * (i - info->first_altivec_reg_save)));
20809 /* AltiVec addressing mode is [reg+reg]. */
20810 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20811 mem = gen_frame_mem (V4SImode, addr);
20813 reg = gen_rtx_REG (V4SImode, i);
20814 emit_move_insn (reg, mem);
20815 if (offset_below_red_zone_p (info->altivec_save_offset
20816 + (i - info->first_altivec_reg_save)
20818 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20823 /* Restore VRSAVE if we must do so before adjusting the stack. */
20825 && TARGET_ALTIVEC_VRSAVE
20826 && info->vrsave_mask != 0
20827 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20828 || (DEFAULT_ABI != ABI_V4
20829 && offset_below_red_zone_p (info->vrsave_save_offset))))
20831 rtx addr, mem, reg;
20833 if (frame_reg_rtx == sp_reg_rtx)
20835 if (use_backchain_to_restore_sp)
20837 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20838 emit_move_insn (frame_reg_rtx,
20839 gen_rtx_MEM (Pmode, sp_reg_rtx));
20842 else if (frame_pointer_needed)
20843 frame_reg_rtx = hard_frame_pointer_rtx;
20846 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20847 GEN_INT (info->vrsave_save_offset + sp_offset));
20848 mem = gen_frame_mem (SImode, addr);
20849 reg = gen_rtx_REG (SImode, 12);
20850 emit_move_insn (reg, mem);
20852 emit_insn (generate_set_vrsave (reg, info, 1));
20856 /* If we have a large stack frame, restore the old stack pointer
20857 using the backchain. */
20858 if (use_backchain_to_restore_sp)
20860 if (frame_reg_rtx == sp_reg_rtx)
20862 /* Under V.4, don't reset the stack pointer until after we're done
20863 loading the saved registers. */
20864 if (DEFAULT_ABI == ABI_V4)
20865 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20867 insn = emit_move_insn (frame_reg_rtx,
20868 gen_rtx_MEM (Pmode, sp_reg_rtx));
20871 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20872 && DEFAULT_ABI == ABI_V4)
20873 /* frame_reg_rtx has been set up by the altivec restore. */
20877 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20878 frame_reg_rtx = sp_reg_rtx;
20881 /* If we have a frame pointer, we can restore the old stack pointer
20883 else if (frame_pointer_needed)
20885 frame_reg_rtx = sp_reg_rtx;
20886 if (DEFAULT_ABI == ABI_V4)
20887 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20888 /* Prevent reordering memory accesses against stack pointer restore. */
20889 else if (cfun->calls_alloca
20890 || offset_below_red_zone_p (-info->total_size))
20892 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20893 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20894 MEM_NOTRAP_P (mem1) = 1;
20895 MEM_NOTRAP_P (mem2) = 1;
20896 emit_insn (gen_frame_tie (mem1, mem2));
20899 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20900 GEN_INT (info->total_size)));
20903 else if (info->push_p
20904 && DEFAULT_ABI != ABI_V4
20905 && !crtl->calls_eh_return)
20907 /* Prevent reordering memory accesses against stack pointer restore. */
20908 if (cfun->calls_alloca
20909 || offset_below_red_zone_p (-info->total_size))
20911 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20912 MEM_NOTRAP_P (mem) = 1;
20913 emit_insn (gen_stack_tie (mem));
20915 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20916 GEN_INT (info->total_size)));
20919 if (insn && frame_reg_rtx == sp_reg_rtx)
20923 REG_NOTES (insn) = cfa_restores;
20924 cfa_restores = NULL_RTX;
20926 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20927 RTX_FRAME_RELATED_P (insn) = 1;
20930 /* Restore AltiVec registers if we have not done so already. */
20931 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20932 && TARGET_ALTIVEC_ABI
20933 && info->altivec_size != 0
20934 && (DEFAULT_ABI == ABI_V4
20935 || !offset_below_red_zone_p (info->altivec_save_offset)))
20939 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20940 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20942 rtx addr, areg, mem, reg;
20944 areg = gen_rtx_REG (Pmode, 0);
20946 (areg, GEN_INT (info->altivec_save_offset
20948 + 16 * (i - info->first_altivec_reg_save)));
20950 /* AltiVec addressing mode is [reg+reg]. */
20951 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20952 mem = gen_frame_mem (V4SImode, addr);
20954 reg = gen_rtx_REG (V4SImode, i);
20955 emit_move_insn (reg, mem);
20956 if (DEFAULT_ABI == ABI_V4)
20957 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20962 /* Restore VRSAVE if we have not done so already. */
20963 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20965 && TARGET_ALTIVEC_VRSAVE
20966 && info->vrsave_mask != 0
20967 && (DEFAULT_ABI == ABI_V4
20968 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20970 rtx addr, mem, reg;
20972 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20973 GEN_INT (info->vrsave_save_offset + sp_offset));
20974 mem = gen_frame_mem (SImode, addr);
20975 reg = gen_rtx_REG (SImode, 12);
20976 emit_move_insn (reg, mem);
20978 emit_insn (generate_set_vrsave (reg, info, 1));
20981 /* Get the old lr if we saved it. If we are restoring registers
20982 out-of-line, then the out-of-line routines can do this for us. */
20983 if (restore_lr && restoring_GPRs_inline)
20985 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20986 info->lr_save_offset + sp_offset);
20988 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20991 /* Get the old cr if we saved it. */
20992 if (info->cr_save_p)
20994 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20995 GEN_INT (info->cr_save_offset + sp_offset));
20996 rtx mem = gen_frame_mem (SImode, addr);
20998 cr_save_reg = gen_rtx_REG (SImode,
20999 DEFAULT_ABI == ABI_AIX
21000 && !restoring_GPRs_inline
21001 && info->first_fp_reg_save < 64
21003 emit_move_insn (cr_save_reg, mem);
21006 /* Set LR here to try to overlap restores below. LR is always saved
21007 above incoming stack, so it never needs REG_CFA_RESTORE. */
21008 if (restore_lr && restoring_GPRs_inline)
21009 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21010 gen_rtx_REG (Pmode, 0));
21012 /* Load exception handler data registers, if needed. */
21013 if (crtl->calls_eh_return)
21015 unsigned int i, regno;
21019 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21020 GEN_INT (sp_offset + 5 * reg_size));
21021 rtx mem = gen_frame_mem (reg_mode, addr);
21023 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21030 regno = EH_RETURN_DATA_REGNO (i);
21031 if (regno == INVALID_REGNUM)
21034 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21035 info->ehrd_offset + sp_offset
21036 + reg_size * (int) i);
21038 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21042 /* Restore GPRs. This is done as a PARALLEL if we are using
21043 the load-multiple instructions. */
21045 && info->spe_64bit_regs_used != 0
21046 && info->first_gp_reg_save != 32)
21048 /* Determine whether we can address all of the registers that need
21049 to be saved with an offset from the stack pointer that fits in
21050 the small const field for SPE memory instructions. */
21051 int spe_regs_addressable_via_sp
21052 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21053 + (32 - info->first_gp_reg_save - 1) * reg_size)
21054 && restoring_GPRs_inline);
21057 if (spe_regs_addressable_via_sp)
21058 spe_offset = info->spe_gp_save_offset + sp_offset;
21061 rtx old_frame_reg_rtx = frame_reg_rtx;
21062 /* Make r11 point to the start of the SPE save area. We worried about
21063 not clobbering it when we were saving registers in the prologue.
21064 There's no need to worry here because the static chain is passed
21065 anew to every function. */
21066 int ool_adjust = (restoring_GPRs_inline
21068 : (info->first_gp_reg_save
21069 - (FIRST_SAVRES_REGISTER+1))*8);
21071 if (frame_reg_rtx == sp_reg_rtx)
21072 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21073 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21074 GEN_INT (info->spe_gp_save_offset
21077 /* Keep the invariant that frame_reg_rtx + sp_offset points
21078 at the top of the stack frame. */
21079 sp_offset = -info->spe_gp_save_offset;
21084 if (restoring_GPRs_inline)
21086 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21087 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21089 rtx offset, addr, mem, reg;
21091 /* We're doing all this to ensure that the immediate offset
21092 fits into the immediate field of 'evldd'. */
21093 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21095 offset = GEN_INT (spe_offset + reg_size * i);
21096 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21097 mem = gen_rtx_MEM (V2SImode, addr);
21098 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21100 insn = emit_move_insn (reg, mem);
21101 if (DEFAULT_ABI == ABI_V4)
21103 if (frame_pointer_needed
21104 && info->first_gp_reg_save + i
21105 == HARD_FRAME_POINTER_REGNUM)
21107 add_reg_note (insn, REG_CFA_DEF_CFA,
21108 plus_constant (frame_reg_rtx,
21110 RTX_FRAME_RELATED_P (insn) = 1;
21113 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21122 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21124 /*savep=*/false, /*gpr=*/true,
21126 emit_jump_insn (par);
21127 /* We don't want anybody else emitting things after we jumped
21132 else if (!restoring_GPRs_inline)
21134 /* We are jumping to an out-of-line function. */
21135 bool can_use_exit = info->first_fp_reg_save == 64;
21138 /* Emit stack reset code if we need it. */
21140 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21141 sp_offset, can_use_exit);
21144 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21147 GEN_INT (sp_offset - info->fp_size)));
21148 if (REGNO (frame_reg_rtx) == 11)
21149 sp_offset += info->fp_size;
21152 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21153 info->gp_save_offset, reg_mode,
21154 /*savep=*/false, /*gpr=*/true,
21155 /*lr=*/can_use_exit);
21159 if (info->cr_save_p)
21161 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21162 if (DEFAULT_ABI == ABI_V4)
21164 = alloc_reg_note (REG_CFA_RESTORE,
21165 gen_rtx_REG (SImode, CR2_REGNO),
21169 emit_jump_insn (par);
21171 /* We don't want anybody else emitting things after we jumped
21176 insn = emit_insn (par);
21177 if (DEFAULT_ABI == ABI_V4)
21179 if (frame_pointer_needed)
21181 add_reg_note (insn, REG_CFA_DEF_CFA,
21182 plus_constant (frame_reg_rtx, sp_offset));
21183 RTX_FRAME_RELATED_P (insn) = 1;
21186 for (i = info->first_gp_reg_save; i < 32; i++)
21188 = alloc_reg_note (REG_CFA_RESTORE,
21189 gen_rtx_REG (reg_mode, i), cfa_restores);
21192 else if (using_load_multiple)
21195 p = rtvec_alloc (32 - info->first_gp_reg_save);
21196 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21198 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21199 GEN_INT (info->gp_save_offset
21202 rtx mem = gen_frame_mem (reg_mode, addr);
21203 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21205 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21206 if (DEFAULT_ABI == ABI_V4)
21207 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21210 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21211 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21213 add_reg_note (insn, REG_CFA_DEF_CFA,
21214 plus_constant (frame_reg_rtx, sp_offset));
21215 RTX_FRAME_RELATED_P (insn) = 1;
21220 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21221 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21223 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21224 GEN_INT (info->gp_save_offset
21227 rtx mem = gen_frame_mem (reg_mode, addr);
21228 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21230 insn = emit_move_insn (reg, mem);
21231 if (DEFAULT_ABI == ABI_V4)
21233 if (frame_pointer_needed
21234 && info->first_gp_reg_save + i
21235 == HARD_FRAME_POINTER_REGNUM)
21237 add_reg_note (insn, REG_CFA_DEF_CFA,
21238 plus_constant (frame_reg_rtx, sp_offset));
21239 RTX_FRAME_RELATED_P (insn) = 1;
21242 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21248 if (restore_lr && !restoring_GPRs_inline)
21250 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21251 info->lr_save_offset + sp_offset);
21253 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21254 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21255 gen_rtx_REG (Pmode, 0));
21258 /* Restore fpr's if we need to do it without calling a function. */
21259 if (restoring_FPRs_inline)
21260 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21261 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21262 && ! call_used_regs[info->first_fp_reg_save+i]))
21264 rtx addr, mem, reg;
21265 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21266 GEN_INT (info->fp_save_offset
21269 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21270 ? DFmode : SFmode), addr);
21271 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21272 ? DFmode : SFmode),
21273 info->first_fp_reg_save + i);
21275 emit_move_insn (reg, mem);
21276 if (DEFAULT_ABI == ABI_V4)
21277 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21281 /* If we saved cr, restore it here. Just those that were used. */
21282 if (info->cr_save_p)
21284 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21285 if (DEFAULT_ABI == ABI_V4)
21287 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21291 /* If this is V.4, unwind the stack pointer after all of the loads
21293 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21294 sp_offset, !restoring_FPRs_inline);
21299 REG_NOTES (insn) = cfa_restores;
21300 cfa_restores = NULL_RTX;
21302 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21303 RTX_FRAME_RELATED_P (insn) = 1;
21306 if (crtl->calls_eh_return)
21308 rtx sa = EH_RETURN_STACKADJ_RTX;
21309 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21315 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21316 if (! restoring_FPRs_inline)
21317 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21319 p = rtvec_alloc (2);
21321 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21322 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21323 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21324 : gen_rtx_CLOBBER (VOIDmode,
21325 gen_rtx_REG (Pmode, 65)));
21327 /* If we have to restore more than two FP registers, branch to the
21328 restore function. It will return to our caller. */
21329 if (! restoring_FPRs_inline)
21334 sym = rs6000_savres_routine_sym (info,
21338 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21339 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21340 gen_rtx_REG (Pmode,
21341 DEFAULT_ABI == ABI_AIX
21343 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21346 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21347 GEN_INT (info->fp_save_offset + 8*i));
21348 mem = gen_frame_mem (DFmode, addr);
21350 RTVEC_ELT (p, i+4) =
21351 gen_rtx_SET (VOIDmode,
21352 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21357 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21361 /* Write function epilogue. */
21364 rs6000_output_function_epilogue (FILE *file,
21365 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21367 if (! HAVE_epilogue)
21369 rtx insn = get_last_insn ();
21370 /* If the last insn was a BARRIER, we don't have to write anything except
21371 the trace table. */
21372 if (GET_CODE (insn) == NOTE)
21373 insn = prev_nonnote_insn (insn);
21374 if (insn == 0 || GET_CODE (insn) != BARRIER)
21376 /* This is slightly ugly, but at least we don't have two
21377 copies of the epilogue-emitting code. */
21380 /* A NOTE_INSN_DELETED is supposed to be at the start
21381 and end of the "toplevel" insn chain. */
21382 emit_note (NOTE_INSN_DELETED);
21383 rs6000_emit_epilogue (FALSE);
21384 emit_note (NOTE_INSN_DELETED);
21386 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21390 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21392 INSN_ADDRESSES_NEW (insn, addr);
21397 if (TARGET_DEBUG_STACK)
21398 debug_rtx_list (get_insns (), 100);
21399 final (get_insns (), file, FALSE);
21405 macho_branch_islands ();
21406 /* Mach-O doesn't support labels at the end of objects, so if
21407 it looks like we might want one, insert a NOP. */
21409 rtx insn = get_last_insn ();
21412 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21413 insn = PREV_INSN (insn);
21417 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21418 fputs ("\tnop\n", file);
21422 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21425 We don't output a traceback table if -finhibit-size-directive was
21426 used. The documentation for -finhibit-size-directive reads
21427 ``don't output a @code{.size} assembler directive, or anything
21428 else that would cause trouble if the function is split in the
21429 middle, and the two halves are placed at locations far apart in
21430 memory.'' The traceback table has this property, since it
21431 includes the offset from the start of the function to the
21432 traceback table itself.
21434 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21435 different traceback table. */
21436 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21437 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21439 const char *fname = NULL;
21440 const char *language_string = lang_hooks.name;
21441 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21443 int optional_tbtab;
21444 rs6000_stack_t *info = rs6000_stack_info ();
21446 if (rs6000_traceback == traceback_full)
21447 optional_tbtab = 1;
21448 else if (rs6000_traceback == traceback_part)
21449 optional_tbtab = 0;
21451 optional_tbtab = !optimize_size && !TARGET_ELF;
21453 if (optional_tbtab)
21455 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21456 while (*fname == '.') /* V.4 encodes . in the name */
21459 /* Need label immediately before tbtab, so we can compute
21460 its offset from the function start. */
21461 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21462 ASM_OUTPUT_LABEL (file, fname);
21465 /* The .tbtab pseudo-op can only be used for the first eight
21466 expressions, since it can't handle the possibly variable
21467 length fields that follow. However, if you omit the optional
21468 fields, the assembler outputs zeros for all optional fields
21469 anyways, giving each variable length field is minimum length
21470 (as defined in sys/debug.h). Thus we can not use the .tbtab
21471 pseudo-op at all. */
21473 /* An all-zero word flags the start of the tbtab, for debuggers
21474 that have to find it by searching forward from the entry
21475 point or from the current pc. */
21476 fputs ("\t.long 0\n", file);
21478 /* Tbtab format type. Use format type 0. */
21479 fputs ("\t.byte 0,", file);
21481 /* Language type. Unfortunately, there does not seem to be any
21482 official way to discover the language being compiled, so we
21483 use language_string.
21484 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21485 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21486 a number, so for now use 9. LTO isn't assigned a number either,
21487 so for now use 0. */
21488 if (! strcmp (language_string, "GNU C")
21489 || ! strcmp (language_string, "GNU GIMPLE"))
21491 else if (! strcmp (language_string, "GNU F77")
21492 || ! strcmp (language_string, "GNU Fortran"))
21494 else if (! strcmp (language_string, "GNU Pascal"))
21496 else if (! strcmp (language_string, "GNU Ada"))
21498 else if (! strcmp (language_string, "GNU C++")
21499 || ! strcmp (language_string, "GNU Objective-C++"))
21501 else if (! strcmp (language_string, "GNU Java"))
21503 else if (! strcmp (language_string, "GNU Objective-C"))
21506 gcc_unreachable ();
21507 fprintf (file, "%d,", i);
21509 /* 8 single bit fields: global linkage (not set for C extern linkage,
21510 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21511 from start of procedure stored in tbtab, internal function, function
21512 has controlled storage, function has no toc, function uses fp,
21513 function logs/aborts fp operations. */
21514 /* Assume that fp operations are used if any fp reg must be saved. */
21515 fprintf (file, "%d,",
21516 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21518 /* 6 bitfields: function is interrupt handler, name present in
21519 proc table, function calls alloca, on condition directives
21520 (controls stack walks, 3 bits), saves condition reg, saves
21522 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21523 set up as a frame pointer, even when there is no alloca call. */
21524 fprintf (file, "%d,",
21525 ((optional_tbtab << 6)
21526 | ((optional_tbtab & frame_pointer_needed) << 5)
21527 | (info->cr_save_p << 1)
21528 | (info->lr_save_p)));
21530 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21532 fprintf (file, "%d,",
21533 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21535 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21536 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21538 if (optional_tbtab)
21540 /* Compute the parameter info from the function decl argument
21543 int next_parm_info_bit = 31;
21545 for (decl = DECL_ARGUMENTS (current_function_decl);
21546 decl; decl = DECL_CHAIN (decl))
21548 rtx parameter = DECL_INCOMING_RTL (decl);
21549 enum machine_mode mode = GET_MODE (parameter);
21551 if (GET_CODE (parameter) == REG)
21553 if (SCALAR_FLOAT_MODE_P (mode))
21574 gcc_unreachable ();
21577 /* If only one bit will fit, don't or in this entry. */
21578 if (next_parm_info_bit > 0)
21579 parm_info |= (bits << (next_parm_info_bit - 1));
21580 next_parm_info_bit -= 2;
21584 fixed_parms += ((GET_MODE_SIZE (mode)
21585 + (UNITS_PER_WORD - 1))
21587 next_parm_info_bit -= 1;
21593 /* Number of fixed point parameters. */
21594 /* This is actually the number of words of fixed point parameters; thus
21595 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21596 fprintf (file, "%d,", fixed_parms);
21598 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21600 /* This is actually the number of fp registers that hold parameters;
21601 and thus the maximum value is 13. */
21602 /* Set parameters on stack bit if parameters are not in their original
21603 registers, regardless of whether they are on the stack? Xlc
21604 seems to set the bit when not optimizing. */
21605 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21607 if (! optional_tbtab)
21610 /* Optional fields follow. Some are variable length. */
21612 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21613 11 double float. */
21614 /* There is an entry for each parameter in a register, in the order that
21615 they occur in the parameter list. Any intervening arguments on the
21616 stack are ignored. If the list overflows a long (max possible length
21617 34 bits) then completely leave off all elements that don't fit. */
21618 /* Only emit this long if there was at least one parameter. */
21619 if (fixed_parms || float_parms)
21620 fprintf (file, "\t.long %d\n", parm_info);
21622 /* Offset from start of code to tb table. */
21623 fputs ("\t.long ", file);
21624 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21625 RS6000_OUTPUT_BASENAME (file, fname);
21627 rs6000_output_function_entry (file, fname);
21630 /* Interrupt handler mask. */
21631 /* Omit this long, since we never set the interrupt handler bit
21634 /* Number of CTL (controlled storage) anchors. */
21635 /* Omit this long, since the has_ctl bit is never set above. */
21637 /* Displacement into stack of each CTL anchor. */
21638 /* Omit this list of longs, because there are no CTL anchors. */
21640 /* Length of function name. */
21643 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21645 /* Function name. */
21646 assemble_string (fname, strlen (fname));
21648 /* Register for alloca automatic storage; this is always reg 31.
21649 Only emit this if the alloca bit was set above. */
21650 if (frame_pointer_needed)
21651 fputs ("\t.byte 31\n", file);
21653 fputs ("\t.align 2\n", file);
21657 /* A C compound statement that outputs the assembler code for a thunk
21658 function, used to implement C++ virtual function calls with
21659 multiple inheritance. The thunk acts as a wrapper around a virtual
21660 function, adjusting the implicit object parameter before handing
21661 control off to the real function.
21663 First, emit code to add the integer DELTA to the location that
21664 contains the incoming first argument. Assume that this argument
21665 contains a pointer, and is the one used to pass the `this' pointer
21666 in C++. This is the incoming argument *before* the function
21667 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21668 values of all other incoming arguments.
21670 After the addition, emit code to jump to FUNCTION, which is a
21671 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21672 not touch the return address. Hence returning from FUNCTION will
21673 return to whoever called the current `thunk'.
21675 The effect must be as if FUNCTION had been called directly with the
21676 adjusted first argument. This macro is responsible for emitting
21677 all of the code for a thunk function; output_function_prologue()
21678 and output_function_epilogue() are not invoked.
21680 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21681 been extracted from it.) It might possibly be useful on some
21682 targets, but probably not.
21684 If you do not define this macro, the target-independent code in the
21685 C++ frontend will generate a less efficient heavyweight thunk that
21686 calls FUNCTION instead of jumping to it. The generic approach does
21687 not support varargs. */
21690 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21691 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21694 rtx this_rtx, insn, funexp;
21696 reload_completed = 1;
21697 epilogue_completed = 1;
21699 /* Mark the end of the (empty) prologue. */
21700 emit_note (NOTE_INSN_PROLOGUE_END);
21702 /* Find the "this" pointer. If the function returns a structure,
21703 the structure return pointer is in r3. */
21704 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21705 this_rtx = gen_rtx_REG (Pmode, 4);
21707 this_rtx = gen_rtx_REG (Pmode, 3);
21709 /* Apply the constant offset, if required. */
21711 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21713 /* Apply the offset from the vtable, if required. */
21716 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21717 rtx tmp = gen_rtx_REG (Pmode, 12);
21719 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21720 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21722 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21723 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21727 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21729 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21731 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21734 /* Generate a tail call to the target function. */
21735 if (!TREE_USED (function))
21737 assemble_external (function);
21738 TREE_USED (function) = 1;
21740 funexp = XEXP (DECL_RTL (function), 0);
21741 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21744 if (MACHOPIC_INDIRECT)
21745 funexp = machopic_indirect_call_target (funexp);
21748 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21749 generate sibcall RTL explicitly. */
21750 insn = emit_call_insn (
21751 gen_rtx_PARALLEL (VOIDmode,
21753 gen_rtx_CALL (VOIDmode,
21754 funexp, const0_rtx),
21755 gen_rtx_USE (VOIDmode, const0_rtx),
21756 gen_rtx_USE (VOIDmode,
21757 gen_rtx_REG (SImode,
21759 gen_rtx_RETURN (VOIDmode))));
21760 SIBLING_CALL_P (insn) = 1;
21763 /* Run just enough of rest_of_compilation to get the insns emitted.
21764 There's not really enough bulk here to make other passes such as
21765 instruction scheduling worth while. Note that use_thunk calls
21766 assemble_start_function and assemble_end_function. */
21767 insn = get_insns ();
21768 insn_locators_alloc ();
21769 shorten_branches (insn);
21770 final_start_function (insn, file, 1);
21771 final (insn, file, 1);
21772 final_end_function ();
21774 reload_completed = 0;
21775 epilogue_completed = 0;
21778 /* A quick summary of the various types of 'constant-pool tables'
21781 Target Flags Name One table per
21782 AIX (none) AIX TOC object file
21783 AIX -mfull-toc AIX TOC object file
21784 AIX -mminimal-toc AIX minimal TOC translation unit
21785 SVR4/EABI (none) SVR4 SDATA object file
21786 SVR4/EABI -fpic SVR4 pic object file
21787 SVR4/EABI -fPIC SVR4 PIC translation unit
21788 SVR4/EABI -mrelocatable EABI TOC function
21789 SVR4/EABI -maix AIX TOC object file
21790 SVR4/EABI -maix -mminimal-toc
21791 AIX minimal TOC translation unit
21793 Name Reg. Set by entries contains:
21794 made by addrs? fp? sum?
21796 AIX TOC 2 crt0 as Y option option
21797 AIX minimal TOC 30 prolog gcc Y Y option
21798 SVR4 SDATA 13 crt0 gcc N Y N
21799 SVR4 pic 30 prolog ld Y not yet N
21800 SVR4 PIC 30 prolog gcc Y option option
21801 EABI TOC 30 prolog gcc Y option option
21805 /* Hash functions for the hash table. */
21808 rs6000_hash_constant (rtx k)
21810 enum rtx_code code = GET_CODE (k);
21811 enum machine_mode mode = GET_MODE (k);
21812 unsigned result = (code << 3) ^ mode;
21813 const char *format;
21816 format = GET_RTX_FORMAT (code);
21817 flen = strlen (format);
21823 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21826 if (mode != VOIDmode)
21827 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21839 for (; fidx < flen; fidx++)
21840 switch (format[fidx])
21845 const char *str = XSTR (k, fidx);
21846 len = strlen (str);
21847 result = result * 613 + len;
21848 for (i = 0; i < len; i++)
21849 result = result * 613 + (unsigned) str[i];
21854 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21858 result = result * 613 + (unsigned) XINT (k, fidx);
21861 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21862 result = result * 613 + (unsigned) XWINT (k, fidx);
21866 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21867 result = result * 613 + (unsigned) (XWINT (k, fidx)
21874 gcc_unreachable ();
21881 toc_hash_function (const void *hash_entry)
21883 const struct toc_hash_struct *thc =
21884 (const struct toc_hash_struct *) hash_entry;
21885 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21888 /* Compare H1 and H2 for equivalence. */
21891 toc_hash_eq (const void *h1, const void *h2)
21893 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21894 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21896 if (((const struct toc_hash_struct *) h1)->key_mode
21897 != ((const struct toc_hash_struct *) h2)->key_mode)
21900 return rtx_equal_p (r1, r2);
21903 /* These are the names given by the C++ front-end to vtables, and
21904 vtable-like objects. Ideally, this logic should not be here;
21905 instead, there should be some programmatic way of inquiring as
21906 to whether or not an object is a vtable. */
21908 #define VTABLE_NAME_P(NAME) \
21909 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21910 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21911 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21912 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21913 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21915 #ifdef NO_DOLLAR_IN_LABEL
21916 /* Return a GGC-allocated character string translating dollar signs in
21917 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21920 rs6000_xcoff_strip_dollar (const char *name)
21925 p = strchr (name, '$');
21927 if (p == 0 || p == name)
21930 len = strlen (name);
21931 strip = (char *) alloca (len + 1);
21932 strcpy (strip, name);
21933 p = strchr (strip, '$');
21937 p = strchr (p + 1, '$');
21940 return ggc_alloc_string (strip, len);
21945 rs6000_output_symbol_ref (FILE *file, rtx x)
21947 /* Currently C++ toc references to vtables can be emitted before it
21948 is decided whether the vtable is public or private. If this is
21949 the case, then the linker will eventually complain that there is
21950 a reference to an unknown section. Thus, for vtables only,
21951 we emit the TOC reference to reference the symbol and not the
21953 const char *name = XSTR (x, 0);
21955 if (VTABLE_NAME_P (name))
21957 RS6000_OUTPUT_BASENAME (file, name);
21960 assemble_name (file, name);
21963 /* Output a TOC entry. We derive the entry name from what is being
21967 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21970 const char *name = buf;
21972 HOST_WIDE_INT offset = 0;
21974 gcc_assert (!TARGET_NO_TOC);
21976 /* When the linker won't eliminate them, don't output duplicate
21977 TOC entries (this happens on AIX if there is any kind of TOC,
21978 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21980 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21982 struct toc_hash_struct *h;
21985 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
21986 time because GGC is not initialized at that point. */
21987 if (toc_hash_table == NULL)
21988 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21989 toc_hash_eq, NULL);
21991 h = ggc_alloc_toc_hash_struct ();
21993 h->key_mode = mode;
21994 h->labelno = labelno;
21996 found = htab_find_slot (toc_hash_table, h, INSERT);
21997 if (*found == NULL)
21999 else /* This is indeed a duplicate.
22000 Set this label equal to that label. */
22002 fputs ("\t.set ", file);
22003 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22004 fprintf (file, "%d,", labelno);
22005 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22006 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22012 /* If we're going to put a double constant in the TOC, make sure it's
22013 aligned properly when strict alignment is on. */
22014 if (GET_CODE (x) == CONST_DOUBLE
22015 && STRICT_ALIGNMENT
22016 && GET_MODE_BITSIZE (mode) >= 64
22017 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22018 ASM_OUTPUT_ALIGN (file, 3);
22021 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22023 /* Handle FP constants specially. Note that if we have a minimal
22024 TOC, things we put here aren't actually in the TOC, so we can allow
22026 if (GET_CODE (x) == CONST_DOUBLE &&
22027 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22029 REAL_VALUE_TYPE rv;
22032 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22033 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22034 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22036 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22040 if (TARGET_MINIMAL_TOC)
22041 fputs (DOUBLE_INT_ASM_OP, file);
22043 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22044 k[0] & 0xffffffff, k[1] & 0xffffffff,
22045 k[2] & 0xffffffff, k[3] & 0xffffffff);
22046 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22047 k[0] & 0xffffffff, k[1] & 0xffffffff,
22048 k[2] & 0xffffffff, k[3] & 0xffffffff);
22053 if (TARGET_MINIMAL_TOC)
22054 fputs ("\t.long ", file);
22056 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22057 k[0] & 0xffffffff, k[1] & 0xffffffff,
22058 k[2] & 0xffffffff, k[3] & 0xffffffff);
22059 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22060 k[0] & 0xffffffff, k[1] & 0xffffffff,
22061 k[2] & 0xffffffff, k[3] & 0xffffffff);
22065 else if (GET_CODE (x) == CONST_DOUBLE &&
22066 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22068 REAL_VALUE_TYPE rv;
22071 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22073 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22074 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22076 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22080 if (TARGET_MINIMAL_TOC)
22081 fputs (DOUBLE_INT_ASM_OP, file);
22083 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22084 k[0] & 0xffffffff, k[1] & 0xffffffff);
22085 fprintf (file, "0x%lx%08lx\n",
22086 k[0] & 0xffffffff, k[1] & 0xffffffff);
22091 if (TARGET_MINIMAL_TOC)
22092 fputs ("\t.long ", file);
22094 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22095 k[0] & 0xffffffff, k[1] & 0xffffffff);
22096 fprintf (file, "0x%lx,0x%lx\n",
22097 k[0] & 0xffffffff, k[1] & 0xffffffff);
22101 else if (GET_CODE (x) == CONST_DOUBLE &&
22102 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22104 REAL_VALUE_TYPE rv;
22107 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22108 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22109 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22111 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22115 if (TARGET_MINIMAL_TOC)
22116 fputs (DOUBLE_INT_ASM_OP, file);
22118 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22119 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22124 if (TARGET_MINIMAL_TOC)
22125 fputs ("\t.long ", file);
22127 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22128 fprintf (file, "0x%lx\n", l & 0xffffffff);
22132 else if (GET_MODE (x) == VOIDmode
22133 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22135 unsigned HOST_WIDE_INT low;
22136 HOST_WIDE_INT high;
22138 if (GET_CODE (x) == CONST_DOUBLE)
22140 low = CONST_DOUBLE_LOW (x);
22141 high = CONST_DOUBLE_HIGH (x);
22144 #if HOST_BITS_PER_WIDE_INT == 32
22147 high = (low & 0x80000000) ? ~0 : 0;
22151 low = INTVAL (x) & 0xffffffff;
22152 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22156 /* TOC entries are always Pmode-sized, but since this
22157 is a bigendian machine then if we're putting smaller
22158 integer constants in the TOC we have to pad them.
22159 (This is still a win over putting the constants in
22160 a separate constant pool, because then we'd have
22161 to have both a TOC entry _and_ the actual constant.)
22163 For a 32-bit target, CONST_INT values are loaded and shifted
22164 entirely within `low' and can be stored in one TOC entry. */
22166 /* It would be easy to make this work, but it doesn't now. */
22167 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22169 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22171 #if HOST_BITS_PER_WIDE_INT == 32
22172 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22173 POINTER_SIZE, &low, &high, 0);
22176 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22177 high = (HOST_WIDE_INT) low >> 32;
22184 if (TARGET_MINIMAL_TOC)
22185 fputs (DOUBLE_INT_ASM_OP, file);
22187 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22188 (long) high & 0xffffffff, (long) low & 0xffffffff);
22189 fprintf (file, "0x%lx%08lx\n",
22190 (long) high & 0xffffffff, (long) low & 0xffffffff);
22195 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22197 if (TARGET_MINIMAL_TOC)
22198 fputs ("\t.long ", file);
22200 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22201 (long) high & 0xffffffff, (long) low & 0xffffffff);
22202 fprintf (file, "0x%lx,0x%lx\n",
22203 (long) high & 0xffffffff, (long) low & 0xffffffff);
22207 if (TARGET_MINIMAL_TOC)
22208 fputs ("\t.long ", file);
22210 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22211 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22217 if (GET_CODE (x) == CONST)
22219 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22220 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22222 base = XEXP (XEXP (x, 0), 0);
22223 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22226 switch (GET_CODE (base))
22229 name = XSTR (base, 0);
22233 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22234 CODE_LABEL_NUMBER (XEXP (base, 0)));
22238 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22242 gcc_unreachable ();
22245 if (TARGET_MINIMAL_TOC)
22246 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22249 fputs ("\t.tc ", file);
22250 RS6000_OUTPUT_BASENAME (file, name);
22253 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22255 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22257 fputs ("[TC],", file);
22260 /* Currently C++ toc references to vtables can be emitted before it
22261 is decided whether the vtable is public or private. If this is
22262 the case, then the linker will eventually complain that there is
22263 a TOC reference to an unknown section. Thus, for vtables only,
22264 we emit the TOC reference to reference the symbol and not the
22266 if (VTABLE_NAME_P (name))
22268 RS6000_OUTPUT_BASENAME (file, name);
22270 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22271 else if (offset > 0)
22272 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22275 output_addr_const (file, x);
22279 /* Output an assembler pseudo-op to write an ASCII string of N characters
22280 starting at P to FILE.
22282 On the RS/6000, we have to do this using the .byte operation and
22283 write out special characters outside the quoted string.
22284 Also, the assembler is broken; very long strings are truncated,
22285 so we must artificially break them up early. */
22288 output_ascii (FILE *file, const char *p, int n)
22291 int i, count_string;
22292 const char *for_string = "\t.byte \"";
22293 const char *for_decimal = "\t.byte ";
22294 const char *to_close = NULL;
22297 for (i = 0; i < n; i++)
22300 if (c >= ' ' && c < 0177)
22303 fputs (for_string, file);
22306 /* Write two quotes to get one. */
22314 for_decimal = "\"\n\t.byte ";
22318 if (count_string >= 512)
22320 fputs (to_close, file);
22322 for_string = "\t.byte \"";
22323 for_decimal = "\t.byte ";
22331 fputs (for_decimal, file);
22332 fprintf (file, "%d", c);
22334 for_string = "\n\t.byte \"";
22335 for_decimal = ", ";
22341 /* Now close the string if we have written one. Then end the line. */
22343 fputs (to_close, file);
22346 /* Generate a unique section name for FILENAME for a section type
22347 represented by SECTION_DESC. Output goes into BUF.
22349 SECTION_DESC can be any string, as long as it is different for each
22350 possible section type.
22352 We name the section in the same manner as xlc. The name begins with an
22353 underscore followed by the filename (after stripping any leading directory
22354 names) with the last period replaced by the string SECTION_DESC. If
22355 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22359 rs6000_gen_section_name (char **buf, const char *filename,
22360 const char *section_desc)
22362 const char *q, *after_last_slash, *last_period = 0;
22366 after_last_slash = filename;
22367 for (q = filename; *q; q++)
22370 after_last_slash = q + 1;
22371 else if (*q == '.')
22375 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22376 *buf = (char *) xmalloc (len);
22381 for (q = after_last_slash; *q; q++)
22383 if (q == last_period)
22385 strcpy (p, section_desc);
22386 p += strlen (section_desc);
22390 else if (ISALNUM (*q))
22394 if (last_period == 0)
22395 strcpy (p, section_desc);
22400 /* Emit profile function. */
22403 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22405 /* Non-standard profiling for kernels, which just saves LR then calls
22406 _mcount without worrying about arg saves. The idea is to change
22407 the function prologue as little as possible as it isn't easy to
22408 account for arg save/restore code added just for _mcount. */
22409 if (TARGET_PROFILE_KERNEL)
22412 if (DEFAULT_ABI == ABI_AIX)
22414 #ifndef NO_PROFILE_COUNTERS
22415 # define NO_PROFILE_COUNTERS 0
22417 if (NO_PROFILE_COUNTERS)
22418 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22419 LCT_NORMAL, VOIDmode, 0);
22423 const char *label_name;
22426 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22427 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22428 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22430 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22431 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22434 else if (DEFAULT_ABI == ABI_DARWIN)
22436 const char *mcount_name = RS6000_MCOUNT;
22437 int caller_addr_regno = LR_REGNO;
22439 /* Be conservative and always set this, at least for now. */
22440 crtl->uses_pic_offset_table = 1;
22443 /* For PIC code, set up a stub and collect the caller's address
22444 from r0, which is where the prologue puts it. */
22445 if (MACHOPIC_INDIRECT
22446 && crtl->uses_pic_offset_table)
22447 caller_addr_regno = 0;
22449 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22450 LCT_NORMAL, VOIDmode, 1,
22451 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22455 /* Write function profiler code. */
22458 output_function_profiler (FILE *file, int labelno)
22462 switch (DEFAULT_ABI)
22465 gcc_unreachable ();
22470 warning (0, "no profiling of 64-bit code for this ABI");
22473 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22474 fprintf (file, "\tmflr %s\n", reg_names[0]);
22475 if (NO_PROFILE_COUNTERS)
22477 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22478 reg_names[0], reg_names[1]);
22480 else if (TARGET_SECURE_PLT && flag_pic)
22482 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22483 reg_names[0], reg_names[1]);
22484 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22485 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22486 reg_names[12], reg_names[12]);
22487 assemble_name (file, buf);
22488 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22489 assemble_name (file, buf);
22490 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22492 else if (flag_pic == 1)
22494 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22495 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22496 reg_names[0], reg_names[1]);
22497 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22498 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22499 assemble_name (file, buf);
22500 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22502 else if (flag_pic > 1)
22504 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22505 reg_names[0], reg_names[1]);
22506 /* Now, we need to get the address of the label. */
22507 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22508 assemble_name (file, buf);
22509 fputs ("-.\n1:", file);
22510 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22511 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22512 reg_names[0], reg_names[11]);
22513 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22514 reg_names[0], reg_names[0], reg_names[11]);
22518 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22519 assemble_name (file, buf);
22520 fputs ("@ha\n", file);
22521 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22522 reg_names[0], reg_names[1]);
22523 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22524 assemble_name (file, buf);
22525 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22528 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22529 fprintf (file, "\tbl %s%s\n",
22530 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22535 if (!TARGET_PROFILE_KERNEL)
22537 /* Don't do anything, done in output_profile_hook (). */
22541 gcc_assert (!TARGET_32BIT);
22543 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22544 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22546 if (cfun->static_chain_decl != NULL)
22548 asm_fprintf (file, "\tstd %s,24(%s)\n",
22549 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22550 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22551 asm_fprintf (file, "\tld %s,24(%s)\n",
22552 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22555 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22563 /* The following variable value is the last issued insn. */
22565 static rtx last_scheduled_insn;
22567 /* The following variable helps to balance issuing of load and
22568 store instructions */
22570 static int load_store_pendulum;
22572 /* Power4 load update and store update instructions are cracked into a
22573 load or store and an integer insn which are executed in the same cycle.
22574 Branches have their own dispatch slot which does not count against the
22575 GCC issue rate, but it changes the program flow so there are no other
22576 instructions to issue in this cycle. */
22579 rs6000_variable_issue_1 (rtx insn, int more)
22581 last_scheduled_insn = insn;
22582 if (GET_CODE (PATTERN (insn)) == USE
22583 || GET_CODE (PATTERN (insn)) == CLOBBER)
22585 cached_can_issue_more = more;
22586 return cached_can_issue_more;
22589 if (insn_terminates_group_p (insn, current_group))
22591 cached_can_issue_more = 0;
22592 return cached_can_issue_more;
22595 /* If no reservation, but reach here */
22596 if (recog_memoized (insn) < 0)
22599 if (rs6000_sched_groups)
22601 if (is_microcoded_insn (insn))
22602 cached_can_issue_more = 0;
22603 else if (is_cracked_insn (insn))
22604 cached_can_issue_more = more > 2 ? more - 2 : 0;
22606 cached_can_issue_more = more - 1;
22608 return cached_can_issue_more;
22611 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22614 cached_can_issue_more = more - 1;
22615 return cached_can_issue_more;
22619 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22621 int r = rs6000_variable_issue_1 (insn, more);
22623 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22627 /* Adjust the cost of a scheduling dependency. Return the new cost of
22628 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22631 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22633 enum attr_type attr_type;
22635 if (! recog_memoized (insn))
22638 switch (REG_NOTE_KIND (link))
22642 /* Data dependency; DEP_INSN writes a register that INSN reads
22643 some cycles later. */
22645 /* Separate a load from a narrower, dependent store. */
22646 if (rs6000_sched_groups
22647 && GET_CODE (PATTERN (insn)) == SET
22648 && GET_CODE (PATTERN (dep_insn)) == SET
22649 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22650 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22651 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22652 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22655 attr_type = get_attr_type (insn);
22660 /* Tell the first scheduling pass about the latency between
22661 a mtctr and bctr (and mtlr and br/blr). The first
22662 scheduling pass will not know about this latency since
22663 the mtctr instruction, which has the latency associated
22664 to it, will be generated by reload. */
22665 return TARGET_POWER ? 5 : 4;
22667 /* Leave some extra cycles between a compare and its
22668 dependent branch, to inhibit expensive mispredicts. */
22669 if ((rs6000_cpu_attr == CPU_PPC603
22670 || rs6000_cpu_attr == CPU_PPC604
22671 || rs6000_cpu_attr == CPU_PPC604E
22672 || rs6000_cpu_attr == CPU_PPC620
22673 || rs6000_cpu_attr == CPU_PPC630
22674 || rs6000_cpu_attr == CPU_PPC750
22675 || rs6000_cpu_attr == CPU_PPC7400
22676 || rs6000_cpu_attr == CPU_PPC7450
22677 || rs6000_cpu_attr == CPU_POWER4
22678 || rs6000_cpu_attr == CPU_POWER5
22679 || rs6000_cpu_attr == CPU_POWER7
22680 || rs6000_cpu_attr == CPU_CELL)
22681 && recog_memoized (dep_insn)
22682 && (INSN_CODE (dep_insn) >= 0))
22684 switch (get_attr_type (dep_insn))
22688 case TYPE_DELAYED_COMPARE:
22689 case TYPE_IMUL_COMPARE:
22690 case TYPE_LMUL_COMPARE:
22691 case TYPE_FPCOMPARE:
22692 case TYPE_CR_LOGICAL:
22693 case TYPE_DELAYED_CR:
22702 case TYPE_STORE_UX:
22704 case TYPE_FPSTORE_U:
22705 case TYPE_FPSTORE_UX:
22706 if ((rs6000_cpu == PROCESSOR_POWER6)
22707 && recog_memoized (dep_insn)
22708 && (INSN_CODE (dep_insn) >= 0))
22711 if (GET_CODE (PATTERN (insn)) != SET)
22712 /* If this happens, we have to extend this to schedule
22713 optimally. Return default for now. */
22716 /* Adjust the cost for the case where the value written
22717 by a fixed point operation is used as the address
22718 gen value on a store. */
22719 switch (get_attr_type (dep_insn))
22726 if (! store_data_bypass_p (dep_insn, insn))
22730 case TYPE_LOAD_EXT:
22731 case TYPE_LOAD_EXT_U:
22732 case TYPE_LOAD_EXT_UX:
22733 case TYPE_VAR_SHIFT_ROTATE:
22734 case TYPE_VAR_DELAYED_COMPARE:
22736 if (! store_data_bypass_p (dep_insn, insn))
22742 case TYPE_FAST_COMPARE:
22745 case TYPE_INSERT_WORD:
22746 case TYPE_INSERT_DWORD:
22747 case TYPE_FPLOAD_U:
22748 case TYPE_FPLOAD_UX:
22750 case TYPE_STORE_UX:
22751 case TYPE_FPSTORE_U:
22752 case TYPE_FPSTORE_UX:
22754 if (! store_data_bypass_p (dep_insn, insn))
22762 case TYPE_IMUL_COMPARE:
22763 case TYPE_LMUL_COMPARE:
22765 if (! store_data_bypass_p (dep_insn, insn))
22771 if (! store_data_bypass_p (dep_insn, insn))
22777 if (! store_data_bypass_p (dep_insn, insn))
22790 case TYPE_LOAD_EXT:
22791 case TYPE_LOAD_EXT_U:
22792 case TYPE_LOAD_EXT_UX:
22793 if ((rs6000_cpu == PROCESSOR_POWER6)
22794 && recog_memoized (dep_insn)
22795 && (INSN_CODE (dep_insn) >= 0))
22798 /* Adjust the cost for the case where the value written
22799 by a fixed point instruction is used within the address
22800 gen portion of a subsequent load(u)(x) */
22801 switch (get_attr_type (dep_insn))
22808 if (set_to_load_agen (dep_insn, insn))
22812 case TYPE_LOAD_EXT:
22813 case TYPE_LOAD_EXT_U:
22814 case TYPE_LOAD_EXT_UX:
22815 case TYPE_VAR_SHIFT_ROTATE:
22816 case TYPE_VAR_DELAYED_COMPARE:
22818 if (set_to_load_agen (dep_insn, insn))
22824 case TYPE_FAST_COMPARE:
22827 case TYPE_INSERT_WORD:
22828 case TYPE_INSERT_DWORD:
22829 case TYPE_FPLOAD_U:
22830 case TYPE_FPLOAD_UX:
22832 case TYPE_STORE_UX:
22833 case TYPE_FPSTORE_U:
22834 case TYPE_FPSTORE_UX:
22836 if (set_to_load_agen (dep_insn, insn))
22844 case TYPE_IMUL_COMPARE:
22845 case TYPE_LMUL_COMPARE:
22847 if (set_to_load_agen (dep_insn, insn))
22853 if (set_to_load_agen (dep_insn, insn))
22859 if (set_to_load_agen (dep_insn, insn))
22870 if ((rs6000_cpu == PROCESSOR_POWER6)
22871 && recog_memoized (dep_insn)
22872 && (INSN_CODE (dep_insn) >= 0)
22873 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22880 /* Fall out to return default cost. */
22884 case REG_DEP_OUTPUT:
22885 /* Output dependency; DEP_INSN writes a register that INSN writes some
22887 if ((rs6000_cpu == PROCESSOR_POWER6)
22888 && recog_memoized (dep_insn)
22889 && (INSN_CODE (dep_insn) >= 0))
22891 attr_type = get_attr_type (insn);
22896 if (get_attr_type (dep_insn) == TYPE_FP)
22900 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22908 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22913 gcc_unreachable ();
22919 /* Debug version of rs6000_adjust_cost. */
22922 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22924 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22930 switch (REG_NOTE_KIND (link))
22932 default: dep = "unknown depencency"; break;
22933 case REG_DEP_TRUE: dep = "data dependency"; break;
22934 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22935 case REG_DEP_ANTI: dep = "anti depencency"; break;
22939 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22940 "%s, insn:\n", ret, cost, dep);
22948 /* The function returns a true if INSN is microcoded.
22949 Return false otherwise. */
22952 is_microcoded_insn (rtx insn)
22954 if (!insn || !NONDEBUG_INSN_P (insn)
22955 || GET_CODE (PATTERN (insn)) == USE
22956 || GET_CODE (PATTERN (insn)) == CLOBBER)
22959 if (rs6000_cpu_attr == CPU_CELL)
22960 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22962 if (rs6000_sched_groups)
22964 enum attr_type type = get_attr_type (insn);
22965 if (type == TYPE_LOAD_EXT_U
22966 || type == TYPE_LOAD_EXT_UX
22967 || type == TYPE_LOAD_UX
22968 || type == TYPE_STORE_UX
22969 || type == TYPE_MFCR)
22976 /* The function returns true if INSN is cracked into 2 instructions
22977 by the processor (and therefore occupies 2 issue slots). */
22980 is_cracked_insn (rtx insn)
22982 if (!insn || !NONDEBUG_INSN_P (insn)
22983 || GET_CODE (PATTERN (insn)) == USE
22984 || GET_CODE (PATTERN (insn)) == CLOBBER)
22987 if (rs6000_sched_groups)
22989 enum attr_type type = get_attr_type (insn);
22990 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22991 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22992 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22993 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22994 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22995 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22996 || type == TYPE_IDIV || type == TYPE_LDIV
22997 || type == TYPE_INSERT_WORD)
23004 /* The function returns true if INSN can be issued only from
23005 the branch slot. */
23008 is_branch_slot_insn (rtx insn)
23010 if (!insn || !NONDEBUG_INSN_P (insn)
23011 || GET_CODE (PATTERN (insn)) == USE
23012 || GET_CODE (PATTERN (insn)) == CLOBBER)
23015 if (rs6000_sched_groups)
23017 enum attr_type type = get_attr_type (insn);
23018 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23026 /* The function returns true if out_inst sets a value that is
23027 used in the address generation computation of in_insn */
23029 set_to_load_agen (rtx out_insn, rtx in_insn)
23031 rtx out_set, in_set;
23033 /* For performance reasons, only handle the simple case where
23034 both loads are a single_set. */
23035 out_set = single_set (out_insn);
23038 in_set = single_set (in_insn);
23040 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23046 /* The function returns true if the target storage location of
23047 out_insn is adjacent to the target storage location of in_insn */
23048 /* Return 1 if memory locations are adjacent. */
23051 adjacent_mem_locations (rtx insn1, rtx insn2)
23054 rtx a = get_store_dest (PATTERN (insn1));
23055 rtx b = get_store_dest (PATTERN (insn2));
23057 if ((GET_CODE (XEXP (a, 0)) == REG
23058 || (GET_CODE (XEXP (a, 0)) == PLUS
23059 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23060 && (GET_CODE (XEXP (b, 0)) == REG
23061 || (GET_CODE (XEXP (b, 0)) == PLUS
23062 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23064 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23067 if (GET_CODE (XEXP (a, 0)) == PLUS)
23069 reg0 = XEXP (XEXP (a, 0), 0);
23070 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23073 reg0 = XEXP (a, 0);
23075 if (GET_CODE (XEXP (b, 0)) == PLUS)
23077 reg1 = XEXP (XEXP (b, 0), 0);
23078 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23081 reg1 = XEXP (b, 0);
23083 val_diff = val1 - val0;
23085 return ((REGNO (reg0) == REGNO (reg1))
23086 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23087 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23093 /* A C statement (sans semicolon) to update the integer scheduling
23094 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23095 INSN earlier, reduce the priority to execute INSN later. Do not
23096 define this macro if you do not need to adjust the scheduling
23097 priorities of insns. */
23100 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23102 /* On machines (like the 750) which have asymmetric integer units,
23103 where one integer unit can do multiply and divides and the other
23104 can't, reduce the priority of multiply/divide so it is scheduled
23105 before other integer operations. */
23108 if (! INSN_P (insn))
23111 if (GET_CODE (PATTERN (insn)) == USE)
23114 switch (rs6000_cpu_attr) {
23116 switch (get_attr_type (insn))
23123 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23124 priority, priority);
23125 if (priority >= 0 && priority < 0x01000000)
23132 if (insn_must_be_first_in_group (insn)
23133 && reload_completed
23134 && current_sched_info->sched_max_insns_priority
23135 && rs6000_sched_restricted_insns_priority)
23138 /* Prioritize insns that can be dispatched only in the first
23140 if (rs6000_sched_restricted_insns_priority == 1)
23141 /* Attach highest priority to insn. This means that in
23142 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23143 precede 'priority' (critical path) considerations. */
23144 return current_sched_info->sched_max_insns_priority;
23145 else if (rs6000_sched_restricted_insns_priority == 2)
23146 /* Increase priority of insn by a minimal amount. This means that in
23147 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23148 considerations precede dispatch-slot restriction considerations. */
23149 return (priority + 1);
23152 if (rs6000_cpu == PROCESSOR_POWER6
23153 && ((load_store_pendulum == -2 && is_load_insn (insn))
23154 || (load_store_pendulum == 2 && is_store_insn (insn))))
23155 /* Attach highest priority to insn if the scheduler has just issued two
23156 stores and this instruction is a load, or two loads and this instruction
23157 is a store. Power6 wants loads and stores scheduled alternately
23159 return current_sched_info->sched_max_insns_priority;
23164 /* Return true if the instruction is nonpipelined on the Cell. */
23166 is_nonpipeline_insn (rtx insn)
23168 enum attr_type type;
23169 if (!insn || !NONDEBUG_INSN_P (insn)
23170 || GET_CODE (PATTERN (insn)) == USE
23171 || GET_CODE (PATTERN (insn)) == CLOBBER)
23174 type = get_attr_type (insn);
23175 if (type == TYPE_IMUL
23176 || type == TYPE_IMUL2
23177 || type == TYPE_IMUL3
23178 || type == TYPE_LMUL
23179 || type == TYPE_IDIV
23180 || type == TYPE_LDIV
23181 || type == TYPE_SDIV
23182 || type == TYPE_DDIV
23183 || type == TYPE_SSQRT
23184 || type == TYPE_DSQRT
23185 || type == TYPE_MFCR
23186 || type == TYPE_MFCRF
23187 || type == TYPE_MFJMPR)
23195 /* Return how many instructions the machine can issue per cycle. */
23198 rs6000_issue_rate (void)
23200 /* Unless scheduling for register pressure, use issue rate of 1 for
23201 first scheduling pass to decrease degradation. */
23202 if (!reload_completed && !flag_sched_pressure)
23205 switch (rs6000_cpu_attr) {
23206 case CPU_RIOS1: /* ? */
23208 case CPU_PPC601: /* ? */
23217 case CPU_PPCE300C2:
23218 case CPU_PPCE300C3:
23219 case CPU_PPCE500MC:
23220 case CPU_PPCE500MC64:
23240 /* Return how many instructions to look ahead for better insn
23244 rs6000_use_sched_lookahead (void)
23246 if (rs6000_cpu_attr == CPU_PPC8540)
23248 if (rs6000_cpu_attr == CPU_CELL)
23249 return (reload_completed ? 8 : 0);
23253 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23255 rs6000_use_sched_lookahead_guard (rtx insn)
23257 if (rs6000_cpu_attr != CPU_CELL)
23260 if (insn == NULL_RTX || !INSN_P (insn))
23263 if (!reload_completed
23264 || is_nonpipeline_insn (insn)
23265 || is_microcoded_insn (insn))
23271 /* Determine is PAT refers to memory. */
23274 is_mem_ref (rtx pat)
23280 /* stack_tie does not produce any real memory traffic. */
23281 if (GET_CODE (pat) == UNSPEC
23282 && XINT (pat, 1) == UNSPEC_TIE)
23285 if (GET_CODE (pat) == MEM)
23288 /* Recursively process the pattern. */
23289 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23291 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23294 ret |= is_mem_ref (XEXP (pat, i));
23295 else if (fmt[i] == 'E')
23296 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23297 ret |= is_mem_ref (XVECEXP (pat, i, j));
23303 /* Determine if PAT is a PATTERN of a load insn. */
23306 is_load_insn1 (rtx pat)
23308 if (!pat || pat == NULL_RTX)
23311 if (GET_CODE (pat) == SET)
23312 return is_mem_ref (SET_SRC (pat));
23314 if (GET_CODE (pat) == PARALLEL)
23318 for (i = 0; i < XVECLEN (pat, 0); i++)
23319 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23326 /* Determine if INSN loads from memory. */
23329 is_load_insn (rtx insn)
23331 if (!insn || !INSN_P (insn))
23334 if (GET_CODE (insn) == CALL_INSN)
23337 return is_load_insn1 (PATTERN (insn));
23340 /* Determine if PAT is a PATTERN of a store insn. */
23343 is_store_insn1 (rtx pat)
23345 if (!pat || pat == NULL_RTX)
23348 if (GET_CODE (pat) == SET)
23349 return is_mem_ref (SET_DEST (pat));
23351 if (GET_CODE (pat) == PARALLEL)
23355 for (i = 0; i < XVECLEN (pat, 0); i++)
23356 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23363 /* Determine if INSN stores to memory. */
23366 is_store_insn (rtx insn)
23368 if (!insn || !INSN_P (insn))
23371 return is_store_insn1 (PATTERN (insn));
23374 /* Return the dest of a store insn. */
23377 get_store_dest (rtx pat)
23379 gcc_assert (is_store_insn1 (pat));
23381 if (GET_CODE (pat) == SET)
23382 return SET_DEST (pat);
23383 else if (GET_CODE (pat) == PARALLEL)
23387 for (i = 0; i < XVECLEN (pat, 0); i++)
23389 rtx inner_pat = XVECEXP (pat, 0, i);
23390 if (GET_CODE (inner_pat) == SET
23391 && is_mem_ref (SET_DEST (inner_pat)))
23395 /* We shouldn't get here, because we should have either a simple
23396 store insn or a store with update which are covered above. */
23400 /* Returns whether the dependence between INSN and NEXT is considered
23401 costly by the given target. */
23404 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23409 /* If the flag is not enabled - no dependence is considered costly;
23410 allow all dependent insns in the same group.
23411 This is the most aggressive option. */
23412 if (rs6000_sched_costly_dep == no_dep_costly)
23415 /* If the flag is set to 1 - a dependence is always considered costly;
23416 do not allow dependent instructions in the same group.
23417 This is the most conservative option. */
23418 if (rs6000_sched_costly_dep == all_deps_costly)
23421 insn = DEP_PRO (dep);
23422 next = DEP_CON (dep);
23424 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23425 && is_load_insn (next)
23426 && is_store_insn (insn))
23427 /* Prevent load after store in the same group. */
23430 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23431 && is_load_insn (next)
23432 && is_store_insn (insn)
23433 && DEP_TYPE (dep) == REG_DEP_TRUE)
23434 /* Prevent load after store in the same group if it is a true
23438 /* The flag is set to X; dependences with latency >= X are considered costly,
23439 and will not be scheduled in the same group. */
23440 if (rs6000_sched_costly_dep <= max_dep_latency
23441 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23447 /* Return the next insn after INSN that is found before TAIL is reached,
23448 skipping any "non-active" insns - insns that will not actually occupy
23449 an issue slot. Return NULL_RTX if such an insn is not found. */
23452 get_next_active_insn (rtx insn, rtx tail)
23454 if (insn == NULL_RTX || insn == tail)
23459 insn = NEXT_INSN (insn);
23460 if (insn == NULL_RTX || insn == tail)
23465 || (NONJUMP_INSN_P (insn)
23466 && GET_CODE (PATTERN (insn)) != USE
23467 && GET_CODE (PATTERN (insn)) != CLOBBER
23468 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23474 /* We are about to begin issuing insns for this clock cycle. */
23477 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23478 rtx *ready ATTRIBUTE_UNUSED,
23479 int *pn_ready ATTRIBUTE_UNUSED,
23480 int clock_var ATTRIBUTE_UNUSED)
23482 int n_ready = *pn_ready;
23485 fprintf (dump, "// rs6000_sched_reorder :\n");
23487 /* Reorder the ready list, if the second to last ready insn
23488 is a nonepipeline insn. */
23489 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23491 if (is_nonpipeline_insn (ready[n_ready - 1])
23492 && (recog_memoized (ready[n_ready - 2]) > 0))
23493 /* Simply swap first two insns. */
23495 rtx tmp = ready[n_ready - 1];
23496 ready[n_ready - 1] = ready[n_ready - 2];
23497 ready[n_ready - 2] = tmp;
23501 if (rs6000_cpu == PROCESSOR_POWER6)
23502 load_store_pendulum = 0;
23504 return rs6000_issue_rate ();
23507 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23510 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23511 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23514 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23516 /* For Power6, we need to handle some special cases to try and keep the
23517 store queue from overflowing and triggering expensive flushes.
23519 This code monitors how load and store instructions are being issued
23520 and skews the ready list one way or the other to increase the likelihood
23521 that a desired instruction is issued at the proper time.
23523 A couple of things are done. First, we maintain a "load_store_pendulum"
23524 to track the current state of load/store issue.
23526 - If the pendulum is at zero, then no loads or stores have been
23527 issued in the current cycle so we do nothing.
23529 - If the pendulum is 1, then a single load has been issued in this
23530 cycle and we attempt to locate another load in the ready list to
23533 - If the pendulum is -2, then two stores have already been
23534 issued in this cycle, so we increase the priority of the first load
23535 in the ready list to increase it's likelihood of being chosen first
23538 - If the pendulum is -1, then a single store has been issued in this
23539 cycle and we attempt to locate another store in the ready list to
23540 issue with it, preferring a store to an adjacent memory location to
23541 facilitate store pairing in the store queue.
23543 - If the pendulum is 2, then two loads have already been
23544 issued in this cycle, so we increase the priority of the first store
23545 in the ready list to increase it's likelihood of being chosen first
23548 - If the pendulum < -2 or > 2, then do nothing.
23550 Note: This code covers the most common scenarios. There exist non
23551 load/store instructions which make use of the LSU and which
23552 would need to be accounted for to strictly model the behavior
23553 of the machine. Those instructions are currently unaccounted
23554 for to help minimize compile time overhead of this code.
23556 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23562 if (is_store_insn (last_scheduled_insn))
23563 /* Issuing a store, swing the load_store_pendulum to the left */
23564 load_store_pendulum--;
23565 else if (is_load_insn (last_scheduled_insn))
23566 /* Issuing a load, swing the load_store_pendulum to the right */
23567 load_store_pendulum++;
23569 return cached_can_issue_more;
23571 /* If the pendulum is balanced, or there is only one instruction on
23572 the ready list, then all is well, so return. */
23573 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23574 return cached_can_issue_more;
23576 if (load_store_pendulum == 1)
23578 /* A load has been issued in this cycle. Scan the ready list
23579 for another load to issue with it */
23584 if (is_load_insn (ready[pos]))
23586 /* Found a load. Move it to the head of the ready list,
23587 and adjust it's priority so that it is more likely to
23590 for (i=pos; i<*pn_ready-1; i++)
23591 ready[i] = ready[i + 1];
23592 ready[*pn_ready-1] = tmp;
23594 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23595 INSN_PRIORITY (tmp)++;
23601 else if (load_store_pendulum == -2)
23603 /* Two stores have been issued in this cycle. Increase the
23604 priority of the first load in the ready list to favor it for
23605 issuing in the next cycle. */
23610 if (is_load_insn (ready[pos])
23612 && INSN_PRIORITY_KNOWN (ready[pos]))
23614 INSN_PRIORITY (ready[pos])++;
23616 /* Adjust the pendulum to account for the fact that a load
23617 was found and increased in priority. This is to prevent
23618 increasing the priority of multiple loads */
23619 load_store_pendulum--;
23626 else if (load_store_pendulum == -1)
23628 /* A store has been issued in this cycle. Scan the ready list for
23629 another store to issue with it, preferring a store to an adjacent
23631 int first_store_pos = -1;
23637 if (is_store_insn (ready[pos]))
23639 /* Maintain the index of the first store found on the
23641 if (first_store_pos == -1)
23642 first_store_pos = pos;
23644 if (is_store_insn (last_scheduled_insn)
23645 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23647 /* Found an adjacent store. Move it to the head of the
23648 ready list, and adjust it's priority so that it is
23649 more likely to stay there */
23651 for (i=pos; i<*pn_ready-1; i++)
23652 ready[i] = ready[i + 1];
23653 ready[*pn_ready-1] = tmp;
23655 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23656 INSN_PRIORITY (tmp)++;
23658 first_store_pos = -1;
23666 if (first_store_pos >= 0)
23668 /* An adjacent store wasn't found, but a non-adjacent store was,
23669 so move the non-adjacent store to the front of the ready
23670 list, and adjust its priority so that it is more likely to
23672 tmp = ready[first_store_pos];
23673 for (i=first_store_pos; i<*pn_ready-1; i++)
23674 ready[i] = ready[i + 1];
23675 ready[*pn_ready-1] = tmp;
23676 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23677 INSN_PRIORITY (tmp)++;
23680 else if (load_store_pendulum == 2)
23682 /* Two loads have been issued in this cycle. Increase the priority
23683 of the first store in the ready list to favor it for issuing in
23689 if (is_store_insn (ready[pos])
23691 && INSN_PRIORITY_KNOWN (ready[pos]))
23693 INSN_PRIORITY (ready[pos])++;
23695 /* Adjust the pendulum to account for the fact that a store
23696 was found and increased in priority. This is to prevent
23697 increasing the priority of multiple stores */
23698 load_store_pendulum++;
23707 return cached_can_issue_more;
23710 /* Return whether the presence of INSN causes a dispatch group termination
23711 of group WHICH_GROUP.
23713 If WHICH_GROUP == current_group, this function will return true if INSN
23714 causes the termination of the current group (i.e, the dispatch group to
23715 which INSN belongs). This means that INSN will be the last insn in the
23716 group it belongs to.
23718 If WHICH_GROUP == previous_group, this function will return true if INSN
23719 causes the termination of the previous group (i.e, the dispatch group that
23720 precedes the group to which INSN belongs). This means that INSN will be
23721 the first insn in the group it belongs to). */
23724 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23731 first = insn_must_be_first_in_group (insn);
23732 last = insn_must_be_last_in_group (insn);
23737 if (which_group == current_group)
23739 else if (which_group == previous_group)
23747 insn_must_be_first_in_group (rtx insn)
23749 enum attr_type type;
23752 || GET_CODE (insn) == NOTE
23753 || DEBUG_INSN_P (insn)
23754 || GET_CODE (PATTERN (insn)) == USE
23755 || GET_CODE (PATTERN (insn)) == CLOBBER)
23758 switch (rs6000_cpu)
23760 case PROCESSOR_POWER5:
23761 if (is_cracked_insn (insn))
23763 case PROCESSOR_POWER4:
23764 if (is_microcoded_insn (insn))
23767 if (!rs6000_sched_groups)
23770 type = get_attr_type (insn);
23777 case TYPE_DELAYED_CR:
23778 case TYPE_CR_LOGICAL:
23792 case PROCESSOR_POWER6:
23793 type = get_attr_type (insn);
23797 case TYPE_INSERT_DWORD:
23801 case TYPE_VAR_SHIFT_ROTATE:
23808 case TYPE_INSERT_WORD:
23809 case TYPE_DELAYED_COMPARE:
23810 case TYPE_IMUL_COMPARE:
23811 case TYPE_LMUL_COMPARE:
23812 case TYPE_FPCOMPARE:
23823 case TYPE_LOAD_EXT_UX:
23825 case TYPE_STORE_UX:
23826 case TYPE_FPLOAD_U:
23827 case TYPE_FPLOAD_UX:
23828 case TYPE_FPSTORE_U:
23829 case TYPE_FPSTORE_UX:
23835 case PROCESSOR_POWER7:
23836 type = get_attr_type (insn);
23840 case TYPE_CR_LOGICAL:
23847 case TYPE_DELAYED_COMPARE:
23848 case TYPE_VAR_DELAYED_COMPARE:
23854 case TYPE_LOAD_EXT:
23855 case TYPE_LOAD_EXT_U:
23856 case TYPE_LOAD_EXT_UX:
23858 case TYPE_STORE_UX:
23859 case TYPE_FPLOAD_U:
23860 case TYPE_FPLOAD_UX:
23861 case TYPE_FPSTORE_U:
23862 case TYPE_FPSTORE_UX:
23878 insn_must_be_last_in_group (rtx insn)
23880 enum attr_type type;
23883 || GET_CODE (insn) == NOTE
23884 || DEBUG_INSN_P (insn)
23885 || GET_CODE (PATTERN (insn)) == USE
23886 || GET_CODE (PATTERN (insn)) == CLOBBER)
23889 switch (rs6000_cpu) {
23890 case PROCESSOR_POWER4:
23891 case PROCESSOR_POWER5:
23892 if (is_microcoded_insn (insn))
23895 if (is_branch_slot_insn (insn))
23899 case PROCESSOR_POWER6:
23900 type = get_attr_type (insn);
23907 case TYPE_VAR_SHIFT_ROTATE:
23914 case TYPE_DELAYED_COMPARE:
23915 case TYPE_IMUL_COMPARE:
23916 case TYPE_LMUL_COMPARE:
23917 case TYPE_FPCOMPARE:
23931 case PROCESSOR_POWER7:
23932 type = get_attr_type (insn);
23940 case TYPE_LOAD_EXT_U:
23941 case TYPE_LOAD_EXT_UX:
23942 case TYPE_STORE_UX:
23955 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23956 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23959 is_costly_group (rtx *group_insns, rtx next_insn)
23962 int issue_rate = rs6000_issue_rate ();
23964 for (i = 0; i < issue_rate; i++)
23966 sd_iterator_def sd_it;
23968 rtx insn = group_insns[i];
23973 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23975 rtx next = DEP_CON (dep);
23977 if (next == next_insn
23978 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23986 /* Utility of the function redefine_groups.
23987 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23988 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23989 to keep it "far" (in a separate group) from GROUP_INSNS, following
23990 one of the following schemes, depending on the value of the flag
23991 -minsert_sched_nops = X:
23992 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23993 in order to force NEXT_INSN into a separate group.
23994 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23995 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23996 insertion (has a group just ended, how many vacant issue slots remain in the
23997 last group, and how many dispatch groups were encountered so far). */
24000 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24001 rtx next_insn, bool *group_end, int can_issue_more,
24006 int issue_rate = rs6000_issue_rate ();
24007 bool end = *group_end;
24010 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24011 return can_issue_more;
24013 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24014 return can_issue_more;
24016 force = is_costly_group (group_insns, next_insn);
24018 return can_issue_more;
24020 if (sched_verbose > 6)
24021 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24022 *group_count ,can_issue_more);
24024 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24027 can_issue_more = 0;
24029 /* Since only a branch can be issued in the last issue_slot, it is
24030 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24031 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24032 in this case the last nop will start a new group and the branch
24033 will be forced to the new group. */
24034 if (can_issue_more && !is_branch_slot_insn (next_insn))
24037 while (can_issue_more > 0)
24040 emit_insn_before (nop, next_insn);
24048 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24050 int n_nops = rs6000_sched_insert_nops;
24052 /* Nops can't be issued from the branch slot, so the effective
24053 issue_rate for nops is 'issue_rate - 1'. */
24054 if (can_issue_more == 0)
24055 can_issue_more = issue_rate;
24057 if (can_issue_more == 0)
24059 can_issue_more = issue_rate - 1;
24062 for (i = 0; i < issue_rate; i++)
24064 group_insns[i] = 0;
24071 emit_insn_before (nop, next_insn);
24072 if (can_issue_more == issue_rate - 1) /* new group begins */
24075 if (can_issue_more == 0)
24077 can_issue_more = issue_rate - 1;
24080 for (i = 0; i < issue_rate; i++)
24082 group_insns[i] = 0;
24088 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24091 /* Is next_insn going to start a new group? */
24094 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24095 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24096 || (can_issue_more < issue_rate &&
24097 insn_terminates_group_p (next_insn, previous_group)));
24098 if (*group_end && end)
24101 if (sched_verbose > 6)
24102 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24103 *group_count, can_issue_more);
24104 return can_issue_more;
24107 return can_issue_more;
24110 /* This function tries to synch the dispatch groups that the compiler "sees"
24111 with the dispatch groups that the processor dispatcher is expected to
24112 form in practice. It tries to achieve this synchronization by forcing the
24113 estimated processor grouping on the compiler (as opposed to the function
24114 'pad_goups' which tries to force the scheduler's grouping on the processor).
24116 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24117 examines the (estimated) dispatch groups that will be formed by the processor
24118 dispatcher. It marks these group boundaries to reflect the estimated
24119 processor grouping, overriding the grouping that the scheduler had marked.
24120 Depending on the value of the flag '-minsert-sched-nops' this function can
24121 force certain insns into separate groups or force a certain distance between
24122 them by inserting nops, for example, if there exists a "costly dependence"
24125 The function estimates the group boundaries that the processor will form as
24126 follows: It keeps track of how many vacant issue slots are available after
24127 each insn. A subsequent insn will start a new group if one of the following
24129 - no more vacant issue slots remain in the current dispatch group.
24130 - only the last issue slot, which is the branch slot, is vacant, but the next
24131 insn is not a branch.
24132 - only the last 2 or less issue slots, including the branch slot, are vacant,
24133 which means that a cracked insn (which occupies two issue slots) can't be
24134 issued in this group.
24135 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24136 start a new group. */
24139 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24141 rtx insn, next_insn;
24143 int can_issue_more;
24146 int group_count = 0;
24150 issue_rate = rs6000_issue_rate ();
24151 group_insns = XALLOCAVEC (rtx, issue_rate);
24152 for (i = 0; i < issue_rate; i++)
24154 group_insns[i] = 0;
24156 can_issue_more = issue_rate;
24158 insn = get_next_active_insn (prev_head_insn, tail);
24161 while (insn != NULL_RTX)
24163 slot = (issue_rate - can_issue_more);
24164 group_insns[slot] = insn;
24166 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24167 if (insn_terminates_group_p (insn, current_group))
24168 can_issue_more = 0;
24170 next_insn = get_next_active_insn (insn, tail);
24171 if (next_insn == NULL_RTX)
24172 return group_count + 1;
24174 /* Is next_insn going to start a new group? */
24176 = (can_issue_more == 0
24177 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24178 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24179 || (can_issue_more < issue_rate &&
24180 insn_terminates_group_p (next_insn, previous_group)));
24182 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24183 next_insn, &group_end, can_issue_more,
24189 can_issue_more = 0;
24190 for (i = 0; i < issue_rate; i++)
24192 group_insns[i] = 0;
24196 if (GET_MODE (next_insn) == TImode && can_issue_more)
24197 PUT_MODE (next_insn, VOIDmode);
24198 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24199 PUT_MODE (next_insn, TImode);
24202 if (can_issue_more == 0)
24203 can_issue_more = issue_rate;
24206 return group_count;
24209 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24210 dispatch group boundaries that the scheduler had marked. Pad with nops
24211 any dispatch groups which have vacant issue slots, in order to force the
24212 scheduler's grouping on the processor dispatcher. The function
24213 returns the number of dispatch groups found. */
24216 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24218 rtx insn, next_insn;
24221 int can_issue_more;
24223 int group_count = 0;
24225 /* Initialize issue_rate. */
24226 issue_rate = rs6000_issue_rate ();
24227 can_issue_more = issue_rate;
24229 insn = get_next_active_insn (prev_head_insn, tail);
24230 next_insn = get_next_active_insn (insn, tail);
24232 while (insn != NULL_RTX)
24235 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24237 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24239 if (next_insn == NULL_RTX)
24244 /* If the scheduler had marked group termination at this location
24245 (between insn and next_insn), and neither insn nor next_insn will
24246 force group termination, pad the group with nops to force group
24249 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24250 && !insn_terminates_group_p (insn, current_group)
24251 && !insn_terminates_group_p (next_insn, previous_group))
24253 if (!is_branch_slot_insn (next_insn))
24256 while (can_issue_more)
24259 emit_insn_before (nop, next_insn);
24264 can_issue_more = issue_rate;
24269 next_insn = get_next_active_insn (insn, tail);
24272 return group_count;
24275 /* We're beginning a new block. Initialize data structures as necessary. */
24278 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24279 int sched_verbose ATTRIBUTE_UNUSED,
24280 int max_ready ATTRIBUTE_UNUSED)
24282 last_scheduled_insn = NULL_RTX;
24283 load_store_pendulum = 0;
24286 /* The following function is called at the end of scheduling BB.
24287 After reload, it inserts nops at insn group bundling. */
24290 rs6000_sched_finish (FILE *dump, int sched_verbose)
24295 fprintf (dump, "=== Finishing schedule.\n");
24297 if (reload_completed && rs6000_sched_groups)
24299 /* Do not run sched_finish hook when selective scheduling enabled. */
24300 if (sel_sched_p ())
24303 if (rs6000_sched_insert_nops == sched_finish_none)
24306 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24307 n_groups = pad_groups (dump, sched_verbose,
24308 current_sched_info->prev_head,
24309 current_sched_info->next_tail);
24311 n_groups = redefine_groups (dump, sched_verbose,
24312 current_sched_info->prev_head,
24313 current_sched_info->next_tail);
24315 if (sched_verbose >= 6)
24317 fprintf (dump, "ngroups = %d\n", n_groups);
24318 print_rtl (dump, current_sched_info->prev_head);
24319 fprintf (dump, "Done finish_sched\n");
24324 struct _rs6000_sched_context
24326 short cached_can_issue_more;
24327 rtx last_scheduled_insn;
24328 int load_store_pendulum;
24331 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24332 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24334 /* Allocate store for new scheduling context. */
24336 rs6000_alloc_sched_context (void)
24338 return xmalloc (sizeof (rs6000_sched_context_def));
24341 /* If CLEAN_P is true then initializes _SC with clean data,
24342 and from the global context otherwise. */
24344 rs6000_init_sched_context (void *_sc, bool clean_p)
24346 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24350 sc->cached_can_issue_more = 0;
24351 sc->last_scheduled_insn = NULL_RTX;
24352 sc->load_store_pendulum = 0;
24356 sc->cached_can_issue_more = cached_can_issue_more;
24357 sc->last_scheduled_insn = last_scheduled_insn;
24358 sc->load_store_pendulum = load_store_pendulum;
24362 /* Sets the global scheduling context to the one pointed to by _SC. */
24364 rs6000_set_sched_context (void *_sc)
24366 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24368 gcc_assert (sc != NULL);
24370 cached_can_issue_more = sc->cached_can_issue_more;
24371 last_scheduled_insn = sc->last_scheduled_insn;
24372 load_store_pendulum = sc->load_store_pendulum;
24377 rs6000_free_sched_context (void *_sc)
24379 gcc_assert (_sc != NULL);
24385 /* Length in units of the trampoline for entering a nested function. */
24388 rs6000_trampoline_size (void)
24392 switch (DEFAULT_ABI)
24395 gcc_unreachable ();
24398 ret = (TARGET_32BIT) ? 12 : 24;
24403 ret = (TARGET_32BIT) ? 40 : 48;
24410 /* Emit RTL insns to initialize the variable parts of a trampoline.
24411 FNADDR is an RTX for the address of the function's pure code.
24412 CXT is an RTX for the static chain value for the function. */
24415 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24417 int regsize = (TARGET_32BIT) ? 4 : 8;
24418 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24419 rtx ctx_reg = force_reg (Pmode, cxt);
24420 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24422 switch (DEFAULT_ABI)
24425 gcc_unreachable ();
24427 /* Under AIX, just build the 3 word function descriptor */
24430 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24431 rtx fn_reg = gen_reg_rtx (Pmode);
24432 rtx toc_reg = gen_reg_rtx (Pmode);
24434 /* Macro to shorten the code expansions below. */
24435 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24437 m_tramp = replace_equiv_address (m_tramp, addr);
24439 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24440 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24441 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24442 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24443 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24449 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24452 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24453 LCT_NORMAL, VOIDmode, 4,
24455 GEN_INT (rs6000_trampoline_size ()), SImode,
24463 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24464 identifier as an argument, so the front end shouldn't look it up. */
24467 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24469 return is_attribute_p ("altivec", attr_id);
24472 /* Handle the "altivec" attribute. The attribute may have
24473 arguments as follows:
24475 __attribute__((altivec(vector__)))
24476 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24477 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24479 and may appear more than once (e.g., 'vector bool char') in a
24480 given declaration. */
24483 rs6000_handle_altivec_attribute (tree *node,
24484 tree name ATTRIBUTE_UNUSED,
24486 int flags ATTRIBUTE_UNUSED,
24487 bool *no_add_attrs)
24489 tree type = *node, result = NULL_TREE;
24490 enum machine_mode mode;
24493 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24494 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24495 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24498 while (POINTER_TYPE_P (type)
24499 || TREE_CODE (type) == FUNCTION_TYPE
24500 || TREE_CODE (type) == METHOD_TYPE
24501 || TREE_CODE (type) == ARRAY_TYPE)
24502 type = TREE_TYPE (type);
24504 mode = TYPE_MODE (type);
24506 /* Check for invalid AltiVec type qualifiers. */
24507 if (type == long_double_type_node)
24508 error ("use of %<long double%> in AltiVec types is invalid");
24509 else if (type == boolean_type_node)
24510 error ("use of boolean types in AltiVec types is invalid");
24511 else if (TREE_CODE (type) == COMPLEX_TYPE)
24512 error ("use of %<complex%> in AltiVec types is invalid");
24513 else if (DECIMAL_FLOAT_MODE_P (mode))
24514 error ("use of decimal floating point types in AltiVec types is invalid");
24515 else if (!TARGET_VSX)
24517 if (type == long_unsigned_type_node || type == long_integer_type_node)
24520 error ("use of %<long%> in AltiVec types is invalid for "
24521 "64-bit code without -mvsx");
24522 else if (rs6000_warn_altivec_long)
24523 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24526 else if (type == long_long_unsigned_type_node
24527 || type == long_long_integer_type_node)
24528 error ("use of %<long long%> in AltiVec types is invalid without "
24530 else if (type == double_type_node)
24531 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24534 switch (altivec_type)
24537 unsigned_p = TYPE_UNSIGNED (type);
24541 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24544 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24547 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24550 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24552 case SFmode: result = V4SF_type_node; break;
24553 case DFmode: result = V2DF_type_node; break;
24554 /* If the user says 'vector int bool', we may be handed the 'bool'
24555 attribute _before_ the 'vector' attribute, and so select the
24556 proper type in the 'b' case below. */
24557 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24558 case V2DImode: case V2DFmode:
24566 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24567 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24568 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24569 case QImode: case V16QImode: result = bool_V16QI_type_node;
24576 case V8HImode: result = pixel_V8HI_type_node;
24582 /* Propagate qualifiers attached to the element type
24583 onto the vector type. */
24584 if (result && result != type && TYPE_QUALS (type))
24585 result = build_qualified_type (result, TYPE_QUALS (type));
24587 *no_add_attrs = true; /* No need to hang on to the attribute. */
24590 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24595 /* AltiVec defines four built-in scalar types that serve as vector
24596 elements; we must teach the compiler how to mangle them. */
24598 static const char *
24599 rs6000_mangle_type (const_tree type)
24601 type = TYPE_MAIN_VARIANT (type);
24603 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24604 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24607 if (type == bool_char_type_node) return "U6__boolc";
24608 if (type == bool_short_type_node) return "U6__bools";
24609 if (type == pixel_type_node) return "u7__pixel";
24610 if (type == bool_int_type_node) return "U6__booli";
24611 if (type == bool_long_type_node) return "U6__booll";
24613 /* Mangle IBM extended float long double as `g' (__float128) on
24614 powerpc*-linux where long-double-64 previously was the default. */
24615 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24617 && TARGET_LONG_DOUBLE_128
24618 && !TARGET_IEEEQUAD)
24621 /* For all other types, use normal C++ mangling. */
24625 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24626 struct attribute_spec.handler. */
24629 rs6000_handle_longcall_attribute (tree *node, tree name,
24630 tree args ATTRIBUTE_UNUSED,
24631 int flags ATTRIBUTE_UNUSED,
24632 bool *no_add_attrs)
24634 if (TREE_CODE (*node) != FUNCTION_TYPE
24635 && TREE_CODE (*node) != FIELD_DECL
24636 && TREE_CODE (*node) != TYPE_DECL)
24638 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24640 *no_add_attrs = true;
24646 /* Set longcall attributes on all functions declared when
24647 rs6000_default_long_calls is true. */
24649 rs6000_set_default_type_attributes (tree type)
24651 if (rs6000_default_long_calls
24652 && (TREE_CODE (type) == FUNCTION_TYPE
24653 || TREE_CODE (type) == METHOD_TYPE))
24654 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24656 TYPE_ATTRIBUTES (type));
24659 darwin_set_default_type_attributes (type);
24663 /* Return a reference suitable for calling a function with the
24664 longcall attribute. */
24667 rs6000_longcall_ref (rtx call_ref)
24669 const char *call_name;
24672 if (GET_CODE (call_ref) != SYMBOL_REF)
24675 /* System V adds '.' to the internal name, so skip them. */
24676 call_name = XSTR (call_ref, 0);
24677 if (*call_name == '.')
24679 while (*call_name == '.')
24682 node = get_identifier (call_name);
24683 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24686 return force_reg (Pmode, call_ref);
24689 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24690 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24693 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24694 struct attribute_spec.handler. */
24696 rs6000_handle_struct_attribute (tree *node, tree name,
24697 tree args ATTRIBUTE_UNUSED,
24698 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24701 if (DECL_P (*node))
24703 if (TREE_CODE (*node) == TYPE_DECL)
24704 type = &TREE_TYPE (*node);
24709 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24710 || TREE_CODE (*type) == UNION_TYPE)))
24712 warning (OPT_Wattributes, "%qE attribute ignored", name);
24713 *no_add_attrs = true;
24716 else if ((is_attribute_p ("ms_struct", name)
24717 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24718 || ((is_attribute_p ("gcc_struct", name)
24719 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24721 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24723 *no_add_attrs = true;
24730 rs6000_ms_bitfield_layout_p (const_tree record_type)
24732 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24733 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24734 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24737 #ifdef USING_ELFOS_H
24739 /* A get_unnamed_section callback, used for switching to toc_section. */
24742 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24744 if (DEFAULT_ABI == ABI_AIX
24745 && TARGET_MINIMAL_TOC
24746 && !TARGET_RELOCATABLE)
24748 if (!toc_initialized)
24750 toc_initialized = 1;
24751 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24752 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24753 fprintf (asm_out_file, "\t.tc ");
24754 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24755 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24756 fprintf (asm_out_file, "\n");
24758 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24759 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24760 fprintf (asm_out_file, " = .+32768\n");
24763 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24765 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24766 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24769 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24770 if (!toc_initialized)
24772 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24773 fprintf (asm_out_file, " = .+32768\n");
24774 toc_initialized = 1;
24779 /* Implement TARGET_ASM_INIT_SECTIONS. */
24782 rs6000_elf_asm_init_sections (void)
24785 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24788 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24789 SDATA2_SECTION_ASM_OP);
24792 /* Implement TARGET_SELECT_RTX_SECTION. */
24795 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24796 unsigned HOST_WIDE_INT align)
24798 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24799 return toc_section;
24801 return default_elf_select_rtx_section (mode, x, align);
24804 /* For a SYMBOL_REF, set generic flags and then perform some
24805 target-specific processing.
24807 When the AIX ABI is requested on a non-AIX system, replace the
24808 function name with the real name (with a leading .) rather than the
24809 function descriptor name. This saves a lot of overriding code to
24810 read the prefixes. */
24813 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24815 default_encode_section_info (decl, rtl, first);
24818 && TREE_CODE (decl) == FUNCTION_DECL
24820 && DEFAULT_ABI == ABI_AIX)
24822 rtx sym_ref = XEXP (rtl, 0);
24823 size_t len = strlen (XSTR (sym_ref, 0));
24824 char *str = XALLOCAVEC (char, len + 2);
24826 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24827 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24832 compare_section_name (const char *section, const char *templ)
24836 len = strlen (templ);
24837 return (strncmp (section, templ, len) == 0
24838 && (section[len] == 0 || section[len] == '.'));
24842 rs6000_elf_in_small_data_p (const_tree decl)
24844 if (rs6000_sdata == SDATA_NONE)
24847 /* We want to merge strings, so we never consider them small data. */
24848 if (TREE_CODE (decl) == STRING_CST)
24851 /* Functions are never in the small data area. */
24852 if (TREE_CODE (decl) == FUNCTION_DECL)
24855 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24857 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24858 if (compare_section_name (section, ".sdata")
24859 || compare_section_name (section, ".sdata2")
24860 || compare_section_name (section, ".gnu.linkonce.s")
24861 || compare_section_name (section, ".sbss")
24862 || compare_section_name (section, ".sbss2")
24863 || compare_section_name (section, ".gnu.linkonce.sb")
24864 || strcmp (section, ".PPC.EMB.sdata0") == 0
24865 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24870 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24873 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24874 /* If it's not public, and we're not going to reference it there,
24875 there's no need to put it in the small data section. */
24876 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24883 #endif /* USING_ELFOS_H */
24885 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24888 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24890 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24893 /* Return a REG that occurs in ADDR with coefficient 1.
24894 ADDR can be effectively incremented by incrementing REG.
24896 r0 is special and we must not select it as an address
24897 register by this routine since our caller will try to
24898 increment the returned register via an "la" instruction. */
24901 find_addr_reg (rtx addr)
24903 while (GET_CODE (addr) == PLUS)
24905 if (GET_CODE (XEXP (addr, 0)) == REG
24906 && REGNO (XEXP (addr, 0)) != 0)
24907 addr = XEXP (addr, 0);
24908 else if (GET_CODE (XEXP (addr, 1)) == REG
24909 && REGNO (XEXP (addr, 1)) != 0)
24910 addr = XEXP (addr, 1);
24911 else if (CONSTANT_P (XEXP (addr, 0)))
24912 addr = XEXP (addr, 1);
24913 else if (CONSTANT_P (XEXP (addr, 1)))
24914 addr = XEXP (addr, 0);
24916 gcc_unreachable ();
24918 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24923 rs6000_fatal_bad_address (rtx op)
24925 fatal_insn ("bad address", op);
24930 typedef struct branch_island_d {
24931 tree function_name;
24936 DEF_VEC_O(branch_island);
24937 DEF_VEC_ALLOC_O(branch_island,gc);
24939 static VEC(branch_island,gc) *branch_islands;
24941 /* Remember to generate a branch island for far calls to the given
24945 add_compiler_branch_island (tree label_name, tree function_name,
24948 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24950 bi->function_name = function_name;
24951 bi->label_name = label_name;
24952 bi->line_number = line_number;
24955 /* Generate far-jump branch islands for everything recorded in
24956 branch_islands. Invoked immediately after the last instruction of
24957 the epilogue has been emitted; the branch islands must be appended
24958 to, and contiguous with, the function body. Mach-O stubs are
24959 generated in machopic_output_stub(). */
24962 macho_branch_islands (void)
24966 while (!VEC_empty (branch_island, branch_islands))
24968 branch_island *bi = VEC_last (branch_island, branch_islands);
24969 const char *label = IDENTIFIER_POINTER (bi->label_name);
24970 const char *name = IDENTIFIER_POINTER (bi->function_name);
24971 char name_buf[512];
24972 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24973 if (name[0] == '*' || name[0] == '&')
24974 strcpy (name_buf, name+1);
24978 strcpy (name_buf+1, name);
24980 strcpy (tmp_buf, "\n");
24981 strcat (tmp_buf, label);
24982 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24983 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24984 dbxout_stabd (N_SLINE, bi->line_number);
24985 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24988 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24989 strcat (tmp_buf, label);
24990 strcat (tmp_buf, "_pic\n");
24991 strcat (tmp_buf, label);
24992 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24994 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24995 strcat (tmp_buf, name_buf);
24996 strcat (tmp_buf, " - ");
24997 strcat (tmp_buf, label);
24998 strcat (tmp_buf, "_pic)\n");
25000 strcat (tmp_buf, "\tmtlr r0\n");
25002 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25003 strcat (tmp_buf, name_buf);
25004 strcat (tmp_buf, " - ");
25005 strcat (tmp_buf, label);
25006 strcat (tmp_buf, "_pic)\n");
25008 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25012 strcat (tmp_buf, ":\nlis r12,hi16(");
25013 strcat (tmp_buf, name_buf);
25014 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25015 strcat (tmp_buf, name_buf);
25016 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25018 output_asm_insn (tmp_buf, 0);
25019 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25020 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25021 dbxout_stabd (N_SLINE, bi->line_number);
25022 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25023 VEC_pop (branch_island, branch_islands);
25027 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25028 already there or not. */
25031 no_previous_def (tree function_name)
25036 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25037 if (function_name == bi->function_name)
25042 /* GET_PREV_LABEL gets the label name from the previous definition of
25046 get_prev_label (tree function_name)
25051 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25052 if (function_name == bi->function_name)
25053 return bi->label_name;
25057 /* INSN is either a function call or a millicode call. It may have an
25058 unconditional jump in its delay slot.
25060 CALL_DEST is the routine we are calling. */
25063 output_call (rtx insn, rtx *operands, int dest_operand_number,
25064 int cookie_operand_number)
25066 static char buf[256];
25067 if (darwin_emit_branch_islands
25068 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25069 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25072 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25074 if (no_previous_def (funname))
25076 rtx label_rtx = gen_label_rtx ();
25077 char *label_buf, temp_buf[256];
25078 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25079 CODE_LABEL_NUMBER (label_rtx));
25080 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25081 labelname = get_identifier (label_buf);
25082 add_compiler_branch_island (labelname, funname, insn_line (insn));
25085 labelname = get_prev_label (funname);
25087 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25088 instruction will reach 'foo', otherwise link as 'bl L42'".
25089 "L42" should be a 'branch island', that will do a far jump to
25090 'foo'. Branch islands are generated in
25091 macho_branch_islands(). */
25092 sprintf (buf, "jbsr %%z%d,%.246s",
25093 dest_operand_number, IDENTIFIER_POINTER (labelname));
25096 sprintf (buf, "bl %%z%d", dest_operand_number);
25100 /* Generate PIC and indirect symbol stubs. */
25103 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25105 unsigned int length;
25106 char *symbol_name, *lazy_ptr_name;
25107 char *local_label_0;
25108 static int label = 0;
25110 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25111 symb = (*targetm.strip_name_encoding) (symb);
25114 length = strlen (symb);
25115 symbol_name = XALLOCAVEC (char, length + 32);
25116 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25118 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25119 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25122 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25124 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25128 fprintf (file, "\t.align 5\n");
25130 fprintf (file, "%s:\n", stub);
25131 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25134 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25135 sprintf (local_label_0, "\"L%011d$spb\"", label);
25137 fprintf (file, "\tmflr r0\n");
25138 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25139 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25140 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25141 lazy_ptr_name, local_label_0);
25142 fprintf (file, "\tmtlr r0\n");
25143 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25144 (TARGET_64BIT ? "ldu" : "lwzu"),
25145 lazy_ptr_name, local_label_0);
25146 fprintf (file, "\tmtctr r12\n");
25147 fprintf (file, "\tbctr\n");
25151 fprintf (file, "\t.align 4\n");
25153 fprintf (file, "%s:\n", stub);
25154 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25156 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25157 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25158 (TARGET_64BIT ? "ldu" : "lwzu"),
25160 fprintf (file, "\tmtctr r12\n");
25161 fprintf (file, "\tbctr\n");
25164 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25165 fprintf (file, "%s:\n", lazy_ptr_name);
25166 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25167 fprintf (file, "%sdyld_stub_binding_helper\n",
25168 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25171 /* Legitimize PIC addresses. If the address is already
25172 position-independent, we return ORIG. Newly generated
25173 position-independent addresses go into a reg. This is REG if non
25174 zero, otherwise we allocate register(s) as necessary. */
25176 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25179 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25184 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25185 reg = gen_reg_rtx (Pmode);
25187 if (GET_CODE (orig) == CONST)
25191 if (GET_CODE (XEXP (orig, 0)) == PLUS
25192 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25195 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25197 /* Use a different reg for the intermediate value, as
25198 it will be marked UNCHANGING. */
25199 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25200 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25203 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25206 if (GET_CODE (offset) == CONST_INT)
25208 if (SMALL_INT (offset))
25209 return plus_constant (base, INTVAL (offset));
25210 else if (! reload_in_progress && ! reload_completed)
25211 offset = force_reg (Pmode, offset);
25214 rtx mem = force_const_mem (Pmode, orig);
25215 return machopic_legitimize_pic_address (mem, Pmode, reg);
25218 return gen_rtx_PLUS (Pmode, base, offset);
25221 /* Fall back on generic machopic code. */
25222 return machopic_legitimize_pic_address (orig, mode, reg);
25225 /* Output a .machine directive for the Darwin assembler, and call
25226 the generic start_file routine. */
25229 rs6000_darwin_file_start (void)
25231 static const struct
25237 { "ppc64", "ppc64", MASK_64BIT },
25238 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25239 { "power4", "ppc970", 0 },
25240 { "G5", "ppc970", 0 },
25241 { "7450", "ppc7450", 0 },
25242 { "7400", "ppc7400", MASK_ALTIVEC },
25243 { "G4", "ppc7400", 0 },
25244 { "750", "ppc750", 0 },
25245 { "740", "ppc750", 0 },
25246 { "G3", "ppc750", 0 },
25247 { "604e", "ppc604e", 0 },
25248 { "604", "ppc604", 0 },
25249 { "603e", "ppc603", 0 },
25250 { "603", "ppc603", 0 },
25251 { "601", "ppc601", 0 },
25252 { NULL, "ppc", 0 } };
25253 const char *cpu_id = "";
25256 rs6000_file_start ();
25257 darwin_file_start ();
25259 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25260 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25261 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25262 && rs6000_select[i].string[0] != '\0')
25263 cpu_id = rs6000_select[i].string;
25265 /* Look through the mapping array. Pick the first name that either
25266 matches the argument, has a bit set in IF_SET that is also set
25267 in the target flags, or has a NULL name. */
25270 while (mapping[i].arg != NULL
25271 && strcmp (mapping[i].arg, cpu_id) != 0
25272 && (mapping[i].if_set & target_flags) == 0)
25275 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25278 #endif /* TARGET_MACHO */
25282 rs6000_elf_reloc_rw_mask (void)
25286 else if (DEFAULT_ABI == ABI_AIX)
25292 /* Record an element in the table of global constructors. SYMBOL is
25293 a SYMBOL_REF of the function to be called; PRIORITY is a number
25294 between 0 and MAX_INIT_PRIORITY.
25296 This differs from default_named_section_asm_out_constructor in
25297 that we have special handling for -mrelocatable. */
25300 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25302 const char *section = ".ctors";
25305 if (priority != DEFAULT_INIT_PRIORITY)
25307 sprintf (buf, ".ctors.%.5u",
25308 /* Invert the numbering so the linker puts us in the proper
25309 order; constructors are run from right to left, and the
25310 linker sorts in increasing order. */
25311 MAX_INIT_PRIORITY - priority);
25315 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25316 assemble_align (POINTER_SIZE);
25318 if (TARGET_RELOCATABLE)
25320 fputs ("\t.long (", asm_out_file);
25321 output_addr_const (asm_out_file, symbol);
25322 fputs (")@fixup\n", asm_out_file);
25325 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25329 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25331 const char *section = ".dtors";
25334 if (priority != DEFAULT_INIT_PRIORITY)
25336 sprintf (buf, ".dtors.%.5u",
25337 /* Invert the numbering so the linker puts us in the proper
25338 order; constructors are run from right to left, and the
25339 linker sorts in increasing order. */
25340 MAX_INIT_PRIORITY - priority);
25344 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25345 assemble_align (POINTER_SIZE);
25347 if (TARGET_RELOCATABLE)
25349 fputs ("\t.long (", asm_out_file);
25350 output_addr_const (asm_out_file, symbol);
25351 fputs (")@fixup\n", asm_out_file);
25354 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25358 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25362 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25363 ASM_OUTPUT_LABEL (file, name);
25364 fputs (DOUBLE_INT_ASM_OP, file);
25365 rs6000_output_function_entry (file, name);
25366 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25369 fputs ("\t.size\t", file);
25370 assemble_name (file, name);
25371 fputs (",24\n\t.type\t.", file);
25372 assemble_name (file, name);
25373 fputs (",@function\n", file);
25374 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25376 fputs ("\t.globl\t.", file);
25377 assemble_name (file, name);
25382 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25383 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25384 rs6000_output_function_entry (file, name);
25385 fputs (":\n", file);
25389 if (TARGET_RELOCATABLE
25390 && !TARGET_SECURE_PLT
25391 && (get_pool_size () != 0 || crtl->profile)
25396 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25398 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25399 fprintf (file, "\t.long ");
25400 assemble_name (file, buf);
25402 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25403 assemble_name (file, buf);
25407 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25408 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25410 if (DEFAULT_ABI == ABI_AIX)
25412 const char *desc_name, *orig_name;
25414 orig_name = (*targetm.strip_name_encoding) (name);
25415 desc_name = orig_name;
25416 while (*desc_name == '.')
25419 if (TREE_PUBLIC (decl))
25420 fprintf (file, "\t.globl %s\n", desc_name);
25422 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25423 fprintf (file, "%s:\n", desc_name);
25424 fprintf (file, "\t.long %s\n", orig_name);
25425 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25426 if (DEFAULT_ABI == ABI_AIX)
25427 fputs ("\t.long 0\n", file);
25428 fprintf (file, "\t.previous\n");
25430 ASM_OUTPUT_LABEL (file, name);
25434 rs6000_elf_end_indicate_exec_stack (void)
25437 file_end_indicate_exec_stack ();
25443 rs6000_xcoff_asm_output_anchor (rtx symbol)
25447 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25448 SYMBOL_REF_BLOCK_OFFSET (symbol));
25449 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25453 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25455 fputs (GLOBAL_ASM_OP, stream);
25456 RS6000_OUTPUT_BASENAME (stream, name);
25457 putc ('\n', stream);
25460 /* A get_unnamed_decl callback, used for read-only sections. PTR
25461 points to the section string variable. */
25464 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25466 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25467 *(const char *const *) directive,
25468 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25471 /* Likewise for read-write sections. */
25474 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25476 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25477 *(const char *const *) directive,
25478 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25481 /* A get_unnamed_section callback, used for switching to toc_section. */
25484 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25486 if (TARGET_MINIMAL_TOC)
25488 /* toc_section is always selected at least once from
25489 rs6000_xcoff_file_start, so this is guaranteed to
25490 always be defined once and only once in each file. */
25491 if (!toc_initialized)
25493 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25494 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25495 toc_initialized = 1;
25497 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25498 (TARGET_32BIT ? "" : ",3"));
25501 fputs ("\t.toc\n", asm_out_file);
25504 /* Implement TARGET_ASM_INIT_SECTIONS. */
25507 rs6000_xcoff_asm_init_sections (void)
25509 read_only_data_section
25510 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25511 &xcoff_read_only_section_name);
25513 private_data_section
25514 = get_unnamed_section (SECTION_WRITE,
25515 rs6000_xcoff_output_readwrite_section_asm_op,
25516 &xcoff_private_data_section_name);
25518 read_only_private_data_section
25519 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25520 &xcoff_private_data_section_name);
25523 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25525 readonly_data_section = read_only_data_section;
25526 exception_section = data_section;
25530 rs6000_xcoff_reloc_rw_mask (void)
25536 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25537 tree decl ATTRIBUTE_UNUSED)
25540 static const char * const suffix[3] = { "PR", "RO", "RW" };
25542 if (flags & SECTION_CODE)
25544 else if (flags & SECTION_WRITE)
25549 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25550 (flags & SECTION_CODE) ? "." : "",
25551 name, suffix[smclass], flags & SECTION_ENTSIZE);
25555 rs6000_xcoff_select_section (tree decl, int reloc,
25556 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25558 if (decl_readonly_section (decl, reloc))
25560 if (TREE_PUBLIC (decl))
25561 return read_only_data_section;
25563 return read_only_private_data_section;
25567 if (TREE_PUBLIC (decl))
25568 return data_section;
25570 return private_data_section;
25575 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25579 /* Use select_section for private and uninitialized data. */
25580 if (!TREE_PUBLIC (decl)
25581 || DECL_COMMON (decl)
25582 || DECL_INITIAL (decl) == NULL_TREE
25583 || DECL_INITIAL (decl) == error_mark_node
25584 || (flag_zero_initialized_in_bss
25585 && initializer_zerop (DECL_INITIAL (decl))))
25588 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25589 name = (*targetm.strip_name_encoding) (name);
25590 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25593 /* Select section for constant in constant pool.
25595 On RS/6000, all constants are in the private read-only data area.
25596 However, if this is being placed in the TOC it must be output as a
25600 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25601 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25603 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25604 return toc_section;
25606 return read_only_private_data_section;
25609 /* Remove any trailing [DS] or the like from the symbol name. */
25611 static const char *
25612 rs6000_xcoff_strip_name_encoding (const char *name)
25617 len = strlen (name);
25618 if (name[len - 1] == ']')
25619 return ggc_alloc_string (name, len - 4);
25624 /* Section attributes. AIX is always PIC. */
25626 static unsigned int
25627 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25629 unsigned int align;
25630 unsigned int flags = default_section_type_flags (decl, name, reloc);
25632 /* Align to at least UNIT size. */
25633 if (flags & SECTION_CODE)
25634 align = MIN_UNITS_PER_WORD;
25636 /* Increase alignment of large objects if not already stricter. */
25637 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25638 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25639 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25641 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25644 /* Output at beginning of assembler file.
25646 Initialize the section names for the RS/6000 at this point.
25648 Specify filename, including full path, to assembler.
25650 We want to go into the TOC section so at least one .toc will be emitted.
25651 Also, in order to output proper .bs/.es pairs, we need at least one static
25652 [RW] section emitted.
25654 Finally, declare mcount when profiling to make the assembler happy. */
25657 rs6000_xcoff_file_start (void)
25659 rs6000_gen_section_name (&xcoff_bss_section_name,
25660 main_input_filename, ".bss_");
25661 rs6000_gen_section_name (&xcoff_private_data_section_name,
25662 main_input_filename, ".rw_");
25663 rs6000_gen_section_name (&xcoff_read_only_section_name,
25664 main_input_filename, ".ro_");
25666 fputs ("\t.file\t", asm_out_file);
25667 output_quoted_string (asm_out_file, main_input_filename);
25668 fputc ('\n', asm_out_file);
25669 if (write_symbols != NO_DEBUG)
25670 switch_to_section (private_data_section);
25671 switch_to_section (text_section);
25673 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25674 rs6000_file_start ();
25677 /* Output at end of assembler file.
25678 On the RS/6000, referencing data should automatically pull in text. */
25681 rs6000_xcoff_file_end (void)
25683 switch_to_section (text_section);
25684 fputs ("_section_.text:\n", asm_out_file);
25685 switch_to_section (data_section);
25686 fputs (TARGET_32BIT
25687 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25690 #endif /* TARGET_XCOFF */
25692 /* Compute a (partial) cost for rtx X. Return true if the complete
25693 cost has been computed, and false if subexpressions should be
25694 scanned. In either case, *TOTAL contains the cost result. */
25697 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25700 enum machine_mode mode = GET_MODE (x);
25704 /* On the RS/6000, if it is valid in the insn, it is free. */
25706 if (((outer_code == SET
25707 || outer_code == PLUS
25708 || outer_code == MINUS)
25709 && (satisfies_constraint_I (x)
25710 || satisfies_constraint_L (x)))
25711 || (outer_code == AND
25712 && (satisfies_constraint_K (x)
25714 ? satisfies_constraint_L (x)
25715 : satisfies_constraint_J (x))
25716 || mask_operand (x, mode)
25718 && mask64_operand (x, DImode))))
25719 || ((outer_code == IOR || outer_code == XOR)
25720 && (satisfies_constraint_K (x)
25722 ? satisfies_constraint_L (x)
25723 : satisfies_constraint_J (x))))
25724 || outer_code == ASHIFT
25725 || outer_code == ASHIFTRT
25726 || outer_code == LSHIFTRT
25727 || outer_code == ROTATE
25728 || outer_code == ROTATERT
25729 || outer_code == ZERO_EXTRACT
25730 || (outer_code == MULT
25731 && satisfies_constraint_I (x))
25732 || ((outer_code == DIV || outer_code == UDIV
25733 || outer_code == MOD || outer_code == UMOD)
25734 && exact_log2 (INTVAL (x)) >= 0)
25735 || (outer_code == COMPARE
25736 && (satisfies_constraint_I (x)
25737 || satisfies_constraint_K (x)))
25738 || (outer_code == EQ
25739 && (satisfies_constraint_I (x)
25740 || satisfies_constraint_K (x)
25742 ? satisfies_constraint_L (x)
25743 : satisfies_constraint_J (x))))
25744 || (outer_code == GTU
25745 && satisfies_constraint_I (x))
25746 || (outer_code == LTU
25747 && satisfies_constraint_P (x)))
25752 else if ((outer_code == PLUS
25753 && reg_or_add_cint_operand (x, VOIDmode))
25754 || (outer_code == MINUS
25755 && reg_or_sub_cint_operand (x, VOIDmode))
25756 || ((outer_code == SET
25757 || outer_code == IOR
25758 || outer_code == XOR)
25760 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25762 *total = COSTS_N_INSNS (1);
25768 if (mode == DImode && code == CONST_DOUBLE)
25770 if ((outer_code == IOR || outer_code == XOR)
25771 && CONST_DOUBLE_HIGH (x) == 0
25772 && (CONST_DOUBLE_LOW (x)
25773 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25778 else if ((outer_code == AND && and64_2_operand (x, DImode))
25779 || ((outer_code == SET
25780 || outer_code == IOR
25781 || outer_code == XOR)
25782 && CONST_DOUBLE_HIGH (x) == 0))
25784 *total = COSTS_N_INSNS (1);
25794 /* When optimizing for size, MEM should be slightly more expensive
25795 than generating address, e.g., (plus (reg) (const)).
25796 L1 cache latency is about two instructions. */
25797 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25805 if (mode == DFmode)
25807 if (GET_CODE (XEXP (x, 0)) == MULT)
25809 /* FNMA accounted in outer NEG. */
25810 if (outer_code == NEG)
25811 *total = rs6000_cost->dmul - rs6000_cost->fp;
25813 *total = rs6000_cost->dmul;
25816 *total = rs6000_cost->fp;
25818 else if (mode == SFmode)
25820 /* FNMA accounted in outer NEG. */
25821 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25824 *total = rs6000_cost->fp;
25827 *total = COSTS_N_INSNS (1);
25831 if (mode == DFmode)
25833 if (GET_CODE (XEXP (x, 0)) == MULT
25834 || GET_CODE (XEXP (x, 1)) == MULT)
25836 /* FNMA accounted in outer NEG. */
25837 if (outer_code == NEG)
25838 *total = rs6000_cost->dmul - rs6000_cost->fp;
25840 *total = rs6000_cost->dmul;
25843 *total = rs6000_cost->fp;
25845 else if (mode == SFmode)
25847 /* FNMA accounted in outer NEG. */
25848 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25851 *total = rs6000_cost->fp;
25854 *total = COSTS_N_INSNS (1);
25858 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25859 && satisfies_constraint_I (XEXP (x, 1)))
25861 if (INTVAL (XEXP (x, 1)) >= -256
25862 && INTVAL (XEXP (x, 1)) <= 255)
25863 *total = rs6000_cost->mulsi_const9;
25865 *total = rs6000_cost->mulsi_const;
25867 /* FMA accounted in outer PLUS/MINUS. */
25868 else if ((mode == DFmode || mode == SFmode)
25869 && (outer_code == PLUS || outer_code == MINUS))
25871 else if (mode == DFmode)
25872 *total = rs6000_cost->dmul;
25873 else if (mode == SFmode)
25874 *total = rs6000_cost->fp;
25875 else if (mode == DImode)
25876 *total = rs6000_cost->muldi;
25878 *total = rs6000_cost->mulsi;
25883 if (FLOAT_MODE_P (mode))
25885 *total = mode == DFmode ? rs6000_cost->ddiv
25886 : rs6000_cost->sdiv;
25893 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25894 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25896 if (code == DIV || code == MOD)
25898 *total = COSTS_N_INSNS (2);
25901 *total = COSTS_N_INSNS (1);
25905 if (GET_MODE (XEXP (x, 1)) == DImode)
25906 *total = rs6000_cost->divdi;
25908 *total = rs6000_cost->divsi;
25910 /* Add in shift and subtract for MOD. */
25911 if (code == MOD || code == UMOD)
25912 *total += COSTS_N_INSNS (2);
25917 *total = COSTS_N_INSNS (4);
25921 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25925 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25929 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25941 *total = COSTS_N_INSNS (1);
25949 /* Handle mul_highpart. */
25950 if (outer_code == TRUNCATE
25951 && GET_CODE (XEXP (x, 0)) == MULT)
25953 if (mode == DImode)
25954 *total = rs6000_cost->muldi;
25956 *total = rs6000_cost->mulsi;
25959 else if (outer_code == AND)
25962 *total = COSTS_N_INSNS (1);
25967 if (GET_CODE (XEXP (x, 0)) == MEM)
25970 *total = COSTS_N_INSNS (1);
25976 if (!FLOAT_MODE_P (mode))
25978 *total = COSTS_N_INSNS (1);
25984 case UNSIGNED_FLOAT:
25987 case FLOAT_TRUNCATE:
25988 *total = rs6000_cost->fp;
25992 if (mode == DFmode)
25995 *total = rs6000_cost->fp;
25999 switch (XINT (x, 1))
26002 *total = rs6000_cost->fp;
26014 *total = COSTS_N_INSNS (1);
26017 else if (FLOAT_MODE_P (mode)
26018 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26020 *total = rs6000_cost->fp;
26028 /* Carry bit requires mode == Pmode.
26029 NEG or PLUS already counted so only add one. */
26031 && (outer_code == NEG || outer_code == PLUS))
26033 *total = COSTS_N_INSNS (1);
26036 if (outer_code == SET)
26038 if (XEXP (x, 1) == const0_rtx)
26040 if (TARGET_ISEL && !TARGET_MFCRF)
26041 *total = COSTS_N_INSNS (8);
26043 *total = COSTS_N_INSNS (2);
26046 else if (mode == Pmode)
26048 *total = COSTS_N_INSNS (3);
26057 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26059 if (TARGET_ISEL && !TARGET_MFCRF)
26060 *total = COSTS_N_INSNS (8);
26062 *total = COSTS_N_INSNS (2);
26066 if (outer_code == COMPARE)
26080 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26083 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26086 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26089 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26090 "total = %d, speed = %s, x:\n",
26091 ret ? "complete" : "scan inner",
26092 GET_RTX_NAME (code),
26093 GET_RTX_NAME (outer_code),
26095 speed ? "true" : "false");
26102 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26105 rs6000_debug_address_cost (rtx x, bool speed)
26107 int ret = TARGET_ADDRESS_COST (x, speed);
26109 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26110 ret, speed ? "true" : "false");
26117 /* A C expression returning the cost of moving data from a register of class
26118 CLASS1 to one of CLASS2. */
26121 rs6000_register_move_cost (enum machine_mode mode,
26122 reg_class_t from, reg_class_t to)
26126 /* Moves from/to GENERAL_REGS. */
26127 if (reg_classes_intersect_p (to, GENERAL_REGS)
26128 || reg_classes_intersect_p (from, GENERAL_REGS))
26130 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26133 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26134 ret = (rs6000_memory_move_cost (mode, from, false)
26135 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26137 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26139 else if (from == CR_REGS)
26142 /* Power6 has slower LR/CTR moves so make them more expensive than
26143 memory in order to bias spills to memory .*/
26144 else if (rs6000_cpu == PROCESSOR_POWER6
26145 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26146 ret = 6 * hard_regno_nregs[0][mode];
26149 /* A move will cost one instruction per GPR moved. */
26150 ret = 2 * hard_regno_nregs[0][mode];
26153 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26154 else if (VECTOR_UNIT_VSX_P (mode)
26155 && reg_classes_intersect_p (to, VSX_REGS)
26156 && reg_classes_intersect_p (from, VSX_REGS))
26157 ret = 2 * hard_regno_nregs[32][mode];
26159 /* Moving between two similar registers is just one instruction. */
26160 else if (reg_classes_intersect_p (to, from))
26161 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26163 /* Everything else has to go through GENERAL_REGS. */
26165 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26166 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26168 if (TARGET_DEBUG_COST)
26170 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26171 ret, GET_MODE_NAME (mode), reg_class_names[from],
26172 reg_class_names[to]);
26177 /* A C expressions returning the cost of moving data of MODE from a register to
26181 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26182 bool in ATTRIBUTE_UNUSED)
26186 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26187 ret = 4 * hard_regno_nregs[0][mode];
26188 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26189 ret = 4 * hard_regno_nregs[32][mode];
26190 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26191 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26193 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26195 if (TARGET_DEBUG_COST)
26197 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26198 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26203 /* Returns a code for a target-specific builtin that implements
26204 reciprocal of the function, or NULL_TREE if not available. */
26207 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26208 bool sqrt ATTRIBUTE_UNUSED)
26210 if (optimize_insn_for_size_p ())
26216 case VSX_BUILTIN_XVSQRTDP:
26217 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26220 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26222 case VSX_BUILTIN_XVSQRTSP:
26223 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26226 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26235 case BUILT_IN_SQRT:
26236 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26239 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26241 case BUILT_IN_SQRTF:
26242 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26245 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26252 /* Load up a constant. If the mode is a vector mode, splat the value across
26253 all of the vector elements. */
26256 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26260 if (mode == SFmode || mode == DFmode)
26262 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26263 reg = force_reg (mode, d);
26265 else if (mode == V4SFmode)
26267 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26268 rtvec v = gen_rtvec (4, d, d, d, d);
26269 reg = gen_reg_rtx (mode);
26270 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26272 else if (mode == V2DFmode)
26274 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26275 rtvec v = gen_rtvec (2, d, d);
26276 reg = gen_reg_rtx (mode);
26277 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26280 gcc_unreachable ();
26285 /* Generate a FMADD instruction:
26286 dst = (m1 * m2) + a
26288 generating different RTL based on the fused multiply/add switch. */
26291 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26293 enum machine_mode mode = GET_MODE (dst);
26295 if (!TARGET_FUSED_MADD)
26297 /* For the simple ops, use the generator function, rather than assuming
26298 that the RTL is standard. */
26299 enum insn_code mcode = optab_handler (smul_optab, mode);
26300 enum insn_code acode = optab_handler (add_optab, mode);
26301 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26302 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26303 rtx mreg = gen_reg_rtx (mode);
26305 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26306 emit_insn (gen_mul (mreg, m1, m2));
26307 emit_insn (gen_add (dst, mreg, a));
26311 emit_insn (gen_rtx_SET (VOIDmode, dst,
26312 gen_rtx_PLUS (mode,
26313 gen_rtx_MULT (mode, m1, m2),
26317 /* Generate a FMSUB instruction:
26318 dst = (m1 * m2) - a
26320 generating different RTL based on the fused multiply/add switch. */
26323 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26325 enum machine_mode mode = GET_MODE (dst);
26327 if (!TARGET_FUSED_MADD
26328 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26330 /* For the simple ops, use the generator function, rather than assuming
26331 that the RTL is standard. */
26332 enum insn_code mcode = optab_handler (smul_optab, mode);
26333 enum insn_code scode = optab_handler (add_optab, mode);
26334 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26335 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26336 rtx mreg = gen_reg_rtx (mode);
26338 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26339 emit_insn (gen_mul (mreg, m1, m2));
26340 emit_insn (gen_sub (dst, mreg, a));
26344 emit_insn (gen_rtx_SET (VOIDmode, dst,
26345 gen_rtx_MINUS (mode,
26346 gen_rtx_MULT (mode, m1, m2),
26350 /* Generate a FNMSUB instruction:
26351 dst = - ((m1 * m2) - a)
26353 Which is equivalent to (except in the prescence of -0.0):
26354 dst = a - (m1 * m2)
26356 generating different RTL based on the fast-math and fused multiply/add
26360 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26362 enum machine_mode mode = GET_MODE (dst);
26364 if (!TARGET_FUSED_MADD)
26366 /* For the simple ops, use the generator function, rather than assuming
26367 that the RTL is standard. */
26368 enum insn_code mcode = optab_handler (smul_optab, mode);
26369 enum insn_code scode = optab_handler (sub_optab, mode);
26370 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26371 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26372 rtx mreg = gen_reg_rtx (mode);
26374 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26375 emit_insn (gen_mul (mreg, m1, m2));
26376 emit_insn (gen_sub (dst, a, mreg));
26381 rtx m = gen_rtx_MULT (mode, m1, m2);
26383 if (!HONOR_SIGNED_ZEROS (mode))
26384 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26387 emit_insn (gen_rtx_SET (VOIDmode, dst,
26389 gen_rtx_MINUS (mode, m, a))));
26393 /* Newton-Raphson approximation of floating point divide with just 2 passes
26394 (either single precision floating point, or newer machines with higher
26395 accuracy estimates). Support both scalar and vector divide. Assumes no
26396 trapping math and finite arguments. */
26399 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26401 enum machine_mode mode = GET_MODE (dst);
26402 rtx x0, e0, e1, y1, u0, v0;
26403 enum insn_code code = optab_handler (smul_optab, mode);
26404 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26405 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26407 gcc_assert (code != CODE_FOR_nothing);
26409 /* x0 = 1./d estimate */
26410 x0 = gen_reg_rtx (mode);
26411 emit_insn (gen_rtx_SET (VOIDmode, x0,
26412 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26415 e0 = gen_reg_rtx (mode);
26416 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26418 e1 = gen_reg_rtx (mode);
26419 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26421 y1 = gen_reg_rtx (mode);
26422 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26424 u0 = gen_reg_rtx (mode);
26425 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26427 v0 = gen_reg_rtx (mode);
26428 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26430 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26433 /* Newton-Raphson approximation of floating point divide that has a low
26434 precision estimate. Assumes no trapping math and finite arguments. */
26437 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26439 enum machine_mode mode = GET_MODE (dst);
26440 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26441 enum insn_code code = optab_handler (smul_optab, mode);
26442 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26444 gcc_assert (code != CODE_FOR_nothing);
26446 one = rs6000_load_constant_and_splat (mode, dconst1);
26448 /* x0 = 1./d estimate */
26449 x0 = gen_reg_rtx (mode);
26450 emit_insn (gen_rtx_SET (VOIDmode, x0,
26451 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26454 e0 = gen_reg_rtx (mode);
26455 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26457 y1 = gen_reg_rtx (mode);
26458 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26460 e1 = gen_reg_rtx (mode);
26461 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26463 y2 = gen_reg_rtx (mode);
26464 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26466 e2 = gen_reg_rtx (mode);
26467 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26469 y3 = gen_reg_rtx (mode);
26470 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26472 u0 = gen_reg_rtx (mode);
26473 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26475 v0 = gen_reg_rtx (mode);
26476 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26478 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26481 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26482 add a reg_note saying that this was a division. Support both scalar and
26483 vector divide. Assumes no trapping math and finite arguments. */
26486 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26488 enum machine_mode mode = GET_MODE (dst);
26490 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26491 rs6000_emit_swdiv_high_precision (dst, n, d);
26493 rs6000_emit_swdiv_low_precision (dst, n, d);
26496 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26499 /* Newton-Raphson approximation of single/double-precision floating point
26500 rsqrt. Assumes no trapping math and finite arguments. */
26503 rs6000_emit_swrsqrt (rtx dst, rtx src)
26505 enum machine_mode mode = GET_MODE (src);
26506 rtx x0 = gen_reg_rtx (mode);
26507 rtx y = gen_reg_rtx (mode);
26508 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26509 REAL_VALUE_TYPE dconst3_2;
26512 enum insn_code code = optab_handler (smul_optab, mode);
26513 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26515 gcc_assert (code != CODE_FOR_nothing);
26517 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26518 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26519 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26521 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26523 /* x0 = rsqrt estimate */
26524 emit_insn (gen_rtx_SET (VOIDmode, x0,
26525 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26528 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26529 rs6000_emit_msub (y, src, halfthree, src);
26531 for (i = 0; i < passes; i++)
26533 rtx x1 = gen_reg_rtx (mode);
26534 rtx u = gen_reg_rtx (mode);
26535 rtx v = gen_reg_rtx (mode);
26537 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26538 emit_insn (gen_mul (u, x0, x0));
26539 rs6000_emit_nmsub (v, y, u, halfthree);
26540 emit_insn (gen_mul (x1, x0, v));
26544 emit_move_insn (dst, x0);
26548 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26549 (Power7) targets. DST is the target, and SRC is the argument operand. */
26552 rs6000_emit_popcount (rtx dst, rtx src)
26554 enum machine_mode mode = GET_MODE (dst);
26557 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26558 if (TARGET_POPCNTD)
26560 if (mode == SImode)
26561 emit_insn (gen_popcntdsi2 (dst, src));
26563 emit_insn (gen_popcntddi2 (dst, src));
26567 tmp1 = gen_reg_rtx (mode);
26569 if (mode == SImode)
26571 emit_insn (gen_popcntbsi2 (tmp1, src));
26572 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26574 tmp2 = force_reg (SImode, tmp2);
26575 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26579 emit_insn (gen_popcntbdi2 (tmp1, src));
26580 tmp2 = expand_mult (DImode, tmp1,
26581 GEN_INT ((HOST_WIDE_INT)
26582 0x01010101 << 32 | 0x01010101),
26584 tmp2 = force_reg (DImode, tmp2);
26585 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26590 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26591 target, and SRC is the argument operand. */
26594 rs6000_emit_parity (rtx dst, rtx src)
26596 enum machine_mode mode = GET_MODE (dst);
26599 tmp = gen_reg_rtx (mode);
26601 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26604 if (mode == SImode)
26606 emit_insn (gen_popcntbsi2 (tmp, src));
26607 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26611 emit_insn (gen_popcntbdi2 (tmp, src));
26612 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26617 if (mode == SImode)
26619 /* Is mult+shift >= shift+xor+shift+xor? */
26620 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26622 rtx tmp1, tmp2, tmp3, tmp4;
26624 tmp1 = gen_reg_rtx (SImode);
26625 emit_insn (gen_popcntbsi2 (tmp1, src));
26627 tmp2 = gen_reg_rtx (SImode);
26628 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26629 tmp3 = gen_reg_rtx (SImode);
26630 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26632 tmp4 = gen_reg_rtx (SImode);
26633 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26634 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26637 rs6000_emit_popcount (tmp, src);
26638 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26642 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26643 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26645 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26647 tmp1 = gen_reg_rtx (DImode);
26648 emit_insn (gen_popcntbdi2 (tmp1, src));
26650 tmp2 = gen_reg_rtx (DImode);
26651 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26652 tmp3 = gen_reg_rtx (DImode);
26653 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26655 tmp4 = gen_reg_rtx (DImode);
26656 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26657 tmp5 = gen_reg_rtx (DImode);
26658 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26660 tmp6 = gen_reg_rtx (DImode);
26661 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26662 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26665 rs6000_emit_popcount (tmp, src);
26666 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26670 /* Return an RTX representing where to find the function value of a
26671 function returning MODE. */
26673 rs6000_complex_function_value (enum machine_mode mode)
26675 unsigned int regno;
26677 enum machine_mode inner = GET_MODE_INNER (mode);
26678 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26680 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26681 regno = FP_ARG_RETURN;
26684 regno = GP_ARG_RETURN;
26686 /* 32-bit is OK since it'll go in r3/r4. */
26687 if (TARGET_32BIT && inner_bytes >= 4)
26688 return gen_rtx_REG (mode, regno);
26691 if (inner_bytes >= 8)
26692 return gen_rtx_REG (mode, regno);
26694 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26696 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26697 GEN_INT (inner_bytes));
26698 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26701 /* Target hook for TARGET_FUNCTION_VALUE.
26703 On the SPE, both FPs and vectors are returned in r3.
26705 On RS/6000 an integer value is in r3 and a floating-point value is in
26706 fp1, unless -msoft-float. */
26709 rs6000_function_value (const_tree valtype,
26710 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26711 bool outgoing ATTRIBUTE_UNUSED)
26713 enum machine_mode mode;
26714 unsigned int regno;
26716 /* Special handling for structs in darwin64. */
26718 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26720 CUMULATIVE_ARGS valcum;
26724 valcum.fregno = FP_ARG_MIN_REG;
26725 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26726 /* Do a trial code generation as if this were going to be passed as
26727 an argument; if any part goes in memory, we return NULL. */
26728 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26731 /* Otherwise fall through to standard ABI rules. */
26734 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26736 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26737 return gen_rtx_PARALLEL (DImode,
26739 gen_rtx_EXPR_LIST (VOIDmode,
26740 gen_rtx_REG (SImode, GP_ARG_RETURN),
26742 gen_rtx_EXPR_LIST (VOIDmode,
26743 gen_rtx_REG (SImode,
26744 GP_ARG_RETURN + 1),
26747 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26749 return gen_rtx_PARALLEL (DCmode,
26751 gen_rtx_EXPR_LIST (VOIDmode,
26752 gen_rtx_REG (SImode, GP_ARG_RETURN),
26754 gen_rtx_EXPR_LIST (VOIDmode,
26755 gen_rtx_REG (SImode,
26756 GP_ARG_RETURN + 1),
26758 gen_rtx_EXPR_LIST (VOIDmode,
26759 gen_rtx_REG (SImode,
26760 GP_ARG_RETURN + 2),
26762 gen_rtx_EXPR_LIST (VOIDmode,
26763 gen_rtx_REG (SImode,
26764 GP_ARG_RETURN + 3),
26768 mode = TYPE_MODE (valtype);
26769 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26770 || POINTER_TYPE_P (valtype))
26771 mode = TARGET_32BIT ? SImode : DImode;
26773 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26774 /* _Decimal128 must use an even/odd register pair. */
26775 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26776 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26777 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26778 regno = FP_ARG_RETURN;
26779 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26780 && targetm.calls.split_complex_arg)
26781 return rs6000_complex_function_value (mode);
26782 else if (TREE_CODE (valtype) == VECTOR_TYPE
26783 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26784 && ALTIVEC_VECTOR_MODE (mode))
26785 regno = ALTIVEC_ARG_RETURN;
26786 else if (TREE_CODE (valtype) == VECTOR_TYPE
26787 && TARGET_VSX && TARGET_ALTIVEC_ABI
26788 && VSX_VECTOR_MODE (mode))
26789 regno = ALTIVEC_ARG_RETURN;
26790 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26791 && (mode == DFmode || mode == DCmode
26792 || mode == TFmode || mode == TCmode))
26793 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26795 regno = GP_ARG_RETURN;
26797 return gen_rtx_REG (mode, regno);
26800 /* Define how to find the value returned by a library function
26801 assuming the value has mode MODE. */
26803 rs6000_libcall_value (enum machine_mode mode)
26805 unsigned int regno;
26807 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26809 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26810 return gen_rtx_PARALLEL (DImode,
26812 gen_rtx_EXPR_LIST (VOIDmode,
26813 gen_rtx_REG (SImode, GP_ARG_RETURN),
26815 gen_rtx_EXPR_LIST (VOIDmode,
26816 gen_rtx_REG (SImode,
26817 GP_ARG_RETURN + 1),
26821 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26822 /* _Decimal128 must use an even/odd register pair. */
26823 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26824 else if (SCALAR_FLOAT_MODE_P (mode)
26825 && TARGET_HARD_FLOAT && TARGET_FPRS
26826 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26827 regno = FP_ARG_RETURN;
26828 else if (ALTIVEC_VECTOR_MODE (mode)
26829 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26830 regno = ALTIVEC_ARG_RETURN;
26831 else if (VSX_VECTOR_MODE (mode)
26832 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26833 regno = ALTIVEC_ARG_RETURN;
26834 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26835 return rs6000_complex_function_value (mode);
26836 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26837 && (mode == DFmode || mode == DCmode
26838 || mode == TFmode || mode == TCmode))
26839 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26841 regno = GP_ARG_RETURN;
26843 return gen_rtx_REG (mode, regno);
26847 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26848 Frame pointer elimination is automatically handled.
26850 For the RS/6000, if frame pointer elimination is being done, we would like
26851 to convert ap into fp, not sp.
26853 We need r30 if -mminimal-toc was specified, and there are constant pool
26857 rs6000_can_eliminate (const int from, const int to)
26859 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26860 ? ! frame_pointer_needed
26861 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26862 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26866 /* Define the offset between two registers, FROM to be eliminated and its
26867 replacement TO, at the start of a routine. */
26869 rs6000_initial_elimination_offset (int from, int to)
26871 rs6000_stack_t *info = rs6000_stack_info ();
26872 HOST_WIDE_INT offset;
26874 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26875 offset = info->push_p ? 0 : -info->total_size;
26876 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26878 offset = info->push_p ? 0 : -info->total_size;
26879 if (FRAME_GROWS_DOWNWARD)
26880 offset += info->fixed_size + info->vars_size + info->parm_size;
26882 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26883 offset = FRAME_GROWS_DOWNWARD
26884 ? info->fixed_size + info->vars_size + info->parm_size
26886 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26887 offset = info->total_size;
26888 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26889 offset = info->push_p ? info->total_size : 0;
26890 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26893 gcc_unreachable ();
26899 rs6000_dwarf_register_span (rtx reg)
26903 unsigned regno = REGNO (reg);
26904 enum machine_mode mode = GET_MODE (reg);
26908 && (SPE_VECTOR_MODE (GET_MODE (reg))
26909 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26910 && mode != SFmode && mode != SDmode && mode != SCmode)))
26915 regno = REGNO (reg);
26917 /* The duality of the SPE register size wreaks all kinds of havoc.
26918 This is a way of distinguishing r0 in 32-bits from r0 in
26920 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26921 gcc_assert (words <= 4);
26922 for (i = 0; i < words; i++, regno++)
26924 if (BYTES_BIG_ENDIAN)
26926 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26927 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26931 parts[2 * i] = gen_rtx_REG (SImode, regno);
26932 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26936 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26939 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26942 rs6000_init_dwarf_reg_sizes_extra (tree address)
26947 enum machine_mode mode = TYPE_MODE (char_type_node);
26948 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26949 rtx mem = gen_rtx_MEM (BLKmode, addr);
26950 rtx value = gen_int_mode (4, mode);
26952 for (i = 1201; i < 1232; i++)
26954 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26955 HOST_WIDE_INT offset
26956 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26958 emit_move_insn (adjust_address (mem, mode, offset), value);
26963 /* Map internal gcc register numbers to DWARF2 register numbers. */
26966 rs6000_dbx_register_number (unsigned int regno)
26968 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26970 if (regno == MQ_REGNO)
26972 if (regno == LR_REGNO)
26974 if (regno == CTR_REGNO)
26976 if (CR_REGNO_P (regno))
26977 return regno - CR0_REGNO + 86;
26978 if (regno == CA_REGNO)
26979 return 101; /* XER */
26980 if (ALTIVEC_REGNO_P (regno))
26981 return regno - FIRST_ALTIVEC_REGNO + 1124;
26982 if (regno == VRSAVE_REGNO)
26984 if (regno == VSCR_REGNO)
26986 if (regno == SPE_ACC_REGNO)
26988 if (regno == SPEFSCR_REGNO)
26990 /* SPE high reg number. We get these values of regno from
26991 rs6000_dwarf_register_span. */
26992 gcc_assert (regno >= 1200 && regno < 1232);
26996 /* target hook eh_return_filter_mode */
26997 static enum machine_mode
26998 rs6000_eh_return_filter_mode (void)
27000 return TARGET_32BIT ? SImode : word_mode;
27003 /* Target hook for scalar_mode_supported_p. */
27005 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27007 if (DECIMAL_FLOAT_MODE_P (mode))
27008 return default_decimal_float_supported_p ();
27010 return default_scalar_mode_supported_p (mode);
27013 /* Target hook for vector_mode_supported_p. */
27015 rs6000_vector_mode_supported_p (enum machine_mode mode)
27018 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27021 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27024 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27031 /* Target hook for invalid_arg_for_unprototyped_fn. */
27032 static const char *
27033 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27035 return (!rs6000_darwin64_abi
27037 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27038 && (funcdecl == NULL_TREE
27039 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27040 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27041 ? N_("AltiVec argument passed to unprototyped function")
27045 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27046 setup by using __stack_chk_fail_local hidden function instead of
27047 calling __stack_chk_fail directly. Otherwise it is better to call
27048 __stack_chk_fail directly. */
27051 rs6000_stack_protect_fail (void)
27053 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27054 ? default_hidden_stack_protect_fail ()
27055 : default_external_stack_protect_fail ();
27059 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27060 int num_operands ATTRIBUTE_UNUSED)
27062 if (rs6000_warn_cell_microcode)
27065 int insn_code_number = recog_memoized (insn);
27066 location_t location = locator_location (INSN_LOCATOR (insn));
27068 /* Punt on insns we cannot recognize. */
27069 if (insn_code_number < 0)
27072 temp = get_insn_template (insn_code_number, insn);
27074 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27075 warning_at (location, OPT_mwarn_cell_microcode,
27076 "emitting microcode insn %s\t[%s] #%d",
27077 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27078 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27079 warning_at (location, OPT_mwarn_cell_microcode,
27080 "emitting conditional microcode insn %s\t[%s] #%d",
27081 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27086 /* Allocate a stack temp and fixup the address so it meets the particular
27087 memory requirements (either offetable or REG+REG addressing). */
27090 rs6000_allocate_stack_temp (enum machine_mode mode,
27091 bool offsettable_p,
27094 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27095 rtx addr = XEXP (stack, 0);
27096 int strict_p = (reload_in_progress || reload_completed);
27098 if (!legitimate_indirect_address_p (addr, strict_p))
27101 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27102 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27104 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27105 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27111 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27112 to such a form to deal with memory reference instructions like STFIWX that
27113 only take reg+reg addressing. */
27116 rs6000_address_for_fpconvert (rtx x)
27118 int strict_p = (reload_in_progress || reload_completed);
27121 gcc_assert (MEM_P (x));
27122 addr = XEXP (x, 0);
27123 if (! legitimate_indirect_address_p (addr, strict_p)
27124 && ! legitimate_indexed_address_p (addr, strict_p))
27125 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27130 /* Expand 32-bit int -> floating point conversions. Return true if
27134 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27136 enum machine_mode dmode = GET_MODE (dest);
27137 rtx (*func_si) (rtx, rtx, rtx, rtx);
27138 rtx (*func_si_mem) (rtx, rtx);
27139 rtx (*func_di) (rtx, rtx);
27142 gcc_assert (GET_MODE (src) == SImode);
27144 if (dmode == SFmode)
27148 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27149 func_si = gen_floatunssisf2_lfiwzx;
27150 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27151 func_di = gen_floatunsdisf2;
27155 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27156 func_si = gen_floatsisf2_lfiwax;
27157 func_si_mem = gen_floatsisf2_lfiwax_mem;
27158 func_di = gen_floatdisf2;
27162 else if (dmode == DFmode)
27166 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27167 func_si = gen_floatunssidf2_lfiwzx;
27168 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27169 func_di = gen_floatunsdidf2;
27173 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27174 func_si = gen_floatsidf2_lfiwax;
27175 func_si_mem = gen_floatsidf2_lfiwax_mem;
27176 func_di = gen_floatdidf2;
27181 gcc_unreachable ();
27185 src = rs6000_address_for_fpconvert (src);
27186 emit_insn (func_si_mem (dest, src));
27188 else if (!TARGET_MFPGPR)
27190 reg = gen_reg_rtx (DImode);
27191 stack = rs6000_allocate_stack_temp (SImode, false, true);
27192 emit_insn (func_si (dest, src, stack, reg));
27197 src = force_reg (SImode, src);
27198 reg = convert_to_mode (DImode, src, unsigned_p);
27199 emit_insn (func_di (dest, reg));
27203 #include "gt-rs6000.h"