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
953 static bool rs6000_function_ok_for_sibcall (tree, tree);
954 static const char *rs6000_invalid_within_doloop (const_rtx);
955 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
956 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
957 static rtx rs6000_generate_compare (rtx, enum machine_mode);
958 static void rs6000_emit_stack_tie (void);
959 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
960 static bool spe_func_has_64bit_regs_p (void);
961 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
963 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
964 static unsigned rs6000_hash_constant (rtx);
965 static unsigned toc_hash_function (const void *);
966 static int toc_hash_eq (const void *, const void *);
967 static bool reg_offset_addressing_ok_p (enum machine_mode);
968 static bool virtual_stack_registers_memory_p (rtx);
969 static bool constant_pool_expr_p (rtx);
970 static bool legitimate_small_data_p (enum machine_mode, rtx);
971 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
972 static struct machine_function * rs6000_init_machine_status (void);
973 static bool rs6000_assemble_integer (rtx, unsigned int, int);
974 static bool no_global_regs_above (int, bool);
975 #ifdef HAVE_GAS_HIDDEN
976 static void rs6000_assemble_visibility (tree, int);
978 static int rs6000_ra_ever_killed (void);
979 static bool rs6000_attribute_takes_identifier_p (const_tree);
980 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
981 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
982 static bool rs6000_ms_bitfield_layout_p (const_tree);
983 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
984 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
985 static const char *rs6000_mangle_type (const_tree);
986 static void rs6000_set_default_type_attributes (tree);
987 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
988 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
989 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
990 enum machine_mode, bool, bool, bool);
991 static bool rs6000_reg_live_or_pic_offset_p (int);
992 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
993 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
994 static void rs6000_restore_saved_cr (rtx, int);
995 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
996 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
997 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
999 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1000 static bool rs6000_return_in_memory (const_tree, const_tree);
1001 static rtx rs6000_function_value (const_tree, const_tree, bool);
1002 static void rs6000_file_start (void);
1004 static int rs6000_elf_reloc_rw_mask (void);
1005 static void rs6000_elf_asm_out_constructor (rtx, int);
1006 static void rs6000_elf_asm_out_destructor (rtx, int);
1007 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1008 static void rs6000_elf_asm_init_sections (void);
1009 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1010 unsigned HOST_WIDE_INT);
1011 static void rs6000_elf_encode_section_info (tree, rtx, int)
1014 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1015 static void rs6000_alloc_sdmode_stack_slot (void);
1016 static void rs6000_instantiate_decls (void);
1018 static void rs6000_xcoff_asm_output_anchor (rtx);
1019 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1020 static void rs6000_xcoff_asm_init_sections (void);
1021 static int rs6000_xcoff_reloc_rw_mask (void);
1022 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1023 static section *rs6000_xcoff_select_section (tree, int,
1024 unsigned HOST_WIDE_INT);
1025 static void rs6000_xcoff_unique_section (tree, int);
1026 static section *rs6000_xcoff_select_rtx_section
1027 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1028 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1029 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1030 static void rs6000_xcoff_file_start (void);
1031 static void rs6000_xcoff_file_end (void);
1033 static int rs6000_variable_issue (FILE *, int, rtx, int);
1034 static int rs6000_register_move_cost (enum machine_mode,
1035 reg_class_t, reg_class_t);
1036 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1037 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1038 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1039 static int rs6000_debug_address_cost (rtx, bool);
1040 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1041 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1042 static void rs6000_sched_init (FILE *, int, int);
1043 static bool is_microcoded_insn (rtx);
1044 static bool is_nonpipeline_insn (rtx);
1045 static bool is_cracked_insn (rtx);
1046 static bool is_branch_slot_insn (rtx);
1047 static bool is_load_insn (rtx);
1048 static rtx get_store_dest (rtx pat);
1049 static bool is_store_insn (rtx);
1050 static bool set_to_load_agen (rtx,rtx);
1051 static bool adjacent_mem_locations (rtx,rtx);
1052 static int rs6000_adjust_priority (rtx, int);
1053 static int rs6000_issue_rate (void);
1054 static bool rs6000_is_costly_dependence (dep_t, int, int);
1055 static rtx get_next_active_insn (rtx, rtx);
1056 static bool insn_terminates_group_p (rtx , enum group_termination);
1057 static bool insn_must_be_first_in_group (rtx);
1058 static bool insn_must_be_last_in_group (rtx);
1059 static bool is_costly_group (rtx *, rtx);
1060 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1061 static int redefine_groups (FILE *, int, rtx, rtx);
1062 static int pad_groups (FILE *, int, rtx, rtx);
1063 static void rs6000_sched_finish (FILE *, int);
1064 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1065 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1066 static int rs6000_use_sched_lookahead (void);
1067 static int rs6000_use_sched_lookahead_guard (rtx);
1068 static void * rs6000_alloc_sched_context (void);
1069 static void rs6000_init_sched_context (void *, bool);
1070 static void rs6000_set_sched_context (void *);
1071 static void rs6000_free_sched_context (void *);
1072 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1073 static tree rs6000_builtin_mask_for_load (void);
1074 static tree rs6000_builtin_mul_widen_even (tree);
1075 static tree rs6000_builtin_mul_widen_odd (tree);
1076 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1077 static tree rs6000_builtin_vec_perm (tree, tree *);
1078 static bool rs6000_builtin_support_vector_misalignment (enum
1082 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1085 static void def_builtin (int, const char *, tree, int);
1086 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1087 static void rs6000_init_builtins (void);
1088 static tree rs6000_builtin_decl (unsigned, bool);
1090 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1091 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1092 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1093 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1094 static void altivec_init_builtins (void);
1095 static unsigned builtin_hash_function (const void *);
1096 static int builtin_hash_eq (const void *, const void *);
1097 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1098 enum machine_mode, enum machine_mode,
1099 enum rs6000_builtins, const char *name);
1100 static void rs6000_common_init_builtins (void);
1101 static void rs6000_init_libfuncs (void);
1103 static void paired_init_builtins (void);
1104 static rtx paired_expand_builtin (tree, rtx, bool *);
1105 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1106 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1107 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1109 static void enable_mask_for_builtins (struct builtin_description *, int,
1110 enum rs6000_builtins,
1111 enum rs6000_builtins);
1112 static void spe_init_builtins (void);
1113 static rtx spe_expand_builtin (tree, rtx, bool *);
1114 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1115 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1116 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1117 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1118 static rs6000_stack_t *rs6000_stack_info (void);
1119 static void debug_stack_info (rs6000_stack_t *);
1121 static rtx altivec_expand_builtin (tree, rtx, bool *);
1122 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1123 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1124 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1125 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1126 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1127 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1128 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1129 static rtx altivec_expand_vec_set_builtin (tree);
1130 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1131 static int get_element_number (tree, tree);
1132 static bool rs6000_handle_option (size_t, const char *, int);
1133 static void rs6000_parse_tls_size_option (void);
1134 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1135 static int first_altivec_reg_to_save (void);
1136 static unsigned int compute_vrsave_mask (void);
1137 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1138 static void is_altivec_return_reg (rtx, void *);
1139 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1140 int easy_vector_constant (rtx, enum machine_mode);
1141 static rtx rs6000_dwarf_register_span (rtx);
1142 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1143 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1144 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1145 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1146 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1147 static rtx rs6000_delegitimize_address (rtx);
1148 static rtx rs6000_tls_get_addr (void);
1149 static rtx rs6000_got_sym (void);
1150 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1151 static const char *rs6000_get_some_local_dynamic_name (void);
1152 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1153 static rtx rs6000_complex_function_value (enum machine_mode);
1154 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1155 enum machine_mode, tree);
1156 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1157 HOST_WIDE_INT, int);
1158 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1159 tree, HOST_WIDE_INT);
1160 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1163 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1164 const_tree, HOST_WIDE_INT,
1166 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1167 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1168 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1169 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1170 enum machine_mode, tree,
1172 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1174 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1176 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1178 static void macho_branch_islands (void);
1179 static int no_previous_def (tree function_name);
1180 static tree get_prev_label (tree function_name);
1181 static void rs6000_darwin_file_start (void);
1184 static tree rs6000_build_builtin_va_list (void);
1185 static void rs6000_va_start (tree, rtx);
1186 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1187 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1188 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1189 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1190 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1191 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1193 static tree rs6000_stack_protect_fail (void);
1195 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1198 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1201 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1203 = rs6000_legitimize_reload_address;
1205 static bool rs6000_mode_dependent_address_p (const_rtx);
1206 static bool rs6000_mode_dependent_address (const_rtx);
1207 static bool rs6000_debug_mode_dependent_address (const_rtx);
1208 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1209 = rs6000_mode_dependent_address;
1211 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1212 enum machine_mode, rtx);
1213 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1216 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1217 enum machine_mode, rtx)
1218 = rs6000_secondary_reload_class;
1220 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1221 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1223 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1224 = rs6000_preferred_reload_class;
1226 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1229 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1233 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1235 = rs6000_secondary_memory_needed;
1237 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1240 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1244 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1247 = rs6000_cannot_change_mode_class;
1249 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1251 struct secondary_reload_info *);
1253 static const reg_class_t *rs6000_ira_cover_classes (void);
1255 const int INSN_NOT_AVAILABLE = -1;
1256 static enum machine_mode rs6000_eh_return_filter_mode (void);
1257 static bool rs6000_can_eliminate (const int, const int);
1258 static void rs6000_trampoline_init (rtx, tree, rtx);
1260 /* Hash table stuff for keeping track of TOC entries. */
1262 struct GTY(()) toc_hash_struct
1264 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1265 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1267 enum machine_mode key_mode;
1271 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1273 /* Hash table to keep track of the argument types for builtin functions. */
1275 struct GTY(()) builtin_hash_struct
1278 enum machine_mode mode[4]; /* return value + 3 arguments. */
1279 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1282 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1284 /* Default register names. */
1285 char rs6000_reg_names[][8] =
1287 "0", "1", "2", "3", "4", "5", "6", "7",
1288 "8", "9", "10", "11", "12", "13", "14", "15",
1289 "16", "17", "18", "19", "20", "21", "22", "23",
1290 "24", "25", "26", "27", "28", "29", "30", "31",
1291 "0", "1", "2", "3", "4", "5", "6", "7",
1292 "8", "9", "10", "11", "12", "13", "14", "15",
1293 "16", "17", "18", "19", "20", "21", "22", "23",
1294 "24", "25", "26", "27", "28", "29", "30", "31",
1295 "mq", "lr", "ctr","ap",
1296 "0", "1", "2", "3", "4", "5", "6", "7",
1298 /* AltiVec registers. */
1299 "0", "1", "2", "3", "4", "5", "6", "7",
1300 "8", "9", "10", "11", "12", "13", "14", "15",
1301 "16", "17", "18", "19", "20", "21", "22", "23",
1302 "24", "25", "26", "27", "28", "29", "30", "31",
1304 /* SPE registers. */
1305 "spe_acc", "spefscr",
1306 /* Soft frame pointer. */
1310 #ifdef TARGET_REGNAMES
1311 static const char alt_reg_names[][8] =
1313 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1314 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1315 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1316 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1317 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1318 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1319 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1320 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1321 "mq", "lr", "ctr", "ap",
1322 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1324 /* AltiVec registers. */
1325 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1326 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1327 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1328 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1330 /* SPE registers. */
1331 "spe_acc", "spefscr",
1332 /* Soft frame pointer. */
1337 /* Table of valid machine attributes. */
1339 static const struct attribute_spec rs6000_attribute_table[] =
1341 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1342 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1343 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1344 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1345 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1346 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1347 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1348 SUBTARGET_ATTRIBUTE_TABLE,
1350 { NULL, 0, 0, false, false, false, NULL }
1353 #ifndef MASK_STRICT_ALIGN
1354 #define MASK_STRICT_ALIGN 0
1356 #ifndef TARGET_PROFILE_KERNEL
1357 #define TARGET_PROFILE_KERNEL 0
1360 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1361 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1363 /* Initialize the GCC target structure. */
1364 #undef TARGET_ATTRIBUTE_TABLE
1365 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1366 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1367 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1368 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1369 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1371 #undef TARGET_ASM_ALIGNED_DI_OP
1372 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1374 /* Default unaligned ops are only provided for ELF. Find the ops needed
1375 for non-ELF systems. */
1376 #ifndef OBJECT_FORMAT_ELF
1378 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1380 #undef TARGET_ASM_UNALIGNED_HI_OP
1381 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1382 #undef TARGET_ASM_UNALIGNED_SI_OP
1383 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1384 #undef TARGET_ASM_UNALIGNED_DI_OP
1385 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1388 #undef TARGET_ASM_UNALIGNED_HI_OP
1389 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1390 #undef TARGET_ASM_UNALIGNED_SI_OP
1391 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1392 #undef TARGET_ASM_UNALIGNED_DI_OP
1393 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1394 #undef TARGET_ASM_ALIGNED_DI_OP
1395 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1399 /* This hook deals with fixups for relocatable code and DI-mode objects
1401 #undef TARGET_ASM_INTEGER
1402 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1404 #ifdef HAVE_GAS_HIDDEN
1405 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1406 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1409 #undef TARGET_HAVE_TLS
1410 #define TARGET_HAVE_TLS HAVE_AS_TLS
1412 #undef TARGET_CANNOT_FORCE_CONST_MEM
1413 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1415 #undef TARGET_DELEGITIMIZE_ADDRESS
1416 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1418 #undef TARGET_ASM_FUNCTION_PROLOGUE
1419 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1420 #undef TARGET_ASM_FUNCTION_EPILOGUE
1421 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1423 #undef TARGET_LEGITIMIZE_ADDRESS
1424 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1426 #undef TARGET_SCHED_VARIABLE_ISSUE
1427 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1429 #undef TARGET_SCHED_ISSUE_RATE
1430 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1431 #undef TARGET_SCHED_ADJUST_COST
1432 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1433 #undef TARGET_SCHED_ADJUST_PRIORITY
1434 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1435 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1436 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1437 #undef TARGET_SCHED_INIT
1438 #define TARGET_SCHED_INIT rs6000_sched_init
1439 #undef TARGET_SCHED_FINISH
1440 #define TARGET_SCHED_FINISH rs6000_sched_finish
1441 #undef TARGET_SCHED_REORDER
1442 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1443 #undef TARGET_SCHED_REORDER2
1444 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1446 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1447 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1449 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1450 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1452 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1453 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1454 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1455 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1456 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1457 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1458 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1459 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1461 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1462 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1463 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1464 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1465 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1466 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1467 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1468 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1469 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1470 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1471 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1472 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1473 rs6000_builtin_support_vector_misalignment
1474 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1475 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1476 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1477 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1478 rs6000_builtin_vectorization_cost
1480 #undef TARGET_INIT_BUILTINS
1481 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1482 #undef TARGET_BUILTIN_DECL
1483 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1485 #undef TARGET_EXPAND_BUILTIN
1486 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1488 #undef TARGET_MANGLE_TYPE
1489 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1491 #undef TARGET_INIT_LIBFUNCS
1492 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1495 #undef TARGET_BINDS_LOCAL_P
1496 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1499 #undef TARGET_MS_BITFIELD_LAYOUT_P
1500 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1502 #undef TARGET_ASM_OUTPUT_MI_THUNK
1503 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1505 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1506 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1508 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1509 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1511 #undef TARGET_INVALID_WITHIN_DOLOOP
1512 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1514 #undef TARGET_REGISTER_MOVE_COST
1515 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1516 #undef TARGET_MEMORY_MOVE_COST
1517 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1518 #undef TARGET_RTX_COSTS
1519 #define TARGET_RTX_COSTS rs6000_rtx_costs
1520 #undef TARGET_ADDRESS_COST
1521 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1523 #undef TARGET_DWARF_REGISTER_SPAN
1524 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1526 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1527 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1529 /* On rs6000, function arguments are promoted, as are function return
1531 #undef TARGET_PROMOTE_FUNCTION_MODE
1532 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1534 #undef TARGET_RETURN_IN_MEMORY
1535 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1537 #undef TARGET_SETUP_INCOMING_VARARGS
1538 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1540 /* Always strict argument naming on rs6000. */
1541 #undef TARGET_STRICT_ARGUMENT_NAMING
1542 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1543 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1544 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1545 #undef TARGET_SPLIT_COMPLEX_ARG
1546 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1547 #undef TARGET_MUST_PASS_IN_STACK
1548 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1549 #undef TARGET_PASS_BY_REFERENCE
1550 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1551 #undef TARGET_ARG_PARTIAL_BYTES
1552 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1554 #undef TARGET_BUILD_BUILTIN_VA_LIST
1555 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1557 #undef TARGET_EXPAND_BUILTIN_VA_START
1558 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1560 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1561 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1563 #undef TARGET_EH_RETURN_FILTER_MODE
1564 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1566 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1567 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1569 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1570 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1572 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1573 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1575 #undef TARGET_HANDLE_OPTION
1576 #define TARGET_HANDLE_OPTION rs6000_handle_option
1578 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1579 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1580 rs6000_builtin_vectorized_function
1582 #undef TARGET_DEFAULT_TARGET_FLAGS
1583 #define TARGET_DEFAULT_TARGET_FLAGS \
1586 #undef TARGET_STACK_PROTECT_FAIL
1587 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1589 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1590 The PowerPC architecture requires only weak consistency among
1591 processors--that is, memory accesses between processors need not be
1592 sequentially consistent and memory accesses among processors can occur
1593 in any order. The ability to order memory accesses weakly provides
1594 opportunities for more efficient use of the system bus. Unless a
1595 dependency exists, the 604e allows read operations to precede store
1597 #undef TARGET_RELAXED_ORDERING
1598 #define TARGET_RELAXED_ORDERING true
1601 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1602 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1605 /* Use a 32-bit anchor range. This leads to sequences like:
1607 addis tmp,anchor,high
1610 where tmp itself acts as an anchor, and can be shared between
1611 accesses to the same 64k page. */
1612 #undef TARGET_MIN_ANCHOR_OFFSET
1613 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1614 #undef TARGET_MAX_ANCHOR_OFFSET
1615 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1616 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1617 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1619 #undef TARGET_BUILTIN_RECIPROCAL
1620 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1622 #undef TARGET_EXPAND_TO_RTL_HOOK
1623 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1625 #undef TARGET_INSTANTIATE_DECLS
1626 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1628 #undef TARGET_SECONDARY_RELOAD
1629 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1631 #undef TARGET_IRA_COVER_CLASSES
1632 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1634 #undef TARGET_LEGITIMATE_ADDRESS_P
1635 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1637 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1638 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1640 #undef TARGET_CAN_ELIMINATE
1641 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1643 #undef TARGET_TRAMPOLINE_INIT
1644 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1646 #undef TARGET_FUNCTION_VALUE
1647 #define TARGET_FUNCTION_VALUE rs6000_function_value
1649 struct gcc_target targetm = TARGET_INITIALIZER;
1651 /* Return number of consecutive hard regs needed starting at reg REGNO
1652 to hold something of mode MODE.
1653 This is ordinarily the length in words of a value of mode MODE
1654 but can be less for certain modes in special long registers.
1656 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1657 scalar instructions. The upper 32 bits are only available to the
1660 POWER and PowerPC GPRs hold 32 bits worth;
1661 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1664 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1666 unsigned HOST_WIDE_INT reg_size;
1668 if (FP_REGNO_P (regno))
1669 reg_size = (VECTOR_MEM_VSX_P (mode)
1670 ? UNITS_PER_VSX_WORD
1671 : UNITS_PER_FP_WORD);
1673 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1674 reg_size = UNITS_PER_SPE_WORD;
1676 else if (ALTIVEC_REGNO_P (regno))
1677 reg_size = UNITS_PER_ALTIVEC_WORD;
1679 /* The value returned for SCmode in the E500 double case is 2 for
1680 ABI compatibility; storing an SCmode value in a single register
1681 would require function_arg and rs6000_spe_function_arg to handle
1682 SCmode so as to pass the value correctly in a pair of
1684 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1685 && !DECIMAL_FLOAT_MODE_P (mode))
1686 reg_size = UNITS_PER_FP_WORD;
1689 reg_size = UNITS_PER_WORD;
1691 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1694 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1697 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1699 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1701 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1702 implementations. Don't allow an item to be split between a FP register
1703 and an Altivec register. */
1704 if (VECTOR_MEM_VSX_P (mode))
1706 if (FP_REGNO_P (regno))
1707 return FP_REGNO_P (last_regno);
1709 if (ALTIVEC_REGNO_P (regno))
1710 return ALTIVEC_REGNO_P (last_regno);
1713 /* The GPRs can hold any mode, but values bigger than one register
1714 cannot go past R31. */
1715 if (INT_REGNO_P (regno))
1716 return INT_REGNO_P (last_regno);
1718 /* The float registers (except for VSX vector modes) can only hold floating
1719 modes and DImode. This excludes the 32-bit decimal float mode for
1721 if (FP_REGNO_P (regno))
1723 if (SCALAR_FLOAT_MODE_P (mode)
1724 && (mode != TDmode || (regno % 2) == 0)
1725 && FP_REGNO_P (last_regno))
1728 if (GET_MODE_CLASS (mode) == MODE_INT
1729 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1732 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1733 && PAIRED_VECTOR_MODE (mode))
1739 /* The CR register can only hold CC modes. */
1740 if (CR_REGNO_P (regno))
1741 return GET_MODE_CLASS (mode) == MODE_CC;
1743 if (CA_REGNO_P (regno))
1744 return mode == BImode;
1746 /* AltiVec only in AldyVec registers. */
1747 if (ALTIVEC_REGNO_P (regno))
1748 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1750 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1751 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1754 /* We cannot put TImode anywhere except general register and it must be able
1755 to fit within the register set. In the future, allow TImode in the
1756 Altivec or VSX registers. */
1758 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1761 /* Print interesting facts about registers. */
1763 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1767 for (r = first_regno; r <= last_regno; ++r)
1769 const char *comma = "";
1772 if (first_regno == last_regno)
1773 fprintf (stderr, "%s:\t", reg_name);
1775 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1778 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1779 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1783 fprintf (stderr, ",\n\t");
1788 if (rs6000_hard_regno_nregs[m][r] > 1)
1789 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1790 rs6000_hard_regno_nregs[m][r]);
1792 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1797 if (call_used_regs[r])
1801 fprintf (stderr, ",\n\t");
1806 len += fprintf (stderr, "%s%s", comma, "call-used");
1814 fprintf (stderr, ",\n\t");
1819 len += fprintf (stderr, "%s%s", comma, "fixed");
1825 fprintf (stderr, ",\n\t");
1829 fprintf (stderr, "%sregno = %d\n", comma, r);
1833 /* Print various interesting information with -mdebug=reg. */
1835 rs6000_debug_reg_global (void)
1837 const char *nl = (const char *)0;
1839 char costly_num[20];
1841 const char *costly_str;
1842 const char *nop_str;
1844 /* Map enum rs6000_vector to string. */
1845 static const char *rs6000_debug_vector_unit[] = {
1854 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1855 LAST_VIRTUAL_REGISTER);
1856 rs6000_debug_reg_print (0, 31, "gr");
1857 rs6000_debug_reg_print (32, 63, "fp");
1858 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1861 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1862 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1863 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1864 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1865 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1866 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1867 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1868 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1869 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1873 "d reg_class = %s\n"
1874 "f reg_class = %s\n"
1875 "v reg_class = %s\n"
1876 "wa reg_class = %s\n"
1877 "wd reg_class = %s\n"
1878 "wf reg_class = %s\n"
1879 "ws reg_class = %s\n\n",
1880 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1881 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1882 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1883 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1884 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1885 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1886 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1888 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1889 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1892 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1894 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1895 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1901 if (rs6000_recip_control)
1903 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1905 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1906 if (rs6000_recip_bits[m])
1909 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1911 (RS6000_RECIP_AUTO_RE_P (m)
1913 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1914 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1916 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1919 fputs ("\n", stderr);
1922 switch (rs6000_sched_costly_dep)
1924 case max_dep_latency:
1925 costly_str = "max_dep_latency";
1929 costly_str = "no_dep_costly";
1932 case all_deps_costly:
1933 costly_str = "all_deps_costly";
1936 case true_store_to_load_dep_costly:
1937 costly_str = "true_store_to_load_dep_costly";
1940 case store_to_load_dep_costly:
1941 costly_str = "store_to_load_dep_costly";
1945 costly_str = costly_num;
1946 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1950 switch (rs6000_sched_insert_nops)
1952 case sched_finish_regroup_exact:
1953 nop_str = "sched_finish_regroup_exact";
1956 case sched_finish_pad_groups:
1957 nop_str = "sched_finish_pad_groups";
1960 case sched_finish_none:
1961 nop_str = "sched_finish_none";
1966 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1971 "always_hint = %s\n"
1972 "align_branch_targets = %s\n"
1973 "sched_restricted_insns_priority = %d\n"
1974 "sched_costly_dep = %s\n"
1975 "sched_insert_nops = %s\n\n",
1976 rs6000_always_hint ? "true" : "false",
1977 rs6000_align_branch_targets ? "true" : "false",
1978 (int)rs6000_sched_restricted_insns_priority,
1979 costly_str, nop_str);
1982 /* Initialize the various global tables that are based on register size. */
1984 rs6000_init_hard_regno_mode_ok (void)
1990 /* Precalculate REGNO_REG_CLASS. */
1991 rs6000_regno_regclass[0] = GENERAL_REGS;
1992 for (r = 1; r < 32; ++r)
1993 rs6000_regno_regclass[r] = BASE_REGS;
1995 for (r = 32; r < 64; ++r)
1996 rs6000_regno_regclass[r] = FLOAT_REGS;
1998 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1999 rs6000_regno_regclass[r] = NO_REGS;
2001 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2002 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2004 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2005 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2006 rs6000_regno_regclass[r] = CR_REGS;
2008 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2009 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2010 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2011 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2012 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2013 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2014 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2015 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2016 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2017 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2019 /* Precalculate vector information, this must be set up before the
2020 rs6000_hard_regno_nregs_internal below. */
2021 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2023 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2024 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2025 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2028 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2029 rs6000_constraints[c] = NO_REGS;
2031 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2032 believes it can use native alignment or still uses 128-bit alignment. */
2033 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2044 /* V2DF mode, VSX only. */
2047 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2048 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2049 rs6000_vector_align[V2DFmode] = align64;
2052 /* V4SF mode, either VSX or Altivec. */
2055 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2056 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2057 rs6000_vector_align[V4SFmode] = align32;
2059 else if (TARGET_ALTIVEC)
2061 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2062 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2063 rs6000_vector_align[V4SFmode] = align32;
2066 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2070 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2071 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2072 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2073 rs6000_vector_align[V4SImode] = align32;
2074 rs6000_vector_align[V8HImode] = align32;
2075 rs6000_vector_align[V16QImode] = align32;
2079 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2080 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2081 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2085 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2086 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2087 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2091 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2092 Altivec doesn't have 64-bit support. */
2095 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2096 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2097 rs6000_vector_align[V2DImode] = align64;
2100 /* DFmode, see if we want to use the VSX unit. */
2101 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2103 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2104 rs6000_vector_mem[DFmode]
2105 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2106 rs6000_vector_align[DFmode] = align64;
2109 /* TODO add SPE and paired floating point vector support. */
2111 /* Register class constaints for the constraints that depend on compile
2113 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2114 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2116 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2117 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2121 /* At present, we just use VSX_REGS, but we have different constraints
2122 based on the use, in case we want to fine tune the default register
2123 class used. wa = any VSX register, wf = register class to use for
2124 V4SF, wd = register class to use for V2DF, and ws = register classs to
2125 use for DF scalars. */
2126 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2127 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2128 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2129 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2135 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2137 /* Set up the reload helper functions. */
2138 if (TARGET_VSX || TARGET_ALTIVEC)
2142 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2143 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2144 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2145 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2146 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2147 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2148 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2149 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2150 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2151 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2152 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2153 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2157 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2158 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2159 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2160 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2161 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2162 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2163 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2164 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2165 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2166 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2167 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2168 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2172 /* Precalculate HARD_REGNO_NREGS. */
2173 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2174 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2175 rs6000_hard_regno_nregs[m][r]
2176 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2178 /* Precalculate HARD_REGNO_MODE_OK. */
2179 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2180 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2181 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2182 rs6000_hard_regno_mode_ok_p[m][r] = true;
2184 /* Precalculate CLASS_MAX_NREGS sizes. */
2185 for (c = 0; c < LIM_REG_CLASSES; ++c)
2189 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2190 reg_size = UNITS_PER_VSX_WORD;
2192 else if (c == ALTIVEC_REGS)
2193 reg_size = UNITS_PER_ALTIVEC_WORD;
2195 else if (c == FLOAT_REGS)
2196 reg_size = UNITS_PER_FP_WORD;
2199 reg_size = UNITS_PER_WORD;
2201 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2202 rs6000_class_max_nregs[m][c]
2203 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2206 if (TARGET_E500_DOUBLE)
2207 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2209 /* Calculate which modes to automatically generate code to use a the
2210 reciprocal divide and square root instructions. In the future, possibly
2211 automatically generate the instructions even if the user did not specify
2212 -mrecip. The older machines double precision reciprocal sqrt estimate is
2213 not accurate enough. */
2214 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2216 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2218 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2219 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2220 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2221 if (VECTOR_UNIT_VSX_P (V2DFmode))
2222 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2224 if (TARGET_FRSQRTES)
2225 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2227 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2228 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2229 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2230 if (VECTOR_UNIT_VSX_P (V2DFmode))
2231 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2233 if (rs6000_recip_control)
2235 if (!TARGET_FUSED_MADD)
2236 warning (0, "-mrecip requires -mfused-madd");
2237 if (!flag_finite_math_only)
2238 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2239 if (flag_trapping_math)
2240 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2241 if (!flag_reciprocal_math)
2242 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2243 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2244 && flag_reciprocal_math)
2246 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2247 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2248 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2250 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2251 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2252 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2254 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2255 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2256 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2258 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2259 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2260 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2262 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2263 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2264 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2266 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2267 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2268 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2270 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2271 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2272 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2274 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2275 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2276 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2280 if (TARGET_DEBUG_REG)
2281 rs6000_debug_reg_global ();
2283 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2285 "SImode variable mult cost = %d\n"
2286 "SImode constant mult cost = %d\n"
2287 "SImode short constant mult cost = %d\n"
2288 "DImode multipliciation cost = %d\n"
2289 "SImode division cost = %d\n"
2290 "DImode division cost = %d\n"
2291 "Simple fp operation cost = %d\n"
2292 "DFmode multiplication cost = %d\n"
2293 "SFmode division cost = %d\n"
2294 "DFmode division cost = %d\n"
2295 "cache line size = %d\n"
2296 "l1 cache size = %d\n"
2297 "l2 cache size = %d\n"
2298 "simultaneous prefetches = %d\n"
2301 rs6000_cost->mulsi_const,
2302 rs6000_cost->mulsi_const9,
2310 rs6000_cost->cache_line_size,
2311 rs6000_cost->l1_cache_size,
2312 rs6000_cost->l2_cache_size,
2313 rs6000_cost->simultaneous_prefetches);
2317 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2320 darwin_rs6000_override_options (void)
2322 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2324 rs6000_altivec_abi = 1;
2325 TARGET_ALTIVEC_VRSAVE = 1;
2326 if (DEFAULT_ABI == ABI_DARWIN)
2328 if (MACHO_DYNAMIC_NO_PIC_P)
2331 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2334 else if (flag_pic == 1)
2339 darwin_one_byte_bool = 1;
2341 if (TARGET_64BIT && ! TARGET_POWERPC64)
2343 target_flags |= MASK_POWERPC64;
2344 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2348 rs6000_default_long_calls = 1;
2349 target_flags |= MASK_SOFT_FLOAT;
2352 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2354 if (!flag_mkernel && !flag_apple_kext
2356 && ! (target_flags_explicit & MASK_ALTIVEC))
2357 target_flags |= MASK_ALTIVEC;
2359 /* Unless the user (not the configurer) has explicitly overridden
2360 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2361 G4 unless targetting the kernel. */
2364 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2365 && ! (target_flags_explicit & MASK_ALTIVEC)
2366 && ! rs6000_select[1].string)
2368 target_flags |= MASK_ALTIVEC;
2373 /* If not otherwise specified by a target, make 'long double' equivalent to
2376 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2377 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2380 /* Override command line options. Mostly we process the processor
2381 type and sometimes adjust other TARGET_ options. */
2384 rs6000_override_options (const char *default_cpu)
2387 struct rs6000_cpu_select *ptr;
2390 /* Simplifications for entries below. */
2393 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2394 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2397 /* This table occasionally claims that a processor does not support
2398 a particular feature even though it does, but the feature is slower
2399 than the alternative. Thus, it shouldn't be relied on as a
2400 complete description of the processor's support.
2402 Please keep this list in order, and don't forget to update the
2403 documentation in invoke.texi when adding a new processor or
2407 const char *const name; /* Canonical processor name. */
2408 const enum processor_type processor; /* Processor type enum value. */
2409 const int target_enable; /* Target flags to enable. */
2410 } const processor_target_table[]
2411 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2412 {"403", PROCESSOR_PPC403,
2413 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2414 {"405", PROCESSOR_PPC405,
2415 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2416 {"405fp", PROCESSOR_PPC405,
2417 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2418 {"440", PROCESSOR_PPC440,
2419 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2420 {"440fp", PROCESSOR_PPC440,
2421 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2422 {"464", PROCESSOR_PPC440,
2423 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2424 {"464fp", PROCESSOR_PPC440,
2425 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2426 {"476", PROCESSOR_PPC476,
2427 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2428 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2429 {"476fp", PROCESSOR_PPC476,
2430 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2431 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2432 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2433 {"601", PROCESSOR_PPC601,
2434 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2435 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2436 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2437 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2438 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2439 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2440 {"620", PROCESSOR_PPC620,
2441 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2442 {"630", PROCESSOR_PPC630,
2443 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2444 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2445 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2446 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2447 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2448 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2449 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2450 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2451 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2453 /* 8548 has a dummy entry for now. */
2454 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2456 {"a2", PROCESSOR_PPCA2,
2457 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2458 | MASK_CMPB | MASK_NO_UPDATE },
2459 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2460 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2461 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2463 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2464 | MASK_PPC_GFXOPT | MASK_ISEL},
2465 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2466 {"970", PROCESSOR_POWER4,
2467 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2468 {"cell", PROCESSOR_CELL,
2469 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2470 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2471 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2472 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2473 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2474 {"G5", PROCESSOR_POWER4,
2475 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2476 {"titan", PROCESSOR_TITAN,
2477 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2478 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2479 {"power2", PROCESSOR_POWER,
2480 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2481 {"power3", PROCESSOR_PPC630,
2482 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2483 {"power4", PROCESSOR_POWER4,
2484 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2486 {"power5", PROCESSOR_POWER5,
2487 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2488 | MASK_MFCRF | MASK_POPCNTB},
2489 {"power5+", PROCESSOR_POWER5,
2490 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2491 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2492 {"power6", PROCESSOR_POWER6,
2493 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2494 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2495 | MASK_RECIP_PRECISION},
2496 {"power6x", PROCESSOR_POWER6,
2497 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2498 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2499 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2500 {"power7", PROCESSOR_POWER7,
2501 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2502 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2503 | MASK_VSX| MASK_RECIP_PRECISION}, /* Don't add MASK_ISEL by default */
2504 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2505 {"powerpc64", PROCESSOR_POWERPC64,
2506 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2507 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2508 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2509 {"rios2", PROCESSOR_RIOS2,
2510 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2511 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2512 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2513 {"rs64", PROCESSOR_RS64A,
2514 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2517 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2519 /* Some OSs don't support saving the high part of 64-bit registers on
2520 context switch. Other OSs don't support saving Altivec registers.
2521 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2522 settings; if the user wants either, the user must explicitly specify
2523 them and we won't interfere with the user's specification. */
2526 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2527 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2528 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2529 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2530 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2531 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2532 | MASK_RECIP_PRECISION)
2535 /* Masks for instructions set at various powerpc ISAs. */
2537 ISA_2_1_MASKS = MASK_MFCRF,
2538 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2540 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and
2541 don't add ALTIVEC, since in general it isn't a win on power6. */
2542 ISA_2_5_MASKS = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2545 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2546 altivec is a win so enable it. */
2547 ISA_2_6_MASKS = (ISA_2_5_MASKS | MASK_ALTIVEC | MASK_POPCNTD
2548 | MASK_VSX | MASK_RECIP_PRECISION)
2551 /* Numerous experiment shows that IRA based loop pressure
2552 calculation works better for RTL loop invariant motion on targets
2553 with enough (>= 32) registers. It is an expensive optimization.
2554 So it is on only for peak performance. */
2556 flag_ira_loop_pressure = 1;
2558 /* Set the pointer size. */
2561 rs6000_pmode = (int)DImode;
2562 rs6000_pointer_size = 64;
2566 rs6000_pmode = (int)SImode;
2567 rs6000_pointer_size = 32;
2570 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2571 #ifdef OS_MISSING_POWERPC64
2572 if (OS_MISSING_POWERPC64)
2573 set_masks &= ~MASK_POWERPC64;
2575 #ifdef OS_MISSING_ALTIVEC
2576 if (OS_MISSING_ALTIVEC)
2577 set_masks &= ~MASK_ALTIVEC;
2580 /* Don't override by the processor default if given explicitly. */
2581 set_masks &= ~target_flags_explicit;
2583 /* Identify the processor type. */
2584 rs6000_select[0].string = default_cpu;
2585 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2587 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2589 ptr = &rs6000_select[i];
2590 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2592 for (j = 0; j < ptt_size; j++)
2593 if (! strcmp (ptr->string, processor_target_table[j].name))
2595 if (ptr->set_tune_p)
2596 rs6000_cpu = processor_target_table[j].processor;
2598 if (ptr->set_arch_p)
2600 target_flags &= ~set_masks;
2601 target_flags |= (processor_target_table[j].target_enable
2608 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2612 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2613 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2616 error ("AltiVec not supported in this target");
2618 error ("Spe not supported in this target");
2621 /* Disable Cell microcode if we are optimizing for the Cell
2622 and not optimizing for size. */
2623 if (rs6000_gen_cell_microcode == -1)
2624 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2627 /* If we are optimizing big endian systems for space and it's OK to
2628 use instructions that would be microcoded on the Cell, use the
2629 load/store multiple and string instructions. */
2630 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2631 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2633 /* Don't allow -mmultiple or -mstring on little endian systems
2634 unless the cpu is a 750, because the hardware doesn't support the
2635 instructions used in little endian mode, and causes an alignment
2636 trap. The 750 does not cause an alignment trap (except when the
2637 target is unaligned). */
2639 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2641 if (TARGET_MULTIPLE)
2643 target_flags &= ~MASK_MULTIPLE;
2644 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2645 warning (0, "-mmultiple is not supported on little endian systems");
2650 target_flags &= ~MASK_STRING;
2651 if ((target_flags_explicit & MASK_STRING) != 0)
2652 warning (0, "-mstring is not supported on little endian systems");
2656 /* Add some warnings for VSX. */
2659 const char *msg = NULL;
2660 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2661 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2663 if (target_flags_explicit & MASK_VSX)
2664 msg = N_("-mvsx requires hardware floating point");
2666 target_flags &= ~ MASK_VSX;
2668 else if (TARGET_PAIRED_FLOAT)
2669 msg = N_("-mvsx and -mpaired are incompatible");
2670 /* The hardware will allow VSX and little endian, but until we make sure
2671 things like vector select, etc. work don't allow VSX on little endian
2672 systems at this point. */
2673 else if (!BYTES_BIG_ENDIAN)
2674 msg = N_("-mvsx used with little endian code");
2675 else if (TARGET_AVOID_XFORM > 0)
2676 msg = N_("-mvsx needs indexed addressing");
2677 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2679 if (target_flags_explicit & MASK_VSX)
2680 msg = N_("-mvsx and -mno-altivec are incompatible");
2682 msg = N_("-mno-altivec disables vsx");
2688 target_flags &= ~ MASK_VSX;
2692 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2693 unless the user explicitly used the -mno-<option> to disable the code. */
2695 target_flags |= (ISA_2_6_MASKS & ~target_flags_explicit);
2696 else if (TARGET_DFP)
2697 target_flags |= (ISA_2_5_MASKS & ~target_flags_explicit);
2698 else if (TARGET_ALTIVEC)
2699 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2701 /* E500mc does "better" if we inline more aggressively. Respect the
2702 user's opinion, though. */
2703 if (rs6000_block_move_inline_limit == 0
2704 && (rs6000_cpu == PROCESSOR_PPCE500MC
2705 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2706 rs6000_block_move_inline_limit = 128;
2708 /* store_one_arg depends on expand_block_move to handle at least the
2709 size of reg_parm_stack_space. */
2710 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2711 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2713 /* Set debug flags */
2714 if (rs6000_debug_name)
2716 if (! strcmp (rs6000_debug_name, "all"))
2717 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2718 = rs6000_debug_addr = rs6000_debug_cost = 1;
2719 else if (! strcmp (rs6000_debug_name, "stack"))
2720 rs6000_debug_stack = 1;
2721 else if (! strcmp (rs6000_debug_name, "arg"))
2722 rs6000_debug_arg = 1;
2723 else if (! strcmp (rs6000_debug_name, "reg"))
2724 rs6000_debug_reg = 1;
2725 else if (! strcmp (rs6000_debug_name, "addr"))
2726 rs6000_debug_addr = 1;
2727 else if (! strcmp (rs6000_debug_name, "cost"))
2728 rs6000_debug_cost = 1;
2730 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2732 /* If the appropriate debug option is enabled, replace the target hooks
2733 with debug versions that call the real version and then prints
2734 debugging information. */
2735 if (TARGET_DEBUG_COST)
2737 targetm.rtx_costs = rs6000_debug_rtx_costs;
2738 targetm.address_cost = rs6000_debug_address_cost;
2739 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2742 if (TARGET_DEBUG_ADDR)
2744 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2745 targetm.legitimize_address = rs6000_debug_legitimize_address;
2746 rs6000_secondary_reload_class_ptr
2747 = rs6000_debug_secondary_reload_class;
2748 rs6000_secondary_memory_needed_ptr
2749 = rs6000_debug_secondary_memory_needed;
2750 rs6000_cannot_change_mode_class_ptr
2751 = rs6000_debug_cannot_change_mode_class;
2752 rs6000_preferred_reload_class_ptr
2753 = rs6000_debug_preferred_reload_class;
2754 rs6000_legitimize_reload_address_ptr
2755 = rs6000_debug_legitimize_reload_address;
2756 rs6000_mode_dependent_address_ptr
2757 = rs6000_debug_mode_dependent_address;
2761 if (rs6000_traceback_name)
2763 if (! strncmp (rs6000_traceback_name, "full", 4))
2764 rs6000_traceback = traceback_full;
2765 else if (! strncmp (rs6000_traceback_name, "part", 4))
2766 rs6000_traceback = traceback_part;
2767 else if (! strncmp (rs6000_traceback_name, "no", 2))
2768 rs6000_traceback = traceback_none;
2770 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2771 rs6000_traceback_name);
2774 if (!rs6000_explicit_options.long_double)
2775 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2777 #ifndef POWERPC_LINUX
2778 if (!rs6000_explicit_options.ieee)
2779 rs6000_ieeequad = 1;
2782 /* Enable Altivec ABI for AIX -maltivec. */
2783 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2784 rs6000_altivec_abi = 1;
2786 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2787 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2788 be explicitly overridden in either case. */
2791 if (!rs6000_explicit_options.altivec_abi
2792 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2793 rs6000_altivec_abi = 1;
2795 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2796 if (!rs6000_explicit_options.vrsave)
2797 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2800 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2801 So far, the only darwin64 targets are also MACH-O. */
2803 && DEFAULT_ABI == ABI_DARWIN
2806 rs6000_darwin64_abi = 1;
2807 /* Default to natural alignment, for better performance. */
2808 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2811 /* Place FP constants in the constant pool instead of TOC
2812 if section anchors enabled. */
2813 if (flag_section_anchors)
2814 TARGET_NO_FP_IN_TOC = 1;
2816 /* Handle -mtls-size option. */
2817 rs6000_parse_tls_size_option ();
2819 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2820 SUBTARGET_OVERRIDE_OPTIONS;
2822 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2823 SUBSUBTARGET_OVERRIDE_OPTIONS;
2825 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2826 SUB3TARGET_OVERRIDE_OPTIONS;
2829 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2830 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2832 /* The e500 and e500mc do not have string instructions, and we set
2833 MASK_STRING above when optimizing for size. */
2834 if ((target_flags & MASK_STRING) != 0)
2835 target_flags = target_flags & ~MASK_STRING;
2837 else if (rs6000_select[1].string != NULL)
2839 /* For the powerpc-eabispe configuration, we set all these by
2840 default, so let's unset them if we manually set another
2841 CPU that is not the E500. */
2842 if (!rs6000_explicit_options.spe_abi)
2844 if (!rs6000_explicit_options.spe)
2846 if (!rs6000_explicit_options.float_gprs)
2847 rs6000_float_gprs = 0;
2848 if (!(target_flags_explicit & MASK_ISEL))
2849 target_flags &= ~MASK_ISEL;
2852 /* Detect invalid option combinations with E500. */
2855 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2856 && rs6000_cpu != PROCESSOR_POWER5
2857 && rs6000_cpu != PROCESSOR_POWER6
2858 && rs6000_cpu != PROCESSOR_POWER7
2859 && rs6000_cpu != PROCESSOR_PPCA2
2860 && rs6000_cpu != PROCESSOR_CELL);
2861 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2862 || rs6000_cpu == PROCESSOR_POWER5
2863 || rs6000_cpu == PROCESSOR_POWER7);
2864 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2865 || rs6000_cpu == PROCESSOR_POWER5
2866 || rs6000_cpu == PROCESSOR_POWER6
2867 || rs6000_cpu == PROCESSOR_POWER7
2868 || rs6000_cpu == PROCESSOR_PPCE500MC
2869 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2871 /* Allow debug switches to override the above settings. */
2872 if (TARGET_ALWAYS_HINT > 0)
2873 rs6000_always_hint = TARGET_ALWAYS_HINT;
2875 if (TARGET_SCHED_GROUPS > 0)
2876 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2878 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2879 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2881 rs6000_sched_restricted_insns_priority
2882 = (rs6000_sched_groups ? 1 : 0);
2884 /* Handle -msched-costly-dep option. */
2885 rs6000_sched_costly_dep
2886 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2888 if (rs6000_sched_costly_dep_str)
2890 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2891 rs6000_sched_costly_dep = no_dep_costly;
2892 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2893 rs6000_sched_costly_dep = all_deps_costly;
2894 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2895 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2896 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2897 rs6000_sched_costly_dep = store_to_load_dep_costly;
2899 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2900 atoi (rs6000_sched_costly_dep_str));
2903 /* Handle -minsert-sched-nops option. */
2904 rs6000_sched_insert_nops
2905 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2907 if (rs6000_sched_insert_nops_str)
2909 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2910 rs6000_sched_insert_nops = sched_finish_none;
2911 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2912 rs6000_sched_insert_nops = sched_finish_pad_groups;
2913 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2914 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2916 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2917 atoi (rs6000_sched_insert_nops_str));
2920 #ifdef TARGET_REGNAMES
2921 /* If the user desires alternate register names, copy in the
2922 alternate names now. */
2923 if (TARGET_REGNAMES)
2924 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2927 /* Set aix_struct_return last, after the ABI is determined.
2928 If -maix-struct-return or -msvr4-struct-return was explicitly
2929 used, don't override with the ABI default. */
2930 if (!rs6000_explicit_options.aix_struct_ret)
2931 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2934 /* IBM XL compiler defaults to unsigned bitfields. */
2935 if (TARGET_XL_COMPAT)
2936 flag_signed_bitfields = 0;
2939 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2940 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2943 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2945 /* We can only guarantee the availability of DI pseudo-ops when
2946 assembling for 64-bit targets. */
2949 targetm.asm_out.aligned_op.di = NULL;
2950 targetm.asm_out.unaligned_op.di = NULL;
2953 /* Set branch target alignment, if not optimizing for size. */
2956 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
2957 aligned 8byte to avoid misprediction by the branch predictor. */
2958 if (rs6000_cpu == PROCESSOR_TITAN
2959 || rs6000_cpu == PROCESSOR_CELL)
2961 if (align_functions <= 0)
2962 align_functions = 8;
2963 if (align_jumps <= 0)
2965 if (align_loops <= 0)
2968 if (rs6000_align_branch_targets)
2970 if (align_functions <= 0)
2971 align_functions = 16;
2972 if (align_jumps <= 0)
2974 if (align_loops <= 0)
2977 if (align_jumps_max_skip <= 0)
2978 align_jumps_max_skip = 15;
2979 if (align_loops_max_skip <= 0)
2980 align_loops_max_skip = 15;
2983 /* Arrange to save and restore machine status around nested functions. */
2984 init_machine_status = rs6000_init_machine_status;
2986 /* We should always be splitting complex arguments, but we can't break
2987 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2988 if (DEFAULT_ABI != ABI_AIX)
2989 targetm.calls.split_complex_arg = NULL;
2991 /* Initialize rs6000_cost with the appropriate target costs. */
2993 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2997 case PROCESSOR_RIOS1:
2998 rs6000_cost = &rios1_cost;
3001 case PROCESSOR_RIOS2:
3002 rs6000_cost = &rios2_cost;
3005 case PROCESSOR_RS64A:
3006 rs6000_cost = &rs64a_cost;
3009 case PROCESSOR_MPCCORE:
3010 rs6000_cost = &mpccore_cost;
3013 case PROCESSOR_PPC403:
3014 rs6000_cost = &ppc403_cost;
3017 case PROCESSOR_PPC405:
3018 rs6000_cost = &ppc405_cost;
3021 case PROCESSOR_PPC440:
3022 rs6000_cost = &ppc440_cost;
3025 case PROCESSOR_PPC476:
3026 rs6000_cost = &ppc476_cost;
3029 case PROCESSOR_PPC601:
3030 rs6000_cost = &ppc601_cost;
3033 case PROCESSOR_PPC603:
3034 rs6000_cost = &ppc603_cost;
3037 case PROCESSOR_PPC604:
3038 rs6000_cost = &ppc604_cost;
3041 case PROCESSOR_PPC604e:
3042 rs6000_cost = &ppc604e_cost;
3045 case PROCESSOR_PPC620:
3046 rs6000_cost = &ppc620_cost;
3049 case PROCESSOR_PPC630:
3050 rs6000_cost = &ppc630_cost;
3053 case PROCESSOR_CELL:
3054 rs6000_cost = &ppccell_cost;
3057 case PROCESSOR_PPC750:
3058 case PROCESSOR_PPC7400:
3059 rs6000_cost = &ppc750_cost;
3062 case PROCESSOR_PPC7450:
3063 rs6000_cost = &ppc7450_cost;
3066 case PROCESSOR_PPC8540:
3067 rs6000_cost = &ppc8540_cost;
3070 case PROCESSOR_PPCE300C2:
3071 case PROCESSOR_PPCE300C3:
3072 rs6000_cost = &ppce300c2c3_cost;
3075 case PROCESSOR_PPCE500MC:
3076 rs6000_cost = &ppce500mc_cost;
3079 case PROCESSOR_PPCE500MC64:
3080 rs6000_cost = &ppce500mc64_cost;
3083 case PROCESSOR_TITAN:
3084 rs6000_cost = &titan_cost;
3087 case PROCESSOR_POWER4:
3088 case PROCESSOR_POWER5:
3089 rs6000_cost = &power4_cost;
3092 case PROCESSOR_POWER6:
3093 rs6000_cost = &power6_cost;
3096 case PROCESSOR_POWER7:
3097 rs6000_cost = &power7_cost;
3100 case PROCESSOR_PPCA2:
3101 rs6000_cost = &ppca2_cost;
3108 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3109 set_param_value ("simultaneous-prefetches",
3110 rs6000_cost->simultaneous_prefetches);
3111 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3112 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3113 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3114 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3115 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3116 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3118 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3119 can be optimized to ap = __builtin_next_arg (0). */
3120 if (DEFAULT_ABI != ABI_V4)
3121 targetm.expand_builtin_va_start = NULL;
3123 /* Set up single/double float flags.
3124 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3125 then set both flags. */
3126 if (TARGET_HARD_FLOAT && TARGET_FPRS
3127 && rs6000_single_float == 0 && rs6000_double_float == 0)
3128 rs6000_single_float = rs6000_double_float = 1;
3130 /* Reset single and double FP flags if target is E500. */
3133 rs6000_single_float = rs6000_double_float = 0;
3134 if (TARGET_E500_SINGLE)
3135 rs6000_single_float = 1;
3136 if (TARGET_E500_DOUBLE)
3137 rs6000_single_float = rs6000_double_float = 1;
3140 /* If not explicitly specified via option, decide whether to generate indexed
3141 load/store instructions. */
3142 if (TARGET_AVOID_XFORM == -1)
3143 /* Avoid indexed addressing when targeting Power6 in order to avoid
3144 the DERAT mispredict penalty. */
3145 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3147 /* Set the -mrecip options. */
3148 if (rs6000_recip_name)
3150 char *p = ASTRDUP (rs6000_recip_name);
3152 unsigned int mask, i;
3155 while ((q = strtok (p, ",")) != NULL)
3166 if (!strcmp (q, "default"))
3167 mask = ((TARGET_RECIP_PRECISION)
3168 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3171 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3172 if (!strcmp (q, recip_options[i].string))
3174 mask = recip_options[i].mask;
3178 if (i == ARRAY_SIZE (recip_options))
3180 error ("Unknown option for -mrecip=%s", q);
3187 rs6000_recip_control &= ~mask;
3189 rs6000_recip_control |= mask;
3193 rs6000_init_hard_regno_mode_ok ();
3196 /* Implement targetm.vectorize.builtin_mask_for_load. */
3198 rs6000_builtin_mask_for_load (void)
3200 if (TARGET_ALTIVEC || TARGET_VSX)
3201 return altivec_builtin_mask_for_load;
3206 /* Implement targetm.vectorize.builtin_conversion.
3207 Returns a decl of a function that implements conversion of an integer vector
3208 into a floating-point vector, or vice-versa. DEST_TYPE is the
3209 destination type and SRC_TYPE the source type of the conversion.
3210 Return NULL_TREE if it is not available. */
3212 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3214 enum tree_code code = (enum tree_code) tcode;
3218 case FIX_TRUNC_EXPR:
3219 switch (TYPE_MODE (dest_type))
3222 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3225 return TYPE_UNSIGNED (dest_type)
3226 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3227 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3230 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3233 return TYPE_UNSIGNED (dest_type)
3234 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3235 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3242 switch (TYPE_MODE (src_type))
3245 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3248 return TYPE_UNSIGNED (src_type)
3249 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3250 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3253 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3256 return TYPE_UNSIGNED (src_type)
3257 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3258 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3269 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3271 rs6000_builtin_mul_widen_even (tree type)
3273 if (!TARGET_ALTIVEC)
3276 switch (TYPE_MODE (type))
3279 return TYPE_UNSIGNED (type)
3280 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3281 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3284 return TYPE_UNSIGNED (type)
3285 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3286 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3292 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3294 rs6000_builtin_mul_widen_odd (tree type)
3296 if (!TARGET_ALTIVEC)
3299 switch (TYPE_MODE (type))
3302 return TYPE_UNSIGNED (type)
3303 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3304 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3307 return TYPE_UNSIGNED (type)
3308 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3309 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3316 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3317 after applying N number of iterations. This routine does not determine
3318 how may iterations are required to reach desired alignment. */
3321 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3328 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3331 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3341 /* Assuming that all other types are naturally aligned. CHECKME! */
3346 /* Return true if the vector misalignment factor is supported by the
3349 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3356 /* Return if movmisalign pattern is not supported for this mode. */
3357 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3360 if (misalignment == -1)
3362 /* Misalignment factor is unknown at compile time but we know
3363 it's word aligned. */
3364 if (rs6000_vector_alignment_reachable (type, is_packed))
3366 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3368 if (element_size == 64 || element_size == 32)
3375 /* VSX supports word-aligned vector. */
3376 if (misalignment % 4 == 0)
3382 /* Implement targetm.vectorize.builtin_vec_perm. */
3384 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3386 tree inner_type = TREE_TYPE (type);
3387 bool uns_p = TYPE_UNSIGNED (inner_type);
3390 *mask_element_type = unsigned_char_type_node;
3392 switch (TYPE_MODE (type))
3396 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3397 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3402 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3403 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3408 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3409 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3413 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3417 if (!TARGET_ALLOW_DF_PERMUTE)
3420 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3424 if (!TARGET_ALLOW_DF_PERMUTE)
3428 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3429 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3441 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3443 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3444 tree vectype, int misalign)
3448 switch (type_of_cost)
3458 case cond_branch_not_taken:
3462 case cond_branch_taken:
3465 case unaligned_load:
3466 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3468 elements = TYPE_VECTOR_SUBPARTS (vectype);
3470 /* Double word aligned. */
3478 /* Double word aligned. */
3482 /* Unknown misalignment. */
3495 /* Misaligned loads are not supported. */
3500 case unaligned_store:
3501 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3503 elements = TYPE_VECTOR_SUBPARTS (vectype);
3505 /* Double word aligned. */
3513 /* Double word aligned. */
3517 /* Unknown misalignment. */
3530 /* Misaligned stores are not supported. */
3540 /* Handle generic options of the form -mfoo=yes/no.
3541 NAME is the option name.
3542 VALUE is the option value.
3543 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3544 whether the option value is 'yes' or 'no' respectively. */
3546 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3550 else if (!strcmp (value, "yes"))
3552 else if (!strcmp (value, "no"))
3555 error ("unknown -m%s= option specified: '%s'", name, value);
3558 /* Validate and record the size specified with the -mtls-size option. */
3561 rs6000_parse_tls_size_option (void)
3563 if (rs6000_tls_size_string == 0)
3565 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3566 rs6000_tls_size = 16;
3567 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3568 rs6000_tls_size = 32;
3569 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3570 rs6000_tls_size = 64;
3572 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3576 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3578 if (DEFAULT_ABI == ABI_DARWIN)
3579 /* The Darwin libraries never set errno, so we might as well
3580 avoid calling them when that's the only reason we would. */
3581 flag_errno_math = 0;
3583 /* Double growth factor to counter reduced min jump length. */
3584 set_param_value ("max-grow-copy-bb-insns", 16);
3586 /* Enable section anchors by default.
3587 Skip section anchors for Objective C and Objective C++
3588 until front-ends fixed. */
3589 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3590 flag_section_anchors = 2;
3593 static enum fpu_type_t
3594 rs6000_parse_fpu_option (const char *option)
3596 if (!strcmp("none", option)) return FPU_NONE;
3597 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3598 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3599 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3600 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3601 error("unknown value %s for -mfpu", option);
3605 /* Returns a function decl for a vectorized version of the builtin function
3606 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3607 if it is not available. */
3610 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3613 enum machine_mode in_mode, out_mode;
3616 if (TREE_CODE (type_out) != VECTOR_TYPE
3617 || TREE_CODE (type_in) != VECTOR_TYPE
3618 || !TARGET_VECTORIZE_BUILTINS)
3621 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3622 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3623 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3624 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3626 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3628 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3631 case BUILT_IN_COPYSIGN:
3632 if (VECTOR_UNIT_VSX_P (V2DFmode)
3633 && out_mode == DFmode && out_n == 2
3634 && in_mode == DFmode && in_n == 2)
3635 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3637 case BUILT_IN_COPYSIGNF:
3638 if (out_mode != SFmode || out_n != 4
3639 || in_mode != SFmode || in_n != 4)
3641 if (VECTOR_UNIT_VSX_P (V4SFmode))
3642 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3643 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3644 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3647 if (VECTOR_UNIT_VSX_P (V2DFmode)
3648 && out_mode == DFmode && out_n == 2
3649 && in_mode == DFmode && in_n == 2)
3650 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3652 case BUILT_IN_SQRTF:
3653 if (VECTOR_UNIT_VSX_P (V4SFmode)
3654 && out_mode == SFmode && out_n == 4
3655 && in_mode == SFmode && in_n == 4)
3656 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3659 if (VECTOR_UNIT_VSX_P (V2DFmode)
3660 && out_mode == DFmode && out_n == 2
3661 && in_mode == DFmode && in_n == 2)
3662 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3664 case BUILT_IN_CEILF:
3665 if (out_mode != SFmode || out_n != 4
3666 || in_mode != SFmode || in_n != 4)
3668 if (VECTOR_UNIT_VSX_P (V4SFmode))
3669 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3670 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3671 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3673 case BUILT_IN_FLOOR:
3674 if (VECTOR_UNIT_VSX_P (V2DFmode)
3675 && out_mode == DFmode && out_n == 2
3676 && in_mode == DFmode && in_n == 2)
3677 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3679 case BUILT_IN_FLOORF:
3680 if (out_mode != SFmode || out_n != 4
3681 || in_mode != SFmode || in_n != 4)
3683 if (VECTOR_UNIT_VSX_P (V4SFmode))
3684 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3685 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3686 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3688 case BUILT_IN_TRUNC:
3689 if (VECTOR_UNIT_VSX_P (V2DFmode)
3690 && out_mode == DFmode && out_n == 2
3691 && in_mode == DFmode && in_n == 2)
3692 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3694 case BUILT_IN_TRUNCF:
3695 if (out_mode != SFmode || out_n != 4
3696 || in_mode != SFmode || in_n != 4)
3698 if (VECTOR_UNIT_VSX_P (V4SFmode))
3699 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3700 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3701 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3703 case BUILT_IN_NEARBYINT:
3704 if (VECTOR_UNIT_VSX_P (V2DFmode)
3705 && flag_unsafe_math_optimizations
3706 && out_mode == DFmode && out_n == 2
3707 && in_mode == DFmode && in_n == 2)
3708 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3710 case BUILT_IN_NEARBYINTF:
3711 if (VECTOR_UNIT_VSX_P (V4SFmode)
3712 && flag_unsafe_math_optimizations
3713 && out_mode == SFmode && out_n == 4
3714 && in_mode == SFmode && in_n == 4)
3715 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3718 if (VECTOR_UNIT_VSX_P (V2DFmode)
3719 && !flag_trapping_math
3720 && out_mode == DFmode && out_n == 2
3721 && in_mode == DFmode && in_n == 2)
3722 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3724 case BUILT_IN_RINTF:
3725 if (VECTOR_UNIT_VSX_P (V4SFmode)
3726 && !flag_trapping_math
3727 && out_mode == SFmode && out_n == 4
3728 && in_mode == SFmode && in_n == 4)
3729 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3736 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3738 enum rs6000_builtins fn
3739 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3742 case RS6000_BUILTIN_RSQRTF:
3743 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3744 && out_mode == SFmode && out_n == 4
3745 && in_mode == SFmode && in_n == 4)
3746 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3748 case RS6000_BUILTIN_RSQRT:
3749 if (VECTOR_UNIT_VSX_P (V2DFmode)
3750 && out_mode == DFmode && out_n == 2
3751 && in_mode == DFmode && in_n == 2)
3752 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3754 case RS6000_BUILTIN_RECIPF:
3755 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3756 && out_mode == SFmode && out_n == 4
3757 && in_mode == SFmode && in_n == 4)
3758 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3760 case RS6000_BUILTIN_RECIP:
3761 if (VECTOR_UNIT_VSX_P (V2DFmode)
3762 && out_mode == DFmode && out_n == 2
3763 && in_mode == DFmode && in_n == 2)
3764 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3775 /* Implement TARGET_HANDLE_OPTION. */
3778 rs6000_handle_option (size_t code, const char *arg, int value)
3780 enum fpu_type_t fpu_type = FPU_NONE;
3786 target_flags &= ~(MASK_POWER | MASK_POWER2
3787 | MASK_MULTIPLE | MASK_STRING);
3788 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3789 | MASK_MULTIPLE | MASK_STRING);
3791 case OPT_mno_powerpc:
3792 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3793 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3794 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3795 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3798 target_flags &= ~MASK_MINIMAL_TOC;
3799 TARGET_NO_FP_IN_TOC = 0;
3800 TARGET_NO_SUM_IN_TOC = 0;
3801 target_flags_explicit |= MASK_MINIMAL_TOC;
3802 #ifdef TARGET_USES_SYSV4_OPT
3803 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3804 just the same as -mminimal-toc. */
3805 target_flags |= MASK_MINIMAL_TOC;
3806 target_flags_explicit |= MASK_MINIMAL_TOC;
3810 #ifdef TARGET_USES_SYSV4_OPT
3812 /* Make -mtoc behave like -mminimal-toc. */
3813 target_flags |= MASK_MINIMAL_TOC;
3814 target_flags_explicit |= MASK_MINIMAL_TOC;
3818 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
3820 if (strcmp (arg, "small") == 0)
3821 cmodel = CMODEL_SMALL;
3822 else if (strcmp (arg, "large") == 0)
3823 cmodel = CMODEL_LARGE;
3826 error ("invalid option for -mcmodel: '%s'", arg);
3829 rs6000_explicit_options.cmodel = true;
3832 #ifdef TARGET_USES_AIX64_OPT
3837 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3838 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3839 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3842 #ifdef TARGET_USES_AIX64_OPT
3847 target_flags &= ~MASK_POWERPC64;
3848 target_flags_explicit |= MASK_POWERPC64;
3851 case OPT_minsert_sched_nops_:
3852 rs6000_sched_insert_nops_str = arg;
3855 case OPT_mminimal_toc:
3858 TARGET_NO_FP_IN_TOC = 0;
3859 TARGET_NO_SUM_IN_TOC = 0;
3866 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3867 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3874 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3875 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3879 case OPT_mpowerpc_gpopt:
3880 case OPT_mpowerpc_gfxopt:
3883 target_flags |= MASK_POWERPC;
3884 target_flags_explicit |= MASK_POWERPC;
3888 case OPT_maix_struct_return:
3889 case OPT_msvr4_struct_return:
3890 rs6000_explicit_options.aix_struct_ret = true;
3894 rs6000_explicit_options.vrsave = true;
3895 TARGET_ALTIVEC_VRSAVE = value;
3899 rs6000_explicit_options.vrsave = true;
3900 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3904 target_flags_explicit |= MASK_ISEL;
3906 rs6000_parse_yes_no_option ("isel", arg, &isel);
3908 target_flags |= MASK_ISEL;
3910 target_flags &= ~MASK_ISEL;
3914 rs6000_explicit_options.spe = true;
3919 rs6000_explicit_options.spe = true;
3920 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3924 rs6000_debug_name = arg;
3927 #ifdef TARGET_USES_SYSV4_OPT
3929 rs6000_abi_name = arg;
3933 rs6000_sdata_name = arg;
3936 case OPT_mtls_size_:
3937 rs6000_tls_size_string = arg;
3940 case OPT_mrelocatable:
3943 target_flags |= MASK_MINIMAL_TOC;
3944 target_flags_explicit |= MASK_MINIMAL_TOC;
3945 TARGET_NO_FP_IN_TOC = 1;
3949 case OPT_mrelocatable_lib:
3952 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3953 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3954 TARGET_NO_FP_IN_TOC = 1;
3958 target_flags &= ~MASK_RELOCATABLE;
3959 target_flags_explicit |= MASK_RELOCATABLE;
3965 if (!strcmp (arg, "altivec"))
3967 rs6000_explicit_options.altivec_abi = true;
3968 rs6000_altivec_abi = 1;
3970 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3973 else if (! strcmp (arg, "no-altivec"))
3975 rs6000_explicit_options.altivec_abi = true;
3976 rs6000_altivec_abi = 0;
3978 else if (! strcmp (arg, "spe"))
3980 rs6000_explicit_options.spe_abi = true;
3982 rs6000_altivec_abi = 0;
3983 if (!TARGET_SPE_ABI)
3984 error ("not configured for ABI: '%s'", arg);
3986 else if (! strcmp (arg, "no-spe"))
3988 rs6000_explicit_options.spe_abi = true;
3992 /* These are here for testing during development only, do not
3993 document in the manual please. */
3994 else if (! strcmp (arg, "d64"))
3996 rs6000_darwin64_abi = 1;
3997 warning (0, "Using darwin64 ABI");
3999 else if (! strcmp (arg, "d32"))
4001 rs6000_darwin64_abi = 0;
4002 warning (0, "Using old darwin ABI");
4005 else if (! strcmp (arg, "ibmlongdouble"))
4007 rs6000_explicit_options.ieee = true;
4008 rs6000_ieeequad = 0;
4009 warning (0, "Using IBM extended precision long double");
4011 else if (! strcmp (arg, "ieeelongdouble"))
4013 rs6000_explicit_options.ieee = true;
4014 rs6000_ieeequad = 1;
4015 warning (0, "Using IEEE extended precision long double");
4020 error ("unknown ABI specified: '%s'", arg);
4026 rs6000_select[1].string = arg;
4030 rs6000_select[2].string = arg;
4033 case OPT_mtraceback_:
4034 rs6000_traceback_name = arg;
4037 case OPT_mfloat_gprs_:
4038 rs6000_explicit_options.float_gprs = true;
4039 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4040 rs6000_float_gprs = 1;
4041 else if (! strcmp (arg, "double"))
4042 rs6000_float_gprs = 2;
4043 else if (! strcmp (arg, "no"))
4044 rs6000_float_gprs = 0;
4047 error ("invalid option for -mfloat-gprs: '%s'", arg);
4052 case OPT_mlong_double_:
4053 rs6000_explicit_options.long_double = true;
4054 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4055 if (value != 64 && value != 128)
4057 error ("Unknown switch -mlong-double-%s", arg);
4058 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4062 rs6000_long_double_type_size = value;
4065 case OPT_msched_costly_dep_:
4066 rs6000_sched_costly_dep_str = arg;
4070 rs6000_explicit_options.alignment = true;
4071 if (! strcmp (arg, "power"))
4073 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4074 some C library functions, so warn about it. The flag may be
4075 useful for performance studies from time to time though, so
4076 don't disable it entirely. */
4077 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4078 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4079 " it is incompatible with the installed C and C++ libraries");
4080 rs6000_alignment_flags = MASK_ALIGN_POWER;
4082 else if (! strcmp (arg, "natural"))
4083 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4086 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4091 case OPT_msingle_float:
4092 if (!TARGET_SINGLE_FPU)
4093 warning (0, "-msingle-float option equivalent to -mhard-float");
4094 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4095 rs6000_double_float = 0;
4096 target_flags &= ~MASK_SOFT_FLOAT;
4097 target_flags_explicit |= MASK_SOFT_FLOAT;
4100 case OPT_mdouble_float:
4101 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4102 rs6000_single_float = 1;
4103 target_flags &= ~MASK_SOFT_FLOAT;
4104 target_flags_explicit |= MASK_SOFT_FLOAT;
4107 case OPT_msimple_fpu:
4108 if (!TARGET_SINGLE_FPU)
4109 warning (0, "-msimple-fpu option ignored");
4112 case OPT_mhard_float:
4113 /* -mhard_float implies -msingle-float and -mdouble-float. */
4114 rs6000_single_float = rs6000_double_float = 1;
4117 case OPT_msoft_float:
4118 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4119 rs6000_single_float = rs6000_double_float = 0;
4123 fpu_type = rs6000_parse_fpu_option(arg);
4124 if (fpu_type != FPU_NONE)
4125 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4127 target_flags &= ~MASK_SOFT_FLOAT;
4128 target_flags_explicit |= MASK_SOFT_FLOAT;
4129 rs6000_xilinx_fpu = 1;
4130 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4131 rs6000_single_float = 1;
4132 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4133 rs6000_single_float = rs6000_double_float = 1;
4134 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4135 rs6000_simple_fpu = 1;
4139 /* -mfpu=none is equivalent to -msoft-float */
4140 target_flags |= MASK_SOFT_FLOAT;
4141 target_flags_explicit |= MASK_SOFT_FLOAT;
4142 rs6000_single_float = rs6000_double_float = 0;
4146 rs6000_recip_name = (value) ? "default" : "none";
4150 rs6000_recip_name = arg;
4156 /* Do anything needed at the start of the asm file. */
4159 rs6000_file_start (void)
4163 const char *start = buffer;
4164 struct rs6000_cpu_select *ptr;
4165 const char *default_cpu = TARGET_CPU_DEFAULT;
4166 FILE *file = asm_out_file;
4168 default_file_start ();
4170 #ifdef TARGET_BI_ARCH
4171 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4175 if (flag_verbose_asm)
4177 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4178 rs6000_select[0].string = default_cpu;
4180 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4182 ptr = &rs6000_select[i];
4183 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4185 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4190 if (PPC405_ERRATUM77)
4192 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4196 #ifdef USING_ELFOS_H
4197 switch (rs6000_sdata)
4199 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4200 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4201 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4202 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4205 if (rs6000_sdata && g_switch_value)
4207 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4217 #ifdef HAVE_AS_GNU_ATTRIBUTE
4218 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4220 fprintf (file, "\t.gnu_attribute 4, %d\n",
4221 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4222 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4224 fprintf (file, "\t.gnu_attribute 8, %d\n",
4225 (TARGET_ALTIVEC_ABI ? 2
4226 : TARGET_SPE_ABI ? 3
4228 fprintf (file, "\t.gnu_attribute 12, %d\n",
4229 aix_struct_return ? 2 : 1);
4234 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4236 switch_to_section (toc_section);
4237 switch_to_section (text_section);
4242 /* Return nonzero if this function is known to have a null epilogue. */
4245 direct_return (void)
4247 if (reload_completed)
4249 rs6000_stack_t *info = rs6000_stack_info ();
4251 if (info->first_gp_reg_save == 32
4252 && info->first_fp_reg_save == 64
4253 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4254 && ! info->lr_save_p
4255 && ! info->cr_save_p
4256 && info->vrsave_mask == 0
4264 /* Return the number of instructions it takes to form a constant in an
4265 integer register. */
4268 num_insns_constant_wide (HOST_WIDE_INT value)
4270 /* signed constant loadable with {cal|addi} */
4271 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4274 /* constant loadable with {cau|addis} */
4275 else if ((value & 0xffff) == 0
4276 && (value >> 31 == -1 || value >> 31 == 0))
4279 #if HOST_BITS_PER_WIDE_INT == 64
4280 else if (TARGET_POWERPC64)
4282 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4283 HOST_WIDE_INT high = value >> 31;
4285 if (high == 0 || high == -1)
4291 return num_insns_constant_wide (high) + 1;
4293 return num_insns_constant_wide (low) + 1;
4295 return (num_insns_constant_wide (high)
4296 + num_insns_constant_wide (low) + 1);
4305 num_insns_constant (rtx op, enum machine_mode mode)
4307 HOST_WIDE_INT low, high;
4309 switch (GET_CODE (op))
4312 #if HOST_BITS_PER_WIDE_INT == 64
4313 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4314 && mask64_operand (op, mode))
4318 return num_insns_constant_wide (INTVAL (op));
4321 if (mode == SFmode || mode == SDmode)
4326 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4327 if (DECIMAL_FLOAT_MODE_P (mode))
4328 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4330 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4331 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4334 if (mode == VOIDmode || mode == DImode)
4336 high = CONST_DOUBLE_HIGH (op);
4337 low = CONST_DOUBLE_LOW (op);
4344 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4345 if (DECIMAL_FLOAT_MODE_P (mode))
4346 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4348 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4349 high = l[WORDS_BIG_ENDIAN == 0];
4350 low = l[WORDS_BIG_ENDIAN != 0];
4354 return (num_insns_constant_wide (low)
4355 + num_insns_constant_wide (high));
4358 if ((high == 0 && low >= 0)
4359 || (high == -1 && low < 0))
4360 return num_insns_constant_wide (low);
4362 else if (mask64_operand (op, mode))
4366 return num_insns_constant_wide (high) + 1;
4369 return (num_insns_constant_wide (high)
4370 + num_insns_constant_wide (low) + 1);
4378 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4379 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4380 corresponding element of the vector, but for V4SFmode and V2SFmode,
4381 the corresponding "float" is interpreted as an SImode integer. */
4384 const_vector_elt_as_int (rtx op, unsigned int elt)
4386 rtx tmp = CONST_VECTOR_ELT (op, elt);
4387 if (GET_MODE (op) == V4SFmode
4388 || GET_MODE (op) == V2SFmode)
4389 tmp = gen_lowpart (SImode, tmp);
4390 return INTVAL (tmp);
4393 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4394 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4395 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4396 all items are set to the same value and contain COPIES replicas of the
4397 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4398 operand and the others are set to the value of the operand's msb. */
4401 vspltis_constant (rtx op, unsigned step, unsigned copies)
4403 enum machine_mode mode = GET_MODE (op);
4404 enum machine_mode inner = GET_MODE_INNER (mode);
4407 unsigned nunits = GET_MODE_NUNITS (mode);
4408 unsigned bitsize = GET_MODE_BITSIZE (inner);
4409 unsigned mask = GET_MODE_MASK (inner);
4411 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4412 HOST_WIDE_INT splat_val = val;
4413 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4415 /* Construct the value to be splatted, if possible. If not, return 0. */
4416 for (i = 2; i <= copies; i *= 2)
4418 HOST_WIDE_INT small_val;
4420 small_val = splat_val >> bitsize;
4422 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4424 splat_val = small_val;
4427 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4428 if (EASY_VECTOR_15 (splat_val))
4431 /* Also check if we can splat, and then add the result to itself. Do so if
4432 the value is positive, of if the splat instruction is using OP's mode;
4433 for splat_val < 0, the splat and the add should use the same mode. */
4434 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4435 && (splat_val >= 0 || (step == 1 && copies == 1)))
4438 /* Also check if are loading up the most significant bit which can be done by
4439 loading up -1 and shifting the value left by -1. */
4440 else if (EASY_VECTOR_MSB (splat_val, inner))
4446 /* Check if VAL is present in every STEP-th element, and the
4447 other elements are filled with its most significant bit. */
4448 for (i = 0; i < nunits - 1; ++i)
4450 HOST_WIDE_INT desired_val;
4451 if (((i + 1) & (step - 1)) == 0)
4454 desired_val = msb_val;
4456 if (desired_val != const_vector_elt_as_int (op, i))
4464 /* Return true if OP is of the given MODE and can be synthesized
4465 with a vspltisb, vspltish or vspltisw. */
4468 easy_altivec_constant (rtx op, enum machine_mode mode)
4470 unsigned step, copies;
4472 if (mode == VOIDmode)
4473 mode = GET_MODE (op);
4474 else if (mode != GET_MODE (op))
4477 /* Start with a vspltisw. */
4478 step = GET_MODE_NUNITS (mode) / 4;
4481 if (vspltis_constant (op, step, copies))
4484 /* Then try with a vspltish. */
4490 if (vspltis_constant (op, step, copies))
4493 /* And finally a vspltisb. */
4499 if (vspltis_constant (op, step, copies))
4505 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4506 result is OP. Abort if it is not possible. */
4509 gen_easy_altivec_constant (rtx op)
4511 enum machine_mode mode = GET_MODE (op);
4512 int nunits = GET_MODE_NUNITS (mode);
4513 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4514 unsigned step = nunits / 4;
4515 unsigned copies = 1;
4517 /* Start with a vspltisw. */
4518 if (vspltis_constant (op, step, copies))
4519 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4521 /* Then try with a vspltish. */
4527 if (vspltis_constant (op, step, copies))
4528 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4530 /* And finally a vspltisb. */
4536 if (vspltis_constant (op, step, copies))
4537 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4543 output_vec_const_move (rtx *operands)
4546 enum machine_mode mode;
4551 mode = GET_MODE (dest);
4553 if (TARGET_VSX && zero_constant (vec, mode))
4554 return "xxlxor %x0,%x0,%x0";
4559 if (zero_constant (vec, mode))
4560 return "vxor %0,%0,%0";
4562 splat_vec = gen_easy_altivec_constant (vec);
4563 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4564 operands[1] = XEXP (splat_vec, 0);
4565 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4568 switch (GET_MODE (splat_vec))
4571 return "vspltisw %0,%1";
4574 return "vspltish %0,%1";
4577 return "vspltisb %0,%1";
4584 gcc_assert (TARGET_SPE);
4586 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4587 pattern of V1DI, V4HI, and V2SF.
4589 FIXME: We should probably return # and add post reload
4590 splitters for these, but this way is so easy ;-). */
4591 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4592 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4593 operands[1] = CONST_VECTOR_ELT (vec, 0);
4594 operands[2] = CONST_VECTOR_ELT (vec, 1);
4596 return "li %0,%1\n\tevmergelo %0,%0,%0";
4598 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4601 /* Initialize TARGET of vector PAIRED to VALS. */
4604 paired_expand_vector_init (rtx target, rtx vals)
4606 enum machine_mode mode = GET_MODE (target);
4607 int n_elts = GET_MODE_NUNITS (mode);
4609 rtx x, new_rtx, tmp, constant_op, op1, op2;
4612 for (i = 0; i < n_elts; ++i)
4614 x = XVECEXP (vals, 0, i);
4615 if (!CONSTANT_P (x))
4620 /* Load from constant pool. */
4621 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4627 /* The vector is initialized only with non-constants. */
4628 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4629 XVECEXP (vals, 0, 1));
4631 emit_move_insn (target, new_rtx);
4635 /* One field is non-constant and the other one is a constant. Load the
4636 constant from the constant pool and use ps_merge instruction to
4637 construct the whole vector. */
4638 op1 = XVECEXP (vals, 0, 0);
4639 op2 = XVECEXP (vals, 0, 1);
4641 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4643 tmp = gen_reg_rtx (GET_MODE (constant_op));
4644 emit_move_insn (tmp, constant_op);
4646 if (CONSTANT_P (op1))
4647 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4649 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4651 emit_move_insn (target, new_rtx);
4655 paired_expand_vector_move (rtx operands[])
4657 rtx op0 = operands[0], op1 = operands[1];
4659 emit_move_insn (op0, op1);
4662 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4663 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4664 operands for the relation operation COND. This is a recursive
4668 paired_emit_vector_compare (enum rtx_code rcode,
4669 rtx dest, rtx op0, rtx op1,
4670 rtx cc_op0, rtx cc_op1)
4672 rtx tmp = gen_reg_rtx (V2SFmode);
4675 gcc_assert (TARGET_PAIRED_FLOAT);
4676 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4682 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4686 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4687 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4691 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4694 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4697 tmp1 = gen_reg_rtx (V2SFmode);
4698 max = gen_reg_rtx (V2SFmode);
4699 min = gen_reg_rtx (V2SFmode);
4700 gen_reg_rtx (V2SFmode);
4702 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4703 emit_insn (gen_selv2sf4
4704 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4705 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4706 emit_insn (gen_selv2sf4
4707 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4708 emit_insn (gen_subv2sf3 (tmp1, min, max));
4709 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4712 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4715 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4718 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4721 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4724 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4733 /* Emit vector conditional expression.
4734 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4735 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4738 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4739 rtx cond, rtx cc_op0, rtx cc_op1)
4741 enum rtx_code rcode = GET_CODE (cond);
4743 if (!TARGET_PAIRED_FLOAT)
4746 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4751 /* Initialize vector TARGET to VALS. */
4754 rs6000_expand_vector_init (rtx target, rtx vals)
4756 enum machine_mode mode = GET_MODE (target);
4757 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4758 int n_elts = GET_MODE_NUNITS (mode);
4759 int n_var = 0, one_var = -1;
4760 bool all_same = true, all_const_zero = true;
4764 for (i = 0; i < n_elts; ++i)
4766 x = XVECEXP (vals, 0, i);
4767 if (!CONSTANT_P (x))
4768 ++n_var, one_var = i;
4769 else if (x != CONST0_RTX (inner_mode))
4770 all_const_zero = false;
4772 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4778 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4779 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4780 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4782 /* Zero register. */
4783 emit_insn (gen_rtx_SET (VOIDmode, target,
4784 gen_rtx_XOR (mode, target, target)));
4787 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4789 /* Splat immediate. */
4790 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4795 /* Load from constant pool. */
4796 emit_move_insn (target, const_vec);
4801 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4802 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4806 rtx element = XVECEXP (vals, 0, 0);
4807 if (mode == V2DFmode)
4808 emit_insn (gen_vsx_splat_v2df (target, element));
4810 emit_insn (gen_vsx_splat_v2di (target, element));
4814 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4815 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4816 if (mode == V2DFmode)
4817 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4819 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4824 /* With single precision floating point on VSX, know that internally single
4825 precision is actually represented as a double, and either make 2 V2DF
4826 vectors, and convert these vectors to single precision, or do one
4827 conversion, and splat the result to the other elements. */
4828 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4832 rtx freg = gen_reg_rtx (V4SFmode);
4833 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4835 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4836 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4840 rtx dbl_even = gen_reg_rtx (V2DFmode);
4841 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4842 rtx flt_even = gen_reg_rtx (V4SFmode);
4843 rtx flt_odd = gen_reg_rtx (V4SFmode);
4845 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4846 copy_to_reg (XVECEXP (vals, 0, 0)),
4847 copy_to_reg (XVECEXP (vals, 0, 1))));
4848 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4849 copy_to_reg (XVECEXP (vals, 0, 2)),
4850 copy_to_reg (XVECEXP (vals, 0, 3))));
4851 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4852 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4853 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4858 /* Store value to stack temp. Load vector element. Splat. However, splat
4859 of 64-bit items is not supported on Altivec. */
4860 if (all_same && GET_MODE_SIZE (mode) <= 4)
4862 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4863 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4864 XVECEXP (vals, 0, 0));
4865 x = gen_rtx_UNSPEC (VOIDmode,
4866 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4867 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4869 gen_rtx_SET (VOIDmode,
4872 x = gen_rtx_VEC_SELECT (inner_mode, target,
4873 gen_rtx_PARALLEL (VOIDmode,
4874 gen_rtvec (1, const0_rtx)));
4875 emit_insn (gen_rtx_SET (VOIDmode, target,
4876 gen_rtx_VEC_DUPLICATE (mode, x)));
4880 /* One field is non-constant. Load constant then overwrite
4884 rtx copy = copy_rtx (vals);
4886 /* Load constant part of vector, substitute neighboring value for
4888 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4889 rs6000_expand_vector_init (target, copy);
4891 /* Insert variable. */
4892 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4896 /* Construct the vector in memory one field at a time
4897 and load the whole vector. */
4898 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4899 for (i = 0; i < n_elts; i++)
4900 emit_move_insn (adjust_address_nv (mem, inner_mode,
4901 i * GET_MODE_SIZE (inner_mode)),
4902 XVECEXP (vals, 0, i));
4903 emit_move_insn (target, mem);
4906 /* Set field ELT of TARGET to VAL. */
4909 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4911 enum machine_mode mode = GET_MODE (target);
4912 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4913 rtx reg = gen_reg_rtx (mode);
4915 int width = GET_MODE_SIZE (inner_mode);
4918 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4920 rtx (*set_func) (rtx, rtx, rtx, rtx)
4921 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4922 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4926 /* Load single variable value. */
4927 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4928 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4929 x = gen_rtx_UNSPEC (VOIDmode,
4930 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4931 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4933 gen_rtx_SET (VOIDmode,
4937 /* Linear sequence. */
4938 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4939 for (i = 0; i < 16; ++i)
4940 XVECEXP (mask, 0, i) = GEN_INT (i);
4942 /* Set permute mask to insert element into target. */
4943 for (i = 0; i < width; ++i)
4944 XVECEXP (mask, 0, elt*width + i)
4945 = GEN_INT (i + 0x10);
4946 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4947 x = gen_rtx_UNSPEC (mode,
4948 gen_rtvec (3, target, reg,
4949 force_reg (V16QImode, x)),
4951 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4954 /* Extract field ELT from VEC into TARGET. */
4957 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4959 enum machine_mode mode = GET_MODE (vec);
4960 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4963 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4965 rtx (*extract_func) (rtx, rtx, rtx)
4966 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4967 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4971 /* Allocate mode-sized buffer. */
4972 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4974 /* Add offset to field within buffer matching vector element. */
4975 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4977 /* Store single field into mode-sized buffer. */
4978 x = gen_rtx_UNSPEC (VOIDmode,
4979 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4980 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4982 gen_rtx_SET (VOIDmode,
4985 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4988 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4989 implement ANDing by the mask IN. */
4991 build_mask64_2_operands (rtx in, rtx *out)
4993 #if HOST_BITS_PER_WIDE_INT >= 64
4994 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4997 gcc_assert (GET_CODE (in) == CONST_INT);
5002 /* Assume c initially something like 0x00fff000000fffff. The idea
5003 is to rotate the word so that the middle ^^^^^^ group of zeros
5004 is at the MS end and can be cleared with an rldicl mask. We then
5005 rotate back and clear off the MS ^^ group of zeros with a
5007 c = ~c; /* c == 0xff000ffffff00000 */
5008 lsb = c & -c; /* lsb == 0x0000000000100000 */
5009 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5010 c = ~c; /* c == 0x00fff000000fffff */
5011 c &= -lsb; /* c == 0x00fff00000000000 */
5012 lsb = c & -c; /* lsb == 0x0000100000000000 */
5013 c = ~c; /* c == 0xff000fffffffffff */
5014 c &= -lsb; /* c == 0xff00000000000000 */
5016 while ((lsb >>= 1) != 0)
5017 shift++; /* shift == 44 on exit from loop */
5018 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5019 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5020 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5024 /* Assume c initially something like 0xff000f0000000000. The idea
5025 is to rotate the word so that the ^^^ middle group of zeros
5026 is at the LS end and can be cleared with an rldicr mask. We then
5027 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5029 lsb = c & -c; /* lsb == 0x0000010000000000 */
5030 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5031 c = ~c; /* c == 0x00fff0ffffffffff */
5032 c &= -lsb; /* c == 0x00fff00000000000 */
5033 lsb = c & -c; /* lsb == 0x0000100000000000 */
5034 c = ~c; /* c == 0xff000fffffffffff */
5035 c &= -lsb; /* c == 0xff00000000000000 */
5037 while ((lsb >>= 1) != 0)
5038 shift++; /* shift == 44 on exit from loop */
5039 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5040 m1 >>= shift; /* m1 == 0x0000000000000fff */
5041 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5044 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5045 masks will be all 1's. We are guaranteed more than one transition. */
5046 out[0] = GEN_INT (64 - shift);
5047 out[1] = GEN_INT (m1);
5048 out[2] = GEN_INT (shift);
5049 out[3] = GEN_INT (m2);
5057 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5060 invalid_e500_subreg (rtx op, enum machine_mode mode)
5062 if (TARGET_E500_DOUBLE)
5064 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5065 subreg:TI and reg:TF. Decimal float modes are like integer
5066 modes (only low part of each register used) for this
5068 if (GET_CODE (op) == SUBREG
5069 && (mode == SImode || mode == DImode || mode == TImode
5070 || mode == DDmode || mode == TDmode)
5071 && REG_P (SUBREG_REG (op))
5072 && (GET_MODE (SUBREG_REG (op)) == DFmode
5073 || GET_MODE (SUBREG_REG (op)) == TFmode))
5076 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5078 if (GET_CODE (op) == SUBREG
5079 && (mode == DFmode || mode == TFmode)
5080 && REG_P (SUBREG_REG (op))
5081 && (GET_MODE (SUBREG_REG (op)) == DImode
5082 || GET_MODE (SUBREG_REG (op)) == TImode
5083 || GET_MODE (SUBREG_REG (op)) == DDmode
5084 || GET_MODE (SUBREG_REG (op)) == TDmode))
5089 && GET_CODE (op) == SUBREG
5091 && REG_P (SUBREG_REG (op))
5092 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5098 /* AIX increases natural record alignment to doubleword if the first
5099 field is an FP double while the FP fields remain word aligned. */
5102 rs6000_special_round_type_align (tree type, unsigned int computed,
5103 unsigned int specified)
5105 unsigned int align = MAX (computed, specified);
5106 tree field = TYPE_FIELDS (type);
5108 /* Skip all non field decls */
5109 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5110 field = DECL_CHAIN (field);
5112 if (field != NULL && field != type)
5114 type = TREE_TYPE (field);
5115 while (TREE_CODE (type) == ARRAY_TYPE)
5116 type = TREE_TYPE (type);
5118 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5119 align = MAX (align, 64);
5125 /* Darwin increases record alignment to the natural alignment of
5129 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5130 unsigned int specified)
5132 unsigned int align = MAX (computed, specified);
5134 if (TYPE_PACKED (type))
5137 /* Find the first field, looking down into aggregates. */
5139 tree field = TYPE_FIELDS (type);
5140 /* Skip all non field decls */
5141 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5142 field = DECL_CHAIN (field);
5145 /* A packed field does not contribute any extra alignment. */
5146 if (DECL_PACKED (field))
5148 type = TREE_TYPE (field);
5149 while (TREE_CODE (type) == ARRAY_TYPE)
5150 type = TREE_TYPE (type);
5151 } while (AGGREGATE_TYPE_P (type));
5153 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5154 align = MAX (align, TYPE_ALIGN (type));
5159 /* Return 1 for an operand in small memory on V.4/eabi. */
5162 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5163 enum machine_mode mode ATTRIBUTE_UNUSED)
5168 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5171 if (DEFAULT_ABI != ABI_V4)
5174 /* Vector and float memory instructions have a limited offset on the
5175 SPE, so using a vector or float variable directly as an operand is
5178 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5181 if (GET_CODE (op) == SYMBOL_REF)
5184 else if (GET_CODE (op) != CONST
5185 || GET_CODE (XEXP (op, 0)) != PLUS
5186 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5187 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5192 rtx sum = XEXP (op, 0);
5193 HOST_WIDE_INT summand;
5195 /* We have to be careful here, because it is the referenced address
5196 that must be 32k from _SDA_BASE_, not just the symbol. */
5197 summand = INTVAL (XEXP (sum, 1));
5198 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5201 sym_ref = XEXP (sum, 0);
5204 return SYMBOL_REF_SMALL_P (sym_ref);
5210 /* Return true if either operand is a general purpose register. */
5213 gpr_or_gpr_p (rtx op0, rtx op1)
5215 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5216 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5220 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5223 reg_offset_addressing_ok_p (enum machine_mode mode)
5233 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5234 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5242 /* Paired vector modes. Only reg+reg addressing is valid. */
5243 if (TARGET_PAIRED_FLOAT)
5255 virtual_stack_registers_memory_p (rtx op)
5259 if (GET_CODE (op) == REG)
5260 regnum = REGNO (op);
5262 else if (GET_CODE (op) == PLUS
5263 && GET_CODE (XEXP (op, 0)) == REG
5264 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5265 regnum = REGNO (XEXP (op, 0));
5270 return (regnum >= FIRST_VIRTUAL_REGISTER
5271 && regnum <= LAST_VIRTUAL_REGISTER);
5275 constant_pool_expr_p (rtx op)
5279 split_const (op, &base, &offset);
5280 return (GET_CODE (base) == SYMBOL_REF
5281 && CONSTANT_POOL_ADDRESS_P (base)
5282 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5285 static rtx tocrel_base, tocrel_offset;
5288 toc_relative_expr_p (rtx op)
5290 if (GET_CODE (op) != CONST)
5293 split_const (op, &tocrel_base, &tocrel_offset);
5294 return (GET_CODE (tocrel_base) == UNSPEC
5295 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5299 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5302 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5303 && GET_CODE (XEXP (x, 0)) == REG
5304 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5305 || ((TARGET_MINIMAL_TOC
5306 || TARGET_CMODEL != CMODEL_SMALL)
5307 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5308 && toc_relative_expr_p (XEXP (x, 1)));
5312 legitimate_small_data_p (enum machine_mode mode, rtx x)
5314 return (DEFAULT_ABI == ABI_V4
5315 && !flag_pic && !TARGET_TOC
5316 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5317 && small_data_operand (x, mode));
5320 /* SPE offset addressing is limited to 5-bits worth of double words. */
5321 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5324 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5326 unsigned HOST_WIDE_INT offset, extra;
5328 if (GET_CODE (x) != PLUS)
5330 if (GET_CODE (XEXP (x, 0)) != REG)
5332 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5334 if (!reg_offset_addressing_ok_p (mode))
5335 return virtual_stack_registers_memory_p (x);
5336 if (legitimate_constant_pool_address_p (x, strict))
5338 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5341 offset = INTVAL (XEXP (x, 1));
5349 /* SPE vector modes. */
5350 return SPE_CONST_OFFSET_OK (offset);
5353 if (TARGET_E500_DOUBLE)
5354 return SPE_CONST_OFFSET_OK (offset);
5356 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5358 if (VECTOR_MEM_VSX_P (DFmode))
5363 /* On e500v2, we may have:
5365 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5367 Which gets addressed with evldd instructions. */
5368 if (TARGET_E500_DOUBLE)
5369 return SPE_CONST_OFFSET_OK (offset);
5371 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5373 else if (offset & 3)
5378 if (TARGET_E500_DOUBLE)
5379 return (SPE_CONST_OFFSET_OK (offset)
5380 && SPE_CONST_OFFSET_OK (offset + 8));
5384 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5386 else if (offset & 3)
5397 return (offset < 0x10000) && (offset + extra < 0x10000);
5401 legitimate_indexed_address_p (rtx x, int strict)
5405 if (GET_CODE (x) != PLUS)
5411 /* Recognize the rtl generated by reload which we know will later be
5412 replaced with proper base and index regs. */
5414 && reload_in_progress
5415 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5419 return (REG_P (op0) && REG_P (op1)
5420 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5421 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5422 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5423 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5427 avoiding_indexed_address_p (enum machine_mode mode)
5429 /* Avoid indexed addressing for modes that have non-indexed
5430 load/store instruction forms. */
5431 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5435 legitimate_indirect_address_p (rtx x, int strict)
5437 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5441 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5443 if (!TARGET_MACHO || !flag_pic
5444 || mode != SImode || GET_CODE (x) != MEM)
5448 if (GET_CODE (x) != LO_SUM)
5450 if (GET_CODE (XEXP (x, 0)) != REG)
5452 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5456 return CONSTANT_P (x);
5460 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5462 if (GET_CODE (x) != LO_SUM)
5464 if (GET_CODE (XEXP (x, 0)) != REG)
5466 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5468 /* Restrict addressing for DI because of our SUBREG hackery. */
5469 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5470 || mode == DDmode || mode == TDmode
5475 if (TARGET_ELF || TARGET_MACHO)
5477 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5481 if (GET_MODE_NUNITS (mode) != 1)
5483 if (GET_MODE_BITSIZE (mode) > 64
5484 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5485 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5486 && (mode == DFmode || mode == DDmode))))
5489 return CONSTANT_P (x);
5496 /* Try machine-dependent ways of modifying an illegitimate address
5497 to be legitimate. If we find one, return the new, valid address.
5498 This is used from only one place: `memory_address' in explow.c.
5500 OLDX is the address as it was before break_out_memory_refs was
5501 called. In some cases it is useful to look at this to decide what
5504 It is always safe for this function to do nothing. It exists to
5505 recognize opportunities to optimize the output.
5507 On RS/6000, first check for the sum of a register with a constant
5508 integer that is out of range. If so, generate code to add the
5509 constant with the low-order 16 bits masked to the register and force
5510 this result into another register (this can be done with `cau').
5511 Then generate an address of REG+(CONST&0xffff), allowing for the
5512 possibility of bit 16 being a one.
5514 Then check for the sum of a register and something not constant, try to
5515 load the other things into a register and return the sum. */
5518 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5519 enum machine_mode mode)
5521 unsigned int extra = 0;
5523 if (!reg_offset_addressing_ok_p (mode))
5525 if (virtual_stack_registers_memory_p (x))
5528 /* In theory we should not be seeing addresses of the form reg+0,
5529 but just in case it is generated, optimize it away. */
5530 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5531 return force_reg (Pmode, XEXP (x, 0));
5533 /* Make sure both operands are registers. */
5534 else if (GET_CODE (x) == PLUS)
5535 return gen_rtx_PLUS (Pmode,
5536 force_reg (Pmode, XEXP (x, 0)),
5537 force_reg (Pmode, XEXP (x, 1)));
5539 return force_reg (Pmode, x);
5541 if (GET_CODE (x) == SYMBOL_REF)
5543 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5545 return rs6000_legitimize_tls_address (x, model);
5555 if (!TARGET_POWERPC64)
5563 extra = TARGET_POWERPC64 ? 8 : 12;
5569 if (GET_CODE (x) == PLUS
5570 && GET_CODE (XEXP (x, 0)) == REG
5571 && GET_CODE (XEXP (x, 1)) == CONST_INT
5572 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5574 && !((TARGET_POWERPC64
5575 && (mode == DImode || mode == TImode)
5576 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5577 || SPE_VECTOR_MODE (mode)
5578 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5579 || mode == DImode || mode == DDmode
5580 || mode == TDmode))))
5582 HOST_WIDE_INT high_int, low_int;
5584 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5585 if (low_int >= 0x8000 - extra)
5587 high_int = INTVAL (XEXP (x, 1)) - low_int;
5588 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5589 GEN_INT (high_int)), 0);
5590 return plus_constant (sum, low_int);
5592 else if (GET_CODE (x) == PLUS
5593 && GET_CODE (XEXP (x, 0)) == REG
5594 && GET_CODE (XEXP (x, 1)) != CONST_INT
5595 && GET_MODE_NUNITS (mode) == 1
5596 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5598 || ((mode != DImode && mode != DFmode && mode != DDmode)
5599 || (TARGET_E500_DOUBLE && mode != DDmode)))
5600 && (TARGET_POWERPC64 || mode != DImode)
5601 && !avoiding_indexed_address_p (mode)
5606 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5607 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5609 else if (SPE_VECTOR_MODE (mode)
5610 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5611 || mode == DDmode || mode == TDmode
5612 || mode == DImode)))
5616 /* We accept [reg + reg] and [reg + OFFSET]. */
5618 if (GET_CODE (x) == PLUS)
5620 rtx op1 = XEXP (x, 0);
5621 rtx op2 = XEXP (x, 1);
5624 op1 = force_reg (Pmode, op1);
5626 if (GET_CODE (op2) != REG
5627 && (GET_CODE (op2) != CONST_INT
5628 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5629 || (GET_MODE_SIZE (mode) > 8
5630 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5631 op2 = force_reg (Pmode, op2);
5633 /* We can't always do [reg + reg] for these, because [reg +
5634 reg + offset] is not a legitimate addressing mode. */
5635 y = gen_rtx_PLUS (Pmode, op1, op2);
5637 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5638 return force_reg (Pmode, y);
5643 return force_reg (Pmode, x);
5649 && GET_CODE (x) != CONST_INT
5650 && GET_CODE (x) != CONST_DOUBLE
5652 && GET_MODE_NUNITS (mode) == 1
5653 && (GET_MODE_BITSIZE (mode) <= 32
5654 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5655 && (mode == DFmode || mode == DDmode))))
5657 rtx reg = gen_reg_rtx (Pmode);
5658 emit_insn (gen_elf_high (reg, x));
5659 return gen_rtx_LO_SUM (Pmode, reg, x);
5661 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5664 && ! MACHO_DYNAMIC_NO_PIC_P
5666 && GET_CODE (x) != CONST_INT
5667 && GET_CODE (x) != CONST_DOUBLE
5669 && GET_MODE_NUNITS (mode) == 1
5670 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5671 || (mode != DFmode && mode != DDmode))
5675 rtx reg = gen_reg_rtx (Pmode);
5676 emit_insn (gen_macho_high (reg, x));
5677 return gen_rtx_LO_SUM (Pmode, reg, x);
5680 && GET_CODE (x) == SYMBOL_REF
5681 && constant_pool_expr_p (x)
5682 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5684 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5685 return create_TOC_reference (x, reg);
5691 /* Debug version of rs6000_legitimize_address. */
5693 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5699 ret = rs6000_legitimize_address (x, oldx, mode);
5700 insns = get_insns ();
5706 "\nrs6000_legitimize_address: mode %s, old code %s, "
5707 "new code %s, modified\n",
5708 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5709 GET_RTX_NAME (GET_CODE (ret)));
5711 fprintf (stderr, "Original address:\n");
5714 fprintf (stderr, "oldx:\n");
5717 fprintf (stderr, "New address:\n");
5722 fprintf (stderr, "Insns added:\n");
5723 debug_rtx_list (insns, 20);
5729 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5730 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5741 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5742 We need to emit DTP-relative relocations. */
5745 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5750 fputs ("\t.long\t", file);
5753 fputs (DOUBLE_INT_ASM_OP, file);
5758 output_addr_const (file, x);
5759 fputs ("@dtprel+0x8000", file);
5762 /* In the name of slightly smaller debug output, and to cater to
5763 general assembler lossage, recognize various UNSPEC sequences
5764 and turn them back into a direct symbol reference. */
5767 rs6000_delegitimize_address (rtx orig_x)
5771 orig_x = delegitimize_mem_from_attrs (orig_x);
5776 if ((GET_CODE (x) == PLUS
5777 || GET_CODE (x) == LO_SUM)
5778 && GET_CODE (XEXP (x, 0)) == REG
5779 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5780 || TARGET_MINIMAL_TOC
5781 || TARGET_CMODEL != CMODEL_SMALL)
5782 && GET_CODE (XEXP (x, 1)) == CONST)
5784 y = XEXP (XEXP (x, 1), 0);
5785 if (GET_CODE (y) == UNSPEC
5786 && XINT (y, 1) == UNSPEC_TOCREL)
5788 y = XVECEXP (y, 0, 0);
5789 if (!MEM_P (orig_x))
5792 return replace_equiv_address_nv (orig_x, y);
5797 && GET_CODE (orig_x) == LO_SUM
5798 && GET_CODE (XEXP (x, 1)) == CONST)
5800 y = XEXP (XEXP (x, 1), 0);
5801 if (GET_CODE (y) == UNSPEC
5802 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5803 return XVECEXP (y, 0, 0);
5809 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5811 static GTY(()) rtx rs6000_tls_symbol;
5813 rs6000_tls_get_addr (void)
5815 if (!rs6000_tls_symbol)
5816 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5818 return rs6000_tls_symbol;
5821 /* Construct the SYMBOL_REF for TLS GOT references. */
5823 static GTY(()) rtx rs6000_got_symbol;
5825 rs6000_got_sym (void)
5827 if (!rs6000_got_symbol)
5829 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5830 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5831 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5834 return rs6000_got_symbol;
5837 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5838 this (thread-local) address. */
5841 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5845 dest = gen_reg_rtx (Pmode);
5846 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5852 tlsreg = gen_rtx_REG (Pmode, 13);
5853 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5857 tlsreg = gen_rtx_REG (Pmode, 2);
5858 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5862 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5866 tmp = gen_reg_rtx (Pmode);
5869 tlsreg = gen_rtx_REG (Pmode, 13);
5870 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5874 tlsreg = gen_rtx_REG (Pmode, 2);
5875 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5879 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5881 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5886 rtx r3, got, tga, tmp1, tmp2, call_insn;
5888 /* We currently use relocations like @got@tlsgd for tls, which
5889 means the linker will handle allocation of tls entries, placing
5890 them in the .got section. So use a pointer to the .got section,
5891 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5892 or to secondary GOT sections used by 32-bit -fPIC. */
5894 got = gen_rtx_REG (Pmode, 2);
5898 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5901 rtx gsym = rs6000_got_sym ();
5902 got = gen_reg_rtx (Pmode);
5904 rs6000_emit_move (got, gsym, Pmode);
5909 tmp1 = gen_reg_rtx (Pmode);
5910 tmp2 = gen_reg_rtx (Pmode);
5911 mem = gen_const_mem (Pmode, tmp1);
5912 lab = gen_label_rtx ();
5913 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5914 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5915 emit_move_insn (tmp2, mem);
5916 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5917 set_unique_reg_note (last, REG_EQUAL, gsym);
5922 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5924 r3 = gen_rtx_REG (Pmode, 3);
5925 tga = rs6000_tls_get_addr ();
5926 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
5928 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5929 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5930 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5931 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5932 else if (DEFAULT_ABI == ABI_V4)
5933 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5936 call_insn = last_call_insn ();
5937 PATTERN (call_insn) = insn;
5938 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5939 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5940 pic_offset_table_rtx);
5942 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5944 r3 = gen_rtx_REG (Pmode, 3);
5945 tga = rs6000_tls_get_addr ();
5946 tmp1 = gen_reg_rtx (Pmode);
5947 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
5949 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5950 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5951 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5952 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5953 else if (DEFAULT_ABI == ABI_V4)
5954 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5957 call_insn = last_call_insn ();
5958 PATTERN (call_insn) = insn;
5959 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5960 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5961 pic_offset_table_rtx);
5963 if (rs6000_tls_size == 16)
5966 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5968 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5970 else if (rs6000_tls_size == 32)
5972 tmp2 = gen_reg_rtx (Pmode);
5974 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5976 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5979 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5981 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5985 tmp2 = gen_reg_rtx (Pmode);
5987 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5989 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5991 insn = gen_rtx_SET (Pmode, dest,
5992 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5998 /* IE, or 64-bit offset LE. */
5999 tmp2 = gen_reg_rtx (Pmode);
6001 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6003 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6006 insn = gen_tls_tls_64 (dest, tmp2, addr);
6008 insn = gen_tls_tls_32 (dest, tmp2, addr);
6016 /* Return 1 if X contains a thread-local symbol. */
6019 rs6000_tls_referenced_p (rtx x)
6021 if (! TARGET_HAVE_TLS)
6024 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6027 /* Return 1 if *X is a thread-local symbol. This is the same as
6028 rs6000_tls_symbol_ref except for the type of the unused argument. */
6031 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6033 return RS6000_SYMBOL_REF_TLS_P (*x);
6036 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6037 replace the input X, or the original X if no replacement is called for.
6038 The output parameter *WIN is 1 if the calling macro should goto WIN,
6041 For RS/6000, we wish to handle large displacements off a base
6042 register by splitting the addend across an addiu/addis and the mem insn.
6043 This cuts number of extra insns needed from 3 to 1.
6045 On Darwin, we use this to generate code for floating point constants.
6046 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6047 The Darwin code is inside #if TARGET_MACHO because only then are the
6048 machopic_* functions defined. */
6050 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6051 int opnum, int type,
6052 int ind_levels ATTRIBUTE_UNUSED, int *win)
6054 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6056 /* We must recognize output that we have already generated ourselves. */
6057 if (GET_CODE (x) == PLUS
6058 && GET_CODE (XEXP (x, 0)) == PLUS
6059 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6060 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6061 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6063 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6064 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6065 opnum, (enum reload_type)type);
6070 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6071 if (GET_CODE (x) == LO_SUM
6072 && GET_CODE (XEXP (x, 0)) == HIGH)
6074 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6075 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6076 opnum, (enum reload_type)type);
6082 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6083 && GET_CODE (x) == LO_SUM
6084 && GET_CODE (XEXP (x, 0)) == PLUS
6085 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6086 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6087 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6088 && machopic_operand_p (XEXP (x, 1)))
6090 /* Result of previous invocation of this function on Darwin
6091 floating point constant. */
6092 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6093 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6094 opnum, (enum reload_type)type);
6100 if (TARGET_CMODEL != CMODEL_SMALL
6101 && GET_CODE (x) == LO_SUM
6102 && GET_CODE (XEXP (x, 0)) == PLUS
6103 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6104 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6105 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6106 && GET_CODE (XEXP (x, 1)) == CONST
6107 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6108 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6109 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6111 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6112 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6113 opnum, (enum reload_type) type);
6118 /* Force ld/std non-word aligned offset into base register by wrapping
6120 if (GET_CODE (x) == PLUS
6121 && GET_CODE (XEXP (x, 0)) == REG
6122 && REGNO (XEXP (x, 0)) < 32
6123 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6124 && GET_CODE (XEXP (x, 1)) == CONST_INT
6126 && (INTVAL (XEXP (x, 1)) & 3) != 0
6127 && VECTOR_MEM_NONE_P (mode)
6128 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6129 && TARGET_POWERPC64)
6131 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6132 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6133 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6134 opnum, (enum reload_type) type);
6139 if (GET_CODE (x) == PLUS
6140 && GET_CODE (XEXP (x, 0)) == REG
6141 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6142 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6143 && GET_CODE (XEXP (x, 1)) == CONST_INT
6145 && !SPE_VECTOR_MODE (mode)
6146 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6147 || mode == DDmode || mode == TDmode
6149 && VECTOR_MEM_NONE_P (mode))
6151 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6152 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6154 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6156 /* Check for 32-bit overflow. */
6157 if (high + low != val)
6163 /* Reload the high part into a base reg; leave the low part
6164 in the mem directly. */
6166 x = gen_rtx_PLUS (GET_MODE (x),
6167 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6171 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6172 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6173 opnum, (enum reload_type)type);
6178 if (GET_CODE (x) == SYMBOL_REF
6180 && VECTOR_MEM_NONE_P (mode)
6181 && !SPE_VECTOR_MODE (mode)
6183 && DEFAULT_ABI == ABI_DARWIN
6184 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6186 && DEFAULT_ABI == ABI_V4
6189 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6190 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6194 && (mode != DImode || TARGET_POWERPC64)
6195 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6196 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6201 rtx offset = machopic_gen_offset (x);
6202 x = gen_rtx_LO_SUM (GET_MODE (x),
6203 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6204 gen_rtx_HIGH (Pmode, offset)), offset);
6208 x = gen_rtx_LO_SUM (GET_MODE (x),
6209 gen_rtx_HIGH (Pmode, x), x);
6211 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6212 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6213 opnum, (enum reload_type)type);
6218 /* Reload an offset address wrapped by an AND that represents the
6219 masking of the lower bits. Strip the outer AND and let reload
6220 convert the offset address into an indirect address. For VSX,
6221 force reload to create the address with an AND in a separate
6222 register, because we can't guarantee an altivec register will
6224 if (VECTOR_MEM_ALTIVEC_P (mode)
6225 && GET_CODE (x) == AND
6226 && GET_CODE (XEXP (x, 0)) == PLUS
6227 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6228 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6229 && GET_CODE (XEXP (x, 1)) == CONST_INT
6230 && INTVAL (XEXP (x, 1)) == -16)
6239 && GET_CODE (x) == SYMBOL_REF
6240 && constant_pool_expr_p (x)
6241 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6243 x = create_TOC_reference (x, NULL_RTX);
6244 if (TARGET_CMODEL != CMODEL_SMALL)
6245 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6246 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6247 opnum, (enum reload_type) type);
6255 /* Debug version of rs6000_legitimize_reload_address. */
6257 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6258 int opnum, int type,
6259 int ind_levels, int *win)
6261 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6264 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6265 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6266 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6270 fprintf (stderr, "Same address returned\n");
6272 fprintf (stderr, "NULL returned\n");
6275 fprintf (stderr, "New address:\n");
6282 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6283 that is a valid memory address for an instruction.
6284 The MODE argument is the machine mode for the MEM expression
6285 that wants to use this address.
6287 On the RS/6000, there are four valid address: a SYMBOL_REF that
6288 refers to a constant pool entry of an address (or the sum of it
6289 plus a constant), a short (16-bit signed) constant plus a register,
6290 the sum of two registers, or a register indirect, possibly with an
6291 auto-increment. For DFmode, DDmode and DImode with a constant plus
6292 register, we must ensure that both words are addressable or PowerPC64
6293 with offset word aligned.
6295 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6296 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6297 because adjacent memory cells are accessed by adding word-sized offsets
6298 during assembly output. */
6300 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6302 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6304 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6305 if (VECTOR_MEM_ALTIVEC_P (mode)
6306 && GET_CODE (x) == AND
6307 && GET_CODE (XEXP (x, 1)) == CONST_INT
6308 && INTVAL (XEXP (x, 1)) == -16)
6311 if (RS6000_SYMBOL_REF_TLS_P (x))
6313 if (legitimate_indirect_address_p (x, reg_ok_strict))
6315 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6316 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6317 && !SPE_VECTOR_MODE (mode)
6320 /* Restrict addressing for DI because of our SUBREG hackery. */
6321 && !(TARGET_E500_DOUBLE
6322 && (mode == DFmode || mode == DDmode || mode == DImode))
6324 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6326 if (virtual_stack_registers_memory_p (x))
6328 if (reg_offset_p && legitimate_small_data_p (mode, x))
6330 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6332 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6335 && GET_CODE (x) == PLUS
6336 && GET_CODE (XEXP (x, 0)) == REG
6337 && (XEXP (x, 0) == virtual_stack_vars_rtx
6338 || XEXP (x, 0) == arg_pointer_rtx)
6339 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6341 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6346 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6348 || (mode != DFmode && mode != DDmode)
6349 || (TARGET_E500_DOUBLE && mode != DDmode))
6350 && (TARGET_POWERPC64 || mode != DImode)
6351 && !avoiding_indexed_address_p (mode)
6352 && legitimate_indexed_address_p (x, reg_ok_strict))
6354 if (GET_CODE (x) == PRE_MODIFY
6358 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6360 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6361 && (TARGET_POWERPC64 || mode != DImode)
6362 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6363 && !SPE_VECTOR_MODE (mode)
6364 /* Restrict addressing for DI because of our SUBREG hackery. */
6365 && !(TARGET_E500_DOUBLE
6366 && (mode == DFmode || mode == DDmode || mode == DImode))
6368 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6369 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6370 || (!avoiding_indexed_address_p (mode)
6371 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6372 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6374 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6379 /* Debug version of rs6000_legitimate_address_p. */
6381 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6384 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6386 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6387 "strict = %d, code = %s\n",
6388 ret ? "true" : "false",
6389 GET_MODE_NAME (mode),
6391 GET_RTX_NAME (GET_CODE (x)));
6397 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6400 rs6000_mode_dependent_address_p (const_rtx addr)
6402 return rs6000_mode_dependent_address_ptr (addr);
6405 /* Go to LABEL if ADDR (a legitimate address expression)
6406 has an effect that depends on the machine mode it is used for.
6408 On the RS/6000 this is true of all integral offsets (since AltiVec
6409 and VSX modes don't allow them) or is a pre-increment or decrement.
6411 ??? Except that due to conceptual problems in offsettable_address_p
6412 we can't really report the problems of integral offsets. So leave
6413 this assuming that the adjustable offset must be valid for the
6414 sub-words of a TFmode operand, which is what we had before. */
6417 rs6000_mode_dependent_address (const_rtx addr)
6419 switch (GET_CODE (addr))
6422 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6423 is considered a legitimate address before reload, so there
6424 are no offset restrictions in that case. Note that this
6425 condition is safe in strict mode because any address involving
6426 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6427 been rejected as illegitimate. */
6428 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6429 && XEXP (addr, 0) != arg_pointer_rtx
6430 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6432 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6433 return val + 12 + 0x8000 >= 0x10000;
6438 /* Anything in the constant pool is sufficiently aligned that
6439 all bytes have the same high part address. */
6440 return !legitimate_constant_pool_address_p (addr, false);
6442 /* Auto-increment cases are now treated generically in recog.c. */
6444 return TARGET_UPDATE;
6446 /* AND is only allowed in Altivec loads. */
6457 /* Debug version of rs6000_mode_dependent_address. */
6459 rs6000_debug_mode_dependent_address (const_rtx addr)
6461 bool ret = rs6000_mode_dependent_address (addr);
6463 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6464 ret ? "true" : "false");
6470 /* Implement FIND_BASE_TERM. */
6473 rs6000_find_base_term (rtx op)
6477 split_const (op, &base, &offset);
6478 if (GET_CODE (base) == UNSPEC)
6479 switch (XINT (base, 1))
6482 case UNSPEC_MACHOPIC_OFFSET:
6483 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6484 for aliasing purposes. */
6485 return XVECEXP (base, 0, 0);
6491 /* More elaborate version of recog's offsettable_memref_p predicate
6492 that works around the ??? note of rs6000_mode_dependent_address.
6493 In particular it accepts
6495 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6497 in 32-bit mode, that the recog predicate rejects. */
6500 rs6000_offsettable_memref_p (rtx op)
6505 /* First mimic offsettable_memref_p. */
6506 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6509 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6510 the latter predicate knows nothing about the mode of the memory
6511 reference and, therefore, assumes that it is the largest supported
6512 mode (TFmode). As a consequence, legitimate offsettable memory
6513 references are rejected. rs6000_legitimate_offset_address_p contains
6514 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6515 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6518 /* Change register usage conditional on target flags. */
6520 rs6000_conditional_register_usage (void)
6524 /* Set MQ register fixed (already call_used) if not POWER
6525 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6530 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6532 fixed_regs[13] = call_used_regs[13]
6533 = call_really_used_regs[13] = 1;
6535 /* Conditionally disable FPRs. */
6536 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6537 for (i = 32; i < 64; i++)
6538 fixed_regs[i] = call_used_regs[i]
6539 = call_really_used_regs[i] = 1;
6541 /* The TOC register is not killed across calls in a way that is
6542 visible to the compiler. */
6543 if (DEFAULT_ABI == ABI_AIX)
6544 call_really_used_regs[2] = 0;
6546 if (DEFAULT_ABI == ABI_V4
6547 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6549 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6551 if (DEFAULT_ABI == ABI_V4
6552 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6554 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6555 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6556 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6558 if (DEFAULT_ABI == ABI_DARWIN
6559 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6560 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6561 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6562 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6564 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6565 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6566 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6570 global_regs[SPEFSCR_REGNO] = 1;
6571 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6572 registers in prologues and epilogues. We no longer use r14
6573 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6574 pool for link-compatibility with older versions of GCC. Once
6575 "old" code has died out, we can return r14 to the allocation
6578 = call_used_regs[14]
6579 = call_really_used_regs[14] = 1;
6582 if (!TARGET_ALTIVEC && !TARGET_VSX)
6584 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6585 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6586 call_really_used_regs[VRSAVE_REGNO] = 1;
6589 if (TARGET_ALTIVEC || TARGET_VSX)
6590 global_regs[VSCR_REGNO] = 1;
6592 if (TARGET_ALTIVEC_ABI)
6594 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6595 call_used_regs[i] = call_really_used_regs[i] = 1;
6597 /* AIX reserves VR20:31 in non-extended ABI mode. */
6599 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6600 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6604 /* Try to output insns to set TARGET equal to the constant C if it can
6605 be done in less than N insns. Do all computations in MODE.
6606 Returns the place where the output has been placed if it can be
6607 done and the insns have been emitted. If it would take more than N
6608 insns, zero is returned and no insns and emitted. */
6611 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6612 rtx source, int n ATTRIBUTE_UNUSED)
6614 rtx result, insn, set;
6615 HOST_WIDE_INT c0, c1;
6622 dest = gen_reg_rtx (mode);
6623 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6627 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6629 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6630 GEN_INT (INTVAL (source)
6631 & (~ (HOST_WIDE_INT) 0xffff))));
6632 emit_insn (gen_rtx_SET (VOIDmode, dest,
6633 gen_rtx_IOR (SImode, copy_rtx (result),
6634 GEN_INT (INTVAL (source) & 0xffff))));
6639 switch (GET_CODE (source))
6642 c0 = INTVAL (source);
6647 #if HOST_BITS_PER_WIDE_INT >= 64
6648 c0 = CONST_DOUBLE_LOW (source);
6651 c0 = CONST_DOUBLE_LOW (source);
6652 c1 = CONST_DOUBLE_HIGH (source);
6660 result = rs6000_emit_set_long_const (dest, c0, c1);
6667 insn = get_last_insn ();
6668 set = single_set (insn);
6669 if (! CONSTANT_P (SET_SRC (set)))
6670 set_unique_reg_note (insn, REG_EQUAL, source);
6675 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6676 fall back to a straight forward decomposition. We do this to avoid
6677 exponential run times encountered when looking for longer sequences
6678 with rs6000_emit_set_const. */
6680 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6682 if (!TARGET_POWERPC64)
6684 rtx operand1, operand2;
6686 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6688 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6690 emit_move_insn (operand1, GEN_INT (c1));
6691 emit_move_insn (operand2, GEN_INT (c2));
6695 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6698 ud2 = (c1 & 0xffff0000) >> 16;
6699 #if HOST_BITS_PER_WIDE_INT >= 64
6703 ud4 = (c2 & 0xffff0000) >> 16;
6705 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6706 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6709 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6711 emit_move_insn (dest, GEN_INT (ud1));
6714 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6715 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6718 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6721 emit_move_insn (dest, GEN_INT (ud2 << 16));
6723 emit_move_insn (copy_rtx (dest),
6724 gen_rtx_IOR (DImode, copy_rtx (dest),
6727 else if (ud3 == 0 && ud4 == 0)
6729 gcc_assert (ud2 & 0x8000);
6730 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6733 emit_move_insn (copy_rtx (dest),
6734 gen_rtx_IOR (DImode, copy_rtx (dest),
6736 emit_move_insn (copy_rtx (dest),
6737 gen_rtx_ZERO_EXTEND (DImode,
6738 gen_lowpart (SImode,
6741 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6742 || (ud4 == 0 && ! (ud3 & 0x8000)))
6745 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6748 emit_move_insn (dest, GEN_INT (ud3 << 16));
6751 emit_move_insn (copy_rtx (dest),
6752 gen_rtx_IOR (DImode, copy_rtx (dest),
6754 emit_move_insn (copy_rtx (dest),
6755 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6758 emit_move_insn (copy_rtx (dest),
6759 gen_rtx_IOR (DImode, copy_rtx (dest),
6765 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6768 emit_move_insn (dest, GEN_INT (ud4 << 16));
6771 emit_move_insn (copy_rtx (dest),
6772 gen_rtx_IOR (DImode, copy_rtx (dest),
6775 emit_move_insn (copy_rtx (dest),
6776 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6779 emit_move_insn (copy_rtx (dest),
6780 gen_rtx_IOR (DImode, copy_rtx (dest),
6781 GEN_INT (ud2 << 16)));
6783 emit_move_insn (copy_rtx (dest),
6784 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6790 /* Helper for the following. Get rid of [r+r] memory refs
6791 in cases where it won't work (TImode, TFmode, TDmode). */
6794 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6796 if (reload_in_progress)
6799 if (GET_CODE (operands[0]) == MEM
6800 && GET_CODE (XEXP (operands[0], 0)) != REG
6801 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
6803 = replace_equiv_address (operands[0],
6804 copy_addr_to_reg (XEXP (operands[0], 0)));
6806 if (GET_CODE (operands[1]) == MEM
6807 && GET_CODE (XEXP (operands[1], 0)) != REG
6808 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
6810 = replace_equiv_address (operands[1],
6811 copy_addr_to_reg (XEXP (operands[1], 0)));
6814 /* Emit a move from SOURCE to DEST in mode MODE. */
6816 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6820 operands[1] = source;
6822 if (TARGET_DEBUG_ADDR)
6825 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6826 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6827 GET_MODE_NAME (mode),
6830 can_create_pseudo_p ());
6832 fprintf (stderr, "source:\n");
6836 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6837 if (GET_CODE (operands[1]) == CONST_DOUBLE
6838 && ! FLOAT_MODE_P (mode)
6839 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6841 /* FIXME. This should never happen. */
6842 /* Since it seems that it does, do the safe thing and convert
6844 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6846 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6847 || FLOAT_MODE_P (mode)
6848 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6849 || CONST_DOUBLE_LOW (operands[1]) < 0)
6850 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6851 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6853 /* Check if GCC is setting up a block move that will end up using FP
6854 registers as temporaries. We must make sure this is acceptable. */
6855 if (GET_CODE (operands[0]) == MEM
6856 && GET_CODE (operands[1]) == MEM
6858 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6859 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6860 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6861 ? 32 : MEM_ALIGN (operands[0])))
6862 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6864 : MEM_ALIGN (operands[1]))))
6865 && ! MEM_VOLATILE_P (operands [0])
6866 && ! MEM_VOLATILE_P (operands [1]))
6868 emit_move_insn (adjust_address (operands[0], SImode, 0),
6869 adjust_address (operands[1], SImode, 0));
6870 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6871 adjust_address (copy_rtx (operands[1]), SImode, 4));
6875 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6876 && !gpc_reg_operand (operands[1], mode))
6877 operands[1] = force_reg (mode, operands[1]);
6879 if (mode == SFmode && ! TARGET_POWERPC
6880 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6881 && GET_CODE (operands[0]) == MEM)
6885 if (reload_in_progress || reload_completed)
6886 regnum = true_regnum (operands[1]);
6887 else if (GET_CODE (operands[1]) == REG)
6888 regnum = REGNO (operands[1]);
6892 /* If operands[1] is a register, on POWER it may have
6893 double-precision data in it, so truncate it to single
6895 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6898 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6899 : gen_reg_rtx (mode));
6900 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6901 operands[1] = newreg;
6905 /* Recognize the case where operand[1] is a reference to thread-local
6906 data and load its address to a register. */
6907 if (rs6000_tls_referenced_p (operands[1]))
6909 enum tls_model model;
6910 rtx tmp = operands[1];
6913 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6915 addend = XEXP (XEXP (tmp, 0), 1);
6916 tmp = XEXP (XEXP (tmp, 0), 0);
6919 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6920 model = SYMBOL_REF_TLS_MODEL (tmp);
6921 gcc_assert (model != 0);
6923 tmp = rs6000_legitimize_tls_address (tmp, model);
6926 tmp = gen_rtx_PLUS (mode, tmp, addend);
6927 tmp = force_operand (tmp, operands[0]);
6932 /* Handle the case where reload calls us with an invalid address. */
6933 if (reload_in_progress && mode == Pmode
6934 && (! general_operand (operands[1], mode)
6935 || ! nonimmediate_operand (operands[0], mode)))
6938 /* 128-bit constant floating-point values on Darwin should really be
6939 loaded as two parts. */
6940 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6941 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6943 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6944 know how to get a DFmode SUBREG of a TFmode. */
6945 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6946 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6947 simplify_gen_subreg (imode, operands[1], mode, 0),
6949 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6950 GET_MODE_SIZE (imode)),
6951 simplify_gen_subreg (imode, operands[1], mode,
6952 GET_MODE_SIZE (imode)),
6957 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6958 cfun->machine->sdmode_stack_slot =
6959 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6961 if (reload_in_progress
6963 && MEM_P (operands[0])
6964 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6965 && REG_P (operands[1]))
6967 if (FP_REGNO_P (REGNO (operands[1])))
6969 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6970 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6971 emit_insn (gen_movsd_store (mem, operands[1]));
6973 else if (INT_REGNO_P (REGNO (operands[1])))
6975 rtx mem = adjust_address_nv (operands[0], mode, 4);
6976 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6977 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6983 if (reload_in_progress
6985 && REG_P (operands[0])
6986 && MEM_P (operands[1])
6987 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6989 if (FP_REGNO_P (REGNO (operands[0])))
6991 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6992 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6993 emit_insn (gen_movsd_load (operands[0], mem));
6995 else if (INT_REGNO_P (REGNO (operands[0])))
6997 rtx mem = adjust_address_nv (operands[1], mode, 4);
6998 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6999 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7006 /* FIXME: In the long term, this switch statement should go away
7007 and be replaced by a sequence of tests based on things like
7013 if (CONSTANT_P (operands[1])
7014 && GET_CODE (operands[1]) != CONST_INT)
7015 operands[1] = force_const_mem (mode, operands[1]);
7020 rs6000_eliminate_indexed_memrefs (operands);
7027 if (CONSTANT_P (operands[1])
7028 && ! easy_fp_constant (operands[1], mode))
7029 operands[1] = force_const_mem (mode, operands[1]);
7042 if (CONSTANT_P (operands[1])
7043 && !easy_vector_constant (operands[1], mode))
7044 operands[1] = force_const_mem (mode, operands[1]);
7049 /* Use default pattern for address of ELF small data */
7052 && DEFAULT_ABI == ABI_V4
7053 && (GET_CODE (operands[1]) == SYMBOL_REF
7054 || GET_CODE (operands[1]) == CONST)
7055 && small_data_operand (operands[1], mode))
7057 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7061 if (DEFAULT_ABI == ABI_V4
7062 && mode == Pmode && mode == SImode
7063 && flag_pic == 1 && got_operand (operands[1], mode))
7065 emit_insn (gen_movsi_got (operands[0], operands[1]));
7069 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7073 && CONSTANT_P (operands[1])
7074 && GET_CODE (operands[1]) != HIGH
7075 && GET_CODE (operands[1]) != CONST_INT)
7077 rtx target = (!can_create_pseudo_p ()
7079 : gen_reg_rtx (mode));
7081 /* If this is a function address on -mcall-aixdesc,
7082 convert it to the address of the descriptor. */
7083 if (DEFAULT_ABI == ABI_AIX
7084 && GET_CODE (operands[1]) == SYMBOL_REF
7085 && XSTR (operands[1], 0)[0] == '.')
7087 const char *name = XSTR (operands[1], 0);
7089 while (*name == '.')
7091 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7092 CONSTANT_POOL_ADDRESS_P (new_ref)
7093 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7094 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7095 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7096 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7097 operands[1] = new_ref;
7100 if (DEFAULT_ABI == ABI_DARWIN)
7103 if (MACHO_DYNAMIC_NO_PIC_P)
7105 /* Take care of any required data indirection. */
7106 operands[1] = rs6000_machopic_legitimize_pic_address (
7107 operands[1], mode, operands[0]);
7108 if (operands[0] != operands[1])
7109 emit_insn (gen_rtx_SET (VOIDmode,
7110 operands[0], operands[1]));
7114 emit_insn (gen_macho_high (target, operands[1]));
7115 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7119 emit_insn (gen_elf_high (target, operands[1]));
7120 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7124 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7125 and we have put it in the TOC, we just need to make a TOC-relative
7128 && GET_CODE (operands[1]) == SYMBOL_REF
7129 && constant_pool_expr_p (operands[1])
7130 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7131 get_pool_mode (operands[1])))
7134 if (TARGET_CMODEL != CMODEL_SMALL)
7136 if (can_create_pseudo_p ())
7137 reg = gen_reg_rtx (Pmode);
7141 operands[1] = create_TOC_reference (operands[1], reg);
7143 else if (mode == Pmode
7144 && CONSTANT_P (operands[1])
7145 && ((GET_CODE (operands[1]) != CONST_INT
7146 && ! easy_fp_constant (operands[1], mode))
7147 || (GET_CODE (operands[1]) == CONST_INT
7148 && (num_insns_constant (operands[1], mode)
7149 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7150 || (GET_CODE (operands[0]) == REG
7151 && FP_REGNO_P (REGNO (operands[0]))))
7152 && GET_CODE (operands[1]) != HIGH
7153 && ! legitimate_constant_pool_address_p (operands[1], false)
7154 && ! toc_relative_expr_p (operands[1])
7155 && (TARGET_CMODEL == CMODEL_SMALL
7156 || can_create_pseudo_p ()
7157 || (REG_P (operands[0])
7158 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7162 /* Darwin uses a special PIC legitimizer. */
7163 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7166 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7168 if (operands[0] != operands[1])
7169 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7174 /* If we are to limit the number of things we put in the TOC and
7175 this is a symbol plus a constant we can add in one insn,
7176 just put the symbol in the TOC and add the constant. Don't do
7177 this if reload is in progress. */
7178 if (GET_CODE (operands[1]) == CONST
7179 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7180 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7181 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7182 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7183 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7184 && ! side_effects_p (operands[0]))
7187 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7188 rtx other = XEXP (XEXP (operands[1], 0), 1);
7190 sym = force_reg (mode, sym);
7191 emit_insn (gen_add3_insn (operands[0], sym, other));
7195 operands[1] = force_const_mem (mode, operands[1]);
7198 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7199 && constant_pool_expr_p (XEXP (operands[1], 0))
7200 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7201 get_pool_constant (XEXP (operands[1], 0)),
7202 get_pool_mode (XEXP (operands[1], 0))))
7206 if (TARGET_CMODEL != CMODEL_SMALL)
7208 if (can_create_pseudo_p ())
7209 reg = gen_reg_rtx (Pmode);
7213 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7214 operands[1] = gen_const_mem (mode, tocref);
7215 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7221 rs6000_eliminate_indexed_memrefs (operands);
7225 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7227 gen_rtx_SET (VOIDmode,
7228 operands[0], operands[1]),
7229 gen_rtx_CLOBBER (VOIDmode,
7230 gen_rtx_SCRATCH (SImode)))));
7236 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7239 /* Above, we may have called force_const_mem which may have returned
7240 an invalid address. If we can, fix this up; otherwise, reload will
7241 have to deal with it. */
7242 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7243 operands[1] = validize_mem (operands[1]);
7246 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7249 /* Nonzero if we can use a floating-point register to pass this arg. */
7250 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7251 (SCALAR_FLOAT_MODE_P (MODE) \
7252 && (CUM)->fregno <= FP_ARG_MAX_REG \
7253 && TARGET_HARD_FLOAT && TARGET_FPRS)
7255 /* Nonzero if we can use an AltiVec register to pass this arg. */
7256 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7257 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7258 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7259 && TARGET_ALTIVEC_ABI \
7262 /* Return a nonzero value to say to return the function value in
7263 memory, just as large structures are always returned. TYPE will be
7264 the data type of the value, and FNTYPE will be the type of the
7265 function doing the returning, or @code{NULL} for libcalls.
7267 The AIX ABI for the RS/6000 specifies that all structures are
7268 returned in memory. The Darwin ABI does the same.
7270 For the Darwin 64 Bit ABI, a function result can be returned in
7271 registers or in memory, depending on the size of the return data
7272 type. If it is returned in registers, the value occupies the same
7273 registers as it would if it were the first and only function
7274 argument. Otherwise, the function places its result in memory at
7275 the location pointed to by GPR3.
7277 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7278 but a draft put them in memory, and GCC used to implement the draft
7279 instead of the final standard. Therefore, aix_struct_return
7280 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7281 compatibility can change DRAFT_V4_STRUCT_RET to override the
7282 default, and -m switches get the final word. See
7283 rs6000_override_options for more details.
7285 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7286 long double support is enabled. These values are returned in memory.
7288 int_size_in_bytes returns -1 for variable size objects, which go in
7289 memory always. The cast to unsigned makes -1 > 8. */
7292 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7294 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7296 && rs6000_darwin64_abi
7297 && TREE_CODE (type) == RECORD_TYPE
7298 && int_size_in_bytes (type) > 0)
7300 CUMULATIVE_ARGS valcum;
7304 valcum.fregno = FP_ARG_MIN_REG;
7305 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7306 /* Do a trial code generation as if this were going to be passed
7307 as an argument; if any part goes in memory, we return NULL. */
7308 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
7311 /* Otherwise fall through to more conventional ABI rules. */
7314 if (AGGREGATE_TYPE_P (type)
7315 && (aix_struct_return
7316 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7319 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7320 modes only exist for GCC vector types if -maltivec. */
7321 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7322 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7325 /* Return synthetic vectors in memory. */
7326 if (TREE_CODE (type) == VECTOR_TYPE
7327 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7329 static bool warned_for_return_big_vectors = false;
7330 if (!warned_for_return_big_vectors)
7332 warning (0, "GCC vector returned by reference: "
7333 "non-standard ABI extension with no compatibility guarantee");
7334 warned_for_return_big_vectors = true;
7339 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7345 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7346 for a call to a function whose data type is FNTYPE.
7347 For a library call, FNTYPE is 0.
7349 For incoming args we set the number of arguments in the prototype large
7350 so we never return a PARALLEL. */
7353 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7354 rtx libname ATTRIBUTE_UNUSED, int incoming,
7355 int libcall, int n_named_args)
7357 static CUMULATIVE_ARGS zero_cumulative;
7359 *cum = zero_cumulative;
7361 cum->fregno = FP_ARG_MIN_REG;
7362 cum->vregno = ALTIVEC_ARG_MIN_REG;
7363 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7364 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7365 ? CALL_LIBCALL : CALL_NORMAL);
7366 cum->sysv_gregno = GP_ARG_MIN_REG;
7367 cum->stdarg = fntype
7368 && (TYPE_ARG_TYPES (fntype) != 0
7369 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
7370 != void_type_node));
7372 cum->nargs_prototype = 0;
7373 if (incoming || cum->prototype)
7374 cum->nargs_prototype = n_named_args;
7376 /* Check for a longcall attribute. */
7377 if ((!fntype && rs6000_default_long_calls)
7379 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7380 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7381 cum->call_cookie |= CALL_LONG;
7383 if (TARGET_DEBUG_ARG)
7385 fprintf (stderr, "\ninit_cumulative_args:");
7388 tree ret_type = TREE_TYPE (fntype);
7389 fprintf (stderr, " ret code = %s,",
7390 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7393 if (cum->call_cookie & CALL_LONG)
7394 fprintf (stderr, " longcall,");
7396 fprintf (stderr, " proto = %d, nargs = %d\n",
7397 cum->prototype, cum->nargs_prototype);
7402 && TARGET_ALTIVEC_ABI
7403 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7405 error ("cannot return value in vector register because"
7406 " altivec instructions are disabled, use -maltivec"
7411 /* Return true if TYPE must be passed on the stack and not in registers. */
7414 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7416 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7417 return must_pass_in_stack_var_size (mode, type);
7419 return must_pass_in_stack_var_size_or_pad (mode, type);
7422 /* If defined, a C expression which determines whether, and in which
7423 direction, to pad out an argument with extra space. The value
7424 should be of type `enum direction': either `upward' to pad above
7425 the argument, `downward' to pad below, or `none' to inhibit
7428 For the AIX ABI structs are always stored left shifted in their
7432 function_arg_padding (enum machine_mode mode, const_tree type)
7434 #ifndef AGGREGATE_PADDING_FIXED
7435 #define AGGREGATE_PADDING_FIXED 0
7437 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7438 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7441 if (!AGGREGATE_PADDING_FIXED)
7443 /* GCC used to pass structures of the same size as integer types as
7444 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7445 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7446 passed padded downward, except that -mstrict-align further
7447 muddied the water in that multi-component structures of 2 and 4
7448 bytes in size were passed padded upward.
7450 The following arranges for best compatibility with previous
7451 versions of gcc, but removes the -mstrict-align dependency. */
7452 if (BYTES_BIG_ENDIAN)
7454 HOST_WIDE_INT size = 0;
7456 if (mode == BLKmode)
7458 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7459 size = int_size_in_bytes (type);
7462 size = GET_MODE_SIZE (mode);
7464 if (size == 1 || size == 2 || size == 4)
7470 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7472 if (type != 0 && AGGREGATE_TYPE_P (type))
7476 /* Fall back to the default. */
7477 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7480 /* If defined, a C expression that gives the alignment boundary, in bits,
7481 of an argument with the specified mode and type. If it is not defined,
7482 PARM_BOUNDARY is used for all arguments.
7484 V.4 wants long longs and doubles to be double word aligned. Just
7485 testing the mode size is a boneheaded way to do this as it means
7486 that other types such as complex int are also double word aligned.
7487 However, we're stuck with this because changing the ABI might break
7488 existing library interfaces.
7490 Doubleword align SPE vectors.
7491 Quadword align Altivec vectors.
7492 Quadword align large synthetic vector types. */
7495 function_arg_boundary (enum machine_mode mode, tree type)
7497 if (DEFAULT_ABI == ABI_V4
7498 && (GET_MODE_SIZE (mode) == 8
7499 || (TARGET_HARD_FLOAT
7501 && (mode == TFmode || mode == TDmode))))
7503 else if (SPE_VECTOR_MODE (mode)
7504 || (type && TREE_CODE (type) == VECTOR_TYPE
7505 && int_size_in_bytes (type) >= 8
7506 && int_size_in_bytes (type) < 16))
7508 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7509 || (type && TREE_CODE (type) == VECTOR_TYPE
7510 && int_size_in_bytes (type) >= 16))
7512 else if (TARGET_MACHO
7513 && rs6000_darwin64_abi
7515 && type && TYPE_ALIGN (type) > 64)
7518 return PARM_BOUNDARY;
7521 /* For a function parm of MODE and TYPE, return the starting word in
7522 the parameter area. NWORDS of the parameter area are already used. */
7525 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
7528 unsigned int parm_offset;
7530 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7531 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7532 return nwords + (-(parm_offset + nwords) & align);
7535 /* Compute the size (in words) of a function argument. */
7537 static unsigned long
7538 rs6000_arg_size (enum machine_mode mode, tree type)
7542 if (mode != BLKmode)
7543 size = GET_MODE_SIZE (mode);
7545 size = int_size_in_bytes (type);
7548 return (size + 3) >> 2;
7550 return (size + 7) >> 3;
7553 /* Use this to flush pending int fields. */
7556 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7557 HOST_WIDE_INT bitpos, int final)
7559 unsigned int startbit, endbit;
7560 int intregs, intoffset;
7561 enum machine_mode mode;
7563 /* Handle the situations where a float is taking up the first half
7564 of the GPR, and the other half is empty (typically due to
7565 alignment restrictions). We can detect this by a 8-byte-aligned
7566 int field, or by seeing that this is the final flush for this
7567 argument. Count the word and continue on. */
7568 if (cum->floats_in_gpr == 1
7569 && (cum->intoffset % 64 == 0
7570 || (cum->intoffset == -1 && final)))
7573 cum->floats_in_gpr = 0;
7576 if (cum->intoffset == -1)
7579 intoffset = cum->intoffset;
7580 cum->intoffset = -1;
7581 cum->floats_in_gpr = 0;
7583 if (intoffset % BITS_PER_WORD != 0)
7585 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7587 if (mode == BLKmode)
7589 /* We couldn't find an appropriate mode, which happens,
7590 e.g., in packed structs when there are 3 bytes to load.
7591 Back intoffset back to the beginning of the word in this
7593 intoffset = intoffset & -BITS_PER_WORD;
7597 startbit = intoffset & -BITS_PER_WORD;
7598 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7599 intregs = (endbit - startbit) / BITS_PER_WORD;
7600 cum->words += intregs;
7601 /* words should be unsigned. */
7602 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7604 int pad = (endbit/BITS_PER_WORD) - cum->words;
7609 /* The darwin64 ABI calls for us to recurse down through structs,
7610 looking for elements passed in registers. Unfortunately, we have
7611 to track int register count here also because of misalignments
7612 in powerpc alignment mode. */
7615 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7617 HOST_WIDE_INT startbitpos)
7621 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7622 if (TREE_CODE (f) == FIELD_DECL)
7624 HOST_WIDE_INT bitpos = startbitpos;
7625 tree ftype = TREE_TYPE (f);
7626 enum machine_mode mode;
7627 if (ftype == error_mark_node)
7629 mode = TYPE_MODE (ftype);
7631 if (DECL_SIZE (f) != 0
7632 && host_integerp (bit_position (f), 1))
7633 bitpos += int_bit_position (f);
7635 /* ??? FIXME: else assume zero offset. */
7637 if (TREE_CODE (ftype) == RECORD_TYPE)
7638 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7639 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7641 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7642 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7643 /* Single-precision floats present a special problem for
7644 us, because they are smaller than an 8-byte GPR, and so
7645 the structure-packing rules combined with the standard
7646 varargs behavior mean that we want to pack float/float
7647 and float/int combinations into a single register's
7648 space. This is complicated by the arg advance flushing,
7649 which works on arbitrarily large groups of int-type
7653 if (cum->floats_in_gpr == 1)
7655 /* Two floats in a word; count the word and reset
7658 cum->floats_in_gpr = 0;
7660 else if (bitpos % 64 == 0)
7662 /* A float at the beginning of an 8-byte word;
7663 count it and put off adjusting cum->words until
7664 we see if a arg advance flush is going to do it
7666 cum->floats_in_gpr++;
7670 /* The float is at the end of a word, preceded
7671 by integer fields, so the arg advance flush
7672 just above has already set cum->words and
7673 everything is taken care of. */
7677 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7679 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7681 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7685 else if (cum->intoffset == -1)
7686 cum->intoffset = bitpos;
7690 /* Check for an item that needs to be considered specially under the darwin 64
7691 bit ABI. These are record types where the mode is BLK or the structure is
7694 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7696 return rs6000_darwin64_abi
7697 && ((mode == BLKmode
7698 && TREE_CODE (type) == RECORD_TYPE
7699 && int_size_in_bytes (type) > 0)
7700 || (type && TREE_CODE (type) == RECORD_TYPE
7701 && int_size_in_bytes (type) == 8)) ? 1 : 0;
7704 /* Update the data in CUM to advance over an argument
7705 of mode MODE and data type TYPE.
7706 (TYPE is null for libcalls where that information may not be available.)
7708 Note that for args passed by reference, function_arg will be called
7709 with MODE and TYPE set to that of the pointer to the arg, not the arg
7713 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7714 tree type, int named, int depth)
7717 /* Only tick off an argument if we're not recursing. */
7719 cum->nargs_prototype--;
7721 if (TARGET_ALTIVEC_ABI
7722 && (ALTIVEC_VECTOR_MODE (mode)
7723 || VSX_VECTOR_MODE (mode)
7724 || (type && TREE_CODE (type) == VECTOR_TYPE
7725 && int_size_in_bytes (type) == 16)))
7729 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7732 if (!TARGET_ALTIVEC)
7733 error ("cannot pass argument in vector register because"
7734 " altivec instructions are disabled, use -maltivec"
7737 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7738 even if it is going to be passed in a vector register.
7739 Darwin does the same for variable-argument functions. */
7740 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7741 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7751 /* Vector parameters must be 16-byte aligned. This places
7752 them at 2 mod 4 in terms of words in 32-bit mode, since
7753 the parameter save area starts at offset 24 from the
7754 stack. In 64-bit mode, they just have to start on an
7755 even word, since the parameter save area is 16-byte
7756 aligned. Space for GPRs is reserved even if the argument
7757 will be passed in memory. */
7759 align = (2 - cum->words) & 3;
7761 align = cum->words & 1;
7762 cum->words += align + rs6000_arg_size (mode, type);
7764 if (TARGET_DEBUG_ARG)
7766 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7768 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7769 cum->nargs_prototype, cum->prototype,
7770 GET_MODE_NAME (mode));
7774 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7776 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7779 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
7781 int size = int_size_in_bytes (type);
7782 /* Variable sized types have size == -1 and are
7783 treated as if consisting entirely of ints.
7784 Pad to 16 byte boundary if needed. */
7785 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7786 && (cum->words % 2) != 0)
7788 /* For varargs, we can just go up by the size of the struct. */
7790 cum->words += (size + 7) / 8;
7793 /* It is tempting to say int register count just goes up by
7794 sizeof(type)/8, but this is wrong in a case such as
7795 { int; double; int; } [powerpc alignment]. We have to
7796 grovel through the fields for these too. */
7798 cum->floats_in_gpr = 0;
7799 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7800 rs6000_darwin64_record_arg_advance_flush (cum,
7801 size * BITS_PER_UNIT, 1);
7803 if (TARGET_DEBUG_ARG)
7805 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
7806 cum->words, TYPE_ALIGN (type), size);
7808 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
7809 cum->nargs_prototype, cum->prototype,
7810 GET_MODE_NAME (mode));
7813 else if (DEFAULT_ABI == ABI_V4)
7815 if (TARGET_HARD_FLOAT && TARGET_FPRS
7816 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7817 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7818 || (mode == TFmode && !TARGET_IEEEQUAD)
7819 || mode == SDmode || mode == DDmode || mode == TDmode))
7821 /* _Decimal128 must use an even/odd register pair. This assumes
7822 that the register number is odd when fregno is odd. */
7823 if (mode == TDmode && (cum->fregno % 2) == 1)
7826 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7827 <= FP_ARG_V4_MAX_REG)
7828 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7831 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7832 if (mode == DFmode || mode == TFmode
7833 || mode == DDmode || mode == TDmode)
7834 cum->words += cum->words & 1;
7835 cum->words += rs6000_arg_size (mode, type);
7840 int n_words = rs6000_arg_size (mode, type);
7841 int gregno = cum->sysv_gregno;
7843 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7844 (r7,r8) or (r9,r10). As does any other 2 word item such
7845 as complex int due to a historical mistake. */
7847 gregno += (1 - gregno) & 1;
7849 /* Multi-reg args are not split between registers and stack. */
7850 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7852 /* Long long and SPE vectors are aligned on the stack.
7853 So are other 2 word items such as complex int due to
7854 a historical mistake. */
7856 cum->words += cum->words & 1;
7857 cum->words += n_words;
7860 /* Note: continuing to accumulate gregno past when we've started
7861 spilling to the stack indicates the fact that we've started
7862 spilling to the stack to expand_builtin_saveregs. */
7863 cum->sysv_gregno = gregno + n_words;
7866 if (TARGET_DEBUG_ARG)
7868 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7869 cum->words, cum->fregno);
7870 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7871 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7872 fprintf (stderr, "mode = %4s, named = %d\n",
7873 GET_MODE_NAME (mode), named);
7878 int n_words = rs6000_arg_size (mode, type);
7879 int start_words = cum->words;
7880 int align_words = rs6000_parm_start (mode, type, start_words);
7882 cum->words = align_words + n_words;
7884 if (SCALAR_FLOAT_MODE_P (mode)
7885 && TARGET_HARD_FLOAT && TARGET_FPRS)
7887 /* _Decimal128 must be passed in an even/odd float register pair.
7888 This assumes that the register number is odd when fregno is
7890 if (mode == TDmode && (cum->fregno % 2) == 1)
7892 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7895 if (TARGET_DEBUG_ARG)
7897 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7898 cum->words, cum->fregno);
7899 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7900 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7901 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7902 named, align_words - start_words, depth);
7908 spe_build_register_parallel (enum machine_mode mode, int gregno)
7915 r1 = gen_rtx_REG (DImode, gregno);
7916 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7917 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7921 r1 = gen_rtx_REG (DImode, gregno);
7922 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7923 r3 = gen_rtx_REG (DImode, gregno + 2);
7924 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7925 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7928 r1 = gen_rtx_REG (DImode, gregno);
7929 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7930 r3 = gen_rtx_REG (DImode, gregno + 2);
7931 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7932 r5 = gen_rtx_REG (DImode, gregno + 4);
7933 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7934 r7 = gen_rtx_REG (DImode, gregno + 6);
7935 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7936 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7943 /* Determine where to put a SIMD argument on the SPE. */
7945 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7948 int gregno = cum->sysv_gregno;
7950 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7951 are passed and returned in a pair of GPRs for ABI compatibility. */
7952 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7953 || mode == DCmode || mode == TCmode))
7955 int n_words = rs6000_arg_size (mode, type);
7957 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7959 gregno += (1 - gregno) & 1;
7961 /* Multi-reg args are not split between registers and stack. */
7962 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7965 return spe_build_register_parallel (mode, gregno);
7969 int n_words = rs6000_arg_size (mode, type);
7971 /* SPE vectors are put in odd registers. */
7972 if (n_words == 2 && (gregno & 1) == 0)
7975 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7978 enum machine_mode m = SImode;
7980 r1 = gen_rtx_REG (m, gregno);
7981 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7982 r2 = gen_rtx_REG (m, gregno + 1);
7983 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7984 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7991 if (gregno <= GP_ARG_MAX_REG)
7992 return gen_rtx_REG (mode, gregno);
7998 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7999 structure between cum->intoffset and bitpos to integer registers. */
8002 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8003 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8005 enum machine_mode mode;
8007 unsigned int startbit, endbit;
8008 int this_regno, intregs, intoffset;
8011 if (cum->intoffset == -1)
8014 intoffset = cum->intoffset;
8015 cum->intoffset = -1;
8017 /* If this is the trailing part of a word, try to only load that
8018 much into the register. Otherwise load the whole register. Note
8019 that in the latter case we may pick up unwanted bits. It's not a
8020 problem at the moment but may wish to revisit. */
8022 if (intoffset % BITS_PER_WORD != 0)
8024 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8026 if (mode == BLKmode)
8028 /* We couldn't find an appropriate mode, which happens,
8029 e.g., in packed structs when there are 3 bytes to load.
8030 Back intoffset back to the beginning of the word in this
8032 intoffset = intoffset & -BITS_PER_WORD;
8039 startbit = intoffset & -BITS_PER_WORD;
8040 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8041 intregs = (endbit - startbit) / BITS_PER_WORD;
8042 this_regno = cum->words + intoffset / BITS_PER_WORD;
8044 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8047 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8051 intoffset /= BITS_PER_UNIT;
8054 regno = GP_ARG_MIN_REG + this_regno;
8055 reg = gen_rtx_REG (mode, regno);
8057 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8060 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8064 while (intregs > 0);
8067 /* Recursive workhorse for the following. */
8070 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8071 HOST_WIDE_INT startbitpos, rtx rvec[],
8076 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8077 if (TREE_CODE (f) == FIELD_DECL)
8079 HOST_WIDE_INT bitpos = startbitpos;
8080 tree ftype = TREE_TYPE (f);
8081 enum machine_mode mode;
8082 if (ftype == error_mark_node)
8084 mode = TYPE_MODE (ftype);
8086 if (DECL_SIZE (f) != 0
8087 && host_integerp (bit_position (f), 1))
8088 bitpos += int_bit_position (f);
8090 /* ??? FIXME: else assume zero offset. */
8092 if (TREE_CODE (ftype) == RECORD_TYPE)
8093 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8094 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8099 case SCmode: mode = SFmode; break;
8100 case DCmode: mode = DFmode; break;
8101 case TCmode: mode = TFmode; break;
8105 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8107 = gen_rtx_EXPR_LIST (VOIDmode,
8108 gen_rtx_REG (mode, cum->fregno++),
8109 GEN_INT (bitpos / BITS_PER_UNIT));
8110 if (mode == TFmode || mode == TDmode)
8113 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8115 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8117 = gen_rtx_EXPR_LIST (VOIDmode,
8118 gen_rtx_REG (mode, cum->vregno++),
8119 GEN_INT (bitpos / BITS_PER_UNIT));
8121 else if (cum->intoffset == -1)
8122 cum->intoffset = bitpos;
8126 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8127 the register(s) to be used for each field and subfield of a struct
8128 being passed by value, along with the offset of where the
8129 register's value may be found in the block. FP fields go in FP
8130 register, vector fields go in vector registers, and everything
8131 else goes in int registers, packed as in memory.
8133 This code is also used for function return values. RETVAL indicates
8134 whether this is the case.
8136 Much of this is taken from the SPARC V9 port, which has a similar
8137 calling convention. */
8140 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8141 int named, bool retval)
8143 rtx rvec[FIRST_PSEUDO_REGISTER];
8144 int k = 1, kbase = 1;
8145 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8146 /* This is a copy; modifications are not visible to our caller. */
8147 CUMULATIVE_ARGS copy_cum = *orig_cum;
8148 CUMULATIVE_ARGS *cum = ©_cum;
8150 /* Pad to 16 byte boundary if needed. */
8151 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8152 && (cum->words % 2) != 0)
8159 /* Put entries into rvec[] for individual FP and vector fields, and
8160 for the chunks of memory that go in int regs. Note we start at
8161 element 1; 0 is reserved for an indication of using memory, and
8162 may or may not be filled in below. */
8163 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8164 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8166 /* If any part of the struct went on the stack put all of it there.
8167 This hack is because the generic code for
8168 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8169 parts of the struct are not at the beginning. */
8173 return NULL_RTX; /* doesn't go in registers at all */
8175 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8177 if (k > 1 || cum->use_stack)
8178 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8183 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8186 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
8190 rtx rvec[GP_ARG_NUM_REG + 1];
8192 if (align_words >= GP_ARG_NUM_REG)
8195 n_units = rs6000_arg_size (mode, type);
8197 /* Optimize the simple case where the arg fits in one gpr, except in
8198 the case of BLKmode due to assign_parms assuming that registers are
8199 BITS_PER_WORD wide. */
8201 || (n_units == 1 && mode != BLKmode))
8202 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8205 if (align_words + n_units > GP_ARG_NUM_REG)
8206 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8207 using a magic NULL_RTX component.
8208 This is not strictly correct. Only some of the arg belongs in
8209 memory, not all of it. However, the normal scheme using
8210 function_arg_partial_nregs can result in unusual subregs, eg.
8211 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8212 store the whole arg to memory is often more efficient than code
8213 to store pieces, and we know that space is available in the right
8214 place for the whole arg. */
8215 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8220 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8221 rtx off = GEN_INT (i++ * 4);
8222 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8224 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8226 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8229 /* Determine where to put an argument to a function.
8230 Value is zero to push the argument on the stack,
8231 or a hard register in which to store the argument.
8233 MODE is the argument's machine mode.
8234 TYPE is the data type of the argument (as a tree).
8235 This is null for libcalls where that information may
8237 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8238 the preceding args and about the function being called. It is
8239 not modified in this routine.
8240 NAMED is nonzero if this argument is a named parameter
8241 (otherwise it is an extra parameter matching an ellipsis).
8243 On RS/6000 the first eight words of non-FP are normally in registers
8244 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8245 Under V.4, the first 8 FP args are in registers.
8247 If this is floating-point and no prototype is specified, we use
8248 both an FP and integer register (or possibly FP reg and stack). Library
8249 functions (when CALL_LIBCALL is set) always have the proper types for args,
8250 so we can pass the FP value just in one register. emit_library_function
8251 doesn't support PARALLEL anyway.
8253 Note that for args passed by reference, function_arg will be called
8254 with MODE and TYPE set to that of the pointer to the arg, not the arg
8258 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8259 tree type, int named)
8261 enum rs6000_abi abi = DEFAULT_ABI;
8263 /* Return a marker to indicate whether CR1 needs to set or clear the
8264 bit that V.4 uses to say fp args were passed in registers.
8265 Assume that we don't need the marker for software floating point,
8266 or compiler generated library calls. */
8267 if (mode == VOIDmode)
8270 && (cum->call_cookie & CALL_LIBCALL) == 0
8272 || (cum->nargs_prototype < 0
8273 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8275 /* For the SPE, we need to crxor CR6 always. */
8277 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8278 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8279 return GEN_INT (cum->call_cookie
8280 | ((cum->fregno == FP_ARG_MIN_REG)
8281 ? CALL_V4_SET_FP_ARGS
8282 : CALL_V4_CLEAR_FP_ARGS));
8285 return GEN_INT (cum->call_cookie);
8288 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8290 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8291 if (rslt != NULL_RTX)
8293 /* Else fall through to usual handling. */
8296 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8297 if (TARGET_64BIT && ! cum->prototype)
8299 /* Vector parameters get passed in vector register
8300 and also in GPRs or memory, in absence of prototype. */
8303 align_words = (cum->words + 1) & ~1;
8305 if (align_words >= GP_ARG_NUM_REG)
8311 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8313 return gen_rtx_PARALLEL (mode,
8315 gen_rtx_EXPR_LIST (VOIDmode,
8317 gen_rtx_EXPR_LIST (VOIDmode,
8318 gen_rtx_REG (mode, cum->vregno),
8322 return gen_rtx_REG (mode, cum->vregno);
8323 else if (TARGET_ALTIVEC_ABI
8324 && (ALTIVEC_VECTOR_MODE (mode)
8325 || VSX_VECTOR_MODE (mode)
8326 || (type && TREE_CODE (type) == VECTOR_TYPE
8327 && int_size_in_bytes (type) == 16)))
8329 if (named || abi == ABI_V4)
8333 /* Vector parameters to varargs functions under AIX or Darwin
8334 get passed in memory and possibly also in GPRs. */
8335 int align, align_words, n_words;
8336 enum machine_mode part_mode;
8338 /* Vector parameters must be 16-byte aligned. This places them at
8339 2 mod 4 in terms of words in 32-bit mode, since the parameter
8340 save area starts at offset 24 from the stack. In 64-bit mode,
8341 they just have to start on an even word, since the parameter
8342 save area is 16-byte aligned. */
8344 align = (2 - cum->words) & 3;
8346 align = cum->words & 1;
8347 align_words = cum->words + align;
8349 /* Out of registers? Memory, then. */
8350 if (align_words >= GP_ARG_NUM_REG)
8353 if (TARGET_32BIT && TARGET_POWERPC64)
8354 return rs6000_mixed_function_arg (mode, type, align_words);
8356 /* The vector value goes in GPRs. Only the part of the
8357 value in GPRs is reported here. */
8359 n_words = rs6000_arg_size (mode, type);
8360 if (align_words + n_words > GP_ARG_NUM_REG)
8361 /* Fortunately, there are only two possibilities, the value
8362 is either wholly in GPRs or half in GPRs and half not. */
8365 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8368 else if (TARGET_SPE_ABI && TARGET_SPE
8369 && (SPE_VECTOR_MODE (mode)
8370 || (TARGET_E500_DOUBLE && (mode == DFmode
8373 || mode == TCmode))))
8374 return rs6000_spe_function_arg (cum, mode, type);
8376 else if (abi == ABI_V4)
8378 if (TARGET_HARD_FLOAT && TARGET_FPRS
8379 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8380 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8381 || (mode == TFmode && !TARGET_IEEEQUAD)
8382 || mode == SDmode || mode == DDmode || mode == TDmode))
8384 /* _Decimal128 must use an even/odd register pair. This assumes
8385 that the register number is odd when fregno is odd. */
8386 if (mode == TDmode && (cum->fregno % 2) == 1)
8389 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8390 <= FP_ARG_V4_MAX_REG)
8391 return gen_rtx_REG (mode, cum->fregno);
8397 int n_words = rs6000_arg_size (mode, type);
8398 int gregno = cum->sysv_gregno;
8400 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8401 (r7,r8) or (r9,r10). As does any other 2 word item such
8402 as complex int due to a historical mistake. */
8404 gregno += (1 - gregno) & 1;
8406 /* Multi-reg args are not split between registers and stack. */
8407 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8410 if (TARGET_32BIT && TARGET_POWERPC64)
8411 return rs6000_mixed_function_arg (mode, type,
8412 gregno - GP_ARG_MIN_REG);
8413 return gen_rtx_REG (mode, gregno);
8418 int align_words = rs6000_parm_start (mode, type, cum->words);
8420 /* _Decimal128 must be passed in an even/odd float register pair.
8421 This assumes that the register number is odd when fregno is odd. */
8422 if (mode == TDmode && (cum->fregno % 2) == 1)
8425 if (USE_FP_FOR_ARG_P (cum, mode, type))
8427 rtx rvec[GP_ARG_NUM_REG + 1];
8431 enum machine_mode fmode = mode;
8432 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8434 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8436 /* Currently, we only ever need one reg here because complex
8437 doubles are split. */
8438 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8439 && (fmode == TFmode || fmode == TDmode));
8441 /* Long double or _Decimal128 split over regs and memory. */
8442 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8445 /* Do we also need to pass this arg in the parameter save
8448 && (cum->nargs_prototype <= 0
8449 || (DEFAULT_ABI == ABI_AIX
8451 && align_words >= GP_ARG_NUM_REG)));
8453 if (!needs_psave && mode == fmode)
8454 return gen_rtx_REG (fmode, cum->fregno);
8459 /* Describe the part that goes in gprs or the stack.
8460 This piece must come first, before the fprs. */
8461 if (align_words < GP_ARG_NUM_REG)
8463 unsigned long n_words = rs6000_arg_size (mode, type);
8465 if (align_words + n_words > GP_ARG_NUM_REG
8466 || (TARGET_32BIT && TARGET_POWERPC64))
8468 /* If this is partially on the stack, then we only
8469 include the portion actually in registers here. */
8470 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8473 if (align_words + n_words > GP_ARG_NUM_REG)
8474 /* Not all of the arg fits in gprs. Say that it
8475 goes in memory too, using a magic NULL_RTX
8476 component. Also see comment in
8477 rs6000_mixed_function_arg for why the normal
8478 function_arg_partial_nregs scheme doesn't work
8480 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8484 r = gen_rtx_REG (rmode,
8485 GP_ARG_MIN_REG + align_words);
8486 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8487 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8489 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8493 /* The whole arg fits in gprs. */
8494 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8495 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8499 /* It's entirely in memory. */
8500 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8503 /* Describe where this piece goes in the fprs. */
8504 r = gen_rtx_REG (fmode, cum->fregno);
8505 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8507 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8509 else if (align_words < GP_ARG_NUM_REG)
8511 if (TARGET_32BIT && TARGET_POWERPC64)
8512 return rs6000_mixed_function_arg (mode, type, align_words);
8514 if (mode == BLKmode)
8517 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8524 /* For an arg passed partly in registers and partly in memory, this is
8525 the number of bytes passed in registers. For args passed entirely in
8526 registers or entirely in memory, zero. When an arg is described by a
8527 PARALLEL, perhaps using more than one register type, this function
8528 returns the number of bytes used by the first element of the PARALLEL. */
8531 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8532 tree type, bool named)
8537 if (DEFAULT_ABI == ABI_V4)
8540 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8541 && cum->nargs_prototype >= 0)
8544 /* In this complicated case we just disable the partial_nregs code. */
8545 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8548 align_words = rs6000_parm_start (mode, type, cum->words);
8550 if (USE_FP_FOR_ARG_P (cum, mode, type))
8552 /* If we are passing this arg in the fixed parameter save area
8553 (gprs or memory) as well as fprs, then this function should
8554 return the number of partial bytes passed in the parameter
8555 save area rather than partial bytes passed in fprs. */
8557 && (cum->nargs_prototype <= 0
8558 || (DEFAULT_ABI == ABI_AIX
8560 && align_words >= GP_ARG_NUM_REG)))
8562 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8563 > FP_ARG_MAX_REG + 1)
8564 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8565 else if (cum->nargs_prototype >= 0)
8569 if (align_words < GP_ARG_NUM_REG
8570 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8571 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8573 if (ret != 0 && TARGET_DEBUG_ARG)
8574 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8579 /* A C expression that indicates when an argument must be passed by
8580 reference. If nonzero for an argument, a copy of that argument is
8581 made in memory and a pointer to the argument is passed instead of
8582 the argument itself. The pointer is passed in whatever way is
8583 appropriate for passing a pointer to that type.
8585 Under V.4, aggregates and long double are passed by reference.
8587 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8588 reference unless the AltiVec vector extension ABI is in force.
8590 As an extension to all ABIs, variable sized types are passed by
8594 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8595 enum machine_mode mode, const_tree type,
8596 bool named ATTRIBUTE_UNUSED)
8598 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8600 if (TARGET_DEBUG_ARG)
8601 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8608 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8610 if (TARGET_DEBUG_ARG)
8611 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8615 if (int_size_in_bytes (type) < 0)
8617 if (TARGET_DEBUG_ARG)
8618 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8622 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8623 modes only exist for GCC vector types if -maltivec. */
8624 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8626 if (TARGET_DEBUG_ARG)
8627 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8631 /* Pass synthetic vectors in memory. */
8632 if (TREE_CODE (type) == VECTOR_TYPE
8633 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8635 static bool warned_for_pass_big_vectors = false;
8636 if (TARGET_DEBUG_ARG)
8637 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8638 if (!warned_for_pass_big_vectors)
8640 warning (0, "GCC vector passed by reference: "
8641 "non-standard ABI extension with no compatibility guarantee");
8642 warned_for_pass_big_vectors = true;
8651 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8654 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8659 for (i = 0; i < nregs; i++)
8661 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8662 if (reload_completed)
8664 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8667 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8668 i * GET_MODE_SIZE (reg_mode));
8671 tem = replace_equiv_address (tem, XEXP (tem, 0));
8675 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8679 /* Perform any needed actions needed for a function that is receiving a
8680 variable number of arguments.
8684 MODE and TYPE are the mode and type of the current parameter.
8686 PRETEND_SIZE is a variable that should be set to the amount of stack
8687 that must be pushed by the prolog to pretend that our caller pushed
8690 Normally, this macro will push all remaining incoming registers on the
8691 stack and set PRETEND_SIZE to the length of the registers pushed. */
8694 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8695 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8698 CUMULATIVE_ARGS next_cum;
8699 int reg_size = TARGET_32BIT ? 4 : 8;
8700 rtx save_area = NULL_RTX, mem;
8701 int first_reg_offset;
8704 /* Skip the last named argument. */
8706 function_arg_advance (&next_cum, mode, type, 1, 0);
8708 if (DEFAULT_ABI == ABI_V4)
8710 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8714 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8715 HOST_WIDE_INT offset = 0;
8717 /* Try to optimize the size of the varargs save area.
8718 The ABI requires that ap.reg_save_area is doubleword
8719 aligned, but we don't need to allocate space for all
8720 the bytes, only those to which we actually will save
8722 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8723 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8724 if (TARGET_HARD_FLOAT && TARGET_FPRS
8725 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8726 && cfun->va_list_fpr_size)
8729 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8730 * UNITS_PER_FP_WORD;
8731 if (cfun->va_list_fpr_size
8732 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8733 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8735 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8736 * UNITS_PER_FP_WORD;
8740 offset = -((first_reg_offset * reg_size) & ~7);
8741 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8743 gpr_reg_num = cfun->va_list_gpr_size;
8744 if (reg_size == 4 && (first_reg_offset & 1))
8747 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8750 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8752 - (int) (GP_ARG_NUM_REG * reg_size);
8754 if (gpr_size + fpr_size)
8757 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8758 gcc_assert (GET_CODE (reg_save_area) == MEM);
8759 reg_save_area = XEXP (reg_save_area, 0);
8760 if (GET_CODE (reg_save_area) == PLUS)
8762 gcc_assert (XEXP (reg_save_area, 0)
8763 == virtual_stack_vars_rtx);
8764 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8765 offset += INTVAL (XEXP (reg_save_area, 1));
8768 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8771 cfun->machine->varargs_save_offset = offset;
8772 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8777 first_reg_offset = next_cum.words;
8778 save_area = virtual_incoming_args_rtx;
8780 if (targetm.calls.must_pass_in_stack (mode, type))
8781 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8784 set = get_varargs_alias_set ();
8785 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8786 && cfun->va_list_gpr_size)
8788 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8790 if (va_list_gpr_counter_field)
8792 /* V4 va_list_gpr_size counts number of registers needed. */
8793 if (nregs > cfun->va_list_gpr_size)
8794 nregs = cfun->va_list_gpr_size;
8798 /* char * va_list instead counts number of bytes needed. */
8799 if (nregs > cfun->va_list_gpr_size / reg_size)
8800 nregs = cfun->va_list_gpr_size / reg_size;
8803 mem = gen_rtx_MEM (BLKmode,
8804 plus_constant (save_area,
8805 first_reg_offset * reg_size));
8806 MEM_NOTRAP_P (mem) = 1;
8807 set_mem_alias_set (mem, set);
8808 set_mem_align (mem, BITS_PER_WORD);
8810 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8814 /* Save FP registers if needed. */
8815 if (DEFAULT_ABI == ABI_V4
8816 && TARGET_HARD_FLOAT && TARGET_FPRS
8818 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8819 && cfun->va_list_fpr_size)
8821 int fregno = next_cum.fregno, nregs;
8822 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8823 rtx lab = gen_label_rtx ();
8824 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8825 * UNITS_PER_FP_WORD);
8828 (gen_rtx_SET (VOIDmode,
8830 gen_rtx_IF_THEN_ELSE (VOIDmode,
8831 gen_rtx_NE (VOIDmode, cr1,
8833 gen_rtx_LABEL_REF (VOIDmode, lab),
8837 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8838 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8840 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8842 plus_constant (save_area, off));
8843 MEM_NOTRAP_P (mem) = 1;
8844 set_mem_alias_set (mem, set);
8845 set_mem_align (mem, GET_MODE_ALIGNMENT (
8846 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8847 ? DFmode : SFmode));
8848 emit_move_insn (mem, gen_rtx_REG (
8849 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8850 ? DFmode : SFmode, fregno));
8857 /* Create the va_list data type. */
8860 rs6000_build_builtin_va_list (void)
8862 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8864 /* For AIX, prefer 'char *' because that's what the system
8865 header files like. */
8866 if (DEFAULT_ABI != ABI_V4)
8867 return build_pointer_type (char_type_node);
8869 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8870 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8871 get_identifier ("__va_list_tag"), record);
8873 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8874 unsigned_char_type_node);
8875 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8876 unsigned_char_type_node);
8877 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8879 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8880 get_identifier ("reserved"), short_unsigned_type_node);
8881 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8882 get_identifier ("overflow_arg_area"),
8884 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8885 get_identifier ("reg_save_area"),
8888 va_list_gpr_counter_field = f_gpr;
8889 va_list_fpr_counter_field = f_fpr;
8891 DECL_FIELD_CONTEXT (f_gpr) = record;
8892 DECL_FIELD_CONTEXT (f_fpr) = record;
8893 DECL_FIELD_CONTEXT (f_res) = record;
8894 DECL_FIELD_CONTEXT (f_ovf) = record;
8895 DECL_FIELD_CONTEXT (f_sav) = record;
8897 TREE_CHAIN (record) = type_decl;
8898 TYPE_NAME (record) = type_decl;
8899 TYPE_FIELDS (record) = f_gpr;
8900 DECL_CHAIN (f_gpr) = f_fpr;
8901 DECL_CHAIN (f_fpr) = f_res;
8902 DECL_CHAIN (f_res) = f_ovf;
8903 DECL_CHAIN (f_ovf) = f_sav;
8905 layout_type (record);
8907 /* The correct type is an array type of one element. */
8908 return build_array_type (record, build_index_type (size_zero_node));
8911 /* Implement va_start. */
8914 rs6000_va_start (tree valist, rtx nextarg)
8916 HOST_WIDE_INT words, n_gpr, n_fpr;
8917 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8918 tree gpr, fpr, ovf, sav, t;
8920 /* Only SVR4 needs something special. */
8921 if (DEFAULT_ABI != ABI_V4)
8923 std_expand_builtin_va_start (valist, nextarg);
8927 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8928 f_fpr = DECL_CHAIN (f_gpr);
8929 f_res = DECL_CHAIN (f_fpr);
8930 f_ovf = DECL_CHAIN (f_res);
8931 f_sav = DECL_CHAIN (f_ovf);
8933 valist = build_va_arg_indirect_ref (valist);
8934 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8935 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8937 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8939 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8942 /* Count number of gp and fp argument registers used. */
8943 words = crtl->args.info.words;
8944 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8946 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8949 if (TARGET_DEBUG_ARG)
8950 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8951 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8952 words, n_gpr, n_fpr);
8954 if (cfun->va_list_gpr_size)
8956 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8957 build_int_cst (NULL_TREE, n_gpr));
8958 TREE_SIDE_EFFECTS (t) = 1;
8959 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8962 if (cfun->va_list_fpr_size)
8964 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8965 build_int_cst (NULL_TREE, n_fpr));
8966 TREE_SIDE_EFFECTS (t) = 1;
8967 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8970 /* Find the overflow area. */
8971 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8973 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8974 size_int (words * UNITS_PER_WORD));
8975 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8976 TREE_SIDE_EFFECTS (t) = 1;
8977 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8979 /* If there were no va_arg invocations, don't set up the register
8981 if (!cfun->va_list_gpr_size
8982 && !cfun->va_list_fpr_size
8983 && n_gpr < GP_ARG_NUM_REG
8984 && n_fpr < FP_ARG_V4_MAX_REG)
8987 /* Find the register save area. */
8988 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8989 if (cfun->machine->varargs_save_offset)
8990 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8991 size_int (cfun->machine->varargs_save_offset));
8992 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8993 TREE_SIDE_EFFECTS (t) = 1;
8994 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8997 /* Implement va_arg. */
9000 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9003 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9004 tree gpr, fpr, ovf, sav, reg, t, u;
9005 int size, rsize, n_reg, sav_ofs, sav_scale;
9006 tree lab_false, lab_over, addr;
9008 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9012 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9014 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9015 return build_va_arg_indirect_ref (t);
9018 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9019 earlier version of gcc, with the property that it always applied alignment
9020 adjustments to the va-args (even for zero-sized types). The cheapest way
9021 to deal with this is to replicate the effect of the part of
9022 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9024 We don't need to check for pass-by-reference because of the test above.
9025 We can return a simplifed answer, since we know there's no offset to add. */
9028 && rs6000_darwin64_abi
9029 && integer_zerop (TYPE_SIZE (type)))
9031 unsigned HOST_WIDE_INT align, boundary;
9032 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9033 align = PARM_BOUNDARY / BITS_PER_UNIT;
9034 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9035 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9036 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9037 boundary /= BITS_PER_UNIT;
9038 if (boundary > align)
9041 /* This updates arg ptr by the amount that would be necessary
9042 to align the zero-sized (but not zero-alignment) item. */
9043 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9044 fold_build2 (POINTER_PLUS_EXPR,
9046 valist_tmp, size_int (boundary - 1)));
9047 gimplify_and_add (t, pre_p);
9049 t = fold_convert (sizetype, valist_tmp);
9050 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9051 fold_convert (TREE_TYPE (valist),
9052 fold_build2 (BIT_AND_EXPR, sizetype, t,
9053 size_int (-boundary))));
9054 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9055 gimplify_and_add (t, pre_p);
9057 /* Since it is zero-sized there's no increment for the item itself. */
9058 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9059 return build_va_arg_indirect_ref (valist_tmp);
9062 if (DEFAULT_ABI != ABI_V4)
9064 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9066 tree elem_type = TREE_TYPE (type);
9067 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9068 int elem_size = GET_MODE_SIZE (elem_mode);
9070 if (elem_size < UNITS_PER_WORD)
9072 tree real_part, imag_part;
9073 gimple_seq post = NULL;
9075 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9077 /* Copy the value into a temporary, lest the formal temporary
9078 be reused out from under us. */
9079 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9080 gimple_seq_add_seq (pre_p, post);
9082 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9085 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9089 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9092 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9093 f_fpr = DECL_CHAIN (f_gpr);
9094 f_res = DECL_CHAIN (f_fpr);
9095 f_ovf = DECL_CHAIN (f_res);
9096 f_sav = DECL_CHAIN (f_ovf);
9098 valist = build_va_arg_indirect_ref (valist);
9099 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9100 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9102 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9104 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9107 size = int_size_in_bytes (type);
9108 rsize = (size + 3) / 4;
9111 if (TARGET_HARD_FLOAT && TARGET_FPRS
9112 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9113 || (TARGET_DOUBLE_FLOAT
9114 && (TYPE_MODE (type) == DFmode
9115 || TYPE_MODE (type) == TFmode
9116 || TYPE_MODE (type) == SDmode
9117 || TYPE_MODE (type) == DDmode
9118 || TYPE_MODE (type) == TDmode))))
9120 /* FP args go in FP registers, if present. */
9122 n_reg = (size + 7) / 8;
9123 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9124 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9125 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9130 /* Otherwise into GP registers. */
9139 /* Pull the value out of the saved registers.... */
9142 addr = create_tmp_var (ptr_type_node, "addr");
9144 /* AltiVec vectors never go in registers when -mabi=altivec. */
9145 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9149 lab_false = create_artificial_label (input_location);
9150 lab_over = create_artificial_label (input_location);
9152 /* Long long and SPE vectors are aligned in the registers.
9153 As are any other 2 gpr item such as complex int due to a
9154 historical mistake. */
9156 if (n_reg == 2 && reg == gpr)
9159 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9160 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9161 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9162 unshare_expr (reg), u);
9164 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9165 reg number is 0 for f1, so we want to make it odd. */
9166 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9168 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9169 build_int_cst (TREE_TYPE (reg), 1));
9170 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9173 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9174 t = build2 (GE_EXPR, boolean_type_node, u, t);
9175 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9176 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9177 gimplify_and_add (t, pre_p);
9181 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9183 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9184 build_int_cst (TREE_TYPE (reg), n_reg));
9185 u = fold_convert (sizetype, u);
9186 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9187 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9189 /* _Decimal32 varargs are located in the second word of the 64-bit
9190 FP register for 32-bit binaries. */
9191 if (!TARGET_POWERPC64
9192 && TARGET_HARD_FLOAT && TARGET_FPRS
9193 && TYPE_MODE (type) == SDmode)
9194 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9196 gimplify_assign (addr, t, pre_p);
9198 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9200 stmt = gimple_build_label (lab_false);
9201 gimple_seq_add_stmt (pre_p, stmt);
9203 if ((n_reg == 2 && !regalign) || n_reg > 2)
9205 /* Ensure that we don't find any more args in regs.
9206 Alignment has taken care of for special cases. */
9207 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9211 /* ... otherwise out of the overflow area. */
9213 /* Care for on-stack alignment if needed. */
9217 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9218 t = fold_convert (sizetype, t);
9219 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9221 t = fold_convert (TREE_TYPE (ovf), t);
9223 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9225 gimplify_assign (unshare_expr (addr), t, pre_p);
9227 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9228 gimplify_assign (unshare_expr (ovf), t, pre_p);
9232 stmt = gimple_build_label (lab_over);
9233 gimple_seq_add_stmt (pre_p, stmt);
9236 if (STRICT_ALIGNMENT
9237 && (TYPE_ALIGN (type)
9238 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9240 /* The value (of type complex double, for example) may not be
9241 aligned in memory in the saved registers, so copy via a
9242 temporary. (This is the same code as used for SPARC.) */
9243 tree tmp = create_tmp_var (type, "va_arg_tmp");
9244 tree dest_addr = build_fold_addr_expr (tmp);
9246 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9247 3, dest_addr, addr, size_int (rsize * 4));
9249 gimplify_and_add (copy, pre_p);
9253 addr = fold_convert (ptrtype, addr);
9254 return build_va_arg_indirect_ref (addr);
9260 def_builtin (int mask, const char *name, tree type, int code)
9262 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9265 if (rs6000_builtin_decls[code])
9266 fatal_error ("internal error: builtin function to %s already processed.",
9269 rs6000_builtin_decls[code] = t =
9270 add_builtin_function (name, type, code, BUILT_IN_MD,
9273 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9274 switch (builtin_classify[code])
9279 /* assume builtin can do anything. */
9280 case RS6000_BTC_MISC:
9283 /* const function, function only depends on the inputs. */
9284 case RS6000_BTC_CONST:
9285 TREE_READONLY (t) = 1;
9286 TREE_NOTHROW (t) = 1;
9289 /* pure function, function can read global memory. */
9290 case RS6000_BTC_PURE:
9291 DECL_PURE_P (t) = 1;
9292 TREE_NOTHROW (t) = 1;
9295 /* Function is a math function. If rounding mode is on, then treat
9296 the function as not reading global memory, but it can have
9297 arbitrary side effects. If it is off, then assume the function is
9298 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9299 attribute in builtin-attribute.def that is used for the math
9301 case RS6000_BTC_FP_PURE:
9302 TREE_NOTHROW (t) = 1;
9303 if (flag_rounding_math)
9305 DECL_PURE_P (t) = 1;
9306 DECL_IS_NOVOPS (t) = 1;
9309 TREE_READONLY (t) = 1;
9315 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9317 static const struct builtin_description bdesc_3arg[] =
9319 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9320 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9321 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9322 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9323 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9324 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9325 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9326 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9327 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9328 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9329 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9330 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9331 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9332 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9333 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9334 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9335 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9336 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9337 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9338 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9339 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9340 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9341 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9342 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9343 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9344 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9345 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9346 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9347 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9348 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9349 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9350 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9351 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9352 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9353 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9371 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9372 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9373 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9374 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9376 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9377 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9378 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9379 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9384 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9385 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9386 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9387 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9388 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9389 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9390 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9391 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9392 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9393 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9395 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9396 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9397 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9398 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9399 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9400 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9401 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9402 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9403 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9404 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9406 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9407 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9408 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9409 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9410 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9411 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9412 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9413 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9414 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9416 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9417 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9418 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9419 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9420 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9421 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9422 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9424 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9425 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9426 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9427 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9428 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9429 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9430 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9431 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9432 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9435 /* DST operations: void foo (void *, const int, const char). */
9437 static const struct builtin_description bdesc_dst[] =
9439 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9440 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9441 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9442 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9450 /* Simple binary operations: VECc = foo (VECa, VECb). */
9452 static struct builtin_description bdesc_2arg[] =
9454 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9455 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9456 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9457 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9458 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9459 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9460 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9461 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9462 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9463 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9464 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9465 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9466 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9467 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9468 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9469 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9470 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9471 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9472 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9473 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9474 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9475 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9476 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9477 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9478 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9479 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9480 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9481 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9482 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9483 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9484 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9485 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9486 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9487 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9488 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9489 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9490 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9491 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9492 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9493 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9494 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9495 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9496 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9497 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9498 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9499 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9500 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9501 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9502 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9503 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9504 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9505 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9506 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9507 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9508 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9509 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9510 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9511 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9512 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9513 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9514 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9515 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9516 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9517 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9518 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9519 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9520 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9521 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9522 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9523 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9524 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9525 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9526 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9527 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9528 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9529 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9530 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9531 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9532 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9533 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9534 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9535 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9536 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9537 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9538 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9539 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9540 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9541 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9542 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9543 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9544 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9545 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9546 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9547 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9548 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9549 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9550 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9551 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9552 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9553 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9554 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9555 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9556 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9557 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9558 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9559 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9560 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9561 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9562 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9563 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9564 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9565 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9566 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9567 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9568 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9569 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9570 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9572 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9573 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9574 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9575 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9576 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9577 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9578 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9579 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9580 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9581 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9582 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9583 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9585 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9586 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9587 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9588 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9589 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9590 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9591 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9592 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9593 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9594 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9595 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9596 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9598 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9599 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9600 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9601 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9602 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9603 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9605 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9606 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9607 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9608 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9609 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9610 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9611 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9612 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9613 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9614 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9615 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9616 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9618 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9619 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9620 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9621 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9622 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9623 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9624 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9625 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9626 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9627 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9628 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9629 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9630 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9631 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9632 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9633 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9634 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9635 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9636 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9637 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9638 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9639 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9640 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9641 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9642 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9643 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9644 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9645 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9646 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9647 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9648 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9649 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9650 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9651 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9652 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9653 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9654 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9655 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9656 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9657 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9658 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9659 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9660 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9663 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9664 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9665 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9666 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9667 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9668 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9669 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9670 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9671 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9672 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9673 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9674 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9675 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9676 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9677 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9678 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9679 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9680 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9681 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9682 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9683 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9684 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9692 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9693 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9696 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9697 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9698 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9699 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9700 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9701 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9702 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9703 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9704 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9705 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9706 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9707 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9708 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9709 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9710 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9711 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9712 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9713 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9714 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9715 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9716 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9717 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9718 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9719 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9720 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9721 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9722 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9727 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9728 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9732 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9738 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9739 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9740 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9746 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9748 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9749 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9751 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9752 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9753 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9754 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9755 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9756 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9757 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9758 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9759 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9760 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9762 /* Place holder, leave as first spe builtin. */
9763 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9764 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9765 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9766 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9767 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9768 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9769 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9770 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9771 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9772 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9773 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9774 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9775 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9776 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9777 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9778 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9779 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9780 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9781 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9782 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9783 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9784 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9785 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9786 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9787 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9788 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9789 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9790 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9791 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9792 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9793 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9794 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9795 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9796 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9797 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9798 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9799 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9800 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9801 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9802 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9803 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9804 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9805 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9806 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9807 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9808 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9809 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9810 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9811 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9812 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9813 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9814 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9815 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9816 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9817 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9818 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9819 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9820 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9821 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9822 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9823 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9824 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9825 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9826 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9827 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9828 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9829 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9830 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9831 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9832 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9833 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9834 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9835 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9836 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9837 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9838 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9839 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9840 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9841 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9842 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9843 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9844 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9845 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9846 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9847 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9848 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9849 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9850 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9851 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9852 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9853 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9854 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9855 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9856 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9857 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9858 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9859 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9860 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9861 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9862 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9863 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9864 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9865 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9866 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9867 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9868 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9869 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9870 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9871 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9873 /* SPE binary operations expecting a 5-bit unsigned literal. */
9874 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9876 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9877 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9878 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9879 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9880 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9881 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9882 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9883 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9884 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9885 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9886 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9887 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9888 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9889 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9890 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9891 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9892 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9893 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9894 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9895 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9896 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9897 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9898 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9899 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9900 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9901 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9903 /* Place-holder. Leave as last binary SPE builtin. */
9904 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9907 /* AltiVec predicates. */
9909 struct builtin_description_predicates
9911 const unsigned int mask;
9912 const enum insn_code icode;
9913 const char *const name;
9914 const enum rs6000_builtins code;
9917 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9919 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9920 ALTIVEC_BUILTIN_VCMPBFP_P },
9921 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9922 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9923 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9924 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9925 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9926 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9927 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9928 ALTIVEC_BUILTIN_VCMPEQUW_P },
9929 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9930 ALTIVEC_BUILTIN_VCMPGTSW_P },
9931 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9932 ALTIVEC_BUILTIN_VCMPGTUW_P },
9933 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9934 ALTIVEC_BUILTIN_VCMPEQUH_P },
9935 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9936 ALTIVEC_BUILTIN_VCMPGTSH_P },
9937 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9938 ALTIVEC_BUILTIN_VCMPGTUH_P },
9939 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9940 ALTIVEC_BUILTIN_VCMPEQUB_P },
9941 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9942 ALTIVEC_BUILTIN_VCMPGTSB_P },
9943 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9944 ALTIVEC_BUILTIN_VCMPGTUB_P },
9946 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9947 VSX_BUILTIN_XVCMPEQSP_P },
9948 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9949 VSX_BUILTIN_XVCMPGESP_P },
9950 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9951 VSX_BUILTIN_XVCMPGTSP_P },
9952 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9953 VSX_BUILTIN_XVCMPEQDP_P },
9954 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9955 VSX_BUILTIN_XVCMPGEDP_P },
9956 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9957 VSX_BUILTIN_XVCMPGTDP_P },
9959 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9960 ALTIVEC_BUILTIN_VCMPEQ_P },
9961 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9962 ALTIVEC_BUILTIN_VCMPGT_P },
9963 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9964 ALTIVEC_BUILTIN_VCMPGE_P }
9967 /* SPE predicates. */
9968 static struct builtin_description bdesc_spe_predicates[] =
9970 /* Place-holder. Leave as first. */
9971 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9972 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9973 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9974 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9975 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9976 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9977 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9978 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9979 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9980 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9981 /* Place-holder. Leave as last. */
9982 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9985 /* SPE evsel predicates. */
9986 static struct builtin_description bdesc_spe_evsel[] =
9988 /* Place-holder. Leave as first. */
9989 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9990 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9991 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9992 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9993 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9994 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9995 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9996 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9997 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9998 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9999 /* Place-holder. Leave as last. */
10000 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10003 /* PAIRED predicates. */
10004 static const struct builtin_description bdesc_paired_preds[] =
10006 /* Place-holder. Leave as first. */
10007 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10008 /* Place-holder. Leave as last. */
10009 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10012 /* ABS* operations. */
10014 static const struct builtin_description bdesc_abs[] =
10016 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10017 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10018 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10019 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10020 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10021 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10022 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10023 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10024 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10025 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10026 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10029 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10032 static struct builtin_description bdesc_1arg[] =
10034 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10035 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10036 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10037 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10038 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10039 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10040 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10041 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10042 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10043 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10044 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10045 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10046 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10047 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10048 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10049 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10050 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10051 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10053 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10054 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10055 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10056 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10057 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10058 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10059 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10061 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10062 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10063 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10064 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10065 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10066 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10067 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10069 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10070 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10071 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10072 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10073 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10074 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10076 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10077 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10078 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10079 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10080 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10081 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10083 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10084 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10085 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10086 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10088 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10089 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10090 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10091 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10092 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10093 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10094 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10095 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10096 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10098 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10099 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10100 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10101 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10102 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10103 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10104 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10105 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10106 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10108 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10109 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10110 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10111 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10112 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10114 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10115 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10116 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10117 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10118 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10119 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10120 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10121 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10122 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10123 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10124 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10125 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10126 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10127 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10128 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10129 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10130 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10131 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10132 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10133 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10135 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10136 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10137 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10139 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10140 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10141 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10142 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10144 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10145 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10146 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10147 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10148 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10149 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10150 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10151 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10152 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10153 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10154 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10155 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10156 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10157 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10158 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10159 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10160 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10161 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10162 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10163 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10164 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10165 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10166 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10167 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10168 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10169 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10170 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10171 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10172 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10173 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10175 /* Place-holder. Leave as last unary SPE builtin. */
10176 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10178 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10179 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10180 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10181 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10182 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10186 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10189 tree arg0 = CALL_EXPR_ARG (exp, 0);
10190 rtx op0 = expand_normal (arg0);
10191 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10192 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10194 if (icode == CODE_FOR_nothing)
10195 /* Builtin not supported on this processor. */
10198 /* If we got invalid arguments bail out before generating bad rtl. */
10199 if (arg0 == error_mark_node)
10202 if (icode == CODE_FOR_altivec_vspltisb
10203 || icode == CODE_FOR_altivec_vspltish
10204 || icode == CODE_FOR_altivec_vspltisw
10205 || icode == CODE_FOR_spe_evsplatfi
10206 || icode == CODE_FOR_spe_evsplati)
10208 /* Only allow 5-bit *signed* literals. */
10209 if (GET_CODE (op0) != CONST_INT
10210 || INTVAL (op0) > 15
10211 || INTVAL (op0) < -16)
10213 error ("argument 1 must be a 5-bit signed literal");
10219 || GET_MODE (target) != tmode
10220 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10221 target = gen_reg_rtx (tmode);
10223 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10224 op0 = copy_to_mode_reg (mode0, op0);
10226 pat = GEN_FCN (icode) (target, op0);
10235 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10237 rtx pat, scratch1, scratch2;
10238 tree arg0 = CALL_EXPR_ARG (exp, 0);
10239 rtx op0 = expand_normal (arg0);
10240 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10241 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10243 /* If we have invalid arguments, bail out before generating bad rtl. */
10244 if (arg0 == error_mark_node)
10248 || GET_MODE (target) != tmode
10249 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10250 target = gen_reg_rtx (tmode);
10252 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10253 op0 = copy_to_mode_reg (mode0, op0);
10255 scratch1 = gen_reg_rtx (mode0);
10256 scratch2 = gen_reg_rtx (mode0);
10258 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10267 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10270 tree arg0 = CALL_EXPR_ARG (exp, 0);
10271 tree arg1 = CALL_EXPR_ARG (exp, 1);
10272 rtx op0 = expand_normal (arg0);
10273 rtx op1 = expand_normal (arg1);
10274 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10275 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10276 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10278 if (icode == CODE_FOR_nothing)
10279 /* Builtin not supported on this processor. */
10282 /* If we got invalid arguments bail out before generating bad rtl. */
10283 if (arg0 == error_mark_node || arg1 == error_mark_node)
10286 if (icode == CODE_FOR_altivec_vcfux
10287 || icode == CODE_FOR_altivec_vcfsx
10288 || icode == CODE_FOR_altivec_vctsxs
10289 || icode == CODE_FOR_altivec_vctuxs
10290 || icode == CODE_FOR_altivec_vspltb
10291 || icode == CODE_FOR_altivec_vsplth
10292 || icode == CODE_FOR_altivec_vspltw
10293 || icode == CODE_FOR_spe_evaddiw
10294 || icode == CODE_FOR_spe_evldd
10295 || icode == CODE_FOR_spe_evldh
10296 || icode == CODE_FOR_spe_evldw
10297 || icode == CODE_FOR_spe_evlhhesplat
10298 || icode == CODE_FOR_spe_evlhhossplat
10299 || icode == CODE_FOR_spe_evlhhousplat
10300 || icode == CODE_FOR_spe_evlwhe
10301 || icode == CODE_FOR_spe_evlwhos
10302 || icode == CODE_FOR_spe_evlwhou
10303 || icode == CODE_FOR_spe_evlwhsplat
10304 || icode == CODE_FOR_spe_evlwwsplat
10305 || icode == CODE_FOR_spe_evrlwi
10306 || icode == CODE_FOR_spe_evslwi
10307 || icode == CODE_FOR_spe_evsrwis
10308 || icode == CODE_FOR_spe_evsubifw
10309 || icode == CODE_FOR_spe_evsrwiu)
10311 /* Only allow 5-bit unsigned literals. */
10313 if (TREE_CODE (arg1) != INTEGER_CST
10314 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10316 error ("argument 2 must be a 5-bit unsigned literal");
10322 || GET_MODE (target) != tmode
10323 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10324 target = gen_reg_rtx (tmode);
10326 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10327 op0 = copy_to_mode_reg (mode0, op0);
10328 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10329 op1 = copy_to_mode_reg (mode1, op1);
10331 pat = GEN_FCN (icode) (target, op0, op1);
10340 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10343 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10344 tree arg0 = CALL_EXPR_ARG (exp, 1);
10345 tree arg1 = CALL_EXPR_ARG (exp, 2);
10346 rtx op0 = expand_normal (arg0);
10347 rtx op1 = expand_normal (arg1);
10348 enum machine_mode tmode = SImode;
10349 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10350 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10353 if (TREE_CODE (cr6_form) != INTEGER_CST)
10355 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10359 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10361 gcc_assert (mode0 == mode1);
10363 /* If we have invalid arguments, bail out before generating bad rtl. */
10364 if (arg0 == error_mark_node || arg1 == error_mark_node)
10368 || GET_MODE (target) != tmode
10369 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10370 target = gen_reg_rtx (tmode);
10372 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10373 op0 = copy_to_mode_reg (mode0, op0);
10374 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10375 op1 = copy_to_mode_reg (mode1, op1);
10377 scratch = gen_reg_rtx (mode0);
10379 pat = GEN_FCN (icode) (scratch, op0, op1);
10384 /* The vec_any* and vec_all* predicates use the same opcodes for two
10385 different operations, but the bits in CR6 will be different
10386 depending on what information we want. So we have to play tricks
10387 with CR6 to get the right bits out.
10389 If you think this is disgusting, look at the specs for the
10390 AltiVec predicates. */
10392 switch (cr6_form_int)
10395 emit_insn (gen_cr6_test_for_zero (target));
10398 emit_insn (gen_cr6_test_for_zero_reverse (target));
10401 emit_insn (gen_cr6_test_for_lt (target));
10404 emit_insn (gen_cr6_test_for_lt_reverse (target));
10407 error ("argument 1 of __builtin_altivec_predicate is out of range");
10415 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10418 tree arg0 = CALL_EXPR_ARG (exp, 0);
10419 tree arg1 = CALL_EXPR_ARG (exp, 1);
10420 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10421 enum machine_mode mode0 = Pmode;
10422 enum machine_mode mode1 = Pmode;
10423 rtx op0 = expand_normal (arg0);
10424 rtx op1 = expand_normal (arg1);
10426 if (icode == CODE_FOR_nothing)
10427 /* Builtin not supported on this processor. */
10430 /* If we got invalid arguments bail out before generating bad rtl. */
10431 if (arg0 == error_mark_node || arg1 == error_mark_node)
10435 || GET_MODE (target) != tmode
10436 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10437 target = gen_reg_rtx (tmode);
10439 op1 = copy_to_mode_reg (mode1, op1);
10441 if (op0 == const0_rtx)
10443 addr = gen_rtx_MEM (tmode, op1);
10447 op0 = copy_to_mode_reg (mode0, op0);
10448 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10451 pat = GEN_FCN (icode) (target, addr);
10461 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10464 tree arg0 = CALL_EXPR_ARG (exp, 0);
10465 tree arg1 = CALL_EXPR_ARG (exp, 1);
10466 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10467 enum machine_mode mode0 = Pmode;
10468 enum machine_mode mode1 = Pmode;
10469 rtx op0 = expand_normal (arg0);
10470 rtx op1 = expand_normal (arg1);
10472 if (icode == CODE_FOR_nothing)
10473 /* Builtin not supported on this processor. */
10476 /* If we got invalid arguments bail out before generating bad rtl. */
10477 if (arg0 == error_mark_node || arg1 == error_mark_node)
10481 || GET_MODE (target) != tmode
10482 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10483 target = gen_reg_rtx (tmode);
10485 op1 = copy_to_mode_reg (mode1, op1);
10487 if (op0 == const0_rtx)
10489 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10493 op0 = copy_to_mode_reg (mode0, op0);
10494 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10497 pat = GEN_FCN (icode) (target, addr);
10507 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10509 tree arg0 = CALL_EXPR_ARG (exp, 0);
10510 tree arg1 = CALL_EXPR_ARG (exp, 1);
10511 tree arg2 = CALL_EXPR_ARG (exp, 2);
10512 rtx op0 = expand_normal (arg0);
10513 rtx op1 = expand_normal (arg1);
10514 rtx op2 = expand_normal (arg2);
10516 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10517 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10518 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10520 /* Invalid arguments. Bail before doing anything stoopid! */
10521 if (arg0 == error_mark_node
10522 || arg1 == error_mark_node
10523 || arg2 == error_mark_node)
10526 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10527 op0 = copy_to_mode_reg (mode2, op0);
10528 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10529 op1 = copy_to_mode_reg (mode0, op1);
10530 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10531 op2 = copy_to_mode_reg (mode1, op2);
10533 pat = GEN_FCN (icode) (op1, op2, op0);
10540 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10542 tree arg0 = CALL_EXPR_ARG (exp, 0);
10543 tree arg1 = CALL_EXPR_ARG (exp, 1);
10544 tree arg2 = CALL_EXPR_ARG (exp, 2);
10545 rtx op0 = expand_normal (arg0);
10546 rtx op1 = expand_normal (arg1);
10547 rtx op2 = expand_normal (arg2);
10549 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10550 enum machine_mode mode1 = Pmode;
10551 enum machine_mode mode2 = Pmode;
10553 /* Invalid arguments. Bail before doing anything stoopid! */
10554 if (arg0 == error_mark_node
10555 || arg1 == error_mark_node
10556 || arg2 == error_mark_node)
10559 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10560 op0 = copy_to_mode_reg (tmode, op0);
10562 op2 = copy_to_mode_reg (mode2, op2);
10564 if (op1 == const0_rtx)
10566 addr = gen_rtx_MEM (tmode, op2);
10570 op1 = copy_to_mode_reg (mode1, op1);
10571 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10574 pat = GEN_FCN (icode) (addr, op0);
10581 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10583 tree arg0 = CALL_EXPR_ARG (exp, 0);
10584 tree arg1 = CALL_EXPR_ARG (exp, 1);
10585 tree arg2 = CALL_EXPR_ARG (exp, 2);
10586 rtx op0 = expand_normal (arg0);
10587 rtx op1 = expand_normal (arg1);
10588 rtx op2 = expand_normal (arg2);
10590 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10591 enum machine_mode mode1 = Pmode;
10592 enum machine_mode mode2 = Pmode;
10594 /* Invalid arguments. Bail before doing anything stoopid! */
10595 if (arg0 == error_mark_node
10596 || arg1 == error_mark_node
10597 || arg2 == error_mark_node)
10600 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10601 op0 = copy_to_mode_reg (tmode, op0);
10603 op2 = copy_to_mode_reg (mode2, op2);
10605 if (op1 == const0_rtx)
10607 addr = gen_rtx_MEM (tmode, op2);
10611 op1 = copy_to_mode_reg (mode1, op1);
10612 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10615 pat = GEN_FCN (icode) (addr, op0);
10622 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10625 tree arg0 = CALL_EXPR_ARG (exp, 0);
10626 tree arg1 = CALL_EXPR_ARG (exp, 1);
10627 tree arg2 = CALL_EXPR_ARG (exp, 2);
10628 rtx op0 = expand_normal (arg0);
10629 rtx op1 = expand_normal (arg1);
10630 rtx op2 = expand_normal (arg2);
10631 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10632 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10633 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10634 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10636 if (icode == CODE_FOR_nothing)
10637 /* Builtin not supported on this processor. */
10640 /* If we got invalid arguments bail out before generating bad rtl. */
10641 if (arg0 == error_mark_node
10642 || arg1 == error_mark_node
10643 || arg2 == error_mark_node)
10648 case CODE_FOR_altivec_vsldoi_v4sf:
10649 case CODE_FOR_altivec_vsldoi_v4si:
10650 case CODE_FOR_altivec_vsldoi_v8hi:
10651 case CODE_FOR_altivec_vsldoi_v16qi:
10652 /* Only allow 4-bit unsigned literals. */
10654 if (TREE_CODE (arg2) != INTEGER_CST
10655 || TREE_INT_CST_LOW (arg2) & ~0xf)
10657 error ("argument 3 must be a 4-bit unsigned literal");
10662 case CODE_FOR_vsx_xxpermdi_v2df:
10663 case CODE_FOR_vsx_xxpermdi_v2di:
10664 case CODE_FOR_vsx_xxsldwi_v16qi:
10665 case CODE_FOR_vsx_xxsldwi_v8hi:
10666 case CODE_FOR_vsx_xxsldwi_v4si:
10667 case CODE_FOR_vsx_xxsldwi_v4sf:
10668 case CODE_FOR_vsx_xxsldwi_v2di:
10669 case CODE_FOR_vsx_xxsldwi_v2df:
10670 /* Only allow 2-bit unsigned literals. */
10672 if (TREE_CODE (arg2) != INTEGER_CST
10673 || TREE_INT_CST_LOW (arg2) & ~0x3)
10675 error ("argument 3 must be a 2-bit unsigned literal");
10680 case CODE_FOR_vsx_set_v2df:
10681 case CODE_FOR_vsx_set_v2di:
10682 /* Only allow 1-bit unsigned literals. */
10684 if (TREE_CODE (arg2) != INTEGER_CST
10685 || TREE_INT_CST_LOW (arg2) & ~0x1)
10687 error ("argument 3 must be a 1-bit unsigned literal");
10697 || GET_MODE (target) != tmode
10698 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10699 target = gen_reg_rtx (tmode);
10701 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10702 op0 = copy_to_mode_reg (mode0, op0);
10703 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10704 op1 = copy_to_mode_reg (mode1, op1);
10705 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10706 op2 = copy_to_mode_reg (mode2, op2);
10708 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10709 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10711 pat = GEN_FCN (icode) (target, op0, op1, op2);
10719 /* Expand the lvx builtins. */
10721 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10723 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10724 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10726 enum machine_mode tmode, mode0;
10728 enum insn_code icode;
10732 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10733 icode = CODE_FOR_vector_load_v16qi;
10735 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10736 icode = CODE_FOR_vector_load_v8hi;
10738 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10739 icode = CODE_FOR_vector_load_v4si;
10741 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10742 icode = CODE_FOR_vector_load_v4sf;
10745 *expandedp = false;
10751 arg0 = CALL_EXPR_ARG (exp, 0);
10752 op0 = expand_normal (arg0);
10753 tmode = insn_data[icode].operand[0].mode;
10754 mode0 = insn_data[icode].operand[1].mode;
10757 || GET_MODE (target) != tmode
10758 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10759 target = gen_reg_rtx (tmode);
10761 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10762 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10764 pat = GEN_FCN (icode) (target, op0);
10771 /* Expand the stvx builtins. */
10773 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10776 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10777 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10779 enum machine_mode mode0, mode1;
10781 enum insn_code icode;
10785 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10786 icode = CODE_FOR_vector_store_v16qi;
10788 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10789 icode = CODE_FOR_vector_store_v8hi;
10791 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10792 icode = CODE_FOR_vector_store_v4si;
10794 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10795 icode = CODE_FOR_vector_store_v4sf;
10798 *expandedp = false;
10802 arg0 = CALL_EXPR_ARG (exp, 0);
10803 arg1 = CALL_EXPR_ARG (exp, 1);
10804 op0 = expand_normal (arg0);
10805 op1 = expand_normal (arg1);
10806 mode0 = insn_data[icode].operand[0].mode;
10807 mode1 = insn_data[icode].operand[1].mode;
10809 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10810 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10811 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10812 op1 = copy_to_mode_reg (mode1, op1);
10814 pat = GEN_FCN (icode) (op0, op1);
10822 /* Expand the dst builtins. */
10824 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10827 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10828 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10829 tree arg0, arg1, arg2;
10830 enum machine_mode mode0, mode1;
10831 rtx pat, op0, op1, op2;
10832 const struct builtin_description *d;
10835 *expandedp = false;
10837 /* Handle DST variants. */
10839 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10840 if (d->code == fcode)
10842 arg0 = CALL_EXPR_ARG (exp, 0);
10843 arg1 = CALL_EXPR_ARG (exp, 1);
10844 arg2 = CALL_EXPR_ARG (exp, 2);
10845 op0 = expand_normal (arg0);
10846 op1 = expand_normal (arg1);
10847 op2 = expand_normal (arg2);
10848 mode0 = insn_data[d->icode].operand[0].mode;
10849 mode1 = insn_data[d->icode].operand[1].mode;
10851 /* Invalid arguments, bail out before generating bad rtl. */
10852 if (arg0 == error_mark_node
10853 || arg1 == error_mark_node
10854 || arg2 == error_mark_node)
10859 if (TREE_CODE (arg2) != INTEGER_CST
10860 || TREE_INT_CST_LOW (arg2) & ~0x3)
10862 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10866 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10867 op0 = copy_to_mode_reg (Pmode, op0);
10868 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10869 op1 = copy_to_mode_reg (mode1, op1);
10871 pat = GEN_FCN (d->icode) (op0, op1, op2);
10881 /* Expand vec_init builtin. */
10883 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10885 enum machine_mode tmode = TYPE_MODE (type);
10886 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10887 int i, n_elt = GET_MODE_NUNITS (tmode);
10888 rtvec v = rtvec_alloc (n_elt);
10890 gcc_assert (VECTOR_MODE_P (tmode));
10891 gcc_assert (n_elt == call_expr_nargs (exp));
10893 for (i = 0; i < n_elt; ++i)
10895 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10896 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10899 if (!target || !register_operand (target, tmode))
10900 target = gen_reg_rtx (tmode);
10902 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10906 /* Return the integer constant in ARG. Constrain it to be in the range
10907 of the subparts of VEC_TYPE; issue an error if not. */
10910 get_element_number (tree vec_type, tree arg)
10912 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10914 if (!host_integerp (arg, 1)
10915 || (elt = tree_low_cst (arg, 1), elt > max))
10917 error ("selector must be an integer constant in the range 0..%wi", max);
10924 /* Expand vec_set builtin. */
10926 altivec_expand_vec_set_builtin (tree exp)
10928 enum machine_mode tmode, mode1;
10929 tree arg0, arg1, arg2;
10933 arg0 = CALL_EXPR_ARG (exp, 0);
10934 arg1 = CALL_EXPR_ARG (exp, 1);
10935 arg2 = CALL_EXPR_ARG (exp, 2);
10937 tmode = TYPE_MODE (TREE_TYPE (arg0));
10938 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10939 gcc_assert (VECTOR_MODE_P (tmode));
10941 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10942 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10943 elt = get_element_number (TREE_TYPE (arg0), arg2);
10945 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10946 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10948 op0 = force_reg (tmode, op0);
10949 op1 = force_reg (mode1, op1);
10951 rs6000_expand_vector_set (op0, op1, elt);
10956 /* Expand vec_ext builtin. */
10958 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10960 enum machine_mode tmode, mode0;
10965 arg0 = CALL_EXPR_ARG (exp, 0);
10966 arg1 = CALL_EXPR_ARG (exp, 1);
10968 op0 = expand_normal (arg0);
10969 elt = get_element_number (TREE_TYPE (arg0), arg1);
10971 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10972 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10973 gcc_assert (VECTOR_MODE_P (mode0));
10975 op0 = force_reg (mode0, op0);
10977 if (optimize || !target || !register_operand (target, tmode))
10978 target = gen_reg_rtx (tmode);
10980 rs6000_expand_vector_extract (target, op0, elt);
10985 /* Expand the builtin in EXP and store the result in TARGET. Store
10986 true in *EXPANDEDP if we found a builtin to expand. */
10988 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10990 const struct builtin_description *d;
10991 const struct builtin_description_predicates *dp;
10993 enum insn_code icode;
10994 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10997 enum machine_mode tmode, mode0;
10998 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11000 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11001 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11002 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11003 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11006 error ("unresolved overload for Altivec builtin %qF", fndecl);
11010 target = altivec_expand_ld_builtin (exp, target, expandedp);
11014 target = altivec_expand_st_builtin (exp, target, expandedp);
11018 target = altivec_expand_dst_builtin (exp, target, expandedp);
11026 case ALTIVEC_BUILTIN_STVX:
11027 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11028 case ALTIVEC_BUILTIN_STVEBX:
11029 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11030 case ALTIVEC_BUILTIN_STVEHX:
11031 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11032 case ALTIVEC_BUILTIN_STVEWX:
11033 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11034 case ALTIVEC_BUILTIN_STVXL:
11035 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11037 case ALTIVEC_BUILTIN_STVLX:
11038 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11039 case ALTIVEC_BUILTIN_STVLXL:
11040 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11041 case ALTIVEC_BUILTIN_STVRX:
11042 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11043 case ALTIVEC_BUILTIN_STVRXL:
11044 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11046 case ALTIVEC_BUILTIN_MFVSCR:
11047 icode = CODE_FOR_altivec_mfvscr;
11048 tmode = insn_data[icode].operand[0].mode;
11051 || GET_MODE (target) != tmode
11052 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11053 target = gen_reg_rtx (tmode);
11055 pat = GEN_FCN (icode) (target);
11061 case ALTIVEC_BUILTIN_MTVSCR:
11062 icode = CODE_FOR_altivec_mtvscr;
11063 arg0 = CALL_EXPR_ARG (exp, 0);
11064 op0 = expand_normal (arg0);
11065 mode0 = insn_data[icode].operand[0].mode;
11067 /* If we got invalid arguments bail out before generating bad rtl. */
11068 if (arg0 == error_mark_node)
11071 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11072 op0 = copy_to_mode_reg (mode0, op0);
11074 pat = GEN_FCN (icode) (op0);
11079 case ALTIVEC_BUILTIN_DSSALL:
11080 emit_insn (gen_altivec_dssall ());
11083 case ALTIVEC_BUILTIN_DSS:
11084 icode = CODE_FOR_altivec_dss;
11085 arg0 = CALL_EXPR_ARG (exp, 0);
11087 op0 = expand_normal (arg0);
11088 mode0 = insn_data[icode].operand[0].mode;
11090 /* If we got invalid arguments bail out before generating bad rtl. */
11091 if (arg0 == error_mark_node)
11094 if (TREE_CODE (arg0) != INTEGER_CST
11095 || TREE_INT_CST_LOW (arg0) & ~0x3)
11097 error ("argument to dss must be a 2-bit unsigned literal");
11101 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11102 op0 = copy_to_mode_reg (mode0, op0);
11104 emit_insn (gen_altivec_dss (op0));
11107 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11108 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11109 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11110 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11111 case VSX_BUILTIN_VEC_INIT_V2DF:
11112 case VSX_BUILTIN_VEC_INIT_V2DI:
11113 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11115 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11116 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11117 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11118 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11119 case VSX_BUILTIN_VEC_SET_V2DF:
11120 case VSX_BUILTIN_VEC_SET_V2DI:
11121 return altivec_expand_vec_set_builtin (exp);
11123 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11124 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11125 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11126 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11127 case VSX_BUILTIN_VEC_EXT_V2DF:
11128 case VSX_BUILTIN_VEC_EXT_V2DI:
11129 return altivec_expand_vec_ext_builtin (exp, target);
11133 /* Fall through. */
11136 /* Expand abs* operations. */
11138 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11139 if (d->code == fcode)
11140 return altivec_expand_abs_builtin (d->icode, exp, target);
11142 /* Expand the AltiVec predicates. */
11143 dp = bdesc_altivec_preds;
11144 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11145 if (dp->code == fcode)
11146 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11148 /* LV* are funky. We initialized them differently. */
11151 case ALTIVEC_BUILTIN_LVSL:
11152 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11153 exp, target, false);
11154 case ALTIVEC_BUILTIN_LVSR:
11155 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11156 exp, target, false);
11157 case ALTIVEC_BUILTIN_LVEBX:
11158 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11159 exp, target, false);
11160 case ALTIVEC_BUILTIN_LVEHX:
11161 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11162 exp, target, false);
11163 case ALTIVEC_BUILTIN_LVEWX:
11164 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11165 exp, target, false);
11166 case ALTIVEC_BUILTIN_LVXL:
11167 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11168 exp, target, false);
11169 case ALTIVEC_BUILTIN_LVX:
11170 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11171 exp, target, false);
11172 case ALTIVEC_BUILTIN_LVLX:
11173 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11174 exp, target, true);
11175 case ALTIVEC_BUILTIN_LVLXL:
11176 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11177 exp, target, true);
11178 case ALTIVEC_BUILTIN_LVRX:
11179 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11180 exp, target, true);
11181 case ALTIVEC_BUILTIN_LVRXL:
11182 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11183 exp, target, true);
11186 /* Fall through. */
11189 *expandedp = false;
11193 /* Expand the builtin in EXP and store the result in TARGET. Store
11194 true in *EXPANDEDP if we found a builtin to expand. */
11196 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11198 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11199 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11200 const struct builtin_description *d;
11207 case PAIRED_BUILTIN_STX:
11208 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11209 case PAIRED_BUILTIN_LX:
11210 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11213 /* Fall through. */
11216 /* Expand the paired predicates. */
11217 d = bdesc_paired_preds;
11218 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11219 if (d->code == fcode)
11220 return paired_expand_predicate_builtin (d->icode, exp, target);
11222 *expandedp = false;
11226 /* Binops that need to be initialized manually, but can be expanded
11227 automagically by rs6000_expand_binop_builtin. */
11228 static struct builtin_description bdesc_2arg_spe[] =
11230 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11231 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11232 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11233 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11234 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11235 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11236 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11237 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11238 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11239 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11240 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11241 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11242 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11243 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11244 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11245 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11246 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11247 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11248 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11249 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11250 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11251 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11254 /* Expand the builtin in EXP and store the result in TARGET. Store
11255 true in *EXPANDEDP if we found a builtin to expand.
11257 This expands the SPE builtins that are not simple unary and binary
11260 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11262 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11264 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11265 enum insn_code icode;
11266 enum machine_mode tmode, mode0;
11268 struct builtin_description *d;
11273 /* Syntax check for a 5-bit unsigned immediate. */
11276 case SPE_BUILTIN_EVSTDD:
11277 case SPE_BUILTIN_EVSTDH:
11278 case SPE_BUILTIN_EVSTDW:
11279 case SPE_BUILTIN_EVSTWHE:
11280 case SPE_BUILTIN_EVSTWHO:
11281 case SPE_BUILTIN_EVSTWWE:
11282 case SPE_BUILTIN_EVSTWWO:
11283 arg1 = CALL_EXPR_ARG (exp, 2);
11284 if (TREE_CODE (arg1) != INTEGER_CST
11285 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11287 error ("argument 2 must be a 5-bit unsigned literal");
11295 /* The evsplat*i instructions are not quite generic. */
11298 case SPE_BUILTIN_EVSPLATFI:
11299 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11301 case SPE_BUILTIN_EVSPLATI:
11302 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11308 d = (struct builtin_description *) bdesc_2arg_spe;
11309 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11310 if (d->code == fcode)
11311 return rs6000_expand_binop_builtin (d->icode, exp, target);
11313 d = (struct builtin_description *) bdesc_spe_predicates;
11314 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11315 if (d->code == fcode)
11316 return spe_expand_predicate_builtin (d->icode, exp, target);
11318 d = (struct builtin_description *) bdesc_spe_evsel;
11319 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11320 if (d->code == fcode)
11321 return spe_expand_evsel_builtin (d->icode, exp, target);
11325 case SPE_BUILTIN_EVSTDDX:
11326 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11327 case SPE_BUILTIN_EVSTDHX:
11328 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11329 case SPE_BUILTIN_EVSTDWX:
11330 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11331 case SPE_BUILTIN_EVSTWHEX:
11332 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11333 case SPE_BUILTIN_EVSTWHOX:
11334 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11335 case SPE_BUILTIN_EVSTWWEX:
11336 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11337 case SPE_BUILTIN_EVSTWWOX:
11338 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11339 case SPE_BUILTIN_EVSTDD:
11340 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11341 case SPE_BUILTIN_EVSTDH:
11342 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11343 case SPE_BUILTIN_EVSTDW:
11344 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11345 case SPE_BUILTIN_EVSTWHE:
11346 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11347 case SPE_BUILTIN_EVSTWHO:
11348 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11349 case SPE_BUILTIN_EVSTWWE:
11350 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11351 case SPE_BUILTIN_EVSTWWO:
11352 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11353 case SPE_BUILTIN_MFSPEFSCR:
11354 icode = CODE_FOR_spe_mfspefscr;
11355 tmode = insn_data[icode].operand[0].mode;
11358 || GET_MODE (target) != tmode
11359 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11360 target = gen_reg_rtx (tmode);
11362 pat = GEN_FCN (icode) (target);
11367 case SPE_BUILTIN_MTSPEFSCR:
11368 icode = CODE_FOR_spe_mtspefscr;
11369 arg0 = CALL_EXPR_ARG (exp, 0);
11370 op0 = expand_normal (arg0);
11371 mode0 = insn_data[icode].operand[0].mode;
11373 if (arg0 == error_mark_node)
11376 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11377 op0 = copy_to_mode_reg (mode0, op0);
11379 pat = GEN_FCN (icode) (op0);
11387 *expandedp = false;
11392 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11394 rtx pat, scratch, tmp;
11395 tree form = CALL_EXPR_ARG (exp, 0);
11396 tree arg0 = CALL_EXPR_ARG (exp, 1);
11397 tree arg1 = CALL_EXPR_ARG (exp, 2);
11398 rtx op0 = expand_normal (arg0);
11399 rtx op1 = expand_normal (arg1);
11400 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11401 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11403 enum rtx_code code;
11405 if (TREE_CODE (form) != INTEGER_CST)
11407 error ("argument 1 of __builtin_paired_predicate must be a constant");
11411 form_int = TREE_INT_CST_LOW (form);
11413 gcc_assert (mode0 == mode1);
11415 if (arg0 == error_mark_node || arg1 == error_mark_node)
11419 || GET_MODE (target) != SImode
11420 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11421 target = gen_reg_rtx (SImode);
11422 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11423 op0 = copy_to_mode_reg (mode0, op0);
11424 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11425 op1 = copy_to_mode_reg (mode1, op1);
11427 scratch = gen_reg_rtx (CCFPmode);
11429 pat = GEN_FCN (icode) (scratch, op0, op1);
11451 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11454 error ("argument 1 of __builtin_paired_predicate is out of range");
11458 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11459 emit_move_insn (target, tmp);
11464 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11466 rtx pat, scratch, tmp;
11467 tree form = CALL_EXPR_ARG (exp, 0);
11468 tree arg0 = CALL_EXPR_ARG (exp, 1);
11469 tree arg1 = CALL_EXPR_ARG (exp, 2);
11470 rtx op0 = expand_normal (arg0);
11471 rtx op1 = expand_normal (arg1);
11472 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11473 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11475 enum rtx_code code;
11477 if (TREE_CODE (form) != INTEGER_CST)
11479 error ("argument 1 of __builtin_spe_predicate must be a constant");
11483 form_int = TREE_INT_CST_LOW (form);
11485 gcc_assert (mode0 == mode1);
11487 if (arg0 == error_mark_node || arg1 == error_mark_node)
11491 || GET_MODE (target) != SImode
11492 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11493 target = gen_reg_rtx (SImode);
11495 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11496 op0 = copy_to_mode_reg (mode0, op0);
11497 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11498 op1 = copy_to_mode_reg (mode1, op1);
11500 scratch = gen_reg_rtx (CCmode);
11502 pat = GEN_FCN (icode) (scratch, op0, op1);
11507 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11508 _lower_. We use one compare, but look in different bits of the
11509 CR for each variant.
11511 There are 2 elements in each SPE simd type (upper/lower). The CR
11512 bits are set as follows:
11514 BIT0 | BIT 1 | BIT 2 | BIT 3
11515 U | L | (U | L) | (U & L)
11517 So, for an "all" relationship, BIT 3 would be set.
11518 For an "any" relationship, BIT 2 would be set. Etc.
11520 Following traditional nomenclature, these bits map to:
11522 BIT0 | BIT 1 | BIT 2 | BIT 3
11525 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11530 /* All variant. OV bit. */
11532 /* We need to get to the OV bit, which is the ORDERED bit. We
11533 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11534 that's ugly and will make validate_condition_mode die.
11535 So let's just use another pattern. */
11536 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11538 /* Any variant. EQ bit. */
11542 /* Upper variant. LT bit. */
11546 /* Lower variant. GT bit. */
11551 error ("argument 1 of __builtin_spe_predicate is out of range");
11555 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11556 emit_move_insn (target, tmp);
11561 /* The evsel builtins look like this:
11563 e = __builtin_spe_evsel_OP (a, b, c, d);
11565 and work like this:
11567 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11568 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11572 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11575 tree arg0 = CALL_EXPR_ARG (exp, 0);
11576 tree arg1 = CALL_EXPR_ARG (exp, 1);
11577 tree arg2 = CALL_EXPR_ARG (exp, 2);
11578 tree arg3 = CALL_EXPR_ARG (exp, 3);
11579 rtx op0 = expand_normal (arg0);
11580 rtx op1 = expand_normal (arg1);
11581 rtx op2 = expand_normal (arg2);
11582 rtx op3 = expand_normal (arg3);
11583 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11584 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11586 gcc_assert (mode0 == mode1);
11588 if (arg0 == error_mark_node || arg1 == error_mark_node
11589 || arg2 == error_mark_node || arg3 == error_mark_node)
11593 || GET_MODE (target) != mode0
11594 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11595 target = gen_reg_rtx (mode0);
11597 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11598 op0 = copy_to_mode_reg (mode0, op0);
11599 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11600 op1 = copy_to_mode_reg (mode0, op1);
11601 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11602 op2 = copy_to_mode_reg (mode0, op2);
11603 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11604 op3 = copy_to_mode_reg (mode0, op3);
11606 /* Generate the compare. */
11607 scratch = gen_reg_rtx (CCmode);
11608 pat = GEN_FCN (icode) (scratch, op0, op1);
11613 if (mode0 == V2SImode)
11614 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11616 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11621 /* Expand an expression EXP that calls a built-in function,
11622 with result going to TARGET if that's convenient
11623 (and in mode MODE if that's convenient).
11624 SUBTARGET may be used as the target for computing one of EXP's operands.
11625 IGNORE is nonzero if the value is to be ignored. */
11628 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11629 enum machine_mode mode ATTRIBUTE_UNUSED,
11630 int ignore ATTRIBUTE_UNUSED)
11632 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11633 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11634 const struct builtin_description *d;
11641 case RS6000_BUILTIN_RECIP:
11642 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11644 case RS6000_BUILTIN_RECIPF:
11645 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11647 case RS6000_BUILTIN_RSQRTF:
11648 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11650 case RS6000_BUILTIN_RSQRT:
11651 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11653 case RS6000_BUILTIN_BSWAP_HI:
11654 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11656 case POWER7_BUILTIN_BPERMD:
11657 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11658 ? CODE_FOR_bpermd_di
11659 : CODE_FOR_bpermd_si), exp, target);
11661 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11662 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11664 int icode = (int) CODE_FOR_altivec_lvsr;
11665 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11666 enum machine_mode mode = insn_data[icode].operand[1].mode;
11670 gcc_assert (TARGET_ALTIVEC);
11672 arg = CALL_EXPR_ARG (exp, 0);
11673 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11674 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11675 addr = memory_address (mode, op);
11676 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11680 /* For the load case need to negate the address. */
11681 op = gen_reg_rtx (GET_MODE (addr));
11682 emit_insn (gen_rtx_SET (VOIDmode, op,
11683 gen_rtx_NEG (GET_MODE (addr), addr)));
11685 op = gen_rtx_MEM (mode, op);
11688 || GET_MODE (target) != tmode
11689 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11690 target = gen_reg_rtx (tmode);
11692 /*pat = gen_altivec_lvsr (target, op);*/
11693 pat = GEN_FCN (icode) (target, op);
11701 case ALTIVEC_BUILTIN_VCFUX:
11702 case ALTIVEC_BUILTIN_VCFSX:
11703 case ALTIVEC_BUILTIN_VCTUXS:
11704 case ALTIVEC_BUILTIN_VCTSXS:
11705 /* FIXME: There's got to be a nicer way to handle this case than
11706 constructing a new CALL_EXPR. */
11707 if (call_expr_nargs (exp) == 1)
11709 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11710 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11718 if (TARGET_ALTIVEC)
11720 ret = altivec_expand_builtin (exp, target, &success);
11727 ret = spe_expand_builtin (exp, target, &success);
11732 if (TARGET_PAIRED_FLOAT)
11734 ret = paired_expand_builtin (exp, target, &success);
11740 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11742 /* Handle simple unary operations. */
11743 d = (struct builtin_description *) bdesc_1arg;
11744 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11745 if (d->code == fcode)
11746 return rs6000_expand_unop_builtin (d->icode, exp, target);
11748 /* Handle simple binary operations. */
11749 d = (struct builtin_description *) bdesc_2arg;
11750 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11751 if (d->code == fcode)
11752 return rs6000_expand_binop_builtin (d->icode, exp, target);
11754 /* Handle simple ternary operations. */
11756 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11757 if (d->code == fcode)
11758 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11760 gcc_unreachable ();
11764 rs6000_init_builtins (void)
11769 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11770 V2SF_type_node = build_vector_type (float_type_node, 2);
11771 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11772 V2DF_type_node = build_vector_type (double_type_node, 2);
11773 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11774 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11775 V4SF_type_node = build_vector_type (float_type_node, 4);
11776 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11777 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11779 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11780 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11781 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11782 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11784 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11785 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11786 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11787 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11789 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11790 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11791 'vector unsigned short'. */
11793 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11794 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11795 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11796 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11797 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11799 long_integer_type_internal_node = long_integer_type_node;
11800 long_unsigned_type_internal_node = long_unsigned_type_node;
11801 intQI_type_internal_node = intQI_type_node;
11802 uintQI_type_internal_node = unsigned_intQI_type_node;
11803 intHI_type_internal_node = intHI_type_node;
11804 uintHI_type_internal_node = unsigned_intHI_type_node;
11805 intSI_type_internal_node = intSI_type_node;
11806 uintSI_type_internal_node = unsigned_intSI_type_node;
11807 intDI_type_internal_node = intDI_type_node;
11808 uintDI_type_internal_node = unsigned_intDI_type_node;
11809 float_type_internal_node = float_type_node;
11810 double_type_internal_node = float_type_node;
11811 void_type_internal_node = void_type_node;
11813 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11815 builtin_mode_to_type[QImode][0] = integer_type_node;
11816 builtin_mode_to_type[HImode][0] = integer_type_node;
11817 builtin_mode_to_type[SImode][0] = intSI_type_node;
11818 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11819 builtin_mode_to_type[DImode][0] = intDI_type_node;
11820 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11821 builtin_mode_to_type[SFmode][0] = float_type_node;
11822 builtin_mode_to_type[DFmode][0] = double_type_node;
11823 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11824 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11825 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11826 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11827 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11828 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11829 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11830 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11831 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11832 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11833 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11834 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11835 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11837 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11838 get_identifier ("__bool char"),
11839 bool_char_type_node);
11840 TYPE_NAME (bool_char_type_node) = tdecl;
11841 (*lang_hooks.decls.pushdecl) (tdecl);
11842 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11843 get_identifier ("__bool short"),
11844 bool_short_type_node);
11845 TYPE_NAME (bool_short_type_node) = tdecl;
11846 (*lang_hooks.decls.pushdecl) (tdecl);
11847 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11848 get_identifier ("__bool int"),
11849 bool_int_type_node);
11850 TYPE_NAME (bool_int_type_node) = tdecl;
11851 (*lang_hooks.decls.pushdecl) (tdecl);
11852 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11854 TYPE_NAME (pixel_type_node) = tdecl;
11855 (*lang_hooks.decls.pushdecl) (tdecl);
11857 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11858 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11859 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11860 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11861 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11863 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11864 get_identifier ("__vector unsigned char"),
11865 unsigned_V16QI_type_node);
11866 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11867 (*lang_hooks.decls.pushdecl) (tdecl);
11868 tdecl = build_decl (BUILTINS_LOCATION,
11869 TYPE_DECL, get_identifier ("__vector signed char"),
11871 TYPE_NAME (V16QI_type_node) = tdecl;
11872 (*lang_hooks.decls.pushdecl) (tdecl);
11873 tdecl = build_decl (BUILTINS_LOCATION,
11874 TYPE_DECL, get_identifier ("__vector __bool char"),
11875 bool_V16QI_type_node);
11876 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11877 (*lang_hooks.decls.pushdecl) (tdecl);
11879 tdecl = build_decl (BUILTINS_LOCATION,
11880 TYPE_DECL, get_identifier ("__vector unsigned short"),
11881 unsigned_V8HI_type_node);
11882 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11883 (*lang_hooks.decls.pushdecl) (tdecl);
11884 tdecl = build_decl (BUILTINS_LOCATION,
11885 TYPE_DECL, get_identifier ("__vector signed short"),
11887 TYPE_NAME (V8HI_type_node) = tdecl;
11888 (*lang_hooks.decls.pushdecl) (tdecl);
11889 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11890 get_identifier ("__vector __bool short"),
11891 bool_V8HI_type_node);
11892 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11893 (*lang_hooks.decls.pushdecl) (tdecl);
11895 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11896 get_identifier ("__vector unsigned int"),
11897 unsigned_V4SI_type_node);
11898 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11899 (*lang_hooks.decls.pushdecl) (tdecl);
11900 tdecl = build_decl (BUILTINS_LOCATION,
11901 TYPE_DECL, get_identifier ("__vector signed int"),
11903 TYPE_NAME (V4SI_type_node) = tdecl;
11904 (*lang_hooks.decls.pushdecl) (tdecl);
11905 tdecl = build_decl (BUILTINS_LOCATION,
11906 TYPE_DECL, get_identifier ("__vector __bool int"),
11907 bool_V4SI_type_node);
11908 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11909 (*lang_hooks.decls.pushdecl) (tdecl);
11911 tdecl = build_decl (BUILTINS_LOCATION,
11912 TYPE_DECL, get_identifier ("__vector float"),
11914 TYPE_NAME (V4SF_type_node) = tdecl;
11915 (*lang_hooks.decls.pushdecl) (tdecl);
11916 tdecl = build_decl (BUILTINS_LOCATION,
11917 TYPE_DECL, get_identifier ("__vector __pixel"),
11918 pixel_V8HI_type_node);
11919 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11920 (*lang_hooks.decls.pushdecl) (tdecl);
11924 tdecl = build_decl (BUILTINS_LOCATION,
11925 TYPE_DECL, get_identifier ("__vector double"),
11927 TYPE_NAME (V2DF_type_node) = tdecl;
11928 (*lang_hooks.decls.pushdecl) (tdecl);
11930 tdecl = build_decl (BUILTINS_LOCATION,
11931 TYPE_DECL, get_identifier ("__vector long"),
11933 TYPE_NAME (V2DI_type_node) = tdecl;
11934 (*lang_hooks.decls.pushdecl) (tdecl);
11936 tdecl = build_decl (BUILTINS_LOCATION,
11937 TYPE_DECL, get_identifier ("__vector unsigned long"),
11938 unsigned_V2DI_type_node);
11939 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11940 (*lang_hooks.decls.pushdecl) (tdecl);
11942 tdecl = build_decl (BUILTINS_LOCATION,
11943 TYPE_DECL, get_identifier ("__vector __bool long"),
11944 bool_V2DI_type_node);
11945 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11946 (*lang_hooks.decls.pushdecl) (tdecl);
11949 if (TARGET_PAIRED_FLOAT)
11950 paired_init_builtins ();
11952 spe_init_builtins ();
11953 if (TARGET_ALTIVEC)
11954 altivec_init_builtins ();
11955 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11956 rs6000_common_init_builtins ();
11959 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11960 RS6000_BUILTIN_RECIP,
11961 "__builtin_recipdiv");
11962 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11963 RS6000_BUILTIN_RECIP);
11967 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11968 RS6000_BUILTIN_RECIPF,
11969 "__builtin_recipdivf");
11970 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11971 RS6000_BUILTIN_RECIPF);
11973 if (TARGET_FRSQRTE)
11975 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
11976 RS6000_BUILTIN_RSQRT,
11977 "__builtin_rsqrt");
11978 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
11979 RS6000_BUILTIN_RSQRT);
11981 if (TARGET_FRSQRTES)
11983 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11984 RS6000_BUILTIN_RSQRTF,
11985 "__builtin_rsqrtf");
11986 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11987 RS6000_BUILTIN_RSQRTF);
11989 if (TARGET_POPCNTD)
11991 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11992 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11993 POWER7_BUILTIN_BPERMD,
11994 "__builtin_bpermd");
11995 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11996 POWER7_BUILTIN_BPERMD);
11998 if (TARGET_POWERPC)
12000 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12001 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12002 unsigned_intHI_type_node,
12004 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12005 RS6000_BUILTIN_BSWAP_HI);
12009 /* AIX libm provides clog as __clog. */
12010 if (built_in_decls [BUILT_IN_CLOG])
12011 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12014 #ifdef SUBTARGET_INIT_BUILTINS
12015 SUBTARGET_INIT_BUILTINS;
12019 /* Returns the rs6000 builtin decl for CODE. */
12022 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12024 if (code >= RS6000_BUILTIN_COUNT)
12025 return error_mark_node;
12027 return rs6000_builtin_decls[code];
12030 /* Search through a set of builtins and enable the mask bits.
12031 DESC is an array of builtins.
12032 SIZE is the total number of builtins.
12033 START is the builtin enum at which to start.
12034 END is the builtin enum at which to end. */
12036 enable_mask_for_builtins (struct builtin_description *desc, int size,
12037 enum rs6000_builtins start,
12038 enum rs6000_builtins end)
12042 for (i = 0; i < size; ++i)
12043 if (desc[i].code == start)
12049 for (; i < size; ++i)
12051 /* Flip all the bits on. */
12052 desc[i].mask = target_flags;
12053 if (desc[i].code == end)
12059 spe_init_builtins (void)
12061 tree endlink = void_list_node;
12062 tree puint_type_node = build_pointer_type (unsigned_type_node);
12063 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12064 struct builtin_description *d;
12067 tree v2si_ftype_4_v2si
12068 = build_function_type
12069 (opaque_V2SI_type_node,
12070 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12071 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12072 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12073 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12076 tree v2sf_ftype_4_v2sf
12077 = build_function_type
12078 (opaque_V2SF_type_node,
12079 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12080 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12081 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12082 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12085 tree int_ftype_int_v2si_v2si
12086 = build_function_type
12087 (integer_type_node,
12088 tree_cons (NULL_TREE, integer_type_node,
12089 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12090 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12093 tree int_ftype_int_v2sf_v2sf
12094 = build_function_type
12095 (integer_type_node,
12096 tree_cons (NULL_TREE, integer_type_node,
12097 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12098 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12101 tree void_ftype_v2si_puint_int
12102 = build_function_type (void_type_node,
12103 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12104 tree_cons (NULL_TREE, puint_type_node,
12105 tree_cons (NULL_TREE,
12109 tree void_ftype_v2si_puint_char
12110 = build_function_type (void_type_node,
12111 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12112 tree_cons (NULL_TREE, puint_type_node,
12113 tree_cons (NULL_TREE,
12117 tree void_ftype_v2si_pv2si_int
12118 = build_function_type (void_type_node,
12119 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12120 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12121 tree_cons (NULL_TREE,
12125 tree void_ftype_v2si_pv2si_char
12126 = build_function_type (void_type_node,
12127 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12128 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12129 tree_cons (NULL_TREE,
12133 tree void_ftype_int
12134 = build_function_type (void_type_node,
12135 tree_cons (NULL_TREE, integer_type_node, endlink));
12137 tree int_ftype_void
12138 = build_function_type (integer_type_node, endlink);
12140 tree v2si_ftype_pv2si_int
12141 = build_function_type (opaque_V2SI_type_node,
12142 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12143 tree_cons (NULL_TREE, integer_type_node,
12146 tree v2si_ftype_puint_int
12147 = build_function_type (opaque_V2SI_type_node,
12148 tree_cons (NULL_TREE, puint_type_node,
12149 tree_cons (NULL_TREE, integer_type_node,
12152 tree v2si_ftype_pushort_int
12153 = build_function_type (opaque_V2SI_type_node,
12154 tree_cons (NULL_TREE, pushort_type_node,
12155 tree_cons (NULL_TREE, integer_type_node,
12158 tree v2si_ftype_signed_char
12159 = build_function_type (opaque_V2SI_type_node,
12160 tree_cons (NULL_TREE, signed_char_type_node,
12163 /* The initialization of the simple binary and unary builtins is
12164 done in rs6000_common_init_builtins, but we have to enable the
12165 mask bits here manually because we have run out of `target_flags'
12166 bits. We really need to redesign this mask business. */
12168 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12169 ARRAY_SIZE (bdesc_2arg),
12170 SPE_BUILTIN_EVADDW,
12171 SPE_BUILTIN_EVXOR);
12172 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12173 ARRAY_SIZE (bdesc_1arg),
12175 SPE_BUILTIN_EVSUBFUSIAAW);
12176 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12177 ARRAY_SIZE (bdesc_spe_predicates),
12178 SPE_BUILTIN_EVCMPEQ,
12179 SPE_BUILTIN_EVFSTSTLT);
12180 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12181 ARRAY_SIZE (bdesc_spe_evsel),
12182 SPE_BUILTIN_EVSEL_CMPGTS,
12183 SPE_BUILTIN_EVSEL_FSTSTEQ);
12185 (*lang_hooks.decls.pushdecl)
12186 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12187 get_identifier ("__ev64_opaque__"),
12188 opaque_V2SI_type_node));
12190 /* Initialize irregular SPE builtins. */
12192 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12193 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12194 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12195 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12196 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12197 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12198 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12199 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12200 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12201 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12202 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12203 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12204 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12205 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12206 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12207 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12208 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12209 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12212 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12213 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12214 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12215 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12216 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12217 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12218 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12219 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12220 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12221 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12222 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12223 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12224 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12225 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12226 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12227 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12228 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12229 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12230 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12231 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12232 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12233 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12236 d = (struct builtin_description *) bdesc_spe_predicates;
12237 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12241 switch (insn_data[d->icode].operand[1].mode)
12244 type = int_ftype_int_v2si_v2si;
12247 type = int_ftype_int_v2sf_v2sf;
12250 gcc_unreachable ();
12253 def_builtin (d->mask, d->name, type, d->code);
12256 /* Evsel predicates. */
12257 d = (struct builtin_description *) bdesc_spe_evsel;
12258 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12262 switch (insn_data[d->icode].operand[1].mode)
12265 type = v2si_ftype_4_v2si;
12268 type = v2sf_ftype_4_v2sf;
12271 gcc_unreachable ();
12274 def_builtin (d->mask, d->name, type, d->code);
12279 paired_init_builtins (void)
12281 const struct builtin_description *d;
12283 tree endlink = void_list_node;
12285 tree int_ftype_int_v2sf_v2sf
12286 = build_function_type
12287 (integer_type_node,
12288 tree_cons (NULL_TREE, integer_type_node,
12289 tree_cons (NULL_TREE, V2SF_type_node,
12290 tree_cons (NULL_TREE, V2SF_type_node,
12292 tree pcfloat_type_node =
12293 build_pointer_type (build_qualified_type
12294 (float_type_node, TYPE_QUAL_CONST));
12296 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12297 long_integer_type_node,
12300 tree void_ftype_v2sf_long_pcfloat =
12301 build_function_type_list (void_type_node,
12303 long_integer_type_node,
12308 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12309 PAIRED_BUILTIN_LX);
12312 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12313 PAIRED_BUILTIN_STX);
12316 d = bdesc_paired_preds;
12317 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12321 switch (insn_data[d->icode].operand[1].mode)
12324 type = int_ftype_int_v2sf_v2sf;
12327 gcc_unreachable ();
12330 def_builtin (d->mask, d->name, type, d->code);
12335 altivec_init_builtins (void)
12337 const struct builtin_description *d;
12338 const struct builtin_description_predicates *dp;
12342 tree pfloat_type_node = build_pointer_type (float_type_node);
12343 tree pint_type_node = build_pointer_type (integer_type_node);
12344 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12345 tree pchar_type_node = build_pointer_type (char_type_node);
12347 tree pvoid_type_node = build_pointer_type (void_type_node);
12349 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12350 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12351 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12352 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12354 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12356 tree int_ftype_opaque
12357 = build_function_type_list (integer_type_node,
12358 opaque_V4SI_type_node, NULL_TREE);
12359 tree opaque_ftype_opaque
12360 = build_function_type (integer_type_node,
12362 tree opaque_ftype_opaque_int
12363 = build_function_type_list (opaque_V4SI_type_node,
12364 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12365 tree opaque_ftype_opaque_opaque_int
12366 = build_function_type_list (opaque_V4SI_type_node,
12367 opaque_V4SI_type_node, opaque_V4SI_type_node,
12368 integer_type_node, NULL_TREE);
12369 tree int_ftype_int_opaque_opaque
12370 = build_function_type_list (integer_type_node,
12371 integer_type_node, opaque_V4SI_type_node,
12372 opaque_V4SI_type_node, NULL_TREE);
12373 tree int_ftype_int_v4si_v4si
12374 = build_function_type_list (integer_type_node,
12375 integer_type_node, V4SI_type_node,
12376 V4SI_type_node, NULL_TREE);
12377 tree v4sf_ftype_pcfloat
12378 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12379 tree void_ftype_pfloat_v4sf
12380 = build_function_type_list (void_type_node,
12381 pfloat_type_node, V4SF_type_node, NULL_TREE);
12382 tree v4si_ftype_pcint
12383 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12384 tree void_ftype_pint_v4si
12385 = build_function_type_list (void_type_node,
12386 pint_type_node, V4SI_type_node, NULL_TREE);
12387 tree v8hi_ftype_pcshort
12388 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12389 tree void_ftype_pshort_v8hi
12390 = build_function_type_list (void_type_node,
12391 pshort_type_node, V8HI_type_node, NULL_TREE);
12392 tree v16qi_ftype_pcchar
12393 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12394 tree void_ftype_pchar_v16qi
12395 = build_function_type_list (void_type_node,
12396 pchar_type_node, V16QI_type_node, NULL_TREE);
12397 tree void_ftype_v4si
12398 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12399 tree v8hi_ftype_void
12400 = build_function_type (V8HI_type_node, void_list_node);
12401 tree void_ftype_void
12402 = build_function_type (void_type_node, void_list_node);
12403 tree void_ftype_int
12404 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12406 tree opaque_ftype_long_pcvoid
12407 = build_function_type_list (opaque_V4SI_type_node,
12408 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12409 tree v16qi_ftype_long_pcvoid
12410 = build_function_type_list (V16QI_type_node,
12411 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12412 tree v8hi_ftype_long_pcvoid
12413 = build_function_type_list (V8HI_type_node,
12414 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12415 tree v4si_ftype_long_pcvoid
12416 = build_function_type_list (V4SI_type_node,
12417 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12419 tree void_ftype_opaque_long_pvoid
12420 = build_function_type_list (void_type_node,
12421 opaque_V4SI_type_node, long_integer_type_node,
12422 pvoid_type_node, NULL_TREE);
12423 tree void_ftype_v4si_long_pvoid
12424 = build_function_type_list (void_type_node,
12425 V4SI_type_node, long_integer_type_node,
12426 pvoid_type_node, NULL_TREE);
12427 tree void_ftype_v16qi_long_pvoid
12428 = build_function_type_list (void_type_node,
12429 V16QI_type_node, long_integer_type_node,
12430 pvoid_type_node, NULL_TREE);
12431 tree void_ftype_v8hi_long_pvoid
12432 = build_function_type_list (void_type_node,
12433 V8HI_type_node, long_integer_type_node,
12434 pvoid_type_node, NULL_TREE);
12435 tree int_ftype_int_v8hi_v8hi
12436 = build_function_type_list (integer_type_node,
12437 integer_type_node, V8HI_type_node,
12438 V8HI_type_node, NULL_TREE);
12439 tree int_ftype_int_v16qi_v16qi
12440 = build_function_type_list (integer_type_node,
12441 integer_type_node, V16QI_type_node,
12442 V16QI_type_node, NULL_TREE);
12443 tree int_ftype_int_v4sf_v4sf
12444 = build_function_type_list (integer_type_node,
12445 integer_type_node, V4SF_type_node,
12446 V4SF_type_node, NULL_TREE);
12447 tree int_ftype_int_v2df_v2df
12448 = build_function_type_list (integer_type_node,
12449 integer_type_node, V2DF_type_node,
12450 V2DF_type_node, NULL_TREE);
12451 tree v4si_ftype_v4si
12452 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12453 tree v8hi_ftype_v8hi
12454 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12455 tree v16qi_ftype_v16qi
12456 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12457 tree v4sf_ftype_v4sf
12458 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12459 tree v2df_ftype_v2df
12460 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12461 tree void_ftype_pcvoid_int_int
12462 = build_function_type_list (void_type_node,
12463 pcvoid_type_node, integer_type_node,
12464 integer_type_node, NULL_TREE);
12466 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12467 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12468 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12469 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12470 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12471 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12472 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12473 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12474 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12475 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12476 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12477 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12478 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12479 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12480 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12481 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12482 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12483 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12484 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12485 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12486 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12487 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12488 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12489 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12490 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12491 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12492 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12493 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12494 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12495 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12496 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12497 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12498 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12499 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12500 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12501 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12502 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12503 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12504 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12505 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12506 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12507 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12508 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12509 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12510 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12511 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12513 if (rs6000_cpu == PROCESSOR_CELL)
12515 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12516 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12517 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12518 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12520 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12521 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12522 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12523 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12525 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12526 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12527 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12528 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12530 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12531 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12532 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12533 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12535 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12536 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12537 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12539 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12540 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12541 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12542 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12543 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12544 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12545 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12546 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12547 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12548 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12549 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12550 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12552 /* Add the DST variants. */
12554 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12555 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12557 /* Initialize the predicates. */
12558 dp = bdesc_altivec_preds;
12559 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12561 enum machine_mode mode1;
12563 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12564 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12565 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12566 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12571 mode1 = insn_data[dp->icode].operand[1].mode;
12576 type = int_ftype_int_opaque_opaque;
12579 type = int_ftype_int_v4si_v4si;
12582 type = int_ftype_int_v8hi_v8hi;
12585 type = int_ftype_int_v16qi_v16qi;
12588 type = int_ftype_int_v4sf_v4sf;
12591 type = int_ftype_int_v2df_v2df;
12594 gcc_unreachable ();
12597 def_builtin (dp->mask, dp->name, type, dp->code);
12600 /* Initialize the abs* operators. */
12602 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12604 enum machine_mode mode0;
12607 mode0 = insn_data[d->icode].operand[0].mode;
12612 type = v4si_ftype_v4si;
12615 type = v8hi_ftype_v8hi;
12618 type = v16qi_ftype_v16qi;
12621 type = v4sf_ftype_v4sf;
12624 type = v2df_ftype_v2df;
12627 gcc_unreachable ();
12630 def_builtin (d->mask, d->name, type, d->code);
12633 if (TARGET_ALTIVEC)
12637 /* Initialize target builtin that implements
12638 targetm.vectorize.builtin_mask_for_load. */
12640 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12641 v16qi_ftype_long_pcvoid,
12642 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12643 BUILT_IN_MD, NULL, NULL_TREE);
12644 TREE_READONLY (decl) = 1;
12645 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12646 altivec_builtin_mask_for_load = decl;
12649 /* Access to the vec_init patterns. */
12650 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12651 integer_type_node, integer_type_node,
12652 integer_type_node, NULL_TREE);
12653 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12654 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12656 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12657 short_integer_type_node,
12658 short_integer_type_node,
12659 short_integer_type_node,
12660 short_integer_type_node,
12661 short_integer_type_node,
12662 short_integer_type_node,
12663 short_integer_type_node, NULL_TREE);
12664 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12665 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12667 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12668 char_type_node, char_type_node,
12669 char_type_node, char_type_node,
12670 char_type_node, char_type_node,
12671 char_type_node, char_type_node,
12672 char_type_node, char_type_node,
12673 char_type_node, char_type_node,
12674 char_type_node, char_type_node,
12675 char_type_node, NULL_TREE);
12676 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12677 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12679 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12680 float_type_node, float_type_node,
12681 float_type_node, NULL_TREE);
12682 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12683 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12687 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12688 double_type_node, NULL_TREE);
12689 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12690 VSX_BUILTIN_VEC_INIT_V2DF);
12692 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12693 intDI_type_node, NULL_TREE);
12694 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12695 VSX_BUILTIN_VEC_INIT_V2DI);
12698 /* Access to the vec_set patterns. */
12699 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12701 integer_type_node, NULL_TREE);
12702 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12703 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12705 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12707 integer_type_node, NULL_TREE);
12708 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12709 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12711 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12713 integer_type_node, NULL_TREE);
12714 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12715 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12717 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12719 integer_type_node, NULL_TREE);
12720 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12721 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12725 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12727 integer_type_node, NULL_TREE);
12728 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12729 VSX_BUILTIN_VEC_SET_V2DF);
12731 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12733 integer_type_node, NULL_TREE);
12734 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12735 VSX_BUILTIN_VEC_SET_V2DI);
12738 /* Access to the vec_extract patterns. */
12739 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12740 integer_type_node, NULL_TREE);
12741 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12742 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12744 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12745 integer_type_node, NULL_TREE);
12746 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12747 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12749 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12750 integer_type_node, NULL_TREE);
12751 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12752 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12754 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12755 integer_type_node, NULL_TREE);
12756 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12757 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12761 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12762 integer_type_node, NULL_TREE);
12763 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12764 VSX_BUILTIN_VEC_EXT_V2DF);
12766 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12767 integer_type_node, NULL_TREE);
12768 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12769 VSX_BUILTIN_VEC_EXT_V2DI);
12773 /* Hash function for builtin functions with up to 3 arguments and a return
12776 builtin_hash_function (const void *hash_entry)
12780 const struct builtin_hash_struct *bh =
12781 (const struct builtin_hash_struct *) hash_entry;
12783 for (i = 0; i < 4; i++)
12785 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12786 ret = (ret * 2) + bh->uns_p[i];
12792 /* Compare builtin hash entries H1 and H2 for equivalence. */
12794 builtin_hash_eq (const void *h1, const void *h2)
12796 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12797 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12799 return ((p1->mode[0] == p2->mode[0])
12800 && (p1->mode[1] == p2->mode[1])
12801 && (p1->mode[2] == p2->mode[2])
12802 && (p1->mode[3] == p2->mode[3])
12803 && (p1->uns_p[0] == p2->uns_p[0])
12804 && (p1->uns_p[1] == p2->uns_p[1])
12805 && (p1->uns_p[2] == p2->uns_p[2])
12806 && (p1->uns_p[3] == p2->uns_p[3]));
12809 /* Map types for builtin functions with an explicit return type and up to 3
12810 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12811 of the argument. */
12813 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12814 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12815 enum rs6000_builtins builtin, const char *name)
12817 struct builtin_hash_struct h;
12818 struct builtin_hash_struct *h2;
12822 tree ret_type = NULL_TREE;
12823 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12826 /* Create builtin_hash_table. */
12827 if (builtin_hash_table == NULL)
12828 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12829 builtin_hash_eq, NULL);
12831 h.type = NULL_TREE;
12832 h.mode[0] = mode_ret;
12833 h.mode[1] = mode_arg0;
12834 h.mode[2] = mode_arg1;
12835 h.mode[3] = mode_arg2;
12841 /* If the builtin is a type that produces unsigned results or takes unsigned
12842 arguments, and it is returned as a decl for the vectorizer (such as
12843 widening multiplies, permute), make sure the arguments and return value
12844 are type correct. */
12847 /* unsigned 2 argument functions. */
12848 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12849 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12850 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12851 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12857 /* unsigned 3 argument functions. */
12858 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12859 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12860 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12861 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12862 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12863 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12864 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12865 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12866 case VSX_BUILTIN_VPERM_16QI_UNS:
12867 case VSX_BUILTIN_VPERM_8HI_UNS:
12868 case VSX_BUILTIN_VPERM_4SI_UNS:
12869 case VSX_BUILTIN_VPERM_2DI_UNS:
12870 case VSX_BUILTIN_XXSEL_16QI_UNS:
12871 case VSX_BUILTIN_XXSEL_8HI_UNS:
12872 case VSX_BUILTIN_XXSEL_4SI_UNS:
12873 case VSX_BUILTIN_XXSEL_2DI_UNS:
12880 /* signed permute functions with unsigned char mask. */
12881 case ALTIVEC_BUILTIN_VPERM_16QI:
12882 case ALTIVEC_BUILTIN_VPERM_8HI:
12883 case ALTIVEC_BUILTIN_VPERM_4SI:
12884 case ALTIVEC_BUILTIN_VPERM_4SF:
12885 case ALTIVEC_BUILTIN_VPERM_2DI:
12886 case ALTIVEC_BUILTIN_VPERM_2DF:
12887 case VSX_BUILTIN_VPERM_16QI:
12888 case VSX_BUILTIN_VPERM_8HI:
12889 case VSX_BUILTIN_VPERM_4SI:
12890 case VSX_BUILTIN_VPERM_4SF:
12891 case VSX_BUILTIN_VPERM_2DI:
12892 case VSX_BUILTIN_VPERM_2DF:
12896 /* unsigned args, signed return. */
12897 case VSX_BUILTIN_XVCVUXDDP_UNS:
12898 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12902 /* signed args, unsigned return. */
12903 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12904 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12912 /* Figure out how many args are present. */
12913 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12917 fatal_error ("internal error: builtin function %s had no type", name);
12919 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12920 if (!ret_type && h.uns_p[0])
12921 ret_type = builtin_mode_to_type[h.mode[0]][0];
12924 fatal_error ("internal error: builtin function %s had an unexpected "
12925 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12927 for (i = 0; i < num_args; i++)
12929 int m = (int) h.mode[i+1];
12930 int uns_p = h.uns_p[i+1];
12932 arg_type[i] = builtin_mode_to_type[m][uns_p];
12933 if (!arg_type[i] && uns_p)
12934 arg_type[i] = builtin_mode_to_type[m][0];
12937 fatal_error ("internal error: builtin function %s, argument %d "
12938 "had unexpected argument type %s", name, i,
12939 GET_MODE_NAME (m));
12942 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12943 if (*found == NULL)
12945 h2 = ggc_alloc_builtin_hash_struct ();
12947 *found = (void *)h2;
12948 args = void_list_node;
12950 for (i = num_args - 1; i >= 0; i--)
12951 args = tree_cons (NULL_TREE, arg_type[i], args);
12953 h2->type = build_function_type (ret_type, args);
12956 return ((struct builtin_hash_struct *)(*found))->type;
12960 rs6000_common_init_builtins (void)
12962 const struct builtin_description *d;
12965 tree opaque_ftype_opaque = NULL_TREE;
12966 tree opaque_ftype_opaque_opaque = NULL_TREE;
12967 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12968 tree v2si_ftype_qi = NULL_TREE;
12969 tree v2si_ftype_v2si_qi = NULL_TREE;
12970 tree v2si_ftype_int_qi = NULL_TREE;
12972 if (!TARGET_PAIRED_FLOAT)
12974 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12975 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12978 /* Add the ternary operators. */
12980 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12983 int mask = d->mask;
12985 if ((mask != 0 && (mask & target_flags) == 0)
12986 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12989 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12990 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12991 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12992 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12994 if (! (type = opaque_ftype_opaque_opaque_opaque))
12995 type = opaque_ftype_opaque_opaque_opaque
12996 = build_function_type_list (opaque_V4SI_type_node,
12997 opaque_V4SI_type_node,
12998 opaque_V4SI_type_node,
12999 opaque_V4SI_type_node,
13004 enum insn_code icode = d->icode;
13005 if (d->name == 0 || icode == CODE_FOR_nothing)
13008 type = builtin_function_type (insn_data[icode].operand[0].mode,
13009 insn_data[icode].operand[1].mode,
13010 insn_data[icode].operand[2].mode,
13011 insn_data[icode].operand[3].mode,
13015 def_builtin (d->mask, d->name, type, d->code);
13018 /* Add the binary operators. */
13020 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13022 enum machine_mode mode0, mode1, mode2;
13024 int mask = d->mask;
13026 if ((mask != 0 && (mask & target_flags) == 0)
13027 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13030 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13031 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13032 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13033 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13035 if (! (type = opaque_ftype_opaque_opaque))
13036 type = opaque_ftype_opaque_opaque
13037 = build_function_type_list (opaque_V4SI_type_node,
13038 opaque_V4SI_type_node,
13039 opaque_V4SI_type_node,
13044 enum insn_code icode = d->icode;
13045 if (d->name == 0 || icode == CODE_FOR_nothing)
13048 mode0 = insn_data[icode].operand[0].mode;
13049 mode1 = insn_data[icode].operand[1].mode;
13050 mode2 = insn_data[icode].operand[2].mode;
13052 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13054 if (! (type = v2si_ftype_v2si_qi))
13055 type = v2si_ftype_v2si_qi
13056 = build_function_type_list (opaque_V2SI_type_node,
13057 opaque_V2SI_type_node,
13062 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13063 && mode2 == QImode)
13065 if (! (type = v2si_ftype_int_qi))
13066 type = v2si_ftype_int_qi
13067 = build_function_type_list (opaque_V2SI_type_node,
13074 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13078 def_builtin (d->mask, d->name, type, d->code);
13081 /* Add the simple unary operators. */
13082 d = (struct builtin_description *) bdesc_1arg;
13083 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13085 enum machine_mode mode0, mode1;
13087 int mask = d->mask;
13089 if ((mask != 0 && (mask & target_flags) == 0)
13090 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13093 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13094 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13095 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13096 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13098 if (! (type = opaque_ftype_opaque))
13099 type = opaque_ftype_opaque
13100 = build_function_type_list (opaque_V4SI_type_node,
13101 opaque_V4SI_type_node,
13106 enum insn_code icode = d->icode;
13107 if (d->name == 0 || icode == CODE_FOR_nothing)
13110 mode0 = insn_data[icode].operand[0].mode;
13111 mode1 = insn_data[icode].operand[1].mode;
13113 if (mode0 == V2SImode && mode1 == QImode)
13115 if (! (type = v2si_ftype_qi))
13116 type = v2si_ftype_qi
13117 = build_function_type_list (opaque_V2SI_type_node,
13123 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13127 def_builtin (d->mask, d->name, type, d->code);
13132 rs6000_init_libfuncs (void)
13134 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13135 && !TARGET_POWER2 && !TARGET_POWERPC)
13137 /* AIX library routines for float->int conversion. */
13138 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13139 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13140 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13141 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13144 if (!TARGET_IEEEQUAD)
13145 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13146 if (!TARGET_XL_COMPAT)
13148 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13149 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13150 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13151 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13153 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13155 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13156 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13157 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13158 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13159 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13160 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13161 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13163 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13164 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13165 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13166 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13167 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13168 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13169 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13170 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13173 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13174 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13178 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13179 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13180 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13181 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13185 /* 32-bit SVR4 quad floating point routines. */
13187 set_optab_libfunc (add_optab, TFmode, "_q_add");
13188 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13189 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13190 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13191 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13192 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13193 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13195 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13196 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13197 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13198 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13199 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13200 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13202 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13203 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13204 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13205 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13206 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13207 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13208 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13209 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13214 /* Expand a block clear operation, and return 1 if successful. Return 0
13215 if we should let the compiler generate normal code.
13217 operands[0] is the destination
13218 operands[1] is the length
13219 operands[3] is the alignment */
13222 expand_block_clear (rtx operands[])
13224 rtx orig_dest = operands[0];
13225 rtx bytes_rtx = operands[1];
13226 rtx align_rtx = operands[3];
13227 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13228 HOST_WIDE_INT align;
13229 HOST_WIDE_INT bytes;
13234 /* If this is not a fixed size move, just call memcpy */
13238 /* This must be a fixed size alignment */
13239 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13240 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13242 /* Anything to clear? */
13243 bytes = INTVAL (bytes_rtx);
13247 /* Use the builtin memset after a point, to avoid huge code bloat.
13248 When optimize_size, avoid any significant code bloat; calling
13249 memset is about 4 instructions, so allow for one instruction to
13250 load zero and three to do clearing. */
13251 if (TARGET_ALTIVEC && align >= 128)
13253 else if (TARGET_POWERPC64 && align >= 32)
13255 else if (TARGET_SPE && align >= 64)
13260 if (optimize_size && bytes > 3 * clear_step)
13262 if (! optimize_size && bytes > 8 * clear_step)
13265 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13267 enum machine_mode mode = BLKmode;
13270 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13275 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13280 else if (bytes >= 8 && TARGET_POWERPC64
13281 /* 64-bit loads and stores require word-aligned
13283 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13288 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13289 { /* move 4 bytes */
13293 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13294 { /* move 2 bytes */
13298 else /* move 1 byte at a time */
13304 dest = adjust_address (orig_dest, mode, offset);
13306 emit_move_insn (dest, CONST0_RTX (mode));
13313 /* Expand a block move operation, and return 1 if successful. Return 0
13314 if we should let the compiler generate normal code.
13316 operands[0] is the destination
13317 operands[1] is the source
13318 operands[2] is the length
13319 operands[3] is the alignment */
13321 #define MAX_MOVE_REG 4
13324 expand_block_move (rtx operands[])
13326 rtx orig_dest = operands[0];
13327 rtx orig_src = operands[1];
13328 rtx bytes_rtx = operands[2];
13329 rtx align_rtx = operands[3];
13330 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13335 rtx stores[MAX_MOVE_REG];
13338 /* If this is not a fixed size move, just call memcpy */
13342 /* This must be a fixed size alignment */
13343 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13344 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13346 /* Anything to move? */
13347 bytes = INTVAL (bytes_rtx);
13351 if (bytes > rs6000_block_move_inline_limit)
13354 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13357 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13358 rtx (*mov) (rtx, rtx);
13360 enum machine_mode mode = BLKmode;
13363 /* Altivec first, since it will be faster than a string move
13364 when it applies, and usually not significantly larger. */
13365 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13369 gen_func.mov = gen_movv4si;
13371 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13375 gen_func.mov = gen_movv2si;
13377 else if (TARGET_STRING
13378 && bytes > 24 /* move up to 32 bytes at a time */
13384 && ! fixed_regs[10]
13385 && ! fixed_regs[11]
13386 && ! fixed_regs[12])
13388 move_bytes = (bytes > 32) ? 32 : bytes;
13389 gen_func.movmemsi = gen_movmemsi_8reg;
13391 else if (TARGET_STRING
13392 && bytes > 16 /* move up to 24 bytes at a time */
13398 && ! fixed_regs[10])
13400 move_bytes = (bytes > 24) ? 24 : bytes;
13401 gen_func.movmemsi = gen_movmemsi_6reg;
13403 else if (TARGET_STRING
13404 && bytes > 8 /* move up to 16 bytes at a time */
13408 && ! fixed_regs[8])
13410 move_bytes = (bytes > 16) ? 16 : bytes;
13411 gen_func.movmemsi = gen_movmemsi_4reg;
13413 else if (bytes >= 8 && TARGET_POWERPC64
13414 /* 64-bit loads and stores require word-aligned
13416 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13420 gen_func.mov = gen_movdi;
13422 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13423 { /* move up to 8 bytes at a time */
13424 move_bytes = (bytes > 8) ? 8 : bytes;
13425 gen_func.movmemsi = gen_movmemsi_2reg;
13427 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13428 { /* move 4 bytes */
13431 gen_func.mov = gen_movsi;
13433 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13434 { /* move 2 bytes */
13437 gen_func.mov = gen_movhi;
13439 else if (TARGET_STRING && bytes > 1)
13440 { /* move up to 4 bytes at a time */
13441 move_bytes = (bytes > 4) ? 4 : bytes;
13442 gen_func.movmemsi = gen_movmemsi_1reg;
13444 else /* move 1 byte at a time */
13448 gen_func.mov = gen_movqi;
13451 src = adjust_address (orig_src, mode, offset);
13452 dest = adjust_address (orig_dest, mode, offset);
13454 if (mode != BLKmode)
13456 rtx tmp_reg = gen_reg_rtx (mode);
13458 emit_insn ((*gen_func.mov) (tmp_reg, src));
13459 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13462 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13465 for (i = 0; i < num_reg; i++)
13466 emit_insn (stores[i]);
13470 if (mode == BLKmode)
13472 /* Move the address into scratch registers. The movmemsi
13473 patterns require zero offset. */
13474 if (!REG_P (XEXP (src, 0)))
13476 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13477 src = replace_equiv_address (src, src_reg);
13479 set_mem_size (src, GEN_INT (move_bytes));
13481 if (!REG_P (XEXP (dest, 0)))
13483 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13484 dest = replace_equiv_address (dest, dest_reg);
13486 set_mem_size (dest, GEN_INT (move_bytes));
13488 emit_insn ((*gen_func.movmemsi) (dest, src,
13489 GEN_INT (move_bytes & 31),
13498 /* Return a string to perform a load_multiple operation.
13499 operands[0] is the vector.
13500 operands[1] is the source address.
13501 operands[2] is the first destination register. */
13504 rs6000_output_load_multiple (rtx operands[3])
13506 /* We have to handle the case where the pseudo used to contain the address
13507 is assigned to one of the output registers. */
13509 int words = XVECLEN (operands[0], 0);
13512 if (XVECLEN (operands[0], 0) == 1)
13513 return "{l|lwz} %2,0(%1)";
13515 for (i = 0; i < words; i++)
13516 if (refers_to_regno_p (REGNO (operands[2]) + i,
13517 REGNO (operands[2]) + i + 1, operands[1], 0))
13521 xop[0] = GEN_INT (4 * (words-1));
13522 xop[1] = operands[1];
13523 xop[2] = operands[2];
13524 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13529 xop[0] = GEN_INT (4 * (words-1));
13530 xop[1] = operands[1];
13531 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13532 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);
13537 for (j = 0; j < words; j++)
13540 xop[0] = GEN_INT (j * 4);
13541 xop[1] = operands[1];
13542 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13543 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13545 xop[0] = GEN_INT (i * 4);
13546 xop[1] = operands[1];
13547 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13552 return "{lsi|lswi} %2,%1,%N0";
13556 /* A validation routine: say whether CODE, a condition code, and MODE
13557 match. The other alternatives either don't make sense or should
13558 never be generated. */
13561 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13563 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13564 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13565 && GET_MODE_CLASS (mode) == MODE_CC);
13567 /* These don't make sense. */
13568 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13569 || mode != CCUNSmode);
13571 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13572 || mode == CCUNSmode);
13574 gcc_assert (mode == CCFPmode
13575 || (code != ORDERED && code != UNORDERED
13576 && code != UNEQ && code != LTGT
13577 && code != UNGT && code != UNLT
13578 && code != UNGE && code != UNLE));
13580 /* These should never be generated except for
13581 flag_finite_math_only. */
13582 gcc_assert (mode != CCFPmode
13583 || flag_finite_math_only
13584 || (code != LE && code != GE
13585 && code != UNEQ && code != LTGT
13586 && code != UNGT && code != UNLT));
13588 /* These are invalid; the information is not there. */
13589 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13593 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13594 mask required to convert the result of a rotate insn into a shift
13595 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13598 includes_lshift_p (rtx shiftop, rtx andop)
13600 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13602 shift_mask <<= INTVAL (shiftop);
13604 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13607 /* Similar, but for right shift. */
13610 includes_rshift_p (rtx shiftop, rtx andop)
13612 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13614 shift_mask >>= INTVAL (shiftop);
13616 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13619 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13620 to perform a left shift. It must have exactly SHIFTOP least
13621 significant 0's, then one or more 1's, then zero or more 0's. */
13624 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13626 if (GET_CODE (andop) == CONST_INT)
13628 HOST_WIDE_INT c, lsb, shift_mask;
13630 c = INTVAL (andop);
13631 if (c == 0 || c == ~0)
13635 shift_mask <<= INTVAL (shiftop);
13637 /* Find the least significant one bit. */
13640 /* It must coincide with the LSB of the shift mask. */
13641 if (-lsb != shift_mask)
13644 /* Invert to look for the next transition (if any). */
13647 /* Remove the low group of ones (originally low group of zeros). */
13650 /* Again find the lsb, and check we have all 1's above. */
13654 else if (GET_CODE (andop) == CONST_DOUBLE
13655 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13657 HOST_WIDE_INT low, high, lsb;
13658 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13660 low = CONST_DOUBLE_LOW (andop);
13661 if (HOST_BITS_PER_WIDE_INT < 64)
13662 high = CONST_DOUBLE_HIGH (andop);
13664 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13665 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13668 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13670 shift_mask_high = ~0;
13671 if (INTVAL (shiftop) > 32)
13672 shift_mask_high <<= INTVAL (shiftop) - 32;
13674 lsb = high & -high;
13676 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13682 lsb = high & -high;
13683 return high == -lsb;
13686 shift_mask_low = ~0;
13687 shift_mask_low <<= INTVAL (shiftop);
13691 if (-lsb != shift_mask_low)
13694 if (HOST_BITS_PER_WIDE_INT < 64)
13699 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13701 lsb = high & -high;
13702 return high == -lsb;
13706 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13712 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13713 to perform a left shift. It must have SHIFTOP or more least
13714 significant 0's, with the remainder of the word 1's. */
13717 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13719 if (GET_CODE (andop) == CONST_INT)
13721 HOST_WIDE_INT c, lsb, shift_mask;
13724 shift_mask <<= INTVAL (shiftop);
13725 c = INTVAL (andop);
13727 /* Find the least significant one bit. */
13730 /* It must be covered by the shift mask.
13731 This test also rejects c == 0. */
13732 if ((lsb & shift_mask) == 0)
13735 /* Check we have all 1's above the transition, and reject all 1's. */
13736 return c == -lsb && lsb != 1;
13738 else if (GET_CODE (andop) == CONST_DOUBLE
13739 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13741 HOST_WIDE_INT low, lsb, shift_mask_low;
13743 low = CONST_DOUBLE_LOW (andop);
13745 if (HOST_BITS_PER_WIDE_INT < 64)
13747 HOST_WIDE_INT high, shift_mask_high;
13749 high = CONST_DOUBLE_HIGH (andop);
13753 shift_mask_high = ~0;
13754 if (INTVAL (shiftop) > 32)
13755 shift_mask_high <<= INTVAL (shiftop) - 32;
13757 lsb = high & -high;
13759 if ((lsb & shift_mask_high) == 0)
13762 return high == -lsb;
13768 shift_mask_low = ~0;
13769 shift_mask_low <<= INTVAL (shiftop);
13773 if ((lsb & shift_mask_low) == 0)
13776 return low == -lsb && lsb != 1;
13782 /* Return 1 if operands will generate a valid arguments to rlwimi
13783 instruction for insert with right shift in 64-bit mode. The mask may
13784 not start on the first bit or stop on the last bit because wrap-around
13785 effects of instruction do not correspond to semantics of RTL insn. */
13788 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13790 if (INTVAL (startop) > 32
13791 && INTVAL (startop) < 64
13792 && INTVAL (sizeop) > 1
13793 && INTVAL (sizeop) + INTVAL (startop) < 64
13794 && INTVAL (shiftop) > 0
13795 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13796 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13802 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13803 for lfq and stfq insns iff the registers are hard registers. */
13806 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13808 /* We might have been passed a SUBREG. */
13809 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13812 /* We might have been passed non floating point registers. */
13813 if (!FP_REGNO_P (REGNO (reg1))
13814 || !FP_REGNO_P (REGNO (reg2)))
13817 return (REGNO (reg1) == REGNO (reg2) - 1);
13820 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13821 addr1 and addr2 must be in consecutive memory locations
13822 (addr2 == addr1 + 8). */
13825 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13828 unsigned int reg1, reg2;
13829 int offset1, offset2;
13831 /* The mems cannot be volatile. */
13832 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13835 addr1 = XEXP (mem1, 0);
13836 addr2 = XEXP (mem2, 0);
13838 /* Extract an offset (if used) from the first addr. */
13839 if (GET_CODE (addr1) == PLUS)
13841 /* If not a REG, return zero. */
13842 if (GET_CODE (XEXP (addr1, 0)) != REG)
13846 reg1 = REGNO (XEXP (addr1, 0));
13847 /* The offset must be constant! */
13848 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13850 offset1 = INTVAL (XEXP (addr1, 1));
13853 else if (GET_CODE (addr1) != REG)
13857 reg1 = REGNO (addr1);
13858 /* This was a simple (mem (reg)) expression. Offset is 0. */
13862 /* And now for the second addr. */
13863 if (GET_CODE (addr2) == PLUS)
13865 /* If not a REG, return zero. */
13866 if (GET_CODE (XEXP (addr2, 0)) != REG)
13870 reg2 = REGNO (XEXP (addr2, 0));
13871 /* The offset must be constant. */
13872 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13874 offset2 = INTVAL (XEXP (addr2, 1));
13877 else if (GET_CODE (addr2) != REG)
13881 reg2 = REGNO (addr2);
13882 /* This was a simple (mem (reg)) expression. Offset is 0. */
13886 /* Both of these must have the same base register. */
13890 /* The offset for the second addr must be 8 more than the first addr. */
13891 if (offset2 != offset1 + 8)
13894 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13901 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13903 static bool eliminated = false;
13906 if (mode != SDmode)
13907 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13910 rtx mem = cfun->machine->sdmode_stack_slot;
13911 gcc_assert (mem != NULL_RTX);
13915 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13916 cfun->machine->sdmode_stack_slot = mem;
13922 if (TARGET_DEBUG_ADDR)
13924 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13925 GET_MODE_NAME (mode));
13927 fprintf (stderr, "\tNULL_RTX\n");
13936 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13938 /* Don't walk into types. */
13939 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13941 *walk_subtrees = 0;
13945 switch (TREE_CODE (*tp))
13954 case MISALIGNED_INDIRECT_REF:
13955 case VIEW_CONVERT_EXPR:
13956 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13966 enum reload_reg_type {
13968 VECTOR_REGISTER_TYPE,
13969 OTHER_REGISTER_TYPE
13972 static enum reload_reg_type
13973 rs6000_reload_register_type (enum reg_class rclass)
13979 return GPR_REGISTER_TYPE;
13984 return VECTOR_REGISTER_TYPE;
13987 return OTHER_REGISTER_TYPE;
13991 /* Inform reload about cases where moving X with a mode MODE to a register in
13992 RCLASS requires an extra scratch or immediate register. Return the class
13993 needed for the immediate register.
13995 For VSX and Altivec, we may need a register to convert sp+offset into
13999 rs6000_secondary_reload (bool in_p,
14001 reg_class_t rclass_i,
14002 enum machine_mode mode,
14003 secondary_reload_info *sri)
14005 enum reg_class rclass = (enum reg_class) rclass_i;
14006 reg_class_t ret = ALL_REGS;
14007 enum insn_code icode;
14008 bool default_p = false;
14010 sri->icode = CODE_FOR_nothing;
14012 /* Convert vector loads and stores into gprs to use an additional base
14014 icode = rs6000_vector_reload[mode][in_p != false];
14015 if (icode != CODE_FOR_nothing)
14018 sri->icode = CODE_FOR_nothing;
14019 sri->extra_cost = 0;
14021 if (GET_CODE (x) == MEM)
14023 rtx addr = XEXP (x, 0);
14025 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14026 an extra register in that case, but it would need an extra
14027 register if the addressing is reg+reg or (reg+reg)&(-16). */
14028 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14030 if (!legitimate_indirect_address_p (addr, false)
14031 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14033 sri->icode = icode;
14034 /* account for splitting the loads, and converting the
14035 address from reg+reg to reg. */
14036 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14037 + ((GET_CODE (addr) == AND) ? 1 : 0));
14040 /* Loads to and stores from vector registers can only do reg+reg
14041 addressing. Altivec registers can also do (reg+reg)&(-16). */
14042 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14043 || rclass == FLOAT_REGS || rclass == NO_REGS)
14045 if (!VECTOR_MEM_ALTIVEC_P (mode)
14046 && GET_CODE (addr) == AND
14047 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14048 && INTVAL (XEXP (addr, 1)) == -16
14049 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14050 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14052 sri->icode = icode;
14053 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14056 else if (!legitimate_indirect_address_p (addr, false)
14057 && (rclass == NO_REGS
14058 || !legitimate_indexed_address_p (addr, false)))
14060 sri->icode = icode;
14061 sri->extra_cost = 1;
14064 icode = CODE_FOR_nothing;
14066 /* Any other loads, including to pseudo registers which haven't been
14067 assigned to a register yet, default to require a scratch
14071 sri->icode = icode;
14072 sri->extra_cost = 2;
14075 else if (REG_P (x))
14077 int regno = true_regnum (x);
14079 icode = CODE_FOR_nothing;
14080 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14084 enum reg_class xclass = REGNO_REG_CLASS (regno);
14085 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14086 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14088 /* If memory is needed, use default_secondary_reload to create the
14090 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14103 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14105 gcc_assert (ret != ALL_REGS);
14107 if (TARGET_DEBUG_ADDR)
14110 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14112 reg_class_names[ret],
14113 in_p ? "true" : "false",
14114 reg_class_names[rclass],
14115 GET_MODE_NAME (mode));
14118 fprintf (stderr, ", default secondary reload");
14120 if (sri->icode != CODE_FOR_nothing)
14121 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14122 insn_data[sri->icode].name, sri->extra_cost);
14124 fprintf (stderr, "\n");
14132 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14133 to SP+reg addressing. */
14136 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14138 int regno = true_regnum (reg);
14139 enum machine_mode mode = GET_MODE (reg);
14140 enum reg_class rclass;
14142 rtx and_op2 = NULL_RTX;
14145 rtx scratch_or_premodify = scratch;
14149 if (TARGET_DEBUG_ADDR)
14151 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14152 store_p ? "store" : "load");
14153 fprintf (stderr, "reg:\n");
14155 fprintf (stderr, "mem:\n");
14157 fprintf (stderr, "scratch:\n");
14158 debug_rtx (scratch);
14161 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14162 gcc_assert (GET_CODE (mem) == MEM);
14163 rclass = REGNO_REG_CLASS (regno);
14164 addr = XEXP (mem, 0);
14168 /* GPRs can handle reg + small constant, all other addresses need to use
14169 the scratch register. */
14172 if (GET_CODE (addr) == AND)
14174 and_op2 = XEXP (addr, 1);
14175 addr = XEXP (addr, 0);
14178 if (GET_CODE (addr) == PRE_MODIFY)
14180 scratch_or_premodify = XEXP (addr, 0);
14181 gcc_assert (REG_P (scratch_or_premodify));
14182 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14183 addr = XEXP (addr, 1);
14186 if (GET_CODE (addr) == PLUS
14187 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14188 || and_op2 != NULL_RTX))
14190 addr_op1 = XEXP (addr, 0);
14191 addr_op2 = XEXP (addr, 1);
14192 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14194 if (!REG_P (addr_op2)
14195 && (GET_CODE (addr_op2) != CONST_INT
14196 || !satisfies_constraint_I (addr_op2)))
14198 if (TARGET_DEBUG_ADDR)
14201 "\nMove plus addr to register %s, mode = %s: ",
14202 rs6000_reg_names[REGNO (scratch)],
14203 GET_MODE_NAME (mode));
14204 debug_rtx (addr_op2);
14206 rs6000_emit_move (scratch, addr_op2, Pmode);
14207 addr_op2 = scratch;
14210 emit_insn (gen_rtx_SET (VOIDmode,
14211 scratch_or_premodify,
14212 gen_rtx_PLUS (Pmode,
14216 addr = scratch_or_premodify;
14217 scratch_or_premodify = scratch;
14219 else if (!legitimate_indirect_address_p (addr, false)
14220 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14222 if (TARGET_DEBUG_ADDR)
14224 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14225 rs6000_reg_names[REGNO (scratch_or_premodify)],
14226 GET_MODE_NAME (mode));
14229 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14230 addr = scratch_or_premodify;
14231 scratch_or_premodify = scratch;
14235 /* Float/Altivec registers can only handle reg+reg addressing. Move
14236 other addresses into a scratch register. */
14241 /* With float regs, we need to handle the AND ourselves, since we can't
14242 use the Altivec instruction with an implicit AND -16. Allow scalar
14243 loads to float registers to use reg+offset even if VSX. */
14244 if (GET_CODE (addr) == AND
14245 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14246 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14247 || INTVAL (XEXP (addr, 1)) != -16
14248 || !VECTOR_MEM_ALTIVEC_P (mode)))
14250 and_op2 = XEXP (addr, 1);
14251 addr = XEXP (addr, 0);
14254 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14255 as the address later. */
14256 if (GET_CODE (addr) == PRE_MODIFY
14257 && (!VECTOR_MEM_VSX_P (mode)
14258 || and_op2 != NULL_RTX
14259 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14261 scratch_or_premodify = XEXP (addr, 0);
14262 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14264 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14265 addr = XEXP (addr, 1);
14268 if (legitimate_indirect_address_p (addr, false) /* reg */
14269 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14270 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14271 || (GET_CODE (addr) == AND /* Altivec memory */
14272 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14273 && INTVAL (XEXP (addr, 1)) == -16
14274 && VECTOR_MEM_ALTIVEC_P (mode))
14275 || (rclass == FLOAT_REGS /* legacy float mem */
14276 && GET_MODE_SIZE (mode) == 8
14277 && and_op2 == NULL_RTX
14278 && scratch_or_premodify == scratch
14279 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14282 else if (GET_CODE (addr) == PLUS)
14284 addr_op1 = XEXP (addr, 0);
14285 addr_op2 = XEXP (addr, 1);
14286 gcc_assert (REG_P (addr_op1));
14288 if (TARGET_DEBUG_ADDR)
14290 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14291 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14292 debug_rtx (addr_op2);
14294 rs6000_emit_move (scratch, addr_op2, Pmode);
14295 emit_insn (gen_rtx_SET (VOIDmode,
14296 scratch_or_premodify,
14297 gen_rtx_PLUS (Pmode,
14300 addr = scratch_or_premodify;
14301 scratch_or_premodify = scratch;
14304 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14305 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14307 if (TARGET_DEBUG_ADDR)
14309 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14310 rs6000_reg_names[REGNO (scratch_or_premodify)],
14311 GET_MODE_NAME (mode));
14315 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14316 addr = scratch_or_premodify;
14317 scratch_or_premodify = scratch;
14321 gcc_unreachable ();
14326 gcc_unreachable ();
14329 /* If the original address involved a pre-modify that we couldn't use the VSX
14330 memory instruction with update, and we haven't taken care of already,
14331 store the address in the pre-modify register and use that as the
14333 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14335 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14336 addr = scratch_or_premodify;
14339 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14340 memory instruction, recreate the AND now, including the clobber which is
14341 generated by the general ANDSI3/ANDDI3 patterns for the
14342 andi. instruction. */
14343 if (and_op2 != NULL_RTX)
14345 if (! legitimate_indirect_address_p (addr, false))
14347 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14351 if (TARGET_DEBUG_ADDR)
14353 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14354 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14355 debug_rtx (and_op2);
14358 and_rtx = gen_rtx_SET (VOIDmode,
14360 gen_rtx_AND (Pmode,
14364 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14365 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14366 gen_rtvec (2, and_rtx, cc_clobber)));
14370 /* Adjust the address if it changed. */
14371 if (addr != XEXP (mem, 0))
14373 mem = change_address (mem, mode, addr);
14374 if (TARGET_DEBUG_ADDR)
14375 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14378 /* Now create the move. */
14380 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14382 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14387 /* Target hook to return the cover classes for Integrated Register Allocator.
14388 Cover classes is a set of non-intersected register classes covering all hard
14389 registers used for register allocation purpose. Any move between two
14390 registers of a cover class should be cheaper than load or store of the
14391 registers. The value is array of register classes with LIM_REG_CLASSES used
14394 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14395 account for the Altivec and Floating registers being subsets of the VSX
14396 register set under VSX, but distinct register sets on pre-VSX machines. */
14398 static const reg_class_t *
14399 rs6000_ira_cover_classes (void)
14401 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14402 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14404 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14407 /* Allocate a 64-bit stack slot to be used for copying SDmode
14408 values through if this function has any SDmode references. */
14411 rs6000_alloc_sdmode_stack_slot (void)
14415 gimple_stmt_iterator gsi;
14417 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14420 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14422 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14425 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14426 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14432 /* Check for any SDmode parameters of the function. */
14433 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14435 if (TREE_TYPE (t) == error_mark_node)
14438 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14439 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14441 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14442 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14450 rs6000_instantiate_decls (void)
14452 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14453 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14456 /* Given an rtx X being reloaded into a reg required to be
14457 in class CLASS, return the class of reg to actually use.
14458 In general this is just CLASS; but on some machines
14459 in some cases it is preferable to use a more restrictive class.
14461 On the RS/6000, we have to return NO_REGS when we want to reload a
14462 floating-point CONST_DOUBLE to force it to be copied to memory.
14464 We also don't want to reload integer values into floating-point
14465 registers if we can at all help it. In fact, this can
14466 cause reload to die, if it tries to generate a reload of CTR
14467 into a FP register and discovers it doesn't have the memory location
14470 ??? Would it be a good idea to have reload do the converse, that is
14471 try to reload floating modes into FP registers if possible?
14474 static enum reg_class
14475 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14477 enum machine_mode mode = GET_MODE (x);
14479 if (VECTOR_UNIT_VSX_P (mode)
14480 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14483 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14484 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14485 && easy_vector_constant (x, mode))
14486 return ALTIVEC_REGS;
14488 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14491 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14492 return GENERAL_REGS;
14494 /* For VSX, prefer the traditional registers for 64-bit values because we can
14495 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14496 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14497 prefer Altivec loads.. */
14498 if (rclass == VSX_REGS)
14500 if (GET_MODE_SIZE (mode) <= 8)
14503 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14504 return ALTIVEC_REGS;
14512 /* Debug version of rs6000_preferred_reload_class. */
14513 static enum reg_class
14514 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14516 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14519 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14521 reg_class_names[ret], reg_class_names[rclass],
14522 GET_MODE_NAME (GET_MODE (x)));
14528 /* If we are copying between FP or AltiVec registers and anything else, we need
14529 a memory location. The exception is when we are targeting ppc64 and the
14530 move to/from fpr to gpr instructions are available. Also, under VSX, you
14531 can copy vector registers from the FP register set to the Altivec register
14532 set and vice versa. */
14535 rs6000_secondary_memory_needed (enum reg_class class1,
14536 enum reg_class class2,
14537 enum machine_mode mode)
14539 if (class1 == class2)
14542 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14543 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14544 between these classes. But we need memory for other things that can go in
14545 FLOAT_REGS like SFmode. */
14547 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14548 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14549 || class1 == FLOAT_REGS))
14550 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14551 && class2 != FLOAT_REGS);
14553 if (class1 == VSX_REGS || class2 == VSX_REGS)
14556 if (class1 == FLOAT_REGS
14557 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14558 || ((mode != DFmode)
14559 && (mode != DDmode)
14560 && (mode != DImode))))
14563 if (class2 == FLOAT_REGS
14564 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14565 || ((mode != DFmode)
14566 && (mode != DDmode)
14567 && (mode != DImode))))
14570 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14576 /* Debug version of rs6000_secondary_memory_needed. */
14578 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14579 enum reg_class class2,
14580 enum machine_mode mode)
14582 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14585 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14586 "class2 = %s, mode = %s\n",
14587 ret ? "true" : "false", reg_class_names[class1],
14588 reg_class_names[class2], GET_MODE_NAME (mode));
14593 /* Return the register class of a scratch register needed to copy IN into
14594 or out of a register in RCLASS in MODE. If it can be done directly,
14595 NO_REGS is returned. */
14597 static enum reg_class
14598 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14603 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14605 && MACHOPIC_INDIRECT
14609 /* We cannot copy a symbolic operand directly into anything
14610 other than BASE_REGS for TARGET_ELF. So indicate that a
14611 register from BASE_REGS is needed as an intermediate
14614 On Darwin, pic addresses require a load from memory, which
14615 needs a base register. */
14616 if (rclass != BASE_REGS
14617 && (GET_CODE (in) == SYMBOL_REF
14618 || GET_CODE (in) == HIGH
14619 || GET_CODE (in) == LABEL_REF
14620 || GET_CODE (in) == CONST))
14624 if (GET_CODE (in) == REG)
14626 regno = REGNO (in);
14627 if (regno >= FIRST_PSEUDO_REGISTER)
14629 regno = true_regnum (in);
14630 if (regno >= FIRST_PSEUDO_REGISTER)
14634 else if (GET_CODE (in) == SUBREG)
14636 regno = true_regnum (in);
14637 if (regno >= FIRST_PSEUDO_REGISTER)
14643 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14645 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14646 || (regno >= 0 && INT_REGNO_P (regno)))
14649 /* Constants, memory, and FP registers can go into FP registers. */
14650 if ((regno == -1 || FP_REGNO_P (regno))
14651 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14652 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14654 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14657 && (regno == -1 || VSX_REGNO_P (regno))
14658 && VSX_REG_CLASS_P (rclass))
14661 /* Memory, and AltiVec registers can go into AltiVec registers. */
14662 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14663 && rclass == ALTIVEC_REGS)
14666 /* We can copy among the CR registers. */
14667 if ((rclass == CR_REGS || rclass == CR0_REGS)
14668 && regno >= 0 && CR_REGNO_P (regno))
14671 /* Otherwise, we need GENERAL_REGS. */
14672 return GENERAL_REGS;
14675 /* Debug version of rs6000_secondary_reload_class. */
14676 static enum reg_class
14677 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14678 enum machine_mode mode, rtx in)
14680 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14682 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14683 "mode = %s, input rtx:\n",
14684 reg_class_names[ret], reg_class_names[rclass],
14685 GET_MODE_NAME (mode));
14691 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14694 rs6000_cannot_change_mode_class (enum machine_mode from,
14695 enum machine_mode to,
14696 enum reg_class rclass)
14698 unsigned from_size = GET_MODE_SIZE (from);
14699 unsigned to_size = GET_MODE_SIZE (to);
14701 if (from_size != to_size)
14703 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14704 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14705 && reg_classes_intersect_p (xclass, rclass));
14708 if (TARGET_E500_DOUBLE
14709 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14710 || (((to) == TFmode) + ((from) == TFmode)) == 1
14711 || (((to) == DDmode) + ((from) == DDmode)) == 1
14712 || (((to) == TDmode) + ((from) == TDmode)) == 1
14713 || (((to) == DImode) + ((from) == DImode)) == 1))
14716 /* Since the VSX register set includes traditional floating point registers
14717 and altivec registers, just check for the size being different instead of
14718 trying to check whether the modes are vector modes. Otherwise it won't
14719 allow say DF and DI to change classes. */
14720 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14721 return (from_size != 8 && from_size != 16);
14723 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14724 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14727 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14728 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14734 /* Debug version of rs6000_cannot_change_mode_class. */
14736 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14737 enum machine_mode to,
14738 enum reg_class rclass)
14740 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14743 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14744 "to = %s, rclass = %s\n",
14745 ret ? "true" : "false",
14746 GET_MODE_NAME (from), GET_MODE_NAME (to),
14747 reg_class_names[rclass]);
14752 /* Given a comparison operation, return the bit number in CCR to test. We
14753 know this is a valid comparison.
14755 SCC_P is 1 if this is for an scc. That means that %D will have been
14756 used instead of %C, so the bits will be in different places.
14758 Return -1 if OP isn't a valid comparison for some reason. */
14761 ccr_bit (rtx op, int scc_p)
14763 enum rtx_code code = GET_CODE (op);
14764 enum machine_mode cc_mode;
14769 if (!COMPARISON_P (op))
14772 reg = XEXP (op, 0);
14774 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14776 cc_mode = GET_MODE (reg);
14777 cc_regnum = REGNO (reg);
14778 base_bit = 4 * (cc_regnum - CR0_REGNO);
14780 validate_condition_mode (code, cc_mode);
14782 /* When generating a sCOND operation, only positive conditions are
14785 || code == EQ || code == GT || code == LT || code == UNORDERED
14786 || code == GTU || code == LTU);
14791 return scc_p ? base_bit + 3 : base_bit + 2;
14793 return base_bit + 2;
14794 case GT: case GTU: case UNLE:
14795 return base_bit + 1;
14796 case LT: case LTU: case UNGE:
14798 case ORDERED: case UNORDERED:
14799 return base_bit + 3;
14802 /* If scc, we will have done a cror to put the bit in the
14803 unordered position. So test that bit. For integer, this is ! LT
14804 unless this is an scc insn. */
14805 return scc_p ? base_bit + 3 : base_bit;
14808 return scc_p ? base_bit + 3 : base_bit + 1;
14811 gcc_unreachable ();
14815 /* Return the GOT register. */
14818 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14820 /* The second flow pass currently (June 1999) can't update
14821 regs_ever_live without disturbing other parts of the compiler, so
14822 update it here to make the prolog/epilogue code happy. */
14823 if (!can_create_pseudo_p ()
14824 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14825 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14827 crtl->uses_pic_offset_table = 1;
14829 return pic_offset_table_rtx;
14832 /* Function to init struct machine_function.
14833 This will be called, via a pointer variable,
14834 from push_function_context. */
14836 static struct machine_function *
14837 rs6000_init_machine_status (void)
14839 return ggc_alloc_cleared_machine_function ();
14842 /* These macros test for integers and extract the low-order bits. */
14844 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14845 && GET_MODE (X) == VOIDmode)
14847 #define INT_LOWPART(X) \
14848 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14851 extract_MB (rtx op)
14854 unsigned long val = INT_LOWPART (op);
14856 /* If the high bit is zero, the value is the first 1 bit we find
14858 if ((val & 0x80000000) == 0)
14860 gcc_assert (val & 0xffffffff);
14863 while (((val <<= 1) & 0x80000000) == 0)
14868 /* If the high bit is set and the low bit is not, or the mask is all
14869 1's, the value is zero. */
14870 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14873 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14876 while (((val >>= 1) & 1) != 0)
14883 extract_ME (rtx op)
14886 unsigned long val = INT_LOWPART (op);
14888 /* If the low bit is zero, the value is the first 1 bit we find from
14890 if ((val & 1) == 0)
14892 gcc_assert (val & 0xffffffff);
14895 while (((val >>= 1) & 1) == 0)
14901 /* If the low bit is set and the high bit is not, or the mask is all
14902 1's, the value is 31. */
14903 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14906 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14909 while (((val <<= 1) & 0x80000000) != 0)
14915 /* Locate some local-dynamic symbol still in use by this function
14916 so that we can print its name in some tls_ld pattern. */
14918 static const char *
14919 rs6000_get_some_local_dynamic_name (void)
14923 if (cfun->machine->some_ld_name)
14924 return cfun->machine->some_ld_name;
14926 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14928 && for_each_rtx (&PATTERN (insn),
14929 rs6000_get_some_local_dynamic_name_1, 0))
14930 return cfun->machine->some_ld_name;
14932 gcc_unreachable ();
14935 /* Helper function for rs6000_get_some_local_dynamic_name. */
14938 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14942 if (GET_CODE (x) == SYMBOL_REF)
14944 const char *str = XSTR (x, 0);
14945 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14947 cfun->machine->some_ld_name = str;
14955 /* Write out a function code label. */
14958 rs6000_output_function_entry (FILE *file, const char *fname)
14960 if (fname[0] != '.')
14962 switch (DEFAULT_ABI)
14965 gcc_unreachable ();
14971 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14980 RS6000_OUTPUT_BASENAME (file, fname);
14983 /* Print an operand. Recognize special options, documented below. */
14986 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14987 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14989 #define SMALL_DATA_RELOC "sda21"
14990 #define SMALL_DATA_REG 0
14994 print_operand (FILE *file, rtx x, int code)
14998 unsigned HOST_WIDE_INT uval;
15003 /* Write out an instruction after the call which may be replaced
15004 with glue code by the loader. This depends on the AIX version. */
15005 asm_fprintf (file, RS6000_CALL_GLUE);
15008 /* %a is output_address. */
15011 /* If X is a constant integer whose low-order 5 bits are zero,
15012 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15013 in the AIX assembler where "sri" with a zero shift count
15014 writes a trash instruction. */
15015 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15022 /* If constant, low-order 16 bits of constant, unsigned.
15023 Otherwise, write normally. */
15025 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15027 print_operand (file, x, 0);
15031 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15032 for 64-bit mask direction. */
15033 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15036 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15040 /* X is a CR register. Print the number of the GT bit of the CR. */
15041 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15042 output_operand_lossage ("invalid %%c value");
15044 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15048 /* Like 'J' but get to the GT bit only. */
15049 gcc_assert (GET_CODE (x) == REG);
15051 /* Bit 1 is GT bit. */
15052 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15054 /* Add one for shift count in rlinm for scc. */
15055 fprintf (file, "%d", i + 1);
15059 /* X is a CR register. Print the number of the EQ bit of the CR */
15060 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15061 output_operand_lossage ("invalid %%E value");
15063 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15067 /* X is a CR register. Print the shift count needed to move it
15068 to the high-order four bits. */
15069 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15070 output_operand_lossage ("invalid %%f value");
15072 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15076 /* Similar, but print the count for the rotate in the opposite
15078 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15079 output_operand_lossage ("invalid %%F value");
15081 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15085 /* X is a constant integer. If it is negative, print "m",
15086 otherwise print "z". This is to make an aze or ame insn. */
15087 if (GET_CODE (x) != CONST_INT)
15088 output_operand_lossage ("invalid %%G value");
15089 else if (INTVAL (x) >= 0)
15096 /* If constant, output low-order five bits. Otherwise, write
15099 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15101 print_operand (file, x, 0);
15105 /* If constant, output low-order six bits. Otherwise, write
15108 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15110 print_operand (file, x, 0);
15114 /* Print `i' if this is a constant, else nothing. */
15120 /* Write the bit number in CCR for jump. */
15121 i = ccr_bit (x, 0);
15123 output_operand_lossage ("invalid %%j code");
15125 fprintf (file, "%d", i);
15129 /* Similar, but add one for shift count in rlinm for scc and pass
15130 scc flag to `ccr_bit'. */
15131 i = ccr_bit (x, 1);
15133 output_operand_lossage ("invalid %%J code");
15135 /* If we want bit 31, write a shift count of zero, not 32. */
15136 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15140 /* X must be a constant. Write the 1's complement of the
15143 output_operand_lossage ("invalid %%k value");
15145 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15149 /* X must be a symbolic constant on ELF. Write an
15150 expression suitable for an 'addi' that adds in the low 16
15151 bits of the MEM. */
15152 if (GET_CODE (x) == CONST)
15154 if (GET_CODE (XEXP (x, 0)) != PLUS
15155 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15156 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15157 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15158 output_operand_lossage ("invalid %%K value");
15160 print_operand_address (file, x);
15161 fputs ("@l", file);
15164 /* %l is output_asm_label. */
15167 /* Write second word of DImode or DFmode reference. Works on register
15168 or non-indexed memory only. */
15169 if (GET_CODE (x) == REG)
15170 fputs (reg_names[REGNO (x) + 1], file);
15171 else if (GET_CODE (x) == MEM)
15173 /* Handle possible auto-increment. Since it is pre-increment and
15174 we have already done it, we can just use an offset of word. */
15175 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15176 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15177 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15179 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15180 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15183 output_address (XEXP (adjust_address_nv (x, SImode,
15187 if (small_data_operand (x, GET_MODE (x)))
15188 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15189 reg_names[SMALL_DATA_REG]);
15194 /* MB value for a mask operand. */
15195 if (! mask_operand (x, SImode))
15196 output_operand_lossage ("invalid %%m value");
15198 fprintf (file, "%d", extract_MB (x));
15202 /* ME value for a mask operand. */
15203 if (! mask_operand (x, SImode))
15204 output_operand_lossage ("invalid %%M value");
15206 fprintf (file, "%d", extract_ME (x));
15209 /* %n outputs the negative of its operand. */
15212 /* Write the number of elements in the vector times 4. */
15213 if (GET_CODE (x) != PARALLEL)
15214 output_operand_lossage ("invalid %%N value");
15216 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15220 /* Similar, but subtract 1 first. */
15221 if (GET_CODE (x) != PARALLEL)
15222 output_operand_lossage ("invalid %%O value");
15224 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15228 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15230 || INT_LOWPART (x) < 0
15231 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15232 output_operand_lossage ("invalid %%p value");
15234 fprintf (file, "%d", i);
15238 /* The operand must be an indirect memory reference. The result
15239 is the register name. */
15240 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15241 || REGNO (XEXP (x, 0)) >= 32)
15242 output_operand_lossage ("invalid %%P value");
15244 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15248 /* This outputs the logical code corresponding to a boolean
15249 expression. The expression may have one or both operands
15250 negated (if one, only the first one). For condition register
15251 logical operations, it will also treat the negated
15252 CR codes as NOTs, but not handle NOTs of them. */
15254 const char *const *t = 0;
15256 enum rtx_code code = GET_CODE (x);
15257 static const char * const tbl[3][3] = {
15258 { "and", "andc", "nor" },
15259 { "or", "orc", "nand" },
15260 { "xor", "eqv", "xor" } };
15264 else if (code == IOR)
15266 else if (code == XOR)
15269 output_operand_lossage ("invalid %%q value");
15271 if (GET_CODE (XEXP (x, 0)) != NOT)
15275 if (GET_CODE (XEXP (x, 1)) == NOT)
15293 /* X is a CR register. Print the mask for `mtcrf'. */
15294 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15295 output_operand_lossage ("invalid %%R value");
15297 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15301 /* Low 5 bits of 32 - value */
15303 output_operand_lossage ("invalid %%s value");
15305 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15309 /* PowerPC64 mask position. All 0's is excluded.
15310 CONST_INT 32-bit mask is considered sign-extended so any
15311 transition must occur within the CONST_INT, not on the boundary. */
15312 if (! mask64_operand (x, DImode))
15313 output_operand_lossage ("invalid %%S value");
15315 uval = INT_LOWPART (x);
15317 if (uval & 1) /* Clear Left */
15319 #if HOST_BITS_PER_WIDE_INT > 64
15320 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15324 else /* Clear Right */
15327 #if HOST_BITS_PER_WIDE_INT > 64
15328 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15334 gcc_assert (i >= 0);
15335 fprintf (file, "%d", i);
15339 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15340 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15342 /* Bit 3 is OV bit. */
15343 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15345 /* If we want bit 31, write a shift count of zero, not 32. */
15346 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15350 /* Print the symbolic name of a branch target register. */
15351 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15352 && REGNO (x) != CTR_REGNO))
15353 output_operand_lossage ("invalid %%T value");
15354 else if (REGNO (x) == LR_REGNO)
15355 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15357 fputs ("ctr", file);
15361 /* High-order 16 bits of constant for use in unsigned operand. */
15363 output_operand_lossage ("invalid %%u value");
15365 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15366 (INT_LOWPART (x) >> 16) & 0xffff);
15370 /* High-order 16 bits of constant for use in signed operand. */
15372 output_operand_lossage ("invalid %%v value");
15374 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15375 (INT_LOWPART (x) >> 16) & 0xffff);
15379 /* Print `u' if this has an auto-increment or auto-decrement. */
15380 if (GET_CODE (x) == MEM
15381 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15382 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15383 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15388 /* Print the trap code for this operand. */
15389 switch (GET_CODE (x))
15392 fputs ("eq", file); /* 4 */
15395 fputs ("ne", file); /* 24 */
15398 fputs ("lt", file); /* 16 */
15401 fputs ("le", file); /* 20 */
15404 fputs ("gt", file); /* 8 */
15407 fputs ("ge", file); /* 12 */
15410 fputs ("llt", file); /* 2 */
15413 fputs ("lle", file); /* 6 */
15416 fputs ("lgt", file); /* 1 */
15419 fputs ("lge", file); /* 5 */
15422 gcc_unreachable ();
15427 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15430 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15431 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15433 print_operand (file, x, 0);
15437 /* MB value for a PowerPC64 rldic operand. */
15438 val = (GET_CODE (x) == CONST_INT
15439 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15444 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15445 if ((val <<= 1) < 0)
15448 #if HOST_BITS_PER_WIDE_INT == 32
15449 if (GET_CODE (x) == CONST_INT && i >= 0)
15450 i += 32; /* zero-extend high-part was all 0's */
15451 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15453 val = CONST_DOUBLE_LOW (x);
15459 for ( ; i < 64; i++)
15460 if ((val <<= 1) < 0)
15465 fprintf (file, "%d", i + 1);
15469 /* X is a FPR or Altivec register used in a VSX context. */
15470 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15471 output_operand_lossage ("invalid %%x value");
15474 int reg = REGNO (x);
15475 int vsx_reg = (FP_REGNO_P (reg)
15477 : reg - FIRST_ALTIVEC_REGNO + 32);
15479 #ifdef TARGET_REGNAMES
15480 if (TARGET_REGNAMES)
15481 fprintf (file, "%%vs%d", vsx_reg);
15484 fprintf (file, "%d", vsx_reg);
15489 if (GET_CODE (x) == MEM
15490 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15491 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15492 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15497 /* Like 'L', for third word of TImode */
15498 if (GET_CODE (x) == REG)
15499 fputs (reg_names[REGNO (x) + 2], file);
15500 else if (GET_CODE (x) == MEM)
15502 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15503 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15504 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15505 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15506 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15508 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15509 if (small_data_operand (x, GET_MODE (x)))
15510 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15511 reg_names[SMALL_DATA_REG]);
15516 /* X is a SYMBOL_REF. Write out the name preceded by a
15517 period and without any trailing data in brackets. Used for function
15518 names. If we are configured for System V (or the embedded ABI) on
15519 the PowerPC, do not emit the period, since those systems do not use
15520 TOCs and the like. */
15521 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15523 /* Mark the decl as referenced so that cgraph will output the
15525 if (SYMBOL_REF_DECL (x))
15526 mark_decl_referenced (SYMBOL_REF_DECL (x));
15528 /* For macho, check to see if we need a stub. */
15531 const char *name = XSTR (x, 0);
15533 if (darwin_emit_branch_islands
15534 && MACHOPIC_INDIRECT
15535 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15536 name = machopic_indirection_name (x, /*stub_p=*/true);
15538 assemble_name (file, name);
15540 else if (!DOT_SYMBOLS)
15541 assemble_name (file, XSTR (x, 0));
15543 rs6000_output_function_entry (file, XSTR (x, 0));
15547 /* Like 'L', for last word of TImode. */
15548 if (GET_CODE (x) == REG)
15549 fputs (reg_names[REGNO (x) + 3], file);
15550 else if (GET_CODE (x) == MEM)
15552 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15553 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15554 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15555 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15556 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15558 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15559 if (small_data_operand (x, GET_MODE (x)))
15560 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15561 reg_names[SMALL_DATA_REG]);
15565 /* Print AltiVec or SPE memory operand. */
15570 gcc_assert (GET_CODE (x) == MEM);
15574 /* Ugly hack because %y is overloaded. */
15575 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15576 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15577 || GET_MODE (x) == TFmode
15578 || GET_MODE (x) == TImode))
15580 /* Handle [reg]. */
15581 if (GET_CODE (tmp) == REG)
15583 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15586 /* Handle [reg+UIMM]. */
15587 else if (GET_CODE (tmp) == PLUS &&
15588 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15592 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15594 x = INTVAL (XEXP (tmp, 1));
15595 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15599 /* Fall through. Must be [reg+reg]. */
15601 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15602 && GET_CODE (tmp) == AND
15603 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15604 && INTVAL (XEXP (tmp, 1)) == -16)
15605 tmp = XEXP (tmp, 0);
15606 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15607 && GET_CODE (tmp) == PRE_MODIFY)
15608 tmp = XEXP (tmp, 1);
15609 if (GET_CODE (tmp) == REG)
15610 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15613 if (!GET_CODE (tmp) == PLUS
15614 || !REG_P (XEXP (tmp, 0))
15615 || !REG_P (XEXP (tmp, 1)))
15617 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15621 if (REGNO (XEXP (tmp, 0)) == 0)
15622 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15623 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15625 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15626 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15632 if (GET_CODE (x) == REG)
15633 fprintf (file, "%s", reg_names[REGNO (x)]);
15634 else if (GET_CODE (x) == MEM)
15636 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15637 know the width from the mode. */
15638 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15639 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15640 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15641 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15642 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15643 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15644 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15645 output_address (XEXP (XEXP (x, 0), 1));
15647 output_address (XEXP (x, 0));
15650 output_addr_const (file, x);
15654 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15658 output_operand_lossage ("invalid %%xn code");
15662 /* Print the address of an operand. */
15665 print_operand_address (FILE *file, rtx x)
15667 if (GET_CODE (x) == REG)
15668 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15669 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15670 || GET_CODE (x) == LABEL_REF)
15672 output_addr_const (file, x);
15673 if (small_data_operand (x, GET_MODE (x)))
15674 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15675 reg_names[SMALL_DATA_REG]);
15677 gcc_assert (!TARGET_TOC);
15679 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15681 gcc_assert (REG_P (XEXP (x, 0)));
15682 if (REGNO (XEXP (x, 0)) == 0)
15683 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15684 reg_names[ REGNO (XEXP (x, 0)) ]);
15686 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15687 reg_names[ REGNO (XEXP (x, 1)) ]);
15689 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15690 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15691 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15693 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15694 && CONSTANT_P (XEXP (x, 1)))
15696 fprintf (file, "lo16(");
15697 output_addr_const (file, XEXP (x, 1));
15698 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15701 else if (legitimate_constant_pool_address_p (x, true))
15703 /* This hack along with a corresponding hack in
15704 rs6000_output_addr_const_extra arranges to output addends
15705 where the assembler expects to find them. eg.
15707 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
15708 without this hack would be output as "x@toc+8@l(9)". We
15709 want "x+8@toc@l(9)". */
15710 output_addr_const (file, tocrel_base);
15711 if (GET_CODE (x) == LO_SUM)
15712 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15714 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15717 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15718 && CONSTANT_P (XEXP (x, 1)))
15720 output_addr_const (file, XEXP (x, 1));
15721 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15725 gcc_unreachable ();
15728 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15731 rs6000_output_addr_const_extra (FILE *file, rtx x)
15733 if (GET_CODE (x) == UNSPEC)
15734 switch (XINT (x, 1))
15736 case UNSPEC_TOCREL:
15737 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
15738 output_addr_const (file, XVECEXP (x, 0, 0));
15739 if (x == tocrel_base && tocrel_offset != const0_rtx)
15741 if (INTVAL (tocrel_offset) >= 0)
15742 fprintf (file, "+");
15743 output_addr_const (file, tocrel_offset);
15745 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15748 assemble_name (file, toc_label_name);
15750 else if (TARGET_ELF)
15751 fputs ("@toc", file);
15755 case UNSPEC_MACHOPIC_OFFSET:
15756 output_addr_const (file, XVECEXP (x, 0, 0));
15758 machopic_output_function_base_name (file);
15765 /* Target hook for assembling integer objects. The PowerPC version has
15766 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15767 is defined. It also needs to handle DI-mode objects on 64-bit
15771 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15773 #ifdef RELOCATABLE_NEEDS_FIXUP
15774 /* Special handling for SI values. */
15775 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15777 static int recurse = 0;
15779 /* For -mrelocatable, we mark all addresses that need to be fixed up
15780 in the .fixup section. */
15781 if (TARGET_RELOCATABLE
15782 && in_section != toc_section
15783 && in_section != text_section
15784 && !unlikely_text_section_p (in_section)
15786 && GET_CODE (x) != CONST_INT
15787 && GET_CODE (x) != CONST_DOUBLE
15793 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15795 ASM_OUTPUT_LABEL (asm_out_file, buf);
15796 fprintf (asm_out_file, "\t.long\t(");
15797 output_addr_const (asm_out_file, x);
15798 fprintf (asm_out_file, ")@fixup\n");
15799 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15800 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15801 fprintf (asm_out_file, "\t.long\t");
15802 assemble_name (asm_out_file, buf);
15803 fprintf (asm_out_file, "\n\t.previous\n");
15807 /* Remove initial .'s to turn a -mcall-aixdesc function
15808 address into the address of the descriptor, not the function
15810 else if (GET_CODE (x) == SYMBOL_REF
15811 && XSTR (x, 0)[0] == '.'
15812 && DEFAULT_ABI == ABI_AIX)
15814 const char *name = XSTR (x, 0);
15815 while (*name == '.')
15818 fprintf (asm_out_file, "\t.long\t%s\n", name);
15822 #endif /* RELOCATABLE_NEEDS_FIXUP */
15823 return default_assemble_integer (x, size, aligned_p);
15826 #ifdef HAVE_GAS_HIDDEN
15827 /* Emit an assembler directive to set symbol visibility for DECL to
15828 VISIBILITY_TYPE. */
15831 rs6000_assemble_visibility (tree decl, int vis)
15833 /* Functions need to have their entry point symbol visibility set as
15834 well as their descriptor symbol visibility. */
15835 if (DEFAULT_ABI == ABI_AIX
15837 && TREE_CODE (decl) == FUNCTION_DECL)
15839 static const char * const visibility_types[] = {
15840 NULL, "internal", "hidden", "protected"
15843 const char *name, *type;
15845 name = ((* targetm.strip_name_encoding)
15846 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15847 type = visibility_types[vis];
15849 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15850 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15853 default_assemble_visibility (decl, vis);
15858 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15860 /* Reversal of FP compares takes care -- an ordered compare
15861 becomes an unordered compare and vice versa. */
15862 if (mode == CCFPmode
15863 && (!flag_finite_math_only
15864 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15865 || code == UNEQ || code == LTGT))
15866 return reverse_condition_maybe_unordered (code);
15868 return reverse_condition (code);
15871 /* Generate a compare for CODE. Return a brand-new rtx that
15872 represents the result of the compare. */
15875 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15877 enum machine_mode comp_mode;
15878 rtx compare_result;
15879 enum rtx_code code = GET_CODE (cmp);
15880 rtx op0 = XEXP (cmp, 0);
15881 rtx op1 = XEXP (cmp, 1);
15883 if (FLOAT_MODE_P (mode))
15884 comp_mode = CCFPmode;
15885 else if (code == GTU || code == LTU
15886 || code == GEU || code == LEU)
15887 comp_mode = CCUNSmode;
15888 else if ((code == EQ || code == NE)
15889 && GET_CODE (op0) == SUBREG
15890 && GET_CODE (op1) == SUBREG
15891 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15892 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15893 /* These are unsigned values, perhaps there will be a later
15894 ordering compare that can be shared with this one.
15895 Unfortunately we cannot detect the signedness of the operands
15896 for non-subregs. */
15897 comp_mode = CCUNSmode;
15899 comp_mode = CCmode;
15901 /* First, the compare. */
15902 compare_result = gen_reg_rtx (comp_mode);
15904 /* E500 FP compare instructions on the GPRs. Yuck! */
15905 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15906 && FLOAT_MODE_P (mode))
15908 rtx cmp, or_result, compare_result2;
15909 enum machine_mode op_mode = GET_MODE (op0);
15911 if (op_mode == VOIDmode)
15912 op_mode = GET_MODE (op1);
15914 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15915 This explains the following mess. */
15919 case EQ: case UNEQ: case NE: case LTGT:
15923 cmp = (flag_finite_math_only && !flag_trapping_math)
15924 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15925 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15929 cmp = (flag_finite_math_only && !flag_trapping_math)
15930 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15931 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15935 cmp = (flag_finite_math_only && !flag_trapping_math)
15936 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15937 : gen_cmptfeq_gpr (compare_result, op0, op1);
15941 gcc_unreachable ();
15945 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15949 cmp = (flag_finite_math_only && !flag_trapping_math)
15950 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15951 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15955 cmp = (flag_finite_math_only && !flag_trapping_math)
15956 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15957 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15961 cmp = (flag_finite_math_only && !flag_trapping_math)
15962 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15963 : gen_cmptfgt_gpr (compare_result, op0, op1);
15967 gcc_unreachable ();
15971 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15975 cmp = (flag_finite_math_only && !flag_trapping_math)
15976 ? gen_tstsflt_gpr (compare_result, op0, op1)
15977 : gen_cmpsflt_gpr (compare_result, op0, op1);
15981 cmp = (flag_finite_math_only && !flag_trapping_math)
15982 ? gen_tstdflt_gpr (compare_result, op0, op1)
15983 : gen_cmpdflt_gpr (compare_result, op0, op1);
15987 cmp = (flag_finite_math_only && !flag_trapping_math)
15988 ? gen_tsttflt_gpr (compare_result, op0, op1)
15989 : gen_cmptflt_gpr (compare_result, op0, op1);
15993 gcc_unreachable ();
15997 gcc_unreachable ();
16000 /* Synthesize LE and GE from LT/GT || EQ. */
16001 if (code == LE || code == GE || code == LEU || code == GEU)
16007 case LE: code = LT; break;
16008 case GE: code = GT; break;
16009 case LEU: code = LT; break;
16010 case GEU: code = GT; break;
16011 default: gcc_unreachable ();
16014 compare_result2 = gen_reg_rtx (CCFPmode);
16020 cmp = (flag_finite_math_only && !flag_trapping_math)
16021 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16022 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16026 cmp = (flag_finite_math_only && !flag_trapping_math)
16027 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16028 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16032 cmp = (flag_finite_math_only && !flag_trapping_math)
16033 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16034 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16038 gcc_unreachable ();
16042 /* OR them together. */
16043 or_result = gen_reg_rtx (CCFPmode);
16044 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16046 compare_result = or_result;
16051 if (code == NE || code == LTGT)
16061 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16062 CLOBBERs to match cmptf_internal2 pattern. */
16063 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16064 && GET_MODE (op0) == TFmode
16065 && !TARGET_IEEEQUAD
16066 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16067 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16069 gen_rtx_SET (VOIDmode,
16071 gen_rtx_COMPARE (comp_mode, op0, op1)),
16072 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16073 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16074 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16075 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16076 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16077 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16078 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16079 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16080 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16081 else if (GET_CODE (op1) == UNSPEC
16082 && XINT (op1, 1) == UNSPEC_SP_TEST)
16084 rtx op1b = XVECEXP (op1, 0, 0);
16085 comp_mode = CCEQmode;
16086 compare_result = gen_reg_rtx (CCEQmode);
16088 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16090 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16093 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16094 gen_rtx_COMPARE (comp_mode, op0, op1)));
16097 /* Some kinds of FP comparisons need an OR operation;
16098 under flag_finite_math_only we don't bother. */
16099 if (FLOAT_MODE_P (mode)
16100 && !flag_finite_math_only
16101 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16102 && (code == LE || code == GE
16103 || code == UNEQ || code == LTGT
16104 || code == UNGT || code == UNLT))
16106 enum rtx_code or1, or2;
16107 rtx or1_rtx, or2_rtx, compare2_rtx;
16108 rtx or_result = gen_reg_rtx (CCEQmode);
16112 case LE: or1 = LT; or2 = EQ; break;
16113 case GE: or1 = GT; or2 = EQ; break;
16114 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16115 case LTGT: or1 = LT; or2 = GT; break;
16116 case UNGT: or1 = UNORDERED; or2 = GT; break;
16117 case UNLT: or1 = UNORDERED; or2 = LT; break;
16118 default: gcc_unreachable ();
16120 validate_condition_mode (or1, comp_mode);
16121 validate_condition_mode (or2, comp_mode);
16122 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16123 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16124 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16125 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16127 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16129 compare_result = or_result;
16133 validate_condition_mode (code, GET_MODE (compare_result));
16135 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16139 /* Emit the RTL for an sISEL pattern. */
16142 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16144 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16148 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16151 enum machine_mode op_mode;
16152 enum rtx_code cond_code;
16153 rtx result = operands[0];
16155 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16157 rs6000_emit_sISEL (mode, operands);
16161 condition_rtx = rs6000_generate_compare (operands[1], mode);
16162 cond_code = GET_CODE (condition_rtx);
16164 if (FLOAT_MODE_P (mode)
16165 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16169 PUT_MODE (condition_rtx, SImode);
16170 t = XEXP (condition_rtx, 0);
16172 gcc_assert (cond_code == NE || cond_code == EQ);
16174 if (cond_code == NE)
16175 emit_insn (gen_e500_flip_gt_bit (t, t));
16177 emit_insn (gen_move_from_CR_gt_bit (result, t));
16181 if (cond_code == NE
16182 || cond_code == GE || cond_code == LE
16183 || cond_code == GEU || cond_code == LEU
16184 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16186 rtx not_result = gen_reg_rtx (CCEQmode);
16187 rtx not_op, rev_cond_rtx;
16188 enum machine_mode cc_mode;
16190 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16192 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16193 SImode, XEXP (condition_rtx, 0), const0_rtx);
16194 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16195 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16196 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16199 op_mode = GET_MODE (XEXP (operands[1], 0));
16200 if (op_mode == VOIDmode)
16201 op_mode = GET_MODE (XEXP (operands[1], 1));
16203 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16205 PUT_MODE (condition_rtx, DImode);
16206 convert_move (result, condition_rtx, 0);
16210 PUT_MODE (condition_rtx, SImode);
16211 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16215 /* Emit a branch of kind CODE to location LOC. */
16218 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16220 rtx condition_rtx, loc_ref;
16222 condition_rtx = rs6000_generate_compare (operands[0], mode);
16223 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16224 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16225 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16226 loc_ref, pc_rtx)));
16229 /* Return the string to output a conditional branch to LABEL, which is
16230 the operand number of the label, or -1 if the branch is really a
16231 conditional return.
16233 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16234 condition code register and its mode specifies what kind of
16235 comparison we made.
16237 REVERSED is nonzero if we should reverse the sense of the comparison.
16239 INSN is the insn. */
16242 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16244 static char string[64];
16245 enum rtx_code code = GET_CODE (op);
16246 rtx cc_reg = XEXP (op, 0);
16247 enum machine_mode mode = GET_MODE (cc_reg);
16248 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16249 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16250 int really_reversed = reversed ^ need_longbranch;
16256 validate_condition_mode (code, mode);
16258 /* Work out which way this really branches. We could use
16259 reverse_condition_maybe_unordered here always but this
16260 makes the resulting assembler clearer. */
16261 if (really_reversed)
16263 /* Reversal of FP compares takes care -- an ordered compare
16264 becomes an unordered compare and vice versa. */
16265 if (mode == CCFPmode)
16266 code = reverse_condition_maybe_unordered (code);
16268 code = reverse_condition (code);
16271 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16273 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16278 /* Opposite of GT. */
16287 gcc_unreachable ();
16293 /* Not all of these are actually distinct opcodes, but
16294 we distinguish them for clarity of the resulting assembler. */
16295 case NE: case LTGT:
16296 ccode = "ne"; break;
16297 case EQ: case UNEQ:
16298 ccode = "eq"; break;
16300 ccode = "ge"; break;
16301 case GT: case GTU: case UNGT:
16302 ccode = "gt"; break;
16304 ccode = "le"; break;
16305 case LT: case LTU: case UNLT:
16306 ccode = "lt"; break;
16307 case UNORDERED: ccode = "un"; break;
16308 case ORDERED: ccode = "nu"; break;
16309 case UNGE: ccode = "nl"; break;
16310 case UNLE: ccode = "ng"; break;
16312 gcc_unreachable ();
16315 /* Maybe we have a guess as to how likely the branch is.
16316 The old mnemonics don't have a way to specify this information. */
16318 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16319 if (note != NULL_RTX)
16321 /* PROB is the difference from 50%. */
16322 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16324 /* Only hint for highly probable/improbable branches on newer
16325 cpus as static prediction overrides processor dynamic
16326 prediction. For older cpus we may as well always hint, but
16327 assume not taken for branches that are very close to 50% as a
16328 mispredicted taken branch is more expensive than a
16329 mispredicted not-taken branch. */
16330 if (rs6000_always_hint
16331 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16332 && br_prob_note_reliable_p (note)))
16334 if (abs (prob) > REG_BR_PROB_BASE / 20
16335 && ((prob > 0) ^ need_longbranch))
16343 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16345 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16347 /* We need to escape any '%' characters in the reg_names string.
16348 Assume they'd only be the first character.... */
16349 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16351 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16355 /* If the branch distance was too far, we may have to use an
16356 unconditional branch to go the distance. */
16357 if (need_longbranch)
16358 s += sprintf (s, ",$+8\n\tb %s", label);
16360 s += sprintf (s, ",%s", label);
16366 /* Return the string to flip the GT bit on a CR. */
16368 output_e500_flip_gt_bit (rtx dst, rtx src)
16370 static char string[64];
16373 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16374 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16377 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16378 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16380 sprintf (string, "crnot %d,%d", a, b);
16384 /* Return insn for VSX or Altivec comparisons. */
16387 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16390 enum machine_mode mode = GET_MODE (op0);
16398 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16404 mask = gen_reg_rtx (mode);
16405 emit_insn (gen_rtx_SET (VOIDmode,
16407 gen_rtx_fmt_ee (code, mode, op0, op1)));
16414 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16415 DMODE is expected destination mode. This is a recursive function. */
16418 rs6000_emit_vector_compare (enum rtx_code rcode,
16420 enum machine_mode dmode)
16423 bool swap_operands = false;
16424 bool try_again = false;
16426 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16427 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16429 /* See if the comparison works as is. */
16430 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16438 swap_operands = true;
16443 swap_operands = true;
16451 /* Invert condition and try again.
16452 e.g., A != B becomes ~(A==B). */
16454 enum rtx_code rev_code;
16455 enum insn_code nor_code;
16458 rev_code = reverse_condition_maybe_unordered (rcode);
16459 if (rev_code == UNKNOWN)
16462 nor_code = optab_handler (one_cmpl_optab, dmode);
16463 if (nor_code == CODE_FOR_nothing)
16466 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16470 mask = gen_reg_rtx (dmode);
16471 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16479 /* Try GT/GTU/LT/LTU OR EQ */
16482 enum insn_code ior_code;
16483 enum rtx_code new_code;
16504 gcc_unreachable ();
16507 ior_code = optab_handler (ior_optab, dmode);
16508 if (ior_code == CODE_FOR_nothing)
16511 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16515 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16519 mask = gen_reg_rtx (dmode);
16520 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16538 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16543 /* You only get two chances. */
16547 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16548 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16549 operands for the relation operation COND. */
16552 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16553 rtx cond, rtx cc_op0, rtx cc_op1)
16555 enum machine_mode dest_mode = GET_MODE (dest);
16556 enum rtx_code rcode = GET_CODE (cond);
16557 enum machine_mode cc_mode = CCmode;
16561 bool invert_move = false;
16563 if (VECTOR_UNIT_NONE_P (dest_mode))
16568 /* Swap operands if we can, and fall back to doing the operation as
16569 specified, and doing a NOR to invert the test. */
16575 /* Invert condition and try again.
16576 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16577 invert_move = true;
16578 rcode = reverse_condition_maybe_unordered (rcode);
16579 if (rcode == UNKNOWN)
16583 /* Mark unsigned tests with CCUNSmode. */
16588 cc_mode = CCUNSmode;
16595 /* Get the vector mask for the given relational operations. */
16596 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16604 op_true = op_false;
16608 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16609 emit_insn (gen_rtx_SET (VOIDmode,
16611 gen_rtx_IF_THEN_ELSE (dest_mode,
16618 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16619 operands of the last comparison is nonzero/true, FALSE_COND if it
16620 is zero/false. Return 0 if the hardware has no such operation. */
16623 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16625 enum rtx_code code = GET_CODE (op);
16626 rtx op0 = XEXP (op, 0);
16627 rtx op1 = XEXP (op, 1);
16628 REAL_VALUE_TYPE c1;
16629 enum machine_mode compare_mode = GET_MODE (op0);
16630 enum machine_mode result_mode = GET_MODE (dest);
16632 bool is_against_zero;
16634 /* These modes should always match. */
16635 if (GET_MODE (op1) != compare_mode
16636 /* In the isel case however, we can use a compare immediate, so
16637 op1 may be a small constant. */
16638 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16640 if (GET_MODE (true_cond) != result_mode)
16642 if (GET_MODE (false_cond) != result_mode)
16645 /* First, work out if the hardware can do this at all, or
16646 if it's too slow.... */
16647 if (!FLOAT_MODE_P (compare_mode))
16650 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16653 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16654 && SCALAR_FLOAT_MODE_P (compare_mode))
16657 is_against_zero = op1 == CONST0_RTX (compare_mode);
16659 /* A floating-point subtract might overflow, underflow, or produce
16660 an inexact result, thus changing the floating-point flags, so it
16661 can't be generated if we care about that. It's safe if one side
16662 of the construct is zero, since then no subtract will be
16664 if (SCALAR_FLOAT_MODE_P (compare_mode)
16665 && flag_trapping_math && ! is_against_zero)
16668 /* Eliminate half of the comparisons by switching operands, this
16669 makes the remaining code simpler. */
16670 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16671 || code == LTGT || code == LT || code == UNLE)
16673 code = reverse_condition_maybe_unordered (code);
16675 true_cond = false_cond;
16679 /* UNEQ and LTGT take four instructions for a comparison with zero,
16680 it'll probably be faster to use a branch here too. */
16681 if (code == UNEQ && HONOR_NANS (compare_mode))
16684 if (GET_CODE (op1) == CONST_DOUBLE)
16685 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16687 /* We're going to try to implement comparisons by performing
16688 a subtract, then comparing against zero. Unfortunately,
16689 Inf - Inf is NaN which is not zero, and so if we don't
16690 know that the operand is finite and the comparison
16691 would treat EQ different to UNORDERED, we can't do it. */
16692 if (HONOR_INFINITIES (compare_mode)
16693 && code != GT && code != UNGE
16694 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16695 /* Constructs of the form (a OP b ? a : b) are safe. */
16696 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16697 || (! rtx_equal_p (op0, true_cond)
16698 && ! rtx_equal_p (op1, true_cond))))
16701 /* At this point we know we can use fsel. */
16703 /* Reduce the comparison to a comparison against zero. */
16704 if (! is_against_zero)
16706 temp = gen_reg_rtx (compare_mode);
16707 emit_insn (gen_rtx_SET (VOIDmode, temp,
16708 gen_rtx_MINUS (compare_mode, op0, op1)));
16710 op1 = CONST0_RTX (compare_mode);
16713 /* If we don't care about NaNs we can reduce some of the comparisons
16714 down to faster ones. */
16715 if (! HONOR_NANS (compare_mode))
16721 true_cond = false_cond;
16734 /* Now, reduce everything down to a GE. */
16741 temp = gen_reg_rtx (compare_mode);
16742 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16747 temp = gen_reg_rtx (compare_mode);
16748 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16753 temp = gen_reg_rtx (compare_mode);
16754 emit_insn (gen_rtx_SET (VOIDmode, temp,
16755 gen_rtx_NEG (compare_mode,
16756 gen_rtx_ABS (compare_mode, op0))));
16761 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16762 temp = gen_reg_rtx (result_mode);
16763 emit_insn (gen_rtx_SET (VOIDmode, temp,
16764 gen_rtx_IF_THEN_ELSE (result_mode,
16765 gen_rtx_GE (VOIDmode,
16767 true_cond, false_cond)));
16768 false_cond = true_cond;
16771 temp = gen_reg_rtx (compare_mode);
16772 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16777 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16778 temp = gen_reg_rtx (result_mode);
16779 emit_insn (gen_rtx_SET (VOIDmode, temp,
16780 gen_rtx_IF_THEN_ELSE (result_mode,
16781 gen_rtx_GE (VOIDmode,
16783 true_cond, false_cond)));
16784 true_cond = false_cond;
16787 temp = gen_reg_rtx (compare_mode);
16788 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16793 gcc_unreachable ();
16796 emit_insn (gen_rtx_SET (VOIDmode, dest,
16797 gen_rtx_IF_THEN_ELSE (result_mode,
16798 gen_rtx_GE (VOIDmode,
16800 true_cond, false_cond)));
16804 /* Same as above, but for ints (isel). */
16807 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16809 rtx condition_rtx, cr;
16810 enum machine_mode mode = GET_MODE (dest);
16811 enum rtx_code cond_code;
16812 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
16815 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16818 /* We still have to do the compare, because isel doesn't do a
16819 compare, it just looks at the CRx bits set by a previous compare
16821 condition_rtx = rs6000_generate_compare (op, mode);
16822 cond_code = GET_CODE (condition_rtx);
16823 cr = XEXP (condition_rtx, 0);
16824 signedp = GET_MODE (cr) == CCmode;
16826 isel_func = (mode == SImode
16827 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
16828 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
16832 case LT: case GT: case LTU: case GTU: case EQ:
16833 /* isel handles these directly. */
16837 /* We need to swap the sense of the comparison. */
16840 true_cond = false_cond;
16842 PUT_CODE (condition_rtx, reverse_condition (cond_code));
16847 false_cond = force_reg (mode, false_cond);
16848 if (true_cond != const0_rtx)
16849 true_cond = force_reg (mode, true_cond);
16851 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
16857 output_isel (rtx *operands)
16859 enum rtx_code code;
16861 code = GET_CODE (operands[1]);
16863 gcc_assert (!(code == GE || code == GEU || code == LE || code == LEU || code == NE));
16865 return "isel %0,%2,%3,%j1";
16869 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16871 enum machine_mode mode = GET_MODE (op0);
16875 /* VSX/altivec have direct min/max insns. */
16876 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16878 emit_insn (gen_rtx_SET (VOIDmode,
16880 gen_rtx_fmt_ee (code, mode, op0, op1)));
16884 if (code == SMAX || code == SMIN)
16889 if (code == SMAX || code == UMAX)
16890 target = emit_conditional_move (dest, c, op0, op1, mode,
16891 op0, op1, mode, 0);
16893 target = emit_conditional_move (dest, c, op0, op1, mode,
16894 op1, op0, mode, 0);
16895 gcc_assert (target);
16896 if (target != dest)
16897 emit_move_insn (dest, target);
16900 /* Emit instructions to perform a load-reserved/store-conditional operation.
16901 The operation performed is an atomic
16902 (set M (CODE:MODE M OP))
16903 If not NULL, BEFORE is atomically set to M before the operation, and
16904 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16905 If SYNC_P then a memory barrier is emitted before the operation.
16906 Either OP or M may be wrapped in a NOT operation. */
16909 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16910 rtx m, rtx op, rtx before_param, rtx after_param,
16913 enum machine_mode used_mode;
16914 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16917 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16918 rtx shift = NULL_RTX;
16921 emit_insn (gen_lwsync ());
16925 /* If this is smaller than SImode, we'll have to use SImode with
16927 if (mode == QImode || mode == HImode)
16931 if (MEM_ALIGN (used_m) >= 32)
16934 if (BYTES_BIG_ENDIAN)
16935 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16937 shift = GEN_INT (ishift);
16938 used_m = change_address (used_m, SImode, 0);
16942 rtx addrSI, aligned_addr;
16943 int shift_mask = mode == QImode ? 0x18 : 0x10;
16945 addrSI = gen_lowpart_common (SImode,
16946 force_reg (Pmode, XEXP (used_m, 0)));
16947 addrSI = force_reg (SImode, addrSI);
16948 shift = gen_reg_rtx (SImode);
16950 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16951 GEN_INT (shift_mask)));
16952 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16954 aligned_addr = expand_binop (Pmode, and_optab,
16956 GEN_INT (-4), NULL_RTX,
16957 1, OPTAB_LIB_WIDEN);
16958 used_m = change_address (used_m, SImode, aligned_addr);
16959 set_mem_align (used_m, 32);
16961 /* It's safe to keep the old alias set of USED_M, because
16962 the operation is atomic and only affects the original
16966 if (GET_CODE (op) == NOT)
16968 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16969 oldop = gen_rtx_NOT (SImode, oldop);
16972 oldop = lowpart_subreg (SImode, op, mode);
16978 newop = expand_binop (SImode, and_optab,
16979 oldop, GEN_INT (imask), NULL_RTX,
16980 1, OPTAB_LIB_WIDEN);
16981 emit_insn (gen_ashlsi3 (newop, newop, shift));
16984 case NOT: /* NAND */
16985 newop = expand_binop (SImode, ior_optab,
16986 oldop, GEN_INT (~imask), NULL_RTX,
16987 1, OPTAB_LIB_WIDEN);
16988 emit_insn (gen_rotlsi3 (newop, newop, shift));
16992 newop = expand_binop (SImode, ior_optab,
16993 oldop, GEN_INT (~imask), NULL_RTX,
16994 1, OPTAB_LIB_WIDEN);
16995 emit_insn (gen_rotlsi3 (newop, newop, shift));
17003 newop = expand_binop (SImode, and_optab,
17004 oldop, GEN_INT (imask), NULL_RTX,
17005 1, OPTAB_LIB_WIDEN);
17006 emit_insn (gen_ashlsi3 (newop, newop, shift));
17008 mask = gen_reg_rtx (SImode);
17009 emit_move_insn (mask, GEN_INT (imask));
17010 emit_insn (gen_ashlsi3 (mask, mask, shift));
17013 newop = gen_rtx_PLUS (SImode, m, newop);
17015 newop = gen_rtx_MINUS (SImode, m, newop);
17016 newop = gen_rtx_AND (SImode, newop, mask);
17017 newop = gen_rtx_IOR (SImode, newop,
17018 gen_rtx_AND (SImode,
17019 gen_rtx_NOT (SImode, mask),
17025 gcc_unreachable ();
17029 used_mode = SImode;
17030 before = gen_reg_rtx (used_mode);
17031 after = gen_reg_rtx (used_mode);
17036 before = before_param;
17037 after = after_param;
17039 if (before == NULL_RTX)
17040 before = gen_reg_rtx (used_mode);
17041 if (after == NULL_RTX)
17042 after = gen_reg_rtx (used_mode);
17045 if ((code == PLUS || code == MINUS)
17046 && used_mode != mode)
17047 the_op = op; /* Computed above. */
17048 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17049 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17050 else if (code == NOT)
17051 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17052 gen_rtx_NOT (used_mode, m),
17053 gen_rtx_NOT (used_mode, op));
17055 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17057 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17058 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17059 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17060 gen_rtx_UNSPEC (used_mode,
17061 gen_rtvec (1, the_op),
17063 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17065 if ((code == PLUS || code == MINUS) && used_mode != mode)
17066 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17067 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17069 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17070 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17072 /* Shift and mask the return values properly. */
17073 if (used_mode != mode && before_param)
17075 emit_insn (gen_lshrsi3 (before, before, shift));
17076 convert_move (before_param, before, 1);
17079 if (used_mode != mode && after_param)
17081 emit_insn (gen_lshrsi3 (after, after, shift));
17082 convert_move (after_param, after, 1);
17085 /* The previous sequence will end with a branch that's dependent on
17086 the conditional store, so placing an isync will ensure that no
17087 other instructions (especially, no load or store instructions)
17088 can start before the atomic operation completes. */
17090 emit_insn (gen_isync ());
17093 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17094 COND is true. Mark the jump as unlikely to be taken. */
17097 emit_unlikely_jump (rtx cond, rtx label)
17099 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17102 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17103 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17104 add_reg_note (x, REG_BR_PROB, very_unlikely);
17107 /* A subroutine of the atomic operation splitters. Emit a load-locked
17108 instruction in MODE. */
17111 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17113 rtx (*fn) (rtx, rtx) = NULL;
17114 if (mode == SImode)
17115 fn = gen_load_locked_si;
17116 else if (mode == DImode)
17117 fn = gen_load_locked_di;
17118 emit_insn (fn (reg, mem));
17121 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17122 instruction in MODE. */
17125 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17127 rtx (*fn) (rtx, rtx, rtx) = NULL;
17128 if (mode == SImode)
17129 fn = gen_store_conditional_si;
17130 else if (mode == DImode)
17131 fn = gen_store_conditional_di;
17133 /* Emit sync before stwcx. to address PPC405 Erratum. */
17134 if (PPC405_ERRATUM77)
17135 emit_insn (gen_memory_barrier ());
17137 emit_insn (fn (res, mem, val));
17140 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17141 to perform. MEM is the memory on which to operate. VAL is the second
17142 operand of the binary operator. BEFORE and AFTER are optional locations to
17143 return the value of MEM either before of after the operation. SCRATCH is
17144 a scratch register. */
17147 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17148 rtx before, rtx after, rtx scratch)
17150 enum machine_mode mode = GET_MODE (mem);
17151 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17153 emit_insn (gen_lwsync ());
17155 label = gen_label_rtx ();
17156 emit_label (label);
17157 label = gen_rtx_LABEL_REF (VOIDmode, label);
17159 if (before == NULL_RTX)
17161 emit_load_locked (mode, before, mem);
17164 x = gen_rtx_IOR (mode,
17165 gen_rtx_NOT (mode, before),
17166 gen_rtx_NOT (mode, val));
17167 else if (code == AND)
17168 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17170 x = gen_rtx_fmt_ee (code, mode, before, val);
17172 if (after != NULL_RTX)
17173 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17174 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17176 emit_store_conditional (mode, cond, mem, scratch);
17178 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17179 emit_unlikely_jump (x, label);
17181 emit_insn (gen_isync ());
17184 /* Expand an atomic compare and swap operation. MEM is the memory on which
17185 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17186 value to be stored. SCRATCH is a scratch GPR. */
17189 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17192 enum machine_mode mode = GET_MODE (mem);
17193 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17195 emit_insn (gen_lwsync ());
17197 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17198 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17199 emit_label (XEXP (label1, 0));
17201 emit_load_locked (mode, retval, mem);
17203 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17204 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17206 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17207 emit_unlikely_jump (x, label2);
17209 emit_move_insn (scratch, newval);
17210 emit_store_conditional (mode, cond, mem, scratch);
17212 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17213 emit_unlikely_jump (x, label1);
17215 emit_insn (gen_isync ());
17216 emit_label (XEXP (label2, 0));
17219 /* Expand an atomic test and set operation. MEM is the memory on which
17220 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17223 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17225 enum machine_mode mode = GET_MODE (mem);
17226 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17228 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17229 emit_label (XEXP (label, 0));
17231 emit_load_locked (mode, retval, mem);
17232 emit_move_insn (scratch, val);
17233 emit_store_conditional (mode, cond, mem, scratch);
17235 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17236 emit_unlikely_jump (x, label);
17238 emit_insn (gen_isync ());
17242 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17244 enum machine_mode mode = GET_MODE (mem);
17245 rtx addrSI, align, wdst, shift, mask;
17246 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17247 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17249 /* Shift amount for subword relative to aligned word. */
17250 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17251 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17252 shift = gen_reg_rtx (SImode);
17253 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17254 GEN_INT (shift_mask)));
17255 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17257 /* Shift and mask old value into position within word. */
17258 oldval = convert_modes (SImode, mode, oldval, 1);
17259 oldval = expand_binop (SImode, and_optab,
17260 oldval, GEN_INT (imask), NULL_RTX,
17261 1, OPTAB_LIB_WIDEN);
17262 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17264 /* Shift and mask new value into position within word. */
17265 newval = convert_modes (SImode, mode, newval, 1);
17266 newval = expand_binop (SImode, and_optab,
17267 newval, GEN_INT (imask), NULL_RTX,
17268 1, OPTAB_LIB_WIDEN);
17269 emit_insn (gen_ashlsi3 (newval, newval, shift));
17271 /* Mask for insertion. */
17272 mask = gen_reg_rtx (SImode);
17273 emit_move_insn (mask, GEN_INT (imask));
17274 emit_insn (gen_ashlsi3 (mask, mask, shift));
17276 /* Address of aligned word containing subword. */
17277 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17278 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17279 mem = change_address (mem, SImode, align);
17280 set_mem_align (mem, 32);
17281 MEM_VOLATILE_P (mem) = 1;
17283 wdst = gen_reg_rtx (SImode);
17284 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17285 oldval, newval, mem));
17287 /* Shift the result back. */
17288 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17290 emit_move_insn (dst, gen_lowpart (mode, wdst));
17294 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17295 rtx oldval, rtx newval, rtx mem,
17298 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17300 emit_insn (gen_lwsync ());
17301 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17302 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17303 emit_label (XEXP (label1, 0));
17305 emit_load_locked (SImode, scratch, mem);
17307 /* Mask subword within loaded value for comparison with oldval.
17308 Use UNSPEC_AND to avoid clobber.*/
17309 emit_insn (gen_rtx_SET (SImode, dest,
17310 gen_rtx_UNSPEC (SImode,
17311 gen_rtvec (2, scratch, mask),
17314 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17315 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17317 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17318 emit_unlikely_jump (x, label2);
17320 /* Clear subword within loaded value for insertion of new value. */
17321 emit_insn (gen_rtx_SET (SImode, scratch,
17322 gen_rtx_AND (SImode,
17323 gen_rtx_NOT (SImode, mask), scratch)));
17324 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17325 emit_store_conditional (SImode, cond, mem, scratch);
17327 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17328 emit_unlikely_jump (x, label1);
17330 emit_insn (gen_isync ());
17331 emit_label (XEXP (label2, 0));
17335 /* Emit instructions to move SRC to DST. Called by splitters for
17336 multi-register moves. It will emit at most one instruction for
17337 each register that is accessed; that is, it won't emit li/lis pairs
17338 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17342 rs6000_split_multireg_move (rtx dst, rtx src)
17344 /* The register number of the first register being moved. */
17346 /* The mode that is to be moved. */
17347 enum machine_mode mode;
17348 /* The mode that the move is being done in, and its size. */
17349 enum machine_mode reg_mode;
17351 /* The number of registers that will be moved. */
17354 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17355 mode = GET_MODE (dst);
17356 nregs = hard_regno_nregs[reg][mode];
17357 if (FP_REGNO_P (reg))
17358 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17359 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17360 else if (ALTIVEC_REGNO_P (reg))
17361 reg_mode = V16QImode;
17362 else if (TARGET_E500_DOUBLE && mode == TFmode)
17365 reg_mode = word_mode;
17366 reg_mode_size = GET_MODE_SIZE (reg_mode);
17368 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17370 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17372 /* Move register range backwards, if we might have destructive
17375 for (i = nregs - 1; i >= 0; i--)
17376 emit_insn (gen_rtx_SET (VOIDmode,
17377 simplify_gen_subreg (reg_mode, dst, mode,
17378 i * reg_mode_size),
17379 simplify_gen_subreg (reg_mode, src, mode,
17380 i * reg_mode_size)));
17386 bool used_update = false;
17387 rtx restore_basereg = NULL_RTX;
17389 if (MEM_P (src) && INT_REGNO_P (reg))
17393 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17394 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17397 breg = XEXP (XEXP (src, 0), 0);
17398 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17399 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17400 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17401 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17402 src = replace_equiv_address (src, breg);
17404 else if (! rs6000_offsettable_memref_p (src))
17406 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17408 rtx basereg = XEXP (XEXP (src, 0), 0);
17411 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17412 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17413 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17414 used_update = true;
17417 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17418 XEXP (XEXP (src, 0), 1)));
17419 src = replace_equiv_address (src, basereg);
17423 rtx basereg = gen_rtx_REG (Pmode, reg);
17424 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17425 src = replace_equiv_address (src, basereg);
17429 breg = XEXP (src, 0);
17430 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17431 breg = XEXP (breg, 0);
17433 /* If the base register we are using to address memory is
17434 also a destination reg, then change that register last. */
17436 && REGNO (breg) >= REGNO (dst)
17437 && REGNO (breg) < REGNO (dst) + nregs)
17438 j = REGNO (breg) - REGNO (dst);
17440 else if (MEM_P (dst) && INT_REGNO_P (reg))
17444 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17445 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17448 breg = XEXP (XEXP (dst, 0), 0);
17449 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17450 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17451 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17453 /* We have to update the breg before doing the store.
17454 Use store with update, if available. */
17458 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17459 emit_insn (TARGET_32BIT
17460 ? (TARGET_POWERPC64
17461 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17462 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17463 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17464 used_update = true;
17467 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17468 dst = replace_equiv_address (dst, breg);
17470 else if (!rs6000_offsettable_memref_p (dst)
17471 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17473 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17475 rtx basereg = XEXP (XEXP (dst, 0), 0);
17478 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17479 emit_insn (gen_rtx_SET (VOIDmode,
17480 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17481 used_update = true;
17484 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17485 XEXP (XEXP (dst, 0), 1)));
17486 dst = replace_equiv_address (dst, basereg);
17490 rtx basereg = XEXP (XEXP (dst, 0), 0);
17491 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17492 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17494 && REG_P (offsetreg)
17495 && REGNO (basereg) != REGNO (offsetreg));
17496 if (REGNO (basereg) == 0)
17498 rtx tmp = offsetreg;
17499 offsetreg = basereg;
17502 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17503 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17504 dst = replace_equiv_address (dst, basereg);
17507 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17508 gcc_assert (rs6000_offsettable_memref_p (dst));
17511 for (i = 0; i < nregs; i++)
17513 /* Calculate index to next subword. */
17518 /* If compiler already emitted move of first word by
17519 store with update, no need to do anything. */
17520 if (j == 0 && used_update)
17523 emit_insn (gen_rtx_SET (VOIDmode,
17524 simplify_gen_subreg (reg_mode, dst, mode,
17525 j * reg_mode_size),
17526 simplify_gen_subreg (reg_mode, src, mode,
17527 j * reg_mode_size)));
17529 if (restore_basereg != NULL_RTX)
17530 emit_insn (restore_basereg);
17535 /* This page contains routines that are used to determine what the
17536 function prologue and epilogue code will do and write them out. */
17538 /* Return the first fixed-point register that is required to be
17539 saved. 32 if none. */
17542 first_reg_to_save (void)
17546 /* Find lowest numbered live register. */
17547 for (first_reg = 13; first_reg <= 31; first_reg++)
17548 if (df_regs_ever_live_p (first_reg)
17549 && (! call_used_regs[first_reg]
17550 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17551 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17552 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17553 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17558 && crtl->uses_pic_offset_table
17559 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17560 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17566 /* Similar, for FP regs. */
17569 first_fp_reg_to_save (void)
17573 /* Find lowest numbered live register. */
17574 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17575 if (df_regs_ever_live_p (first_reg))
17581 /* Similar, for AltiVec regs. */
17584 first_altivec_reg_to_save (void)
17588 /* Stack frame remains as is unless we are in AltiVec ABI. */
17589 if (! TARGET_ALTIVEC_ABI)
17590 return LAST_ALTIVEC_REGNO + 1;
17592 /* On Darwin, the unwind routines are compiled without
17593 TARGET_ALTIVEC, and use save_world to save/restore the
17594 altivec registers when necessary. */
17595 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17596 && ! TARGET_ALTIVEC)
17597 return FIRST_ALTIVEC_REGNO + 20;
17599 /* Find lowest numbered live register. */
17600 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17601 if (df_regs_ever_live_p (i))
17607 /* Return a 32-bit mask of the AltiVec registers we need to set in
17608 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17609 the 32-bit word is 0. */
17611 static unsigned int
17612 compute_vrsave_mask (void)
17614 unsigned int i, mask = 0;
17616 /* On Darwin, the unwind routines are compiled without
17617 TARGET_ALTIVEC, and use save_world to save/restore the
17618 call-saved altivec registers when necessary. */
17619 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17620 && ! TARGET_ALTIVEC)
17623 /* First, find out if we use _any_ altivec registers. */
17624 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17625 if (df_regs_ever_live_p (i))
17626 mask |= ALTIVEC_REG_BIT (i);
17631 /* Next, remove the argument registers from the set. These must
17632 be in the VRSAVE mask set by the caller, so we don't need to add
17633 them in again. More importantly, the mask we compute here is
17634 used to generate CLOBBERs in the set_vrsave insn, and we do not
17635 wish the argument registers to die. */
17636 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17637 mask &= ~ALTIVEC_REG_BIT (i);
17639 /* Similarly, remove the return value from the set. */
17642 diddle_return_value (is_altivec_return_reg, &yes);
17644 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17650 /* For a very restricted set of circumstances, we can cut down the
17651 size of prologues/epilogues by calling our own save/restore-the-world
17655 compute_save_world_info (rs6000_stack_t *info_ptr)
17657 info_ptr->world_save_p = 1;
17658 info_ptr->world_save_p
17659 = (WORLD_SAVE_P (info_ptr)
17660 && DEFAULT_ABI == ABI_DARWIN
17661 && ! (cfun->calls_setjmp && flag_exceptions)
17662 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17663 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17664 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17665 && info_ptr->cr_save_p);
17667 /* This will not work in conjunction with sibcalls. Make sure there
17668 are none. (This check is expensive, but seldom executed.) */
17669 if (WORLD_SAVE_P (info_ptr))
17672 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17673 if ( GET_CODE (insn) == CALL_INSN
17674 && SIBLING_CALL_P (insn))
17676 info_ptr->world_save_p = 0;
17681 if (WORLD_SAVE_P (info_ptr))
17683 /* Even if we're not touching VRsave, make sure there's room on the
17684 stack for it, if it looks like we're calling SAVE_WORLD, which
17685 will attempt to save it. */
17686 info_ptr->vrsave_size = 4;
17688 /* If we are going to save the world, we need to save the link register too. */
17689 info_ptr->lr_save_p = 1;
17691 /* "Save" the VRsave register too if we're saving the world. */
17692 if (info_ptr->vrsave_mask == 0)
17693 info_ptr->vrsave_mask = compute_vrsave_mask ();
17695 /* Because the Darwin register save/restore routines only handle
17696 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17698 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17699 && (info_ptr->first_altivec_reg_save
17700 >= FIRST_SAVED_ALTIVEC_REGNO));
17707 is_altivec_return_reg (rtx reg, void *xyes)
17709 bool *yes = (bool *) xyes;
17710 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17715 /* Calculate the stack information for the current function. This is
17716 complicated by having two separate calling sequences, the AIX calling
17717 sequence and the V.4 calling sequence.
17719 AIX (and Darwin/Mac OS X) stack frames look like:
17721 SP----> +---------------------------------------+
17722 | back chain to caller | 0 0
17723 +---------------------------------------+
17724 | saved CR | 4 8 (8-11)
17725 +---------------------------------------+
17727 +---------------------------------------+
17728 | reserved for compilers | 12 24
17729 +---------------------------------------+
17730 | reserved for binders | 16 32
17731 +---------------------------------------+
17732 | saved TOC pointer | 20 40
17733 +---------------------------------------+
17734 | Parameter save area (P) | 24 48
17735 +---------------------------------------+
17736 | Alloca space (A) | 24+P etc.
17737 +---------------------------------------+
17738 | Local variable space (L) | 24+P+A
17739 +---------------------------------------+
17740 | Float/int conversion temporary (X) | 24+P+A+L
17741 +---------------------------------------+
17742 | Save area for AltiVec registers (W) | 24+P+A+L+X
17743 +---------------------------------------+
17744 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17745 +---------------------------------------+
17746 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17747 +---------------------------------------+
17748 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17749 +---------------------------------------+
17750 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17751 +---------------------------------------+
17752 old SP->| back chain to caller's caller |
17753 +---------------------------------------+
17755 The required alignment for AIX configurations is two words (i.e., 8
17759 V.4 stack frames look like:
17761 SP----> +---------------------------------------+
17762 | back chain to caller | 0
17763 +---------------------------------------+
17764 | caller's saved LR | 4
17765 +---------------------------------------+
17766 | Parameter save area (P) | 8
17767 +---------------------------------------+
17768 | Alloca space (A) | 8+P
17769 +---------------------------------------+
17770 | Varargs save area (V) | 8+P+A
17771 +---------------------------------------+
17772 | Local variable space (L) | 8+P+A+V
17773 +---------------------------------------+
17774 | Float/int conversion temporary (X) | 8+P+A+V+L
17775 +---------------------------------------+
17776 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17777 +---------------------------------------+
17778 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17779 +---------------------------------------+
17780 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17781 +---------------------------------------+
17782 | SPE: area for 64-bit GP registers |
17783 +---------------------------------------+
17784 | SPE alignment padding |
17785 +---------------------------------------+
17786 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17787 +---------------------------------------+
17788 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17789 +---------------------------------------+
17790 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17791 +---------------------------------------+
17792 old SP->| back chain to caller's caller |
17793 +---------------------------------------+
17795 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17796 given. (But note below and in sysv4.h that we require only 8 and
17797 may round up the size of our stack frame anyways. The historical
17798 reason is early versions of powerpc-linux which didn't properly
17799 align the stack at program startup. A happy side-effect is that
17800 -mno-eabi libraries can be used with -meabi programs.)
17802 The EABI configuration defaults to the V.4 layout. However,
17803 the stack alignment requirements may differ. If -mno-eabi is not
17804 given, the required stack alignment is 8 bytes; if -mno-eabi is
17805 given, the required alignment is 16 bytes. (But see V.4 comment
17808 #ifndef ABI_STACK_BOUNDARY
17809 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17812 static rs6000_stack_t *
17813 rs6000_stack_info (void)
17815 static rs6000_stack_t info;
17816 rs6000_stack_t *info_ptr = &info;
17817 int reg_size = TARGET_32BIT ? 4 : 8;
17821 HOST_WIDE_INT non_fixed_size;
17823 memset (&info, 0, sizeof (info));
17827 /* Cache value so we don't rescan instruction chain over and over. */
17828 if (cfun->machine->insn_chain_scanned_p == 0)
17829 cfun->machine->insn_chain_scanned_p
17830 = spe_func_has_64bit_regs_p () + 1;
17831 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17834 /* Select which calling sequence. */
17835 info_ptr->abi = DEFAULT_ABI;
17837 /* Calculate which registers need to be saved & save area size. */
17838 info_ptr->first_gp_reg_save = first_reg_to_save ();
17839 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17840 even if it currently looks like we won't. Reload may need it to
17841 get at a constant; if so, it will have already created a constant
17842 pool entry for it. */
17843 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17844 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17845 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17846 && crtl->uses_const_pool
17847 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17848 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17850 first_gp = info_ptr->first_gp_reg_save;
17852 info_ptr->gp_size = reg_size * (32 - first_gp);
17854 /* For the SPE, we have an additional upper 32-bits on each GPR.
17855 Ideally we should save the entire 64-bits only when the upper
17856 half is used in SIMD instructions. Since we only record
17857 registers live (not the size they are used in), this proves
17858 difficult because we'd have to traverse the instruction chain at
17859 the right time, taking reload into account. This is a real pain,
17860 so we opt to save the GPRs in 64-bits always if but one register
17861 gets used in 64-bits. Otherwise, all the registers in the frame
17862 get saved in 32-bits.
17864 So... since when we save all GPRs (except the SP) in 64-bits, the
17865 traditional GP save area will be empty. */
17866 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17867 info_ptr->gp_size = 0;
17869 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17870 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17872 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17873 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17874 - info_ptr->first_altivec_reg_save);
17876 /* Does this function call anything? */
17877 info_ptr->calls_p = (! current_function_is_leaf
17878 || cfun->machine->ra_needs_full_frame);
17880 /* Determine if we need to save the link register. */
17881 if ((DEFAULT_ABI == ABI_AIX
17883 && !TARGET_PROFILE_KERNEL)
17884 #ifdef TARGET_RELOCATABLE
17885 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17887 || (info_ptr->first_fp_reg_save != 64
17888 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17889 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17890 || info_ptr->calls_p
17891 || rs6000_ra_ever_killed ())
17893 info_ptr->lr_save_p = 1;
17894 df_set_regs_ever_live (LR_REGNO, true);
17897 /* Determine if we need to save the condition code registers. */
17898 if (df_regs_ever_live_p (CR2_REGNO)
17899 || df_regs_ever_live_p (CR3_REGNO)
17900 || df_regs_ever_live_p (CR4_REGNO))
17902 info_ptr->cr_save_p = 1;
17903 if (DEFAULT_ABI == ABI_V4)
17904 info_ptr->cr_size = reg_size;
17907 /* If the current function calls __builtin_eh_return, then we need
17908 to allocate stack space for registers that will hold data for
17909 the exception handler. */
17910 if (crtl->calls_eh_return)
17913 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17916 /* SPE saves EH registers in 64-bits. */
17917 ehrd_size = i * (TARGET_SPE_ABI
17918 && info_ptr->spe_64bit_regs_used != 0
17919 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17924 /* Determine various sizes. */
17925 info_ptr->reg_size = reg_size;
17926 info_ptr->fixed_size = RS6000_SAVE_AREA;
17927 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17928 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17929 TARGET_ALTIVEC ? 16 : 8);
17930 if (FRAME_GROWS_DOWNWARD)
17931 info_ptr->vars_size
17932 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17933 + info_ptr->parm_size,
17934 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17935 - (info_ptr->fixed_size + info_ptr->vars_size
17936 + info_ptr->parm_size);
17938 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17939 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17941 info_ptr->spe_gp_size = 0;
17943 if (TARGET_ALTIVEC_ABI)
17944 info_ptr->vrsave_mask = compute_vrsave_mask ();
17946 info_ptr->vrsave_mask = 0;
17948 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17949 info_ptr->vrsave_size = 4;
17951 info_ptr->vrsave_size = 0;
17953 compute_save_world_info (info_ptr);
17955 /* Calculate the offsets. */
17956 switch (DEFAULT_ABI)
17960 gcc_unreachable ();
17964 info_ptr->fp_save_offset = - info_ptr->fp_size;
17965 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17967 if (TARGET_ALTIVEC_ABI)
17969 info_ptr->vrsave_save_offset
17970 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17972 /* Align stack so vector save area is on a quadword boundary.
17973 The padding goes above the vectors. */
17974 if (info_ptr->altivec_size != 0)
17975 info_ptr->altivec_padding_size
17976 = info_ptr->vrsave_save_offset & 0xF;
17978 info_ptr->altivec_padding_size = 0;
17980 info_ptr->altivec_save_offset
17981 = info_ptr->vrsave_save_offset
17982 - info_ptr->altivec_padding_size
17983 - info_ptr->altivec_size;
17984 gcc_assert (info_ptr->altivec_size == 0
17985 || info_ptr->altivec_save_offset % 16 == 0);
17987 /* Adjust for AltiVec case. */
17988 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17991 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17992 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17993 info_ptr->lr_save_offset = 2*reg_size;
17997 info_ptr->fp_save_offset = - info_ptr->fp_size;
17998 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17999 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18001 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18003 /* Align stack so SPE GPR save area is aligned on a
18004 double-word boundary. */
18005 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18006 info_ptr->spe_padding_size
18007 = 8 - (-info_ptr->cr_save_offset % 8);
18009 info_ptr->spe_padding_size = 0;
18011 info_ptr->spe_gp_save_offset
18012 = info_ptr->cr_save_offset
18013 - info_ptr->spe_padding_size
18014 - info_ptr->spe_gp_size;
18016 /* Adjust for SPE case. */
18017 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18019 else if (TARGET_ALTIVEC_ABI)
18021 info_ptr->vrsave_save_offset
18022 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18024 /* Align stack so vector save area is on a quadword boundary. */
18025 if (info_ptr->altivec_size != 0)
18026 info_ptr->altivec_padding_size
18027 = 16 - (-info_ptr->vrsave_save_offset % 16);
18029 info_ptr->altivec_padding_size = 0;
18031 info_ptr->altivec_save_offset
18032 = info_ptr->vrsave_save_offset
18033 - info_ptr->altivec_padding_size
18034 - info_ptr->altivec_size;
18036 /* Adjust for AltiVec case. */
18037 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18040 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18041 info_ptr->ehrd_offset -= ehrd_size;
18042 info_ptr->lr_save_offset = reg_size;
18046 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18047 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18048 + info_ptr->gp_size
18049 + info_ptr->altivec_size
18050 + info_ptr->altivec_padding_size
18051 + info_ptr->spe_gp_size
18052 + info_ptr->spe_padding_size
18054 + info_ptr->cr_size
18055 + info_ptr->vrsave_size,
18058 non_fixed_size = (info_ptr->vars_size
18059 + info_ptr->parm_size
18060 + info_ptr->save_size);
18062 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18063 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18065 /* Determine if we need to allocate any stack frame:
18067 For AIX we need to push the stack if a frame pointer is needed
18068 (because the stack might be dynamically adjusted), if we are
18069 debugging, if we make calls, or if the sum of fp_save, gp_save,
18070 and local variables are more than the space needed to save all
18071 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18072 + 18*8 = 288 (GPR13 reserved).
18074 For V.4 we don't have the stack cushion that AIX uses, but assume
18075 that the debugger can handle stackless frames. */
18077 if (info_ptr->calls_p)
18078 info_ptr->push_p = 1;
18080 else if (DEFAULT_ABI == ABI_V4)
18081 info_ptr->push_p = non_fixed_size != 0;
18083 else if (frame_pointer_needed)
18084 info_ptr->push_p = 1;
18086 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18087 info_ptr->push_p = 1;
18090 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18092 /* Zero offsets if we're not saving those registers. */
18093 if (info_ptr->fp_size == 0)
18094 info_ptr->fp_save_offset = 0;
18096 if (info_ptr->gp_size == 0)
18097 info_ptr->gp_save_offset = 0;
18099 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18100 info_ptr->altivec_save_offset = 0;
18102 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18103 info_ptr->vrsave_save_offset = 0;
18105 if (! TARGET_SPE_ABI
18106 || info_ptr->spe_64bit_regs_used == 0
18107 || info_ptr->spe_gp_size == 0)
18108 info_ptr->spe_gp_save_offset = 0;
18110 if (! info_ptr->lr_save_p)
18111 info_ptr->lr_save_offset = 0;
18113 if (! info_ptr->cr_save_p)
18114 info_ptr->cr_save_offset = 0;
18119 /* Return true if the current function uses any GPRs in 64-bit SIMD
18123 spe_func_has_64bit_regs_p (void)
18127 /* Functions that save and restore all the call-saved registers will
18128 need to save/restore the registers in 64-bits. */
18129 if (crtl->calls_eh_return
18130 || cfun->calls_setjmp
18131 || crtl->has_nonlocal_goto)
18134 insns = get_insns ();
18136 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18142 /* FIXME: This should be implemented with attributes...
18144 (set_attr "spe64" "true")....then,
18145 if (get_spe64(insn)) return true;
18147 It's the only reliable way to do the stuff below. */
18149 i = PATTERN (insn);
18150 if (GET_CODE (i) == SET)
18152 enum machine_mode mode = GET_MODE (SET_SRC (i));
18154 if (SPE_VECTOR_MODE (mode))
18156 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18166 debug_stack_info (rs6000_stack_t *info)
18168 const char *abi_string;
18171 info = rs6000_stack_info ();
18173 fprintf (stderr, "\nStack information for function %s:\n",
18174 ((current_function_decl && DECL_NAME (current_function_decl))
18175 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18180 default: abi_string = "Unknown"; break;
18181 case ABI_NONE: abi_string = "NONE"; break;
18182 case ABI_AIX: abi_string = "AIX"; break;
18183 case ABI_DARWIN: abi_string = "Darwin"; break;
18184 case ABI_V4: abi_string = "V.4"; break;
18187 fprintf (stderr, "\tABI = %5s\n", abi_string);
18189 if (TARGET_ALTIVEC_ABI)
18190 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18192 if (TARGET_SPE_ABI)
18193 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18195 if (info->first_gp_reg_save != 32)
18196 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18198 if (info->first_fp_reg_save != 64)
18199 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18201 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18202 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18203 info->first_altivec_reg_save);
18205 if (info->lr_save_p)
18206 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18208 if (info->cr_save_p)
18209 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18211 if (info->vrsave_mask)
18212 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18215 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18218 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18220 if (info->gp_save_offset)
18221 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18223 if (info->fp_save_offset)
18224 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18226 if (info->altivec_save_offset)
18227 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18228 info->altivec_save_offset);
18230 if (info->spe_gp_save_offset)
18231 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18232 info->spe_gp_save_offset);
18234 if (info->vrsave_save_offset)
18235 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18236 info->vrsave_save_offset);
18238 if (info->lr_save_offset)
18239 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18241 if (info->cr_save_offset)
18242 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18244 if (info->varargs_save_offset)
18245 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18247 if (info->total_size)
18248 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18251 if (info->vars_size)
18252 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18255 if (info->parm_size)
18256 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18258 if (info->fixed_size)
18259 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18262 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18264 if (info->spe_gp_size)
18265 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18268 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18270 if (info->altivec_size)
18271 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18273 if (info->vrsave_size)
18274 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18276 if (info->altivec_padding_size)
18277 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18278 info->altivec_padding_size);
18280 if (info->spe_padding_size)
18281 fprintf (stderr, "\tspe_padding_size = %5d\n",
18282 info->spe_padding_size);
18285 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18287 if (info->save_size)
18288 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18290 if (info->reg_size != 4)
18291 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18293 fprintf (stderr, "\n");
18297 rs6000_return_addr (int count, rtx frame)
18299 /* Currently we don't optimize very well between prolog and body
18300 code and for PIC code the code can be actually quite bad, so
18301 don't try to be too clever here. */
18302 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18304 cfun->machine->ra_needs_full_frame = 1;
18311 plus_constant (copy_to_reg
18312 (gen_rtx_MEM (Pmode,
18313 memory_address (Pmode, frame))),
18314 RETURN_ADDRESS_OFFSET)));
18317 cfun->machine->ra_need_lr = 1;
18318 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18321 /* Say whether a function is a candidate for sibcall handling or not.
18322 We do not allow indirect calls to be optimized into sibling calls.
18323 Also, we can't do it if there are any vector parameters; there's
18324 nowhere to put the VRsave code so it works; note that functions with
18325 vector parameters are required to have a prototype, so the argument
18326 type info must be available here. (The tail recursion case can work
18327 with vector parameters, but there's no way to distinguish here.) */
18329 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18334 if (TARGET_ALTIVEC_VRSAVE)
18336 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18337 type; type = TREE_CHAIN (type))
18339 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18343 if (DEFAULT_ABI == ABI_DARWIN
18344 || ((*targetm.binds_local_p) (decl)
18345 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18347 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18349 if (!lookup_attribute ("longcall", attr_list)
18350 || lookup_attribute ("shortcall", attr_list))
18357 /* NULL if INSN insn is valid within a low-overhead loop.
18358 Otherwise return why doloop cannot be applied.
18359 PowerPC uses the COUNT register for branch on table instructions. */
18361 static const char *
18362 rs6000_invalid_within_doloop (const_rtx insn)
18365 return "Function call in the loop.";
18368 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18369 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18370 return "Computed branch in the loop.";
18376 rs6000_ra_ever_killed (void)
18382 if (cfun->is_thunk)
18385 if (cfun->machine->lr_save_state)
18386 return cfun->machine->lr_save_state - 1;
18388 /* regs_ever_live has LR marked as used if any sibcalls are present,
18389 but this should not force saving and restoring in the
18390 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18391 clobbers LR, so that is inappropriate. */
18393 /* Also, the prologue can generate a store into LR that
18394 doesn't really count, like this:
18397 bcl to set PIC register
18401 When we're called from the epilogue, we need to avoid counting
18402 this as a store. */
18404 push_topmost_sequence ();
18405 top = get_insns ();
18406 pop_topmost_sequence ();
18407 reg = gen_rtx_REG (Pmode, LR_REGNO);
18409 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18415 if (!SIBLING_CALL_P (insn))
18418 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18420 else if (set_of (reg, insn) != NULL_RTX
18421 && !prologue_epilogue_contains (insn))
18428 /* Emit instructions needed to load the TOC register.
18429 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18430 a constant pool; or for SVR4 -fpic. */
18433 rs6000_emit_load_toc_table (int fromprolog)
18436 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18438 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18441 rtx lab, tmp1, tmp2, got;
18443 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18444 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18446 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18448 got = rs6000_got_sym ();
18449 tmp1 = tmp2 = dest;
18452 tmp1 = gen_reg_rtx (Pmode);
18453 tmp2 = gen_reg_rtx (Pmode);
18455 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18456 emit_move_insn (tmp1,
18457 gen_rtx_REG (Pmode, LR_REGNO));
18458 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18459 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18461 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18463 emit_insn (gen_load_toc_v4_pic_si ());
18464 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18466 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18469 rtx temp0 = (fromprolog
18470 ? gen_rtx_REG (Pmode, 0)
18471 : gen_reg_rtx (Pmode));
18477 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18478 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18480 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18481 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18483 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18484 emit_move_insn (dest,
18485 gen_rtx_REG (Pmode, LR_REGNO));
18486 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18492 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18493 lab = gen_label_rtx ();
18494 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18495 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18496 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18498 emit_insn (gen_addsi3 (dest, temp0, dest));
18500 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18502 /* This is for AIX code running in non-PIC ELF32. */
18505 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18506 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18508 emit_insn (gen_elf_high (dest, realsym));
18509 emit_insn (gen_elf_low (dest, dest, realsym));
18513 gcc_assert (DEFAULT_ABI == ABI_AIX);
18516 emit_insn (gen_load_toc_aix_si (dest));
18518 emit_insn (gen_load_toc_aix_di (dest));
18522 /* Emit instructions to restore the link register after determining where
18523 its value has been stored. */
18526 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18528 rs6000_stack_t *info = rs6000_stack_info ();
18531 operands[0] = source;
18532 operands[1] = scratch;
18534 if (info->lr_save_p)
18536 rtx frame_rtx = stack_pointer_rtx;
18537 HOST_WIDE_INT sp_offset = 0;
18540 if (frame_pointer_needed
18541 || cfun->calls_alloca
18542 || info->total_size > 32767)
18544 tmp = gen_frame_mem (Pmode, frame_rtx);
18545 emit_move_insn (operands[1], tmp);
18546 frame_rtx = operands[1];
18548 else if (info->push_p)
18549 sp_offset = info->total_size;
18551 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18552 tmp = gen_frame_mem (Pmode, tmp);
18553 emit_move_insn (tmp, operands[0]);
18556 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18558 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18559 state of lr_save_p so any change from here on would be a bug. In
18560 particular, stop rs6000_ra_ever_killed from considering the SET
18561 of lr we may have added just above. */
18562 cfun->machine->lr_save_state = info->lr_save_p + 1;
18565 static GTY(()) alias_set_type set = -1;
18568 get_TOC_alias_set (void)
18571 set = new_alias_set ();
18575 /* This returns nonzero if the current function uses the TOC. This is
18576 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18577 is generated by the ABI_V4 load_toc_* patterns. */
18584 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18587 rtx pat = PATTERN (insn);
18590 if (GET_CODE (pat) == PARALLEL)
18591 for (i = 0; i < XVECLEN (pat, 0); i++)
18593 rtx sub = XVECEXP (pat, 0, i);
18594 if (GET_CODE (sub) == USE)
18596 sub = XEXP (sub, 0);
18597 if (GET_CODE (sub) == UNSPEC
18598 && XINT (sub, 1) == UNSPEC_TOC)
18608 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18610 rtx tocrel, tocreg;
18612 if (TARGET_DEBUG_ADDR)
18614 if (GET_CODE (symbol) == SYMBOL_REF)
18615 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18619 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18620 GET_RTX_NAME (GET_CODE (symbol)));
18621 debug_rtx (symbol);
18625 if (!can_create_pseudo_p ())
18626 df_set_regs_ever_live (TOC_REGISTER, true);
18628 tocrel = gen_rtx_CONST (Pmode,
18629 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18631 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18632 if (TARGET_CMODEL != CMODEL_SMALL)
18634 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18635 if (largetoc_reg != NULL)
18637 emit_move_insn (largetoc_reg, hi);
18640 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18643 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18646 /* Issue assembly directives that create a reference to the given DWARF
18647 FRAME_TABLE_LABEL from the current function section. */
18649 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18651 fprintf (asm_out_file, "\t.ref %s\n",
18652 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18655 /* If _Unwind_* has been called from within the same module,
18656 toc register is not guaranteed to be saved to 40(1) on function
18657 entry. Save it there in that case. */
18660 rs6000_aix_emit_builtin_unwind_init (void)
18663 rtx stack_top = gen_reg_rtx (Pmode);
18664 rtx opcode_addr = gen_reg_rtx (Pmode);
18665 rtx opcode = gen_reg_rtx (SImode);
18666 rtx tocompare = gen_reg_rtx (SImode);
18667 rtx no_toc_save_needed = gen_label_rtx ();
18669 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18670 emit_move_insn (stack_top, mem);
18672 mem = gen_frame_mem (Pmode,
18673 gen_rtx_PLUS (Pmode, stack_top,
18674 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18675 emit_move_insn (opcode_addr, mem);
18676 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18677 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18678 : 0xE8410028, SImode));
18680 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18681 SImode, NULL_RTX, NULL_RTX,
18682 no_toc_save_needed, -1);
18684 mem = gen_frame_mem (Pmode,
18685 gen_rtx_PLUS (Pmode, stack_top,
18686 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18687 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18688 emit_label (no_toc_save_needed);
18691 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18692 and the change to the stack pointer. */
18695 rs6000_emit_stack_tie (void)
18697 rtx mem = gen_frame_mem (BLKmode,
18698 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18700 emit_insn (gen_stack_tie (mem));
18703 /* Emit the correct code for allocating stack space, as insns.
18704 If COPY_REG, make sure a copy of the old frame is left there.
18705 The generated code may use hard register 0 as a temporary. */
18708 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18711 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18712 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18713 rtx todec = gen_int_mode (-size, Pmode);
18716 if (INTVAL (todec) != -size)
18718 warning (0, "stack frame too large");
18719 emit_insn (gen_trap ());
18723 if (crtl->limit_stack)
18725 if (REG_P (stack_limit_rtx)
18726 && REGNO (stack_limit_rtx) > 1
18727 && REGNO (stack_limit_rtx) <= 31)
18729 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18730 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18733 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18735 && DEFAULT_ABI == ABI_V4)
18737 rtx toload = gen_rtx_CONST (VOIDmode,
18738 gen_rtx_PLUS (Pmode,
18742 emit_insn (gen_elf_high (tmp_reg, toload));
18743 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18744 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18748 warning (0, "stack limit expression is not supported");
18752 emit_move_insn (copy_reg, stack_reg);
18756 /* Need a note here so that try_split doesn't get confused. */
18757 if (get_last_insn () == NULL_RTX)
18758 emit_note (NOTE_INSN_DELETED);
18759 insn = emit_move_insn (tmp_reg, todec);
18760 try_split (PATTERN (insn), insn, 0);
18764 insn = emit_insn (TARGET_32BIT
18765 ? gen_movsi_update_stack (stack_reg, stack_reg,
18767 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18768 todec, stack_reg));
18769 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18770 it now and set the alias set/attributes. The above gen_*_update
18771 calls will generate a PARALLEL with the MEM set being the first
18773 par = PATTERN (insn);
18774 gcc_assert (GET_CODE (par) == PARALLEL);
18775 set = XVECEXP (par, 0, 0);
18776 gcc_assert (GET_CODE (set) == SET);
18777 mem = SET_DEST (set);
18778 gcc_assert (MEM_P (mem));
18779 MEM_NOTRAP_P (mem) = 1;
18780 set_mem_alias_set (mem, get_frame_alias_set ());
18782 RTX_FRAME_RELATED_P (insn) = 1;
18783 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18784 gen_rtx_SET (VOIDmode, stack_reg,
18785 gen_rtx_PLUS (Pmode, stack_reg,
18786 GEN_INT (-size))));
18789 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18790 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18791 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18792 deduce these equivalences by itself so it wasn't necessary to hold
18793 its hand so much. */
18796 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18797 rtx reg2, rtx rreg)
18801 /* copy_rtx will not make unique copies of registers, so we need to
18802 ensure we don't have unwanted sharing here. */
18804 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18807 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18809 real = copy_rtx (PATTERN (insn));
18811 if (reg2 != NULL_RTX)
18812 real = replace_rtx (real, reg2, rreg);
18814 real = replace_rtx (real, reg,
18815 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18816 STACK_POINTER_REGNUM),
18819 /* We expect that 'real' is either a SET or a PARALLEL containing
18820 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18821 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18823 if (GET_CODE (real) == SET)
18827 temp = simplify_rtx (SET_SRC (set));
18829 SET_SRC (set) = temp;
18830 temp = simplify_rtx (SET_DEST (set));
18832 SET_DEST (set) = temp;
18833 if (GET_CODE (SET_DEST (set)) == MEM)
18835 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18837 XEXP (SET_DEST (set), 0) = temp;
18844 gcc_assert (GET_CODE (real) == PARALLEL);
18845 for (i = 0; i < XVECLEN (real, 0); i++)
18846 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18848 rtx set = XVECEXP (real, 0, i);
18850 temp = simplify_rtx (SET_SRC (set));
18852 SET_SRC (set) = temp;
18853 temp = simplify_rtx (SET_DEST (set));
18855 SET_DEST (set) = temp;
18856 if (GET_CODE (SET_DEST (set)) == MEM)
18858 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18860 XEXP (SET_DEST (set), 0) = temp;
18862 RTX_FRAME_RELATED_P (set) = 1;
18866 RTX_FRAME_RELATED_P (insn) = 1;
18867 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18870 /* Returns an insn that has a vrsave set operation with the
18871 appropriate CLOBBERs. */
18874 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18877 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18878 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18881 = gen_rtx_SET (VOIDmode,
18883 gen_rtx_UNSPEC_VOLATILE (SImode,
18884 gen_rtvec (2, reg, vrsave),
18885 UNSPECV_SET_VRSAVE));
18889 /* We need to clobber the registers in the mask so the scheduler
18890 does not move sets to VRSAVE before sets of AltiVec registers.
18892 However, if the function receives nonlocal gotos, reload will set
18893 all call saved registers live. We will end up with:
18895 (set (reg 999) (mem))
18896 (parallel [ (set (reg vrsave) (unspec blah))
18897 (clobber (reg 999))])
18899 The clobber will cause the store into reg 999 to be dead, and
18900 flow will attempt to delete an epilogue insn. In this case, we
18901 need an unspec use/set of the register. */
18903 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18904 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18906 if (!epiloguep || call_used_regs [i])
18907 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18908 gen_rtx_REG (V4SImode, i));
18911 rtx reg = gen_rtx_REG (V4SImode, i);
18914 = gen_rtx_SET (VOIDmode,
18916 gen_rtx_UNSPEC (V4SImode,
18917 gen_rtvec (1, reg), 27));
18921 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18923 for (i = 0; i < nclobs; ++i)
18924 XVECEXP (insn, 0, i) = clobs[i];
18929 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18930 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18933 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18934 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18936 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18937 rtx replacea, replaceb;
18939 int_rtx = GEN_INT (offset);
18941 /* Some cases that need register indexed addressing. */
18942 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18943 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18944 || (TARGET_E500_DOUBLE && mode == DFmode)
18946 && SPE_VECTOR_MODE (mode)
18947 && !SPE_CONST_OFFSET_OK (offset)))
18949 /* Whomever calls us must make sure r11 is available in the
18950 flow path of instructions in the prologue. */
18951 offset_rtx = gen_rtx_REG (Pmode, 11);
18952 emit_move_insn (offset_rtx, int_rtx);
18954 replacea = offset_rtx;
18955 replaceb = int_rtx;
18959 offset_rtx = int_rtx;
18960 replacea = NULL_RTX;
18961 replaceb = NULL_RTX;
18964 reg = gen_rtx_REG (mode, regno);
18965 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18966 mem = gen_frame_mem (mode, addr);
18968 insn = emit_move_insn (mem, reg);
18970 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18973 /* Emit an offset memory reference suitable for a frame store, while
18974 converting to a valid addressing mode. */
18977 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18979 rtx int_rtx, offset_rtx;
18981 int_rtx = GEN_INT (offset);
18983 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18984 || (TARGET_E500_DOUBLE && mode == DFmode))
18986 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18987 emit_move_insn (offset_rtx, int_rtx);
18990 offset_rtx = int_rtx;
18992 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18995 /* Look for user-defined global regs. We should not save and restore these,
18996 and cannot use stmw/lmw if there are any in its range. */
18999 no_global_regs_above (int first, bool gpr)
19002 int last = gpr ? 32 : 64;
19003 for (i = first; i < last; i++)
19004 if (global_regs[i])
19009 #ifndef TARGET_FIX_AND_CONTINUE
19010 #define TARGET_FIX_AND_CONTINUE 0
19013 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19014 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19015 #define LAST_SAVRES_REGISTER 31
19016 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19018 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19020 /* Temporary holding space for an out-of-line register save/restore
19022 static char savres_routine_name[30];
19024 /* Return the name for an out-of-line register save/restore routine.
19025 We are saving/restoring GPRs if GPR is true. */
19028 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19029 bool savep, bool gpr, bool lr)
19031 const char *prefix = "";
19032 const char *suffix = "";
19034 /* Different targets are supposed to define
19035 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19036 routine name could be defined with:
19038 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19040 This is a nice idea in practice, but in reality, things are
19041 complicated in several ways:
19043 - ELF targets have save/restore routines for GPRs.
19045 - SPE targets use different prefixes for 32/64-bit registers, and
19046 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19048 - PPC64 ELF targets have routines for save/restore of GPRs that
19049 differ in what they do with the link register, so having a set
19050 prefix doesn't work. (We only use one of the save routines at
19051 the moment, though.)
19053 - PPC32 elf targets have "exit" versions of the restore routines
19054 that restore the link register and can save some extra space.
19055 These require an extra suffix. (There are also "tail" versions
19056 of the restore routines and "GOT" versions of the save routines,
19057 but we don't generate those at present. Same problems apply,
19060 We deal with all this by synthesizing our own prefix/suffix and
19061 using that for the simple sprintf call shown above. */
19064 /* No floating point saves on the SPE. */
19068 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19070 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19075 else if (DEFAULT_ABI == ABI_V4)
19081 prefix = savep ? "_savegpr_" : "_restgpr_";
19083 prefix = savep ? "_savefpr_" : "_restfpr_";
19088 else if (DEFAULT_ABI == ABI_AIX)
19090 #ifndef POWERPC_LINUX
19091 /* No out-of-line save/restore routines for GPRs on AIX. */
19092 gcc_assert (!TARGET_AIX || !gpr);
19098 ? (lr ? "_savegpr0_" : "_savegpr1_")
19099 : (lr ? "_restgpr0_" : "_restgpr1_"));
19100 #ifdef POWERPC_LINUX
19102 prefix = (savep ? "_savefpr_" : "_restfpr_");
19106 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19107 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19110 else if (DEFAULT_ABI == ABI_DARWIN)
19111 sorry ("Out-of-line save/restore routines not supported on Darwin");
19113 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19115 return savres_routine_name;
19118 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19119 We are saving/restoring GPRs if GPR is true. */
19122 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19125 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19127 int select = ((savep ? 1 : 0) << 2
19129 /* On the SPE, we never have any FPRs, but we do have
19130 32/64-bit versions of the routines. */
19131 ? (info->spe_64bit_regs_used ? 1 : 0)
19132 : (gpr ? 1 : 0)) << 1)
19135 /* Don't generate bogus routine names. */
19136 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19137 && regno <= LAST_SAVRES_REGISTER);
19139 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19145 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19147 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19148 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19149 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19155 /* Emit a sequence of insns, including a stack tie if needed, for
19156 resetting the stack pointer. If SAVRES is true, then don't reset the
19157 stack pointer, but move the base of the frame into r11 for use by
19158 out-of-line register restore routines. */
19161 rs6000_emit_stack_reset (rs6000_stack_t *info,
19162 rtx sp_reg_rtx, rtx frame_reg_rtx,
19163 int sp_offset, bool savres)
19165 /* This blockage is needed so that sched doesn't decide to move
19166 the sp change before the register restores. */
19167 if (frame_reg_rtx != sp_reg_rtx
19169 && info->spe_64bit_regs_used != 0
19170 && info->first_gp_reg_save != 32))
19171 rs6000_emit_stack_tie ();
19173 if (frame_reg_rtx != sp_reg_rtx)
19175 if (sp_offset != 0)
19177 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19178 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19179 GEN_INT (sp_offset)));
19182 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19184 else if (sp_offset != 0)
19186 /* If we are restoring registers out-of-line, we will be using the
19187 "exit" variants of the restore routines, which will reset the
19188 stack for us. But we do need to point r11 into the right place
19189 for those routines. */
19190 rtx dest_reg = (savres
19191 ? gen_rtx_REG (Pmode, 11)
19194 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19195 GEN_INT (sp_offset)));
19202 /* Construct a parallel rtx describing the effect of a call to an
19203 out-of-line register save/restore routine. */
19206 rs6000_make_savres_rtx (rs6000_stack_t *info,
19207 rtx frame_reg_rtx, int save_area_offset,
19208 enum machine_mode reg_mode,
19209 bool savep, bool gpr, bool lr)
19212 int offset, start_reg, end_reg, n_regs;
19213 int reg_size = GET_MODE_SIZE (reg_mode);
19219 ? info->first_gp_reg_save
19220 : info->first_fp_reg_save);
19221 end_reg = gpr ? 32 : 64;
19222 n_regs = end_reg - start_reg;
19223 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19226 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19228 RTVEC_ELT (p, offset++)
19229 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19231 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19232 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19233 RTVEC_ELT (p, offset++)
19234 = gen_rtx_USE (VOIDmode,
19235 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19239 for (i = 0; i < end_reg - start_reg; i++)
19241 rtx addr, reg, mem;
19242 reg = gen_rtx_REG (reg_mode, start_reg + i);
19243 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19244 GEN_INT (save_area_offset + reg_size*i));
19245 mem = gen_frame_mem (reg_mode, addr);
19247 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19249 savep ? reg : mem);
19254 rtx addr, reg, mem;
19255 reg = gen_rtx_REG (Pmode, 0);
19256 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19257 GEN_INT (info->lr_save_offset));
19258 mem = gen_frame_mem (Pmode, addr);
19259 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19262 return gen_rtx_PARALLEL (VOIDmode, p);
19265 /* Determine whether the gp REG is really used. */
19268 rs6000_reg_live_or_pic_offset_p (int reg)
19270 return ((df_regs_ever_live_p (reg)
19271 && (!call_used_regs[reg]
19272 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19273 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19274 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19275 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19276 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19280 SAVRES_MULTIPLE = 0x1,
19281 SAVRES_INLINE_FPRS = 0x2,
19282 SAVRES_INLINE_GPRS = 0x4,
19283 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19284 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19285 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19288 /* Determine the strategy for savings/restoring registers. */
19291 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19292 int using_static_chain_p, int sibcall)
19294 bool using_multiple_p;
19296 bool savres_fprs_inline;
19297 bool savres_gprs_inline;
19298 bool noclobber_global_gprs
19299 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19302 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19303 && (!TARGET_SPE_ABI
19304 || info->spe_64bit_regs_used == 0)
19305 && info->first_gp_reg_save < 31
19306 && noclobber_global_gprs);
19307 /* Don't bother to try to save things out-of-line if r11 is occupied
19308 by the static chain. It would require too much fiddling and the
19309 static chain is rarely used anyway. */
19310 common = (using_static_chain_p
19312 || crtl->calls_eh_return
19313 || !info->lr_save_p
19314 || cfun->machine->ra_need_lr
19315 || info->total_size > 32767);
19316 savres_fprs_inline = (common
19317 || info->first_fp_reg_save == 64
19318 || !no_global_regs_above (info->first_fp_reg_save,
19320 /* The out-of-line FP routines use
19321 double-precision stores; we can't use those
19322 routines if we don't have such stores. */
19323 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19324 || FP_SAVE_INLINE (info->first_fp_reg_save));
19325 savres_gprs_inline = (common
19326 /* Saving CR interferes with the exit routines
19327 used on the SPE, so just punt here. */
19330 && info->spe_64bit_regs_used != 0
19331 && info->cr_save_p != 0)
19332 || info->first_gp_reg_save == 32
19333 || !noclobber_global_gprs
19334 || GP_SAVE_INLINE (info->first_gp_reg_save));
19337 /* If we are going to use store multiple, then don't even bother
19338 with the out-of-line routines, since the store-multiple instruction
19339 will always be smaller. */
19340 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19343 /* The situation is more complicated with load multiple. We'd
19344 prefer to use the out-of-line routines for restores, since the
19345 "exit" out-of-line routines can handle the restore of LR and
19346 the frame teardown. But we can only use the out-of-line
19347 routines if we know that we've used store multiple or
19348 out-of-line routines in the prologue, i.e. if we've saved all
19349 the registers from first_gp_reg_save. Otherwise, we risk
19350 loading garbage from the stack. Furthermore, we can only use
19351 the "exit" out-of-line gpr restore if we haven't saved any
19353 bool saved_all = !savres_gprs_inline || using_multiple_p;
19355 if (saved_all && info->first_fp_reg_save != 64)
19356 /* We can't use the exit routine; use load multiple if it's
19358 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19361 strategy = (using_multiple_p
19362 | (savres_fprs_inline << 1)
19363 | (savres_gprs_inline << 2));
19364 #ifdef POWERPC_LINUX
19367 if (!savres_fprs_inline)
19368 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19369 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19370 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19373 if (TARGET_AIX && !savres_fprs_inline)
19374 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19379 /* Emit function prologue as insns. */
19382 rs6000_emit_prologue (void)
19384 rs6000_stack_t *info = rs6000_stack_info ();
19385 enum machine_mode reg_mode = Pmode;
19386 int reg_size = TARGET_32BIT ? 4 : 8;
19387 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19388 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19389 rtx frame_reg_rtx = sp_reg_rtx;
19390 rtx cr_save_rtx = NULL_RTX;
19393 int saving_FPRs_inline;
19394 int saving_GPRs_inline;
19395 int using_store_multiple;
19396 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19397 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19398 && call_used_regs[STATIC_CHAIN_REGNUM]);
19399 HOST_WIDE_INT sp_offset = 0;
19401 if (TARGET_FIX_AND_CONTINUE)
19403 /* gdb on darwin arranges to forward a function from the old
19404 address by modifying the first 5 instructions of the function
19405 to branch to the overriding function. This is necessary to
19406 permit function pointers that point to the old function to
19407 actually forward to the new function. */
19408 emit_insn (gen_nop ());
19409 emit_insn (gen_nop ());
19410 emit_insn (gen_nop ());
19411 emit_insn (gen_nop ());
19412 emit_insn (gen_nop ());
19415 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19417 reg_mode = V2SImode;
19421 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19422 /*static_chain_p=*/using_static_chain_p,
19424 using_store_multiple = strategy & SAVRES_MULTIPLE;
19425 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19426 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19428 /* For V.4, update stack before we do any saving and set back pointer. */
19429 if (! WORLD_SAVE_P (info)
19431 && (DEFAULT_ABI == ABI_V4
19432 || crtl->calls_eh_return))
19434 bool need_r11 = (TARGET_SPE
19435 ? (!saving_GPRs_inline
19436 && info->spe_64bit_regs_used == 0)
19437 : (!saving_FPRs_inline || !saving_GPRs_inline));
19438 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19440 if (info->total_size < 32767)
19441 sp_offset = info->total_size;
19443 frame_reg_rtx = copy_reg;
19444 else if (info->cr_save_p
19446 || info->first_fp_reg_save < 64
19447 || info->first_gp_reg_save < 32
19448 || info->altivec_size != 0
19449 || info->vrsave_mask != 0
19450 || crtl->calls_eh_return)
19452 copy_reg = frame_ptr_rtx;
19453 frame_reg_rtx = copy_reg;
19457 /* The prologue won't be saving any regs so there is no need
19458 to set up a frame register to access any frame save area.
19459 We also won't be using sp_offset anywhere below, but set
19460 the correct value anyway to protect against future
19461 changes to this function. */
19462 sp_offset = info->total_size;
19464 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19465 if (frame_reg_rtx != sp_reg_rtx)
19466 rs6000_emit_stack_tie ();
19469 /* Handle world saves specially here. */
19470 if (WORLD_SAVE_P (info))
19477 /* save_world expects lr in r0. */
19478 reg0 = gen_rtx_REG (Pmode, 0);
19479 if (info->lr_save_p)
19481 insn = emit_move_insn (reg0,
19482 gen_rtx_REG (Pmode, LR_REGNO));
19483 RTX_FRAME_RELATED_P (insn) = 1;
19486 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19487 assumptions about the offsets of various bits of the stack
19489 gcc_assert (info->gp_save_offset == -220
19490 && info->fp_save_offset == -144
19491 && info->lr_save_offset == 8
19492 && info->cr_save_offset == 4
19495 && (!crtl->calls_eh_return
19496 || info->ehrd_offset == -432)
19497 && info->vrsave_save_offset == -224
19498 && info->altivec_save_offset == -416);
19500 treg = gen_rtx_REG (SImode, 11);
19501 emit_move_insn (treg, GEN_INT (-info->total_size));
19503 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19504 in R11. It also clobbers R12, so beware! */
19506 /* Preserve CR2 for save_world prologues */
19508 sz += 32 - info->first_gp_reg_save;
19509 sz += 64 - info->first_fp_reg_save;
19510 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19511 p = rtvec_alloc (sz);
19513 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19514 gen_rtx_REG (SImode,
19516 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19517 gen_rtx_SYMBOL_REF (Pmode,
19519 /* We do floats first so that the instruction pattern matches
19521 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19523 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19524 ? DFmode : SFmode),
19525 info->first_fp_reg_save + i);
19526 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19527 GEN_INT (info->fp_save_offset
19528 + sp_offset + 8 * i));
19529 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19530 ? DFmode : SFmode), addr);
19532 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19534 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19536 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19537 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19538 GEN_INT (info->altivec_save_offset
19539 + sp_offset + 16 * i));
19540 rtx mem = gen_frame_mem (V4SImode, addr);
19542 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19544 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19546 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19547 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19548 GEN_INT (info->gp_save_offset
19549 + sp_offset + reg_size * i));
19550 rtx mem = gen_frame_mem (reg_mode, addr);
19552 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19556 /* CR register traditionally saved as CR2. */
19557 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19558 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19559 GEN_INT (info->cr_save_offset
19561 rtx mem = gen_frame_mem (reg_mode, addr);
19563 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19565 /* Explain about use of R0. */
19566 if (info->lr_save_p)
19568 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19569 GEN_INT (info->lr_save_offset
19571 rtx mem = gen_frame_mem (reg_mode, addr);
19573 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19575 /* Explain what happens to the stack pointer. */
19577 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19578 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19581 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19582 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19583 treg, GEN_INT (-info->total_size));
19584 sp_offset = info->total_size;
19587 /* If we use the link register, get it into r0. */
19588 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19590 rtx addr, reg, mem;
19592 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19593 gen_rtx_REG (Pmode, LR_REGNO));
19594 RTX_FRAME_RELATED_P (insn) = 1;
19596 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19597 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19599 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19600 GEN_INT (info->lr_save_offset + sp_offset));
19601 reg = gen_rtx_REG (Pmode, 0);
19602 mem = gen_rtx_MEM (Pmode, addr);
19603 /* This should not be of rs6000_sr_alias_set, because of
19604 __builtin_return_address. */
19606 insn = emit_move_insn (mem, reg);
19607 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19608 NULL_RTX, NULL_RTX);
19612 /* If we need to save CR, put it into r12 or r11. */
19613 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19618 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19620 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19621 RTX_FRAME_RELATED_P (insn) = 1;
19622 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19623 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19624 But that's OK. All we have to do is specify that _one_ condition
19625 code register is saved in this stack slot. The thrower's epilogue
19626 will then restore all the call-saved registers.
19627 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19628 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19629 gen_rtx_REG (SImode, CR2_REGNO));
19630 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19633 /* Do any required saving of fpr's. If only one or two to save, do
19634 it ourselves. Otherwise, call function. */
19635 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19638 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19639 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19640 && ! call_used_regs[info->first_fp_reg_save+i]))
19641 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19642 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19644 info->first_fp_reg_save + i,
19645 info->fp_save_offset + sp_offset + 8 * i,
19648 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19652 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19653 info->fp_save_offset + sp_offset,
19655 /*savep=*/true, /*gpr=*/false,
19657 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19659 insn = emit_insn (par);
19660 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19661 NULL_RTX, NULL_RTX);
19664 /* Save GPRs. This is done as a PARALLEL if we are using
19665 the store-multiple instructions. */
19666 if (!WORLD_SAVE_P (info)
19668 && info->spe_64bit_regs_used != 0
19669 && info->first_gp_reg_save != 32)
19672 rtx spe_save_area_ptr;
19674 /* Determine whether we can address all of the registers that need
19675 to be saved with an offset from the stack pointer that fits in
19676 the small const field for SPE memory instructions. */
19677 int spe_regs_addressable_via_sp
19678 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19679 + (32 - info->first_gp_reg_save - 1) * reg_size)
19680 && saving_GPRs_inline);
19683 if (spe_regs_addressable_via_sp)
19685 spe_save_area_ptr = frame_reg_rtx;
19686 spe_offset = info->spe_gp_save_offset + sp_offset;
19690 /* Make r11 point to the start of the SPE save area. We need
19691 to be careful here if r11 is holding the static chain. If
19692 it is, then temporarily save it in r0. We would use r0 as
19693 our base register here, but using r0 as a base register in
19694 loads and stores means something different from what we
19696 int ool_adjust = (saving_GPRs_inline
19698 : (info->first_gp_reg_save
19699 - (FIRST_SAVRES_REGISTER+1))*8);
19700 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19701 + sp_offset - ool_adjust);
19703 if (using_static_chain_p)
19705 rtx r0 = gen_rtx_REG (Pmode, 0);
19706 gcc_assert (info->first_gp_reg_save > 11);
19708 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19711 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19712 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19714 GEN_INT (offset)));
19715 /* We need to make sure the move to r11 gets noted for
19716 properly outputting unwind information. */
19717 if (!saving_GPRs_inline)
19718 rs6000_frame_related (insn, frame_reg_rtx, offset,
19719 NULL_RTX, NULL_RTX);
19723 if (saving_GPRs_inline)
19725 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19726 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19728 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19729 rtx offset, addr, mem;
19731 /* We're doing all this to ensure that the offset fits into
19732 the immediate offset of 'evstdd'. */
19733 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19735 offset = GEN_INT (reg_size * i + spe_offset);
19736 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19737 mem = gen_rtx_MEM (V2SImode, addr);
19739 insn = emit_move_insn (mem, reg);
19741 rs6000_frame_related (insn, spe_save_area_ptr,
19742 info->spe_gp_save_offset
19743 + sp_offset + reg_size * i,
19744 offset, const0_rtx);
19751 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19753 /*savep=*/true, /*gpr=*/true,
19755 insn = emit_insn (par);
19756 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19757 NULL_RTX, NULL_RTX);
19761 /* Move the static chain pointer back. */
19762 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19763 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19765 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19769 /* Need to adjust r11 (r12) if we saved any FPRs. */
19770 if (info->first_fp_reg_save != 64)
19772 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19774 rtx offset = GEN_INT (sp_offset
19775 + (-8 * (64-info->first_fp_reg_save)));
19776 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19779 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19780 info->gp_save_offset + sp_offset,
19782 /*savep=*/true, /*gpr=*/true,
19784 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19786 insn = emit_insn (par);
19787 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19788 NULL_RTX, NULL_RTX);
19790 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19794 p = rtvec_alloc (32 - info->first_gp_reg_save);
19795 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19797 rtx addr, reg, mem;
19798 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19799 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19800 GEN_INT (info->gp_save_offset
19803 mem = gen_frame_mem (reg_mode, addr);
19805 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19807 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19808 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19809 NULL_RTX, NULL_RTX);
19811 else if (!WORLD_SAVE_P (info))
19814 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19815 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19817 rtx addr, reg, mem;
19818 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19820 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19821 GEN_INT (info->gp_save_offset
19824 mem = gen_frame_mem (reg_mode, addr);
19826 insn = emit_move_insn (mem, reg);
19827 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19828 NULL_RTX, NULL_RTX);
19832 /* ??? There's no need to emit actual instructions here, but it's the
19833 easiest way to get the frame unwind information emitted. */
19834 if (crtl->calls_eh_return)
19836 unsigned int i, regno;
19838 /* In AIX ABI we need to pretend we save r2 here. */
19841 rtx addr, reg, mem;
19843 reg = gen_rtx_REG (reg_mode, 2);
19844 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19845 GEN_INT (sp_offset + 5 * reg_size));
19846 mem = gen_frame_mem (reg_mode, addr);
19848 insn = emit_move_insn (mem, reg);
19849 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19850 NULL_RTX, NULL_RTX);
19851 PATTERN (insn) = gen_blockage ();
19856 regno = EH_RETURN_DATA_REGNO (i);
19857 if (regno == INVALID_REGNUM)
19860 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19861 info->ehrd_offset + sp_offset
19862 + reg_size * (int) i,
19867 /* Save CR if we use any that must be preserved. */
19868 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19870 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19871 GEN_INT (info->cr_save_offset + sp_offset));
19872 rtx mem = gen_frame_mem (SImode, addr);
19873 /* See the large comment above about why CR2_REGNO is used. */
19874 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19876 /* If r12 was used to hold the original sp, copy cr into r0 now
19878 if (REGNO (frame_reg_rtx) == 12)
19882 cr_save_rtx = gen_rtx_REG (SImode, 0);
19883 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19884 RTX_FRAME_RELATED_P (insn) = 1;
19885 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19886 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19888 insn = emit_move_insn (mem, cr_save_rtx);
19890 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19891 NULL_RTX, NULL_RTX);
19894 /* Update stack and set back pointer unless this is V.4,
19895 for which it was done previously. */
19896 if (!WORLD_SAVE_P (info) && info->push_p
19897 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19899 rtx copy_reg = NULL;
19901 if (info->total_size < 32767)
19902 sp_offset = info->total_size;
19903 else if (info->altivec_size != 0
19904 || info->vrsave_mask != 0)
19906 copy_reg = frame_ptr_rtx;
19907 frame_reg_rtx = copy_reg;
19910 sp_offset = info->total_size;
19911 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19912 if (frame_reg_rtx != sp_reg_rtx)
19913 rs6000_emit_stack_tie ();
19916 /* Set frame pointer, if needed. */
19917 if (frame_pointer_needed)
19919 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19921 RTX_FRAME_RELATED_P (insn) = 1;
19924 /* Save AltiVec registers if needed. Save here because the red zone does
19925 not include AltiVec registers. */
19926 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19930 /* There should be a non inline version of this, for when we
19931 are saving lots of vector registers. */
19932 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19933 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19935 rtx areg, savereg, mem;
19938 offset = info->altivec_save_offset + sp_offset
19939 + 16 * (i - info->first_altivec_reg_save);
19941 savereg = gen_rtx_REG (V4SImode, i);
19943 areg = gen_rtx_REG (Pmode, 0);
19944 emit_move_insn (areg, GEN_INT (offset));
19946 /* AltiVec addressing mode is [reg+reg]. */
19947 mem = gen_frame_mem (V4SImode,
19948 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19950 insn = emit_move_insn (mem, savereg);
19952 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19953 areg, GEN_INT (offset));
19957 /* VRSAVE is a bit vector representing which AltiVec registers
19958 are used. The OS uses this to determine which vector
19959 registers to save on a context switch. We need to save
19960 VRSAVE on the stack frame, add whatever AltiVec registers we
19961 used in this function, and do the corresponding magic in the
19964 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19965 && info->vrsave_mask != 0)
19967 rtx reg, mem, vrsave;
19970 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19971 as frame_reg_rtx and r11 as the static chain pointer for
19972 nested functions. */
19973 reg = gen_rtx_REG (SImode, 0);
19974 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19976 emit_insn (gen_get_vrsave_internal (reg));
19978 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19980 if (!WORLD_SAVE_P (info))
19983 offset = info->vrsave_save_offset + sp_offset;
19984 mem = gen_frame_mem (SImode,
19985 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19986 GEN_INT (offset)));
19987 insn = emit_move_insn (mem, reg);
19990 /* Include the registers in the mask. */
19991 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19993 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19996 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19997 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19998 || (DEFAULT_ABI == ABI_V4
19999 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20000 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20002 /* If emit_load_toc_table will use the link register, we need to save
20003 it. We use R12 for this purpose because emit_load_toc_table
20004 can use register 0. This allows us to use a plain 'blr' to return
20005 from the procedure more often. */
20006 int save_LR_around_toc_setup = (TARGET_ELF
20007 && DEFAULT_ABI != ABI_AIX
20009 && ! info->lr_save_p
20010 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20011 if (save_LR_around_toc_setup)
20013 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20015 insn = emit_move_insn (frame_ptr_rtx, lr);
20016 RTX_FRAME_RELATED_P (insn) = 1;
20018 rs6000_emit_load_toc_table (TRUE);
20020 insn = emit_move_insn (lr, frame_ptr_rtx);
20021 RTX_FRAME_RELATED_P (insn) = 1;
20024 rs6000_emit_load_toc_table (TRUE);
20028 if (DEFAULT_ABI == ABI_DARWIN
20029 && flag_pic && crtl->uses_pic_offset_table)
20031 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20032 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20034 /* Save and restore LR locally around this call (in R0). */
20035 if (!info->lr_save_p)
20036 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20038 emit_insn (gen_load_macho_picbase (src));
20040 emit_move_insn (gen_rtx_REG (Pmode,
20041 RS6000_PIC_OFFSET_TABLE_REGNUM),
20044 if (!info->lr_save_p)
20045 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20050 /* Write function prologue. */
20053 rs6000_output_function_prologue (FILE *file,
20054 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20056 rs6000_stack_t *info = rs6000_stack_info ();
20058 if (TARGET_DEBUG_STACK)
20059 debug_stack_info (info);
20061 /* Write .extern for any function we will call to save and restore
20063 if (info->first_fp_reg_save < 64
20064 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20067 int regno = info->first_fp_reg_save - 32;
20069 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20070 /*gpr=*/false, /*lr=*/false);
20071 fprintf (file, "\t.extern %s\n", name);
20073 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20074 /*gpr=*/false, /*lr=*/true);
20075 fprintf (file, "\t.extern %s\n", name);
20078 /* Write .extern for AIX common mode routines, if needed. */
20079 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20081 fputs ("\t.extern __mulh\n", file);
20082 fputs ("\t.extern __mull\n", file);
20083 fputs ("\t.extern __divss\n", file);
20084 fputs ("\t.extern __divus\n", file);
20085 fputs ("\t.extern __quoss\n", file);
20086 fputs ("\t.extern __quous\n", file);
20087 common_mode_defined = 1;
20090 if (! HAVE_prologue)
20096 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20097 the "toplevel" insn chain. */
20098 emit_note (NOTE_INSN_DELETED);
20099 rs6000_emit_prologue ();
20100 emit_note (NOTE_INSN_DELETED);
20102 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20106 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20108 INSN_ADDRESSES_NEW (insn, addr);
20113 prologue = get_insns ();
20116 if (TARGET_DEBUG_STACK)
20117 debug_rtx_list (prologue, 100);
20119 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20123 rs6000_pic_labelno++;
20126 /* Non-zero if vmx regs are restored before the frame pop, zero if
20127 we restore after the pop when possible. */
20128 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20130 /* Reload CR from REG. */
20133 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20138 if (using_mfcr_multiple)
20140 for (i = 0; i < 8; i++)
20141 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20143 gcc_assert (count);
20146 if (using_mfcr_multiple && count > 1)
20151 p = rtvec_alloc (count);
20154 for (i = 0; i < 8; i++)
20155 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20157 rtvec r = rtvec_alloc (2);
20158 RTVEC_ELT (r, 0) = reg;
20159 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20160 RTVEC_ELT (p, ndx) =
20161 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20162 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20165 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20166 gcc_assert (ndx == count);
20169 for (i = 0; i < 8; i++)
20170 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20172 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20178 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20179 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20180 below stack pointer not cloberred by signals. */
20183 offset_below_red_zone_p (HOST_WIDE_INT offset)
20185 return offset < (DEFAULT_ABI == ABI_V4
20187 : TARGET_32BIT ? -220 : -288);
20190 /* Emit function epilogue as insns. */
20193 rs6000_emit_epilogue (int sibcall)
20195 rs6000_stack_t *info;
20196 int restoring_GPRs_inline;
20197 int restoring_FPRs_inline;
20198 int using_load_multiple;
20199 int using_mtcr_multiple;
20200 int use_backchain_to_restore_sp;
20204 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20205 rtx frame_reg_rtx = sp_reg_rtx;
20206 rtx cfa_restores = NULL_RTX;
20208 rtx cr_save_reg = NULL_RTX;
20209 enum machine_mode reg_mode = Pmode;
20210 int reg_size = TARGET_32BIT ? 4 : 8;
20213 info = rs6000_stack_info ();
20215 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20217 reg_mode = V2SImode;
20221 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20222 /*static_chain_p=*/0, sibcall);
20223 using_load_multiple = strategy & SAVRES_MULTIPLE;
20224 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20225 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20226 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20227 || rs6000_cpu == PROCESSOR_PPC603
20228 || rs6000_cpu == PROCESSOR_PPC750
20230 /* Restore via the backchain when we have a large frame, since this
20231 is more efficient than an addis, addi pair. The second condition
20232 here will not trigger at the moment; We don't actually need a
20233 frame pointer for alloca, but the generic parts of the compiler
20234 give us one anyway. */
20235 use_backchain_to_restore_sp = (info->total_size > 32767
20236 || info->total_size
20237 + (info->lr_save_p ? info->lr_save_offset : 0)
20239 || (cfun->calls_alloca
20240 && !frame_pointer_needed));
20241 restore_lr = (info->lr_save_p
20242 && (restoring_FPRs_inline
20243 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20244 && (restoring_GPRs_inline
20245 || info->first_fp_reg_save < 64));
20247 if (WORLD_SAVE_P (info))
20251 const char *alloc_rname;
20254 /* eh_rest_world_r10 will return to the location saved in the LR
20255 stack slot (which is not likely to be our caller.)
20256 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20257 rest_world is similar, except any R10 parameter is ignored.
20258 The exception-handling stuff that was here in 2.95 is no
20259 longer necessary. */
20263 + 32 - info->first_gp_reg_save
20264 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20265 + 63 + 1 - info->first_fp_reg_save);
20267 strcpy (rname, ((crtl->calls_eh_return) ?
20268 "*eh_rest_world_r10" : "*rest_world"));
20269 alloc_rname = ggc_strdup (rname);
20272 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20273 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20274 gen_rtx_REG (Pmode,
20277 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20278 /* The instruction pattern requires a clobber here;
20279 it is shared with the restVEC helper. */
20281 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20284 /* CR register traditionally saved as CR2. */
20285 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20286 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20287 GEN_INT (info->cr_save_offset));
20288 rtx mem = gen_frame_mem (reg_mode, addr);
20290 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20293 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20295 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20296 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20297 GEN_INT (info->gp_save_offset
20299 rtx mem = gen_frame_mem (reg_mode, addr);
20301 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20303 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20305 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20306 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20307 GEN_INT (info->altivec_save_offset
20309 rtx mem = gen_frame_mem (V4SImode, addr);
20311 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20313 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20315 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20316 ? DFmode : SFmode),
20317 info->first_fp_reg_save + i);
20318 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20319 GEN_INT (info->fp_save_offset
20321 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20322 ? DFmode : SFmode), addr);
20324 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20327 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20329 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20331 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20333 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20335 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20336 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20341 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20343 sp_offset = info->total_size;
20345 /* Restore AltiVec registers if we must do so before adjusting the
20347 if (TARGET_ALTIVEC_ABI
20348 && info->altivec_size != 0
20349 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20350 || (DEFAULT_ABI != ABI_V4
20351 && offset_below_red_zone_p (info->altivec_save_offset))))
20355 if (use_backchain_to_restore_sp)
20357 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20358 emit_move_insn (frame_reg_rtx,
20359 gen_rtx_MEM (Pmode, sp_reg_rtx));
20362 else if (frame_pointer_needed)
20363 frame_reg_rtx = hard_frame_pointer_rtx;
20365 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20366 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20368 rtx addr, areg, mem, reg;
20370 areg = gen_rtx_REG (Pmode, 0);
20372 (areg, GEN_INT (info->altivec_save_offset
20374 + 16 * (i - info->first_altivec_reg_save)));
20376 /* AltiVec addressing mode is [reg+reg]. */
20377 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20378 mem = gen_frame_mem (V4SImode, addr);
20380 reg = gen_rtx_REG (V4SImode, i);
20381 emit_move_insn (reg, mem);
20382 if (offset_below_red_zone_p (info->altivec_save_offset
20383 + (i - info->first_altivec_reg_save)
20385 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20390 /* Restore VRSAVE if we must do so before adjusting the stack. */
20392 && TARGET_ALTIVEC_VRSAVE
20393 && info->vrsave_mask != 0
20394 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20395 || (DEFAULT_ABI != ABI_V4
20396 && offset_below_red_zone_p (info->vrsave_save_offset))))
20398 rtx addr, mem, reg;
20400 if (frame_reg_rtx == sp_reg_rtx)
20402 if (use_backchain_to_restore_sp)
20404 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20405 emit_move_insn (frame_reg_rtx,
20406 gen_rtx_MEM (Pmode, sp_reg_rtx));
20409 else if (frame_pointer_needed)
20410 frame_reg_rtx = hard_frame_pointer_rtx;
20413 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20414 GEN_INT (info->vrsave_save_offset + sp_offset));
20415 mem = gen_frame_mem (SImode, addr);
20416 reg = gen_rtx_REG (SImode, 12);
20417 emit_move_insn (reg, mem);
20419 emit_insn (generate_set_vrsave (reg, info, 1));
20423 /* If we have a large stack frame, restore the old stack pointer
20424 using the backchain. */
20425 if (use_backchain_to_restore_sp)
20427 if (frame_reg_rtx == sp_reg_rtx)
20429 /* Under V.4, don't reset the stack pointer until after we're done
20430 loading the saved registers. */
20431 if (DEFAULT_ABI == ABI_V4)
20432 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20434 insn = emit_move_insn (frame_reg_rtx,
20435 gen_rtx_MEM (Pmode, sp_reg_rtx));
20438 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20439 && DEFAULT_ABI == ABI_V4)
20440 /* frame_reg_rtx has been set up by the altivec restore. */
20444 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20445 frame_reg_rtx = sp_reg_rtx;
20448 /* If we have a frame pointer, we can restore the old stack pointer
20450 else if (frame_pointer_needed)
20452 frame_reg_rtx = sp_reg_rtx;
20453 if (DEFAULT_ABI == ABI_V4)
20454 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20455 /* Prevent reordering memory accesses against stack pointer restore. */
20456 else if (cfun->calls_alloca
20457 || offset_below_red_zone_p (-info->total_size))
20459 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20460 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20461 MEM_NOTRAP_P (mem1) = 1;
20462 MEM_NOTRAP_P (mem2) = 1;
20463 emit_insn (gen_frame_tie (mem1, mem2));
20466 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20467 GEN_INT (info->total_size)));
20470 else if (info->push_p
20471 && DEFAULT_ABI != ABI_V4
20472 && !crtl->calls_eh_return)
20474 /* Prevent reordering memory accesses against stack pointer restore. */
20475 if (cfun->calls_alloca
20476 || offset_below_red_zone_p (-info->total_size))
20478 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20479 MEM_NOTRAP_P (mem) = 1;
20480 emit_insn (gen_stack_tie (mem));
20482 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20483 GEN_INT (info->total_size)));
20486 if (insn && frame_reg_rtx == sp_reg_rtx)
20490 REG_NOTES (insn) = cfa_restores;
20491 cfa_restores = NULL_RTX;
20493 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20494 RTX_FRAME_RELATED_P (insn) = 1;
20497 /* Restore AltiVec registers if we have not done so already. */
20498 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20499 && TARGET_ALTIVEC_ABI
20500 && info->altivec_size != 0
20501 && (DEFAULT_ABI == ABI_V4
20502 || !offset_below_red_zone_p (info->altivec_save_offset)))
20506 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20507 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20509 rtx addr, areg, mem, reg;
20511 areg = gen_rtx_REG (Pmode, 0);
20513 (areg, GEN_INT (info->altivec_save_offset
20515 + 16 * (i - info->first_altivec_reg_save)));
20517 /* AltiVec addressing mode is [reg+reg]. */
20518 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20519 mem = gen_frame_mem (V4SImode, addr);
20521 reg = gen_rtx_REG (V4SImode, i);
20522 emit_move_insn (reg, mem);
20523 if (DEFAULT_ABI == ABI_V4)
20524 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20529 /* Restore VRSAVE if we have not done so already. */
20530 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20532 && TARGET_ALTIVEC_VRSAVE
20533 && info->vrsave_mask != 0
20534 && (DEFAULT_ABI == ABI_V4
20535 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20537 rtx addr, mem, reg;
20539 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20540 GEN_INT (info->vrsave_save_offset + sp_offset));
20541 mem = gen_frame_mem (SImode, addr);
20542 reg = gen_rtx_REG (SImode, 12);
20543 emit_move_insn (reg, mem);
20545 emit_insn (generate_set_vrsave (reg, info, 1));
20548 /* Get the old lr if we saved it. If we are restoring registers
20549 out-of-line, then the out-of-line routines can do this for us. */
20550 if (restore_lr && restoring_GPRs_inline)
20552 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20553 info->lr_save_offset + sp_offset);
20555 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20558 /* Get the old cr if we saved it. */
20559 if (info->cr_save_p)
20561 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20562 GEN_INT (info->cr_save_offset + sp_offset));
20563 rtx mem = gen_frame_mem (SImode, addr);
20565 cr_save_reg = gen_rtx_REG (SImode,
20566 DEFAULT_ABI == ABI_AIX
20567 && !restoring_GPRs_inline
20568 && info->first_fp_reg_save < 64
20570 emit_move_insn (cr_save_reg, mem);
20573 /* Set LR here to try to overlap restores below. LR is always saved
20574 above incoming stack, so it never needs REG_CFA_RESTORE. */
20575 if (restore_lr && restoring_GPRs_inline)
20576 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20577 gen_rtx_REG (Pmode, 0));
20579 /* Load exception handler data registers, if needed. */
20580 if (crtl->calls_eh_return)
20582 unsigned int i, regno;
20586 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20587 GEN_INT (sp_offset + 5 * reg_size));
20588 rtx mem = gen_frame_mem (reg_mode, addr);
20590 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20597 regno = EH_RETURN_DATA_REGNO (i);
20598 if (regno == INVALID_REGNUM)
20601 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20602 info->ehrd_offset + sp_offset
20603 + reg_size * (int) i);
20605 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20609 /* Restore GPRs. This is done as a PARALLEL if we are using
20610 the load-multiple instructions. */
20612 && info->spe_64bit_regs_used != 0
20613 && info->first_gp_reg_save != 32)
20615 /* Determine whether we can address all of the registers that need
20616 to be saved with an offset from the stack pointer that fits in
20617 the small const field for SPE memory instructions. */
20618 int spe_regs_addressable_via_sp
20619 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20620 + (32 - info->first_gp_reg_save - 1) * reg_size)
20621 && restoring_GPRs_inline);
20624 if (spe_regs_addressable_via_sp)
20625 spe_offset = info->spe_gp_save_offset + sp_offset;
20628 rtx old_frame_reg_rtx = frame_reg_rtx;
20629 /* Make r11 point to the start of the SPE save area. We worried about
20630 not clobbering it when we were saving registers in the prologue.
20631 There's no need to worry here because the static chain is passed
20632 anew to every function. */
20633 int ool_adjust = (restoring_GPRs_inline
20635 : (info->first_gp_reg_save
20636 - (FIRST_SAVRES_REGISTER+1))*8);
20638 if (frame_reg_rtx == sp_reg_rtx)
20639 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20640 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20641 GEN_INT (info->spe_gp_save_offset
20644 /* Keep the invariant that frame_reg_rtx + sp_offset points
20645 at the top of the stack frame. */
20646 sp_offset = -info->spe_gp_save_offset;
20651 if (restoring_GPRs_inline)
20653 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20654 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20656 rtx offset, addr, mem, reg;
20658 /* We're doing all this to ensure that the immediate offset
20659 fits into the immediate field of 'evldd'. */
20660 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20662 offset = GEN_INT (spe_offset + reg_size * i);
20663 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20664 mem = gen_rtx_MEM (V2SImode, addr);
20665 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20667 insn = emit_move_insn (reg, mem);
20668 if (DEFAULT_ABI == ABI_V4)
20670 if (frame_pointer_needed
20671 && info->first_gp_reg_save + i
20672 == HARD_FRAME_POINTER_REGNUM)
20674 add_reg_note (insn, REG_CFA_DEF_CFA,
20675 plus_constant (frame_reg_rtx,
20677 RTX_FRAME_RELATED_P (insn) = 1;
20680 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20689 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20691 /*savep=*/false, /*gpr=*/true,
20693 emit_jump_insn (par);
20694 /* We don't want anybody else emitting things after we jumped
20699 else if (!restoring_GPRs_inline)
20701 /* We are jumping to an out-of-line function. */
20702 bool can_use_exit = info->first_fp_reg_save == 64;
20705 /* Emit stack reset code if we need it. */
20707 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20708 sp_offset, can_use_exit);
20711 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20714 GEN_INT (sp_offset - info->fp_size)));
20715 if (REGNO (frame_reg_rtx) == 11)
20716 sp_offset += info->fp_size;
20719 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20720 info->gp_save_offset, reg_mode,
20721 /*savep=*/false, /*gpr=*/true,
20722 /*lr=*/can_use_exit);
20726 if (info->cr_save_p)
20728 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20729 if (DEFAULT_ABI == ABI_V4)
20731 = alloc_reg_note (REG_CFA_RESTORE,
20732 gen_rtx_REG (SImode, CR2_REGNO),
20736 emit_jump_insn (par);
20738 /* We don't want anybody else emitting things after we jumped
20743 insn = emit_insn (par);
20744 if (DEFAULT_ABI == ABI_V4)
20746 if (frame_pointer_needed)
20748 add_reg_note (insn, REG_CFA_DEF_CFA,
20749 plus_constant (frame_reg_rtx, sp_offset));
20750 RTX_FRAME_RELATED_P (insn) = 1;
20753 for (i = info->first_gp_reg_save; i < 32; i++)
20755 = alloc_reg_note (REG_CFA_RESTORE,
20756 gen_rtx_REG (reg_mode, i), cfa_restores);
20759 else if (using_load_multiple)
20762 p = rtvec_alloc (32 - info->first_gp_reg_save);
20763 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20765 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20766 GEN_INT (info->gp_save_offset
20769 rtx mem = gen_frame_mem (reg_mode, addr);
20770 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20772 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20773 if (DEFAULT_ABI == ABI_V4)
20774 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20777 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20778 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20780 add_reg_note (insn, REG_CFA_DEF_CFA,
20781 plus_constant (frame_reg_rtx, sp_offset));
20782 RTX_FRAME_RELATED_P (insn) = 1;
20787 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20788 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20790 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20791 GEN_INT (info->gp_save_offset
20794 rtx mem = gen_frame_mem (reg_mode, addr);
20795 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20797 insn = emit_move_insn (reg, mem);
20798 if (DEFAULT_ABI == ABI_V4)
20800 if (frame_pointer_needed
20801 && info->first_gp_reg_save + i
20802 == HARD_FRAME_POINTER_REGNUM)
20804 add_reg_note (insn, REG_CFA_DEF_CFA,
20805 plus_constant (frame_reg_rtx, sp_offset));
20806 RTX_FRAME_RELATED_P (insn) = 1;
20809 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20815 if (restore_lr && !restoring_GPRs_inline)
20817 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20818 info->lr_save_offset + sp_offset);
20820 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20821 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20822 gen_rtx_REG (Pmode, 0));
20825 /* Restore fpr's if we need to do it without calling a function. */
20826 if (restoring_FPRs_inline)
20827 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20828 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20829 && ! call_used_regs[info->first_fp_reg_save+i]))
20831 rtx addr, mem, reg;
20832 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20833 GEN_INT (info->fp_save_offset
20836 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20837 ? DFmode : SFmode), addr);
20838 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20839 ? DFmode : SFmode),
20840 info->first_fp_reg_save + i);
20842 emit_move_insn (reg, mem);
20843 if (DEFAULT_ABI == ABI_V4)
20844 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20848 /* If we saved cr, restore it here. Just those that were used. */
20849 if (info->cr_save_p)
20851 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20852 if (DEFAULT_ABI == ABI_V4)
20854 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20858 /* If this is V.4, unwind the stack pointer after all of the loads
20860 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20861 sp_offset, !restoring_FPRs_inline);
20866 REG_NOTES (insn) = cfa_restores;
20867 cfa_restores = NULL_RTX;
20869 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20870 RTX_FRAME_RELATED_P (insn) = 1;
20873 if (crtl->calls_eh_return)
20875 rtx sa = EH_RETURN_STACKADJ_RTX;
20876 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20882 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20883 if (! restoring_FPRs_inline)
20884 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20886 p = rtvec_alloc (2);
20888 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20889 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20890 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20891 : gen_rtx_CLOBBER (VOIDmode,
20892 gen_rtx_REG (Pmode, 65)));
20894 /* If we have to restore more than two FP registers, branch to the
20895 restore function. It will return to our caller. */
20896 if (! restoring_FPRs_inline)
20901 sym = rs6000_savres_routine_sym (info,
20905 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20906 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20907 gen_rtx_REG (Pmode,
20908 DEFAULT_ABI == ABI_AIX
20910 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20913 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20914 GEN_INT (info->fp_save_offset + 8*i));
20915 mem = gen_frame_mem (DFmode, addr);
20917 RTVEC_ELT (p, i+4) =
20918 gen_rtx_SET (VOIDmode,
20919 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20924 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20928 /* Write function epilogue. */
20931 rs6000_output_function_epilogue (FILE *file,
20932 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20934 if (! HAVE_epilogue)
20936 rtx insn = get_last_insn ();
20937 /* If the last insn was a BARRIER, we don't have to write anything except
20938 the trace table. */
20939 if (GET_CODE (insn) == NOTE)
20940 insn = prev_nonnote_insn (insn);
20941 if (insn == 0 || GET_CODE (insn) != BARRIER)
20943 /* This is slightly ugly, but at least we don't have two
20944 copies of the epilogue-emitting code. */
20947 /* A NOTE_INSN_DELETED is supposed to be at the start
20948 and end of the "toplevel" insn chain. */
20949 emit_note (NOTE_INSN_DELETED);
20950 rs6000_emit_epilogue (FALSE);
20951 emit_note (NOTE_INSN_DELETED);
20953 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20957 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20959 INSN_ADDRESSES_NEW (insn, addr);
20964 if (TARGET_DEBUG_STACK)
20965 debug_rtx_list (get_insns (), 100);
20966 final (get_insns (), file, FALSE);
20972 macho_branch_islands ();
20973 /* Mach-O doesn't support labels at the end of objects, so if
20974 it looks like we might want one, insert a NOP. */
20976 rtx insn = get_last_insn ();
20979 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20980 insn = PREV_INSN (insn);
20984 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20985 fputs ("\tnop\n", file);
20989 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20992 We don't output a traceback table if -finhibit-size-directive was
20993 used. The documentation for -finhibit-size-directive reads
20994 ``don't output a @code{.size} assembler directive, or anything
20995 else that would cause trouble if the function is split in the
20996 middle, and the two halves are placed at locations far apart in
20997 memory.'' The traceback table has this property, since it
20998 includes the offset from the start of the function to the
20999 traceback table itself.
21001 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21002 different traceback table. */
21003 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21004 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21006 const char *fname = NULL;
21007 const char *language_string = lang_hooks.name;
21008 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21010 int optional_tbtab;
21011 rs6000_stack_t *info = rs6000_stack_info ();
21013 if (rs6000_traceback == traceback_full)
21014 optional_tbtab = 1;
21015 else if (rs6000_traceback == traceback_part)
21016 optional_tbtab = 0;
21018 optional_tbtab = !optimize_size && !TARGET_ELF;
21020 if (optional_tbtab)
21022 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21023 while (*fname == '.') /* V.4 encodes . in the name */
21026 /* Need label immediately before tbtab, so we can compute
21027 its offset from the function start. */
21028 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21029 ASM_OUTPUT_LABEL (file, fname);
21032 /* The .tbtab pseudo-op can only be used for the first eight
21033 expressions, since it can't handle the possibly variable
21034 length fields that follow. However, if you omit the optional
21035 fields, the assembler outputs zeros for all optional fields
21036 anyways, giving each variable length field is minimum length
21037 (as defined in sys/debug.h). Thus we can not use the .tbtab
21038 pseudo-op at all. */
21040 /* An all-zero word flags the start of the tbtab, for debuggers
21041 that have to find it by searching forward from the entry
21042 point or from the current pc. */
21043 fputs ("\t.long 0\n", file);
21045 /* Tbtab format type. Use format type 0. */
21046 fputs ("\t.byte 0,", file);
21048 /* Language type. Unfortunately, there does not seem to be any
21049 official way to discover the language being compiled, so we
21050 use language_string.
21051 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21052 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21053 a number, so for now use 9. LTO isn't assigned a number either,
21054 so for now use 0. */
21055 if (! strcmp (language_string, "GNU C")
21056 || ! strcmp (language_string, "GNU GIMPLE"))
21058 else if (! strcmp (language_string, "GNU F77")
21059 || ! strcmp (language_string, "GNU Fortran"))
21061 else if (! strcmp (language_string, "GNU Pascal"))
21063 else if (! strcmp (language_string, "GNU Ada"))
21065 else if (! strcmp (language_string, "GNU C++")
21066 || ! strcmp (language_string, "GNU Objective-C++"))
21068 else if (! strcmp (language_string, "GNU Java"))
21070 else if (! strcmp (language_string, "GNU Objective-C"))
21073 gcc_unreachable ();
21074 fprintf (file, "%d,", i);
21076 /* 8 single bit fields: global linkage (not set for C extern linkage,
21077 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21078 from start of procedure stored in tbtab, internal function, function
21079 has controlled storage, function has no toc, function uses fp,
21080 function logs/aborts fp operations. */
21081 /* Assume that fp operations are used if any fp reg must be saved. */
21082 fprintf (file, "%d,",
21083 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21085 /* 6 bitfields: function is interrupt handler, name present in
21086 proc table, function calls alloca, on condition directives
21087 (controls stack walks, 3 bits), saves condition reg, saves
21089 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21090 set up as a frame pointer, even when there is no alloca call. */
21091 fprintf (file, "%d,",
21092 ((optional_tbtab << 6)
21093 | ((optional_tbtab & frame_pointer_needed) << 5)
21094 | (info->cr_save_p << 1)
21095 | (info->lr_save_p)));
21097 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21099 fprintf (file, "%d,",
21100 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21102 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21103 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21105 if (optional_tbtab)
21107 /* Compute the parameter info from the function decl argument
21110 int next_parm_info_bit = 31;
21112 for (decl = DECL_ARGUMENTS (current_function_decl);
21113 decl; decl = DECL_CHAIN (decl))
21115 rtx parameter = DECL_INCOMING_RTL (decl);
21116 enum machine_mode mode = GET_MODE (parameter);
21118 if (GET_CODE (parameter) == REG)
21120 if (SCALAR_FLOAT_MODE_P (mode))
21141 gcc_unreachable ();
21144 /* If only one bit will fit, don't or in this entry. */
21145 if (next_parm_info_bit > 0)
21146 parm_info |= (bits << (next_parm_info_bit - 1));
21147 next_parm_info_bit -= 2;
21151 fixed_parms += ((GET_MODE_SIZE (mode)
21152 + (UNITS_PER_WORD - 1))
21154 next_parm_info_bit -= 1;
21160 /* Number of fixed point parameters. */
21161 /* This is actually the number of words of fixed point parameters; thus
21162 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21163 fprintf (file, "%d,", fixed_parms);
21165 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21167 /* This is actually the number of fp registers that hold parameters;
21168 and thus the maximum value is 13. */
21169 /* Set parameters on stack bit if parameters are not in their original
21170 registers, regardless of whether they are on the stack? Xlc
21171 seems to set the bit when not optimizing. */
21172 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21174 if (! optional_tbtab)
21177 /* Optional fields follow. Some are variable length. */
21179 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21180 11 double float. */
21181 /* There is an entry for each parameter in a register, in the order that
21182 they occur in the parameter list. Any intervening arguments on the
21183 stack are ignored. If the list overflows a long (max possible length
21184 34 bits) then completely leave off all elements that don't fit. */
21185 /* Only emit this long if there was at least one parameter. */
21186 if (fixed_parms || float_parms)
21187 fprintf (file, "\t.long %d\n", parm_info);
21189 /* Offset from start of code to tb table. */
21190 fputs ("\t.long ", file);
21191 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21192 RS6000_OUTPUT_BASENAME (file, fname);
21194 rs6000_output_function_entry (file, fname);
21197 /* Interrupt handler mask. */
21198 /* Omit this long, since we never set the interrupt handler bit
21201 /* Number of CTL (controlled storage) anchors. */
21202 /* Omit this long, since the has_ctl bit is never set above. */
21204 /* Displacement into stack of each CTL anchor. */
21205 /* Omit this list of longs, because there are no CTL anchors. */
21207 /* Length of function name. */
21210 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21212 /* Function name. */
21213 assemble_string (fname, strlen (fname));
21215 /* Register for alloca automatic storage; this is always reg 31.
21216 Only emit this if the alloca bit was set above. */
21217 if (frame_pointer_needed)
21218 fputs ("\t.byte 31\n", file);
21220 fputs ("\t.align 2\n", file);
21224 /* A C compound statement that outputs the assembler code for a thunk
21225 function, used to implement C++ virtual function calls with
21226 multiple inheritance. The thunk acts as a wrapper around a virtual
21227 function, adjusting the implicit object parameter before handing
21228 control off to the real function.
21230 First, emit code to add the integer DELTA to the location that
21231 contains the incoming first argument. Assume that this argument
21232 contains a pointer, and is the one used to pass the `this' pointer
21233 in C++. This is the incoming argument *before* the function
21234 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21235 values of all other incoming arguments.
21237 After the addition, emit code to jump to FUNCTION, which is a
21238 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21239 not touch the return address. Hence returning from FUNCTION will
21240 return to whoever called the current `thunk'.
21242 The effect must be as if FUNCTION had been called directly with the
21243 adjusted first argument. This macro is responsible for emitting
21244 all of the code for a thunk function; output_function_prologue()
21245 and output_function_epilogue() are not invoked.
21247 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21248 been extracted from it.) It might possibly be useful on some
21249 targets, but probably not.
21251 If you do not define this macro, the target-independent code in the
21252 C++ frontend will generate a less efficient heavyweight thunk that
21253 calls FUNCTION instead of jumping to it. The generic approach does
21254 not support varargs. */
21257 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21258 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21261 rtx this_rtx, insn, funexp;
21263 reload_completed = 1;
21264 epilogue_completed = 1;
21266 /* Mark the end of the (empty) prologue. */
21267 emit_note (NOTE_INSN_PROLOGUE_END);
21269 /* Find the "this" pointer. If the function returns a structure,
21270 the structure return pointer is in r3. */
21271 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21272 this_rtx = gen_rtx_REG (Pmode, 4);
21274 this_rtx = gen_rtx_REG (Pmode, 3);
21276 /* Apply the constant offset, if required. */
21278 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21280 /* Apply the offset from the vtable, if required. */
21283 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21284 rtx tmp = gen_rtx_REG (Pmode, 12);
21286 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21287 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21289 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21290 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21294 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21296 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21298 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21301 /* Generate a tail call to the target function. */
21302 if (!TREE_USED (function))
21304 assemble_external (function);
21305 TREE_USED (function) = 1;
21307 funexp = XEXP (DECL_RTL (function), 0);
21308 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21311 if (MACHOPIC_INDIRECT)
21312 funexp = machopic_indirect_call_target (funexp);
21315 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21316 generate sibcall RTL explicitly. */
21317 insn = emit_call_insn (
21318 gen_rtx_PARALLEL (VOIDmode,
21320 gen_rtx_CALL (VOIDmode,
21321 funexp, const0_rtx),
21322 gen_rtx_USE (VOIDmode, const0_rtx),
21323 gen_rtx_USE (VOIDmode,
21324 gen_rtx_REG (SImode,
21326 gen_rtx_RETURN (VOIDmode))));
21327 SIBLING_CALL_P (insn) = 1;
21330 /* Run just enough of rest_of_compilation to get the insns emitted.
21331 There's not really enough bulk here to make other passes such as
21332 instruction scheduling worth while. Note that use_thunk calls
21333 assemble_start_function and assemble_end_function. */
21334 insn = get_insns ();
21335 insn_locators_alloc ();
21336 shorten_branches (insn);
21337 final_start_function (insn, file, 1);
21338 final (insn, file, 1);
21339 final_end_function ();
21341 reload_completed = 0;
21342 epilogue_completed = 0;
21345 /* A quick summary of the various types of 'constant-pool tables'
21348 Target Flags Name One table per
21349 AIX (none) AIX TOC object file
21350 AIX -mfull-toc AIX TOC object file
21351 AIX -mminimal-toc AIX minimal TOC translation unit
21352 SVR4/EABI (none) SVR4 SDATA object file
21353 SVR4/EABI -fpic SVR4 pic object file
21354 SVR4/EABI -fPIC SVR4 PIC translation unit
21355 SVR4/EABI -mrelocatable EABI TOC function
21356 SVR4/EABI -maix AIX TOC object file
21357 SVR4/EABI -maix -mminimal-toc
21358 AIX minimal TOC translation unit
21360 Name Reg. Set by entries contains:
21361 made by addrs? fp? sum?
21363 AIX TOC 2 crt0 as Y option option
21364 AIX minimal TOC 30 prolog gcc Y Y option
21365 SVR4 SDATA 13 crt0 gcc N Y N
21366 SVR4 pic 30 prolog ld Y not yet N
21367 SVR4 PIC 30 prolog gcc Y option option
21368 EABI TOC 30 prolog gcc Y option option
21372 /* Hash functions for the hash table. */
21375 rs6000_hash_constant (rtx k)
21377 enum rtx_code code = GET_CODE (k);
21378 enum machine_mode mode = GET_MODE (k);
21379 unsigned result = (code << 3) ^ mode;
21380 const char *format;
21383 format = GET_RTX_FORMAT (code);
21384 flen = strlen (format);
21390 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21393 if (mode != VOIDmode)
21394 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21406 for (; fidx < flen; fidx++)
21407 switch (format[fidx])
21412 const char *str = XSTR (k, fidx);
21413 len = strlen (str);
21414 result = result * 613 + len;
21415 for (i = 0; i < len; i++)
21416 result = result * 613 + (unsigned) str[i];
21421 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21425 result = result * 613 + (unsigned) XINT (k, fidx);
21428 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21429 result = result * 613 + (unsigned) XWINT (k, fidx);
21433 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21434 result = result * 613 + (unsigned) (XWINT (k, fidx)
21441 gcc_unreachable ();
21448 toc_hash_function (const void *hash_entry)
21450 const struct toc_hash_struct *thc =
21451 (const struct toc_hash_struct *) hash_entry;
21452 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21455 /* Compare H1 and H2 for equivalence. */
21458 toc_hash_eq (const void *h1, const void *h2)
21460 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21461 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21463 if (((const struct toc_hash_struct *) h1)->key_mode
21464 != ((const struct toc_hash_struct *) h2)->key_mode)
21467 return rtx_equal_p (r1, r2);
21470 /* These are the names given by the C++ front-end to vtables, and
21471 vtable-like objects. Ideally, this logic should not be here;
21472 instead, there should be some programmatic way of inquiring as
21473 to whether or not an object is a vtable. */
21475 #define VTABLE_NAME_P(NAME) \
21476 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21477 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21478 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21479 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21480 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21482 #ifdef NO_DOLLAR_IN_LABEL
21483 /* Return a GGC-allocated character string translating dollar signs in
21484 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21487 rs6000_xcoff_strip_dollar (const char *name)
21492 p = strchr (name, '$');
21494 if (p == 0 || p == name)
21497 len = strlen (name);
21498 strip = (char *) alloca (len + 1);
21499 strcpy (strip, name);
21500 p = strchr (strip, '$');
21504 p = strchr (p + 1, '$');
21507 return ggc_alloc_string (strip, len);
21512 rs6000_output_symbol_ref (FILE *file, rtx x)
21514 /* Currently C++ toc references to vtables can be emitted before it
21515 is decided whether the vtable is public or private. If this is
21516 the case, then the linker will eventually complain that there is
21517 a reference to an unknown section. Thus, for vtables only,
21518 we emit the TOC reference to reference the symbol and not the
21520 const char *name = XSTR (x, 0);
21522 if (VTABLE_NAME_P (name))
21524 RS6000_OUTPUT_BASENAME (file, name);
21527 assemble_name (file, name);
21530 /* Output a TOC entry. We derive the entry name from what is being
21534 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21537 const char *name = buf;
21539 HOST_WIDE_INT offset = 0;
21541 gcc_assert (!TARGET_NO_TOC);
21543 /* When the linker won't eliminate them, don't output duplicate
21544 TOC entries (this happens on AIX if there is any kind of TOC,
21545 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21547 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21549 struct toc_hash_struct *h;
21552 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21553 time because GGC is not initialized at that point. */
21554 if (toc_hash_table == NULL)
21555 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21556 toc_hash_eq, NULL);
21558 h = ggc_alloc_toc_hash_struct ();
21560 h->key_mode = mode;
21561 h->labelno = labelno;
21563 found = htab_find_slot (toc_hash_table, h, INSERT);
21564 if (*found == NULL)
21566 else /* This is indeed a duplicate.
21567 Set this label equal to that label. */
21569 fputs ("\t.set ", file);
21570 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21571 fprintf (file, "%d,", labelno);
21572 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21573 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21579 /* If we're going to put a double constant in the TOC, make sure it's
21580 aligned properly when strict alignment is on. */
21581 if (GET_CODE (x) == CONST_DOUBLE
21582 && STRICT_ALIGNMENT
21583 && GET_MODE_BITSIZE (mode) >= 64
21584 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21585 ASM_OUTPUT_ALIGN (file, 3);
21588 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21590 /* Handle FP constants specially. Note that if we have a minimal
21591 TOC, things we put here aren't actually in the TOC, so we can allow
21593 if (GET_CODE (x) == CONST_DOUBLE &&
21594 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21596 REAL_VALUE_TYPE rv;
21599 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21600 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21601 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21603 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21607 if (TARGET_MINIMAL_TOC)
21608 fputs (DOUBLE_INT_ASM_OP, file);
21610 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21611 k[0] & 0xffffffff, k[1] & 0xffffffff,
21612 k[2] & 0xffffffff, k[3] & 0xffffffff);
21613 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21614 k[0] & 0xffffffff, k[1] & 0xffffffff,
21615 k[2] & 0xffffffff, k[3] & 0xffffffff);
21620 if (TARGET_MINIMAL_TOC)
21621 fputs ("\t.long ", file);
21623 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21624 k[0] & 0xffffffff, k[1] & 0xffffffff,
21625 k[2] & 0xffffffff, k[3] & 0xffffffff);
21626 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21627 k[0] & 0xffffffff, k[1] & 0xffffffff,
21628 k[2] & 0xffffffff, k[3] & 0xffffffff);
21632 else if (GET_CODE (x) == CONST_DOUBLE &&
21633 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21635 REAL_VALUE_TYPE rv;
21638 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21640 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21641 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21643 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21647 if (TARGET_MINIMAL_TOC)
21648 fputs (DOUBLE_INT_ASM_OP, file);
21650 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21651 k[0] & 0xffffffff, k[1] & 0xffffffff);
21652 fprintf (file, "0x%lx%08lx\n",
21653 k[0] & 0xffffffff, k[1] & 0xffffffff);
21658 if (TARGET_MINIMAL_TOC)
21659 fputs ("\t.long ", file);
21661 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21662 k[0] & 0xffffffff, k[1] & 0xffffffff);
21663 fprintf (file, "0x%lx,0x%lx\n",
21664 k[0] & 0xffffffff, k[1] & 0xffffffff);
21668 else if (GET_CODE (x) == CONST_DOUBLE &&
21669 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21671 REAL_VALUE_TYPE rv;
21674 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21675 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21676 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21678 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21682 if (TARGET_MINIMAL_TOC)
21683 fputs (DOUBLE_INT_ASM_OP, file);
21685 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21686 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21691 if (TARGET_MINIMAL_TOC)
21692 fputs ("\t.long ", file);
21694 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21695 fprintf (file, "0x%lx\n", l & 0xffffffff);
21699 else if (GET_MODE (x) == VOIDmode
21700 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21702 unsigned HOST_WIDE_INT low;
21703 HOST_WIDE_INT high;
21705 if (GET_CODE (x) == CONST_DOUBLE)
21707 low = CONST_DOUBLE_LOW (x);
21708 high = CONST_DOUBLE_HIGH (x);
21711 #if HOST_BITS_PER_WIDE_INT == 32
21714 high = (low & 0x80000000) ? ~0 : 0;
21718 low = INTVAL (x) & 0xffffffff;
21719 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21723 /* TOC entries are always Pmode-sized, but since this
21724 is a bigendian machine then if we're putting smaller
21725 integer constants in the TOC we have to pad them.
21726 (This is still a win over putting the constants in
21727 a separate constant pool, because then we'd have
21728 to have both a TOC entry _and_ the actual constant.)
21730 For a 32-bit target, CONST_INT values are loaded and shifted
21731 entirely within `low' and can be stored in one TOC entry. */
21733 /* It would be easy to make this work, but it doesn't now. */
21734 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21736 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21738 #if HOST_BITS_PER_WIDE_INT == 32
21739 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21740 POINTER_SIZE, &low, &high, 0);
21743 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21744 high = (HOST_WIDE_INT) low >> 32;
21751 if (TARGET_MINIMAL_TOC)
21752 fputs (DOUBLE_INT_ASM_OP, file);
21754 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21755 (long) high & 0xffffffff, (long) low & 0xffffffff);
21756 fprintf (file, "0x%lx%08lx\n",
21757 (long) high & 0xffffffff, (long) low & 0xffffffff);
21762 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21764 if (TARGET_MINIMAL_TOC)
21765 fputs ("\t.long ", file);
21767 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21768 (long) high & 0xffffffff, (long) low & 0xffffffff);
21769 fprintf (file, "0x%lx,0x%lx\n",
21770 (long) high & 0xffffffff, (long) low & 0xffffffff);
21774 if (TARGET_MINIMAL_TOC)
21775 fputs ("\t.long ", file);
21777 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21778 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21784 if (GET_CODE (x) == CONST)
21786 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21787 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21789 base = XEXP (XEXP (x, 0), 0);
21790 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21793 switch (GET_CODE (base))
21796 name = XSTR (base, 0);
21800 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21801 CODE_LABEL_NUMBER (XEXP (base, 0)));
21805 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21809 gcc_unreachable ();
21812 if (TARGET_MINIMAL_TOC)
21813 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21816 fputs ("\t.tc ", file);
21817 RS6000_OUTPUT_BASENAME (file, name);
21820 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21822 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21824 fputs ("[TC],", file);
21827 /* Currently C++ toc references to vtables can be emitted before it
21828 is decided whether the vtable is public or private. If this is
21829 the case, then the linker will eventually complain that there is
21830 a TOC reference to an unknown section. Thus, for vtables only,
21831 we emit the TOC reference to reference the symbol and not the
21833 if (VTABLE_NAME_P (name))
21835 RS6000_OUTPUT_BASENAME (file, name);
21837 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21838 else if (offset > 0)
21839 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21842 output_addr_const (file, x);
21846 /* Output an assembler pseudo-op to write an ASCII string of N characters
21847 starting at P to FILE.
21849 On the RS/6000, we have to do this using the .byte operation and
21850 write out special characters outside the quoted string.
21851 Also, the assembler is broken; very long strings are truncated,
21852 so we must artificially break them up early. */
21855 output_ascii (FILE *file, const char *p, int n)
21858 int i, count_string;
21859 const char *for_string = "\t.byte \"";
21860 const char *for_decimal = "\t.byte ";
21861 const char *to_close = NULL;
21864 for (i = 0; i < n; i++)
21867 if (c >= ' ' && c < 0177)
21870 fputs (for_string, file);
21873 /* Write two quotes to get one. */
21881 for_decimal = "\"\n\t.byte ";
21885 if (count_string >= 512)
21887 fputs (to_close, file);
21889 for_string = "\t.byte \"";
21890 for_decimal = "\t.byte ";
21898 fputs (for_decimal, file);
21899 fprintf (file, "%d", c);
21901 for_string = "\n\t.byte \"";
21902 for_decimal = ", ";
21908 /* Now close the string if we have written one. Then end the line. */
21910 fputs (to_close, file);
21913 /* Generate a unique section name for FILENAME for a section type
21914 represented by SECTION_DESC. Output goes into BUF.
21916 SECTION_DESC can be any string, as long as it is different for each
21917 possible section type.
21919 We name the section in the same manner as xlc. The name begins with an
21920 underscore followed by the filename (after stripping any leading directory
21921 names) with the last period replaced by the string SECTION_DESC. If
21922 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21926 rs6000_gen_section_name (char **buf, const char *filename,
21927 const char *section_desc)
21929 const char *q, *after_last_slash, *last_period = 0;
21933 after_last_slash = filename;
21934 for (q = filename; *q; q++)
21937 after_last_slash = q + 1;
21938 else if (*q == '.')
21942 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21943 *buf = (char *) xmalloc (len);
21948 for (q = after_last_slash; *q; q++)
21950 if (q == last_period)
21952 strcpy (p, section_desc);
21953 p += strlen (section_desc);
21957 else if (ISALNUM (*q))
21961 if (last_period == 0)
21962 strcpy (p, section_desc);
21967 /* Emit profile function. */
21970 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21972 /* Non-standard profiling for kernels, which just saves LR then calls
21973 _mcount without worrying about arg saves. The idea is to change
21974 the function prologue as little as possible as it isn't easy to
21975 account for arg save/restore code added just for _mcount. */
21976 if (TARGET_PROFILE_KERNEL)
21979 if (DEFAULT_ABI == ABI_AIX)
21981 #ifndef NO_PROFILE_COUNTERS
21982 # define NO_PROFILE_COUNTERS 0
21984 if (NO_PROFILE_COUNTERS)
21985 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21986 LCT_NORMAL, VOIDmode, 0);
21990 const char *label_name;
21993 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21994 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21995 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21997 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21998 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22001 else if (DEFAULT_ABI == ABI_DARWIN)
22003 const char *mcount_name = RS6000_MCOUNT;
22004 int caller_addr_regno = LR_REGNO;
22006 /* Be conservative and always set this, at least for now. */
22007 crtl->uses_pic_offset_table = 1;
22010 /* For PIC code, set up a stub and collect the caller's address
22011 from r0, which is where the prologue puts it. */
22012 if (MACHOPIC_INDIRECT
22013 && crtl->uses_pic_offset_table)
22014 caller_addr_regno = 0;
22016 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22017 LCT_NORMAL, VOIDmode, 1,
22018 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22022 /* Write function profiler code. */
22025 output_function_profiler (FILE *file, int labelno)
22029 switch (DEFAULT_ABI)
22032 gcc_unreachable ();
22037 warning (0, "no profiling of 64-bit code for this ABI");
22040 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22041 fprintf (file, "\tmflr %s\n", reg_names[0]);
22042 if (NO_PROFILE_COUNTERS)
22044 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22045 reg_names[0], reg_names[1]);
22047 else if (TARGET_SECURE_PLT && flag_pic)
22049 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22050 reg_names[0], reg_names[1]);
22051 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22052 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22053 reg_names[12], reg_names[12]);
22054 assemble_name (file, buf);
22055 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22056 assemble_name (file, buf);
22057 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22059 else if (flag_pic == 1)
22061 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22062 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22063 reg_names[0], reg_names[1]);
22064 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22065 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22066 assemble_name (file, buf);
22067 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22069 else if (flag_pic > 1)
22071 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22072 reg_names[0], reg_names[1]);
22073 /* Now, we need to get the address of the label. */
22074 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22075 assemble_name (file, buf);
22076 fputs ("-.\n1:", file);
22077 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22078 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22079 reg_names[0], reg_names[11]);
22080 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22081 reg_names[0], reg_names[0], reg_names[11]);
22085 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22086 assemble_name (file, buf);
22087 fputs ("@ha\n", file);
22088 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22089 reg_names[0], reg_names[1]);
22090 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22091 assemble_name (file, buf);
22092 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22095 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22096 fprintf (file, "\tbl %s%s\n",
22097 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22102 if (!TARGET_PROFILE_KERNEL)
22104 /* Don't do anything, done in output_profile_hook (). */
22108 gcc_assert (!TARGET_32BIT);
22110 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22111 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22113 if (cfun->static_chain_decl != NULL)
22115 asm_fprintf (file, "\tstd %s,24(%s)\n",
22116 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22117 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22118 asm_fprintf (file, "\tld %s,24(%s)\n",
22119 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22122 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22130 /* The following variable value is the last issued insn. */
22132 static rtx last_scheduled_insn;
22134 /* The following variable helps to balance issuing of load and
22135 store instructions */
22137 static int load_store_pendulum;
22139 /* Power4 load update and store update instructions are cracked into a
22140 load or store and an integer insn which are executed in the same cycle.
22141 Branches have their own dispatch slot which does not count against the
22142 GCC issue rate, but it changes the program flow so there are no other
22143 instructions to issue in this cycle. */
22146 rs6000_variable_issue_1 (rtx insn, int more)
22148 last_scheduled_insn = insn;
22149 if (GET_CODE (PATTERN (insn)) == USE
22150 || GET_CODE (PATTERN (insn)) == CLOBBER)
22152 cached_can_issue_more = more;
22153 return cached_can_issue_more;
22156 if (insn_terminates_group_p (insn, current_group))
22158 cached_can_issue_more = 0;
22159 return cached_can_issue_more;
22162 /* If no reservation, but reach here */
22163 if (recog_memoized (insn) < 0)
22166 if (rs6000_sched_groups)
22168 if (is_microcoded_insn (insn))
22169 cached_can_issue_more = 0;
22170 else if (is_cracked_insn (insn))
22171 cached_can_issue_more = more > 2 ? more - 2 : 0;
22173 cached_can_issue_more = more - 1;
22175 return cached_can_issue_more;
22178 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22181 cached_can_issue_more = more - 1;
22182 return cached_can_issue_more;
22186 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22188 int r = rs6000_variable_issue_1 (insn, more);
22190 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22194 /* Adjust the cost of a scheduling dependency. Return the new cost of
22195 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22198 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22200 enum attr_type attr_type;
22202 if (! recog_memoized (insn))
22205 switch (REG_NOTE_KIND (link))
22209 /* Data dependency; DEP_INSN writes a register that INSN reads
22210 some cycles later. */
22212 /* Separate a load from a narrower, dependent store. */
22213 if (rs6000_sched_groups
22214 && GET_CODE (PATTERN (insn)) == SET
22215 && GET_CODE (PATTERN (dep_insn)) == SET
22216 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22217 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22218 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22219 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22222 attr_type = get_attr_type (insn);
22227 /* Tell the first scheduling pass about the latency between
22228 a mtctr and bctr (and mtlr and br/blr). The first
22229 scheduling pass will not know about this latency since
22230 the mtctr instruction, which has the latency associated
22231 to it, will be generated by reload. */
22232 return TARGET_POWER ? 5 : 4;
22234 /* Leave some extra cycles between a compare and its
22235 dependent branch, to inhibit expensive mispredicts. */
22236 if ((rs6000_cpu_attr == CPU_PPC603
22237 || rs6000_cpu_attr == CPU_PPC604
22238 || rs6000_cpu_attr == CPU_PPC604E
22239 || rs6000_cpu_attr == CPU_PPC620
22240 || rs6000_cpu_attr == CPU_PPC630
22241 || rs6000_cpu_attr == CPU_PPC750
22242 || rs6000_cpu_attr == CPU_PPC7400
22243 || rs6000_cpu_attr == CPU_PPC7450
22244 || rs6000_cpu_attr == CPU_POWER4
22245 || rs6000_cpu_attr == CPU_POWER5
22246 || rs6000_cpu_attr == CPU_POWER7
22247 || rs6000_cpu_attr == CPU_CELL)
22248 && recog_memoized (dep_insn)
22249 && (INSN_CODE (dep_insn) >= 0))
22251 switch (get_attr_type (dep_insn))
22255 case TYPE_DELAYED_COMPARE:
22256 case TYPE_IMUL_COMPARE:
22257 case TYPE_LMUL_COMPARE:
22258 case TYPE_FPCOMPARE:
22259 case TYPE_CR_LOGICAL:
22260 case TYPE_DELAYED_CR:
22269 case TYPE_STORE_UX:
22271 case TYPE_FPSTORE_U:
22272 case TYPE_FPSTORE_UX:
22273 if ((rs6000_cpu == PROCESSOR_POWER6)
22274 && recog_memoized (dep_insn)
22275 && (INSN_CODE (dep_insn) >= 0))
22278 if (GET_CODE (PATTERN (insn)) != SET)
22279 /* If this happens, we have to extend this to schedule
22280 optimally. Return default for now. */
22283 /* Adjust the cost for the case where the value written
22284 by a fixed point operation is used as the address
22285 gen value on a store. */
22286 switch (get_attr_type (dep_insn))
22293 if (! store_data_bypass_p (dep_insn, insn))
22297 case TYPE_LOAD_EXT:
22298 case TYPE_LOAD_EXT_U:
22299 case TYPE_LOAD_EXT_UX:
22300 case TYPE_VAR_SHIFT_ROTATE:
22301 case TYPE_VAR_DELAYED_COMPARE:
22303 if (! store_data_bypass_p (dep_insn, insn))
22309 case TYPE_FAST_COMPARE:
22312 case TYPE_INSERT_WORD:
22313 case TYPE_INSERT_DWORD:
22314 case TYPE_FPLOAD_U:
22315 case TYPE_FPLOAD_UX:
22317 case TYPE_STORE_UX:
22318 case TYPE_FPSTORE_U:
22319 case TYPE_FPSTORE_UX:
22321 if (! store_data_bypass_p (dep_insn, insn))
22329 case TYPE_IMUL_COMPARE:
22330 case TYPE_LMUL_COMPARE:
22332 if (! store_data_bypass_p (dep_insn, insn))
22338 if (! store_data_bypass_p (dep_insn, insn))
22344 if (! store_data_bypass_p (dep_insn, insn))
22357 case TYPE_LOAD_EXT:
22358 case TYPE_LOAD_EXT_U:
22359 case TYPE_LOAD_EXT_UX:
22360 if ((rs6000_cpu == PROCESSOR_POWER6)
22361 && recog_memoized (dep_insn)
22362 && (INSN_CODE (dep_insn) >= 0))
22365 /* Adjust the cost for the case where the value written
22366 by a fixed point instruction is used within the address
22367 gen portion of a subsequent load(u)(x) */
22368 switch (get_attr_type (dep_insn))
22375 if (set_to_load_agen (dep_insn, insn))
22379 case TYPE_LOAD_EXT:
22380 case TYPE_LOAD_EXT_U:
22381 case TYPE_LOAD_EXT_UX:
22382 case TYPE_VAR_SHIFT_ROTATE:
22383 case TYPE_VAR_DELAYED_COMPARE:
22385 if (set_to_load_agen (dep_insn, insn))
22391 case TYPE_FAST_COMPARE:
22394 case TYPE_INSERT_WORD:
22395 case TYPE_INSERT_DWORD:
22396 case TYPE_FPLOAD_U:
22397 case TYPE_FPLOAD_UX:
22399 case TYPE_STORE_UX:
22400 case TYPE_FPSTORE_U:
22401 case TYPE_FPSTORE_UX:
22403 if (set_to_load_agen (dep_insn, insn))
22411 case TYPE_IMUL_COMPARE:
22412 case TYPE_LMUL_COMPARE:
22414 if (set_to_load_agen (dep_insn, insn))
22420 if (set_to_load_agen (dep_insn, insn))
22426 if (set_to_load_agen (dep_insn, insn))
22437 if ((rs6000_cpu == PROCESSOR_POWER6)
22438 && recog_memoized (dep_insn)
22439 && (INSN_CODE (dep_insn) >= 0)
22440 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22447 /* Fall out to return default cost. */
22451 case REG_DEP_OUTPUT:
22452 /* Output dependency; DEP_INSN writes a register that INSN writes some
22454 if ((rs6000_cpu == PROCESSOR_POWER6)
22455 && recog_memoized (dep_insn)
22456 && (INSN_CODE (dep_insn) >= 0))
22458 attr_type = get_attr_type (insn);
22463 if (get_attr_type (dep_insn) == TYPE_FP)
22467 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22475 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22480 gcc_unreachable ();
22486 /* Debug version of rs6000_adjust_cost. */
22489 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22491 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22497 switch (REG_NOTE_KIND (link))
22499 default: dep = "unknown depencency"; break;
22500 case REG_DEP_TRUE: dep = "data dependency"; break;
22501 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22502 case REG_DEP_ANTI: dep = "anti depencency"; break;
22506 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22507 "%s, insn:\n", ret, cost, dep);
22515 /* The function returns a true if INSN is microcoded.
22516 Return false otherwise. */
22519 is_microcoded_insn (rtx insn)
22521 if (!insn || !NONDEBUG_INSN_P (insn)
22522 || GET_CODE (PATTERN (insn)) == USE
22523 || GET_CODE (PATTERN (insn)) == CLOBBER)
22526 if (rs6000_cpu_attr == CPU_CELL)
22527 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22529 if (rs6000_sched_groups)
22531 enum attr_type type = get_attr_type (insn);
22532 if (type == TYPE_LOAD_EXT_U
22533 || type == TYPE_LOAD_EXT_UX
22534 || type == TYPE_LOAD_UX
22535 || type == TYPE_STORE_UX
22536 || type == TYPE_MFCR)
22543 /* The function returns true if INSN is cracked into 2 instructions
22544 by the processor (and therefore occupies 2 issue slots). */
22547 is_cracked_insn (rtx insn)
22549 if (!insn || !NONDEBUG_INSN_P (insn)
22550 || GET_CODE (PATTERN (insn)) == USE
22551 || GET_CODE (PATTERN (insn)) == CLOBBER)
22554 if (rs6000_sched_groups)
22556 enum attr_type type = get_attr_type (insn);
22557 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22558 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22559 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22560 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22561 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22562 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22563 || type == TYPE_IDIV || type == TYPE_LDIV
22564 || type == TYPE_INSERT_WORD)
22571 /* The function returns true if INSN can be issued only from
22572 the branch slot. */
22575 is_branch_slot_insn (rtx insn)
22577 if (!insn || !NONDEBUG_INSN_P (insn)
22578 || GET_CODE (PATTERN (insn)) == USE
22579 || GET_CODE (PATTERN (insn)) == CLOBBER)
22582 if (rs6000_sched_groups)
22584 enum attr_type type = get_attr_type (insn);
22585 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22593 /* The function returns true if out_inst sets a value that is
22594 used in the address generation computation of in_insn */
22596 set_to_load_agen (rtx out_insn, rtx in_insn)
22598 rtx out_set, in_set;
22600 /* For performance reasons, only handle the simple case where
22601 both loads are a single_set. */
22602 out_set = single_set (out_insn);
22605 in_set = single_set (in_insn);
22607 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22613 /* The function returns true if the target storage location of
22614 out_insn is adjacent to the target storage location of in_insn */
22615 /* Return 1 if memory locations are adjacent. */
22618 adjacent_mem_locations (rtx insn1, rtx insn2)
22621 rtx a = get_store_dest (PATTERN (insn1));
22622 rtx b = get_store_dest (PATTERN (insn2));
22624 if ((GET_CODE (XEXP (a, 0)) == REG
22625 || (GET_CODE (XEXP (a, 0)) == PLUS
22626 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22627 && (GET_CODE (XEXP (b, 0)) == REG
22628 || (GET_CODE (XEXP (b, 0)) == PLUS
22629 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22631 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22634 if (GET_CODE (XEXP (a, 0)) == PLUS)
22636 reg0 = XEXP (XEXP (a, 0), 0);
22637 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22640 reg0 = XEXP (a, 0);
22642 if (GET_CODE (XEXP (b, 0)) == PLUS)
22644 reg1 = XEXP (XEXP (b, 0), 0);
22645 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22648 reg1 = XEXP (b, 0);
22650 val_diff = val1 - val0;
22652 return ((REGNO (reg0) == REGNO (reg1))
22653 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22654 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22660 /* A C statement (sans semicolon) to update the integer scheduling
22661 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22662 INSN earlier, reduce the priority to execute INSN later. Do not
22663 define this macro if you do not need to adjust the scheduling
22664 priorities of insns. */
22667 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22669 /* On machines (like the 750) which have asymmetric integer units,
22670 where one integer unit can do multiply and divides and the other
22671 can't, reduce the priority of multiply/divide so it is scheduled
22672 before other integer operations. */
22675 if (! INSN_P (insn))
22678 if (GET_CODE (PATTERN (insn)) == USE)
22681 switch (rs6000_cpu_attr) {
22683 switch (get_attr_type (insn))
22690 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22691 priority, priority);
22692 if (priority >= 0 && priority < 0x01000000)
22699 if (insn_must_be_first_in_group (insn)
22700 && reload_completed
22701 && current_sched_info->sched_max_insns_priority
22702 && rs6000_sched_restricted_insns_priority)
22705 /* Prioritize insns that can be dispatched only in the first
22707 if (rs6000_sched_restricted_insns_priority == 1)
22708 /* Attach highest priority to insn. This means that in
22709 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22710 precede 'priority' (critical path) considerations. */
22711 return current_sched_info->sched_max_insns_priority;
22712 else if (rs6000_sched_restricted_insns_priority == 2)
22713 /* Increase priority of insn by a minimal amount. This means that in
22714 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22715 considerations precede dispatch-slot restriction considerations. */
22716 return (priority + 1);
22719 if (rs6000_cpu == PROCESSOR_POWER6
22720 && ((load_store_pendulum == -2 && is_load_insn (insn))
22721 || (load_store_pendulum == 2 && is_store_insn (insn))))
22722 /* Attach highest priority to insn if the scheduler has just issued two
22723 stores and this instruction is a load, or two loads and this instruction
22724 is a store. Power6 wants loads and stores scheduled alternately
22726 return current_sched_info->sched_max_insns_priority;
22731 /* Return true if the instruction is nonpipelined on the Cell. */
22733 is_nonpipeline_insn (rtx insn)
22735 enum attr_type type;
22736 if (!insn || !NONDEBUG_INSN_P (insn)
22737 || GET_CODE (PATTERN (insn)) == USE
22738 || GET_CODE (PATTERN (insn)) == CLOBBER)
22741 type = get_attr_type (insn);
22742 if (type == TYPE_IMUL
22743 || type == TYPE_IMUL2
22744 || type == TYPE_IMUL3
22745 || type == TYPE_LMUL
22746 || type == TYPE_IDIV
22747 || type == TYPE_LDIV
22748 || type == TYPE_SDIV
22749 || type == TYPE_DDIV
22750 || type == TYPE_SSQRT
22751 || type == TYPE_DSQRT
22752 || type == TYPE_MFCR
22753 || type == TYPE_MFCRF
22754 || type == TYPE_MFJMPR)
22762 /* Return how many instructions the machine can issue per cycle. */
22765 rs6000_issue_rate (void)
22767 /* Unless scheduling for register pressure, use issue rate of 1 for
22768 first scheduling pass to decrease degradation. */
22769 if (!reload_completed && !flag_sched_pressure)
22772 switch (rs6000_cpu_attr) {
22773 case CPU_RIOS1: /* ? */
22775 case CPU_PPC601: /* ? */
22784 case CPU_PPCE300C2:
22785 case CPU_PPCE300C3:
22786 case CPU_PPCE500MC:
22787 case CPU_PPCE500MC64:
22807 /* Return how many instructions to look ahead for better insn
22811 rs6000_use_sched_lookahead (void)
22813 if (rs6000_cpu_attr == CPU_PPC8540)
22815 if (rs6000_cpu_attr == CPU_CELL)
22816 return (reload_completed ? 8 : 0);
22820 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22822 rs6000_use_sched_lookahead_guard (rtx insn)
22824 if (rs6000_cpu_attr != CPU_CELL)
22827 if (insn == NULL_RTX || !INSN_P (insn))
22830 if (!reload_completed
22831 || is_nonpipeline_insn (insn)
22832 || is_microcoded_insn (insn))
22838 /* Determine is PAT refers to memory. */
22841 is_mem_ref (rtx pat)
22847 /* stack_tie does not produce any real memory traffic. */
22848 if (GET_CODE (pat) == UNSPEC
22849 && XINT (pat, 1) == UNSPEC_TIE)
22852 if (GET_CODE (pat) == MEM)
22855 /* Recursively process the pattern. */
22856 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22858 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22861 ret |= is_mem_ref (XEXP (pat, i));
22862 else if (fmt[i] == 'E')
22863 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22864 ret |= is_mem_ref (XVECEXP (pat, i, j));
22870 /* Determine if PAT is a PATTERN of a load insn. */
22873 is_load_insn1 (rtx pat)
22875 if (!pat || pat == NULL_RTX)
22878 if (GET_CODE (pat) == SET)
22879 return is_mem_ref (SET_SRC (pat));
22881 if (GET_CODE (pat) == PARALLEL)
22885 for (i = 0; i < XVECLEN (pat, 0); i++)
22886 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22893 /* Determine if INSN loads from memory. */
22896 is_load_insn (rtx insn)
22898 if (!insn || !INSN_P (insn))
22901 if (GET_CODE (insn) == CALL_INSN)
22904 return is_load_insn1 (PATTERN (insn));
22907 /* Determine if PAT is a PATTERN of a store insn. */
22910 is_store_insn1 (rtx pat)
22912 if (!pat || pat == NULL_RTX)
22915 if (GET_CODE (pat) == SET)
22916 return is_mem_ref (SET_DEST (pat));
22918 if (GET_CODE (pat) == PARALLEL)
22922 for (i = 0; i < XVECLEN (pat, 0); i++)
22923 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22930 /* Determine if INSN stores to memory. */
22933 is_store_insn (rtx insn)
22935 if (!insn || !INSN_P (insn))
22938 return is_store_insn1 (PATTERN (insn));
22941 /* Return the dest of a store insn. */
22944 get_store_dest (rtx pat)
22946 gcc_assert (is_store_insn1 (pat));
22948 if (GET_CODE (pat) == SET)
22949 return SET_DEST (pat);
22950 else if (GET_CODE (pat) == PARALLEL)
22954 for (i = 0; i < XVECLEN (pat, 0); i++)
22956 rtx inner_pat = XVECEXP (pat, 0, i);
22957 if (GET_CODE (inner_pat) == SET
22958 && is_mem_ref (SET_DEST (inner_pat)))
22962 /* We shouldn't get here, because we should have either a simple
22963 store insn or a store with update which are covered above. */
22967 /* Returns whether the dependence between INSN and NEXT is considered
22968 costly by the given target. */
22971 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22976 /* If the flag is not enabled - no dependence is considered costly;
22977 allow all dependent insns in the same group.
22978 This is the most aggressive option. */
22979 if (rs6000_sched_costly_dep == no_dep_costly)
22982 /* If the flag is set to 1 - a dependence is always considered costly;
22983 do not allow dependent instructions in the same group.
22984 This is the most conservative option. */
22985 if (rs6000_sched_costly_dep == all_deps_costly)
22988 insn = DEP_PRO (dep);
22989 next = DEP_CON (dep);
22991 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22992 && is_load_insn (next)
22993 && is_store_insn (insn))
22994 /* Prevent load after store in the same group. */
22997 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22998 && is_load_insn (next)
22999 && is_store_insn (insn)
23000 && DEP_TYPE (dep) == REG_DEP_TRUE)
23001 /* Prevent load after store in the same group if it is a true
23005 /* The flag is set to X; dependences with latency >= X are considered costly,
23006 and will not be scheduled in the same group. */
23007 if (rs6000_sched_costly_dep <= max_dep_latency
23008 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23014 /* Return the next insn after INSN that is found before TAIL is reached,
23015 skipping any "non-active" insns - insns that will not actually occupy
23016 an issue slot. Return NULL_RTX if such an insn is not found. */
23019 get_next_active_insn (rtx insn, rtx tail)
23021 if (insn == NULL_RTX || insn == tail)
23026 insn = NEXT_INSN (insn);
23027 if (insn == NULL_RTX || insn == tail)
23032 || (NONJUMP_INSN_P (insn)
23033 && GET_CODE (PATTERN (insn)) != USE
23034 && GET_CODE (PATTERN (insn)) != CLOBBER
23035 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23041 /* We are about to begin issuing insns for this clock cycle. */
23044 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23045 rtx *ready ATTRIBUTE_UNUSED,
23046 int *pn_ready ATTRIBUTE_UNUSED,
23047 int clock_var ATTRIBUTE_UNUSED)
23049 int n_ready = *pn_ready;
23052 fprintf (dump, "// rs6000_sched_reorder :\n");
23054 /* Reorder the ready list, if the second to last ready insn
23055 is a nonepipeline insn. */
23056 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23058 if (is_nonpipeline_insn (ready[n_ready - 1])
23059 && (recog_memoized (ready[n_ready - 2]) > 0))
23060 /* Simply swap first two insns. */
23062 rtx tmp = ready[n_ready - 1];
23063 ready[n_ready - 1] = ready[n_ready - 2];
23064 ready[n_ready - 2] = tmp;
23068 if (rs6000_cpu == PROCESSOR_POWER6)
23069 load_store_pendulum = 0;
23071 return rs6000_issue_rate ();
23074 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23077 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23078 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23081 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23083 /* For Power6, we need to handle some special cases to try and keep the
23084 store queue from overflowing and triggering expensive flushes.
23086 This code monitors how load and store instructions are being issued
23087 and skews the ready list one way or the other to increase the likelihood
23088 that a desired instruction is issued at the proper time.
23090 A couple of things are done. First, we maintain a "load_store_pendulum"
23091 to track the current state of load/store issue.
23093 - If the pendulum is at zero, then no loads or stores have been
23094 issued in the current cycle so we do nothing.
23096 - If the pendulum is 1, then a single load has been issued in this
23097 cycle and we attempt to locate another load in the ready list to
23100 - If the pendulum is -2, then two stores have already been
23101 issued in this cycle, so we increase the priority of the first load
23102 in the ready list to increase it's likelihood of being chosen first
23105 - If the pendulum is -1, then a single store has been issued in this
23106 cycle and we attempt to locate another store in the ready list to
23107 issue with it, preferring a store to an adjacent memory location to
23108 facilitate store pairing in the store queue.
23110 - If the pendulum is 2, then two loads have already been
23111 issued in this cycle, so we increase the priority of the first store
23112 in the ready list to increase it's likelihood of being chosen first
23115 - If the pendulum < -2 or > 2, then do nothing.
23117 Note: This code covers the most common scenarios. There exist non
23118 load/store instructions which make use of the LSU and which
23119 would need to be accounted for to strictly model the behavior
23120 of the machine. Those instructions are currently unaccounted
23121 for to help minimize compile time overhead of this code.
23123 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23129 if (is_store_insn (last_scheduled_insn))
23130 /* Issuing a store, swing the load_store_pendulum to the left */
23131 load_store_pendulum--;
23132 else if (is_load_insn (last_scheduled_insn))
23133 /* Issuing a load, swing the load_store_pendulum to the right */
23134 load_store_pendulum++;
23136 return cached_can_issue_more;
23138 /* If the pendulum is balanced, or there is only one instruction on
23139 the ready list, then all is well, so return. */
23140 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23141 return cached_can_issue_more;
23143 if (load_store_pendulum == 1)
23145 /* A load has been issued in this cycle. Scan the ready list
23146 for another load to issue with it */
23151 if (is_load_insn (ready[pos]))
23153 /* Found a load. Move it to the head of the ready list,
23154 and adjust it's priority so that it is more likely to
23157 for (i=pos; i<*pn_ready-1; i++)
23158 ready[i] = ready[i + 1];
23159 ready[*pn_ready-1] = tmp;
23161 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23162 INSN_PRIORITY (tmp)++;
23168 else if (load_store_pendulum == -2)
23170 /* Two stores have been issued in this cycle. Increase the
23171 priority of the first load in the ready list to favor it for
23172 issuing in the next cycle. */
23177 if (is_load_insn (ready[pos])
23179 && INSN_PRIORITY_KNOWN (ready[pos]))
23181 INSN_PRIORITY (ready[pos])++;
23183 /* Adjust the pendulum to account for the fact that a load
23184 was found and increased in priority. This is to prevent
23185 increasing the priority of multiple loads */
23186 load_store_pendulum--;
23193 else if (load_store_pendulum == -1)
23195 /* A store has been issued in this cycle. Scan the ready list for
23196 another store to issue with it, preferring a store to an adjacent
23198 int first_store_pos = -1;
23204 if (is_store_insn (ready[pos]))
23206 /* Maintain the index of the first store found on the
23208 if (first_store_pos == -1)
23209 first_store_pos = pos;
23211 if (is_store_insn (last_scheduled_insn)
23212 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23214 /* Found an adjacent store. Move it to the head of the
23215 ready list, and adjust it's priority so that it is
23216 more likely to stay there */
23218 for (i=pos; i<*pn_ready-1; i++)
23219 ready[i] = ready[i + 1];
23220 ready[*pn_ready-1] = tmp;
23222 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23223 INSN_PRIORITY (tmp)++;
23225 first_store_pos = -1;
23233 if (first_store_pos >= 0)
23235 /* An adjacent store wasn't found, but a non-adjacent store was,
23236 so move the non-adjacent store to the front of the ready
23237 list, and adjust its priority so that it is more likely to
23239 tmp = ready[first_store_pos];
23240 for (i=first_store_pos; i<*pn_ready-1; i++)
23241 ready[i] = ready[i + 1];
23242 ready[*pn_ready-1] = tmp;
23243 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23244 INSN_PRIORITY (tmp)++;
23247 else if (load_store_pendulum == 2)
23249 /* Two loads have been issued in this cycle. Increase the priority
23250 of the first store in the ready list to favor it for issuing in
23256 if (is_store_insn (ready[pos])
23258 && INSN_PRIORITY_KNOWN (ready[pos]))
23260 INSN_PRIORITY (ready[pos])++;
23262 /* Adjust the pendulum to account for the fact that a store
23263 was found and increased in priority. This is to prevent
23264 increasing the priority of multiple stores */
23265 load_store_pendulum++;
23274 return cached_can_issue_more;
23277 /* Return whether the presence of INSN causes a dispatch group termination
23278 of group WHICH_GROUP.
23280 If WHICH_GROUP == current_group, this function will return true if INSN
23281 causes the termination of the current group (i.e, the dispatch group to
23282 which INSN belongs). This means that INSN will be the last insn in the
23283 group it belongs to.
23285 If WHICH_GROUP == previous_group, this function will return true if INSN
23286 causes the termination of the previous group (i.e, the dispatch group that
23287 precedes the group to which INSN belongs). This means that INSN will be
23288 the first insn in the group it belongs to). */
23291 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23298 first = insn_must_be_first_in_group (insn);
23299 last = insn_must_be_last_in_group (insn);
23304 if (which_group == current_group)
23306 else if (which_group == previous_group)
23314 insn_must_be_first_in_group (rtx insn)
23316 enum attr_type type;
23319 || GET_CODE (insn) == NOTE
23320 || DEBUG_INSN_P (insn)
23321 || GET_CODE (PATTERN (insn)) == USE
23322 || GET_CODE (PATTERN (insn)) == CLOBBER)
23325 switch (rs6000_cpu)
23327 case PROCESSOR_POWER5:
23328 if (is_cracked_insn (insn))
23330 case PROCESSOR_POWER4:
23331 if (is_microcoded_insn (insn))
23334 if (!rs6000_sched_groups)
23337 type = get_attr_type (insn);
23344 case TYPE_DELAYED_CR:
23345 case TYPE_CR_LOGICAL:
23359 case PROCESSOR_POWER6:
23360 type = get_attr_type (insn);
23364 case TYPE_INSERT_DWORD:
23368 case TYPE_VAR_SHIFT_ROTATE:
23375 case TYPE_INSERT_WORD:
23376 case TYPE_DELAYED_COMPARE:
23377 case TYPE_IMUL_COMPARE:
23378 case TYPE_LMUL_COMPARE:
23379 case TYPE_FPCOMPARE:
23390 case TYPE_LOAD_EXT_UX:
23392 case TYPE_STORE_UX:
23393 case TYPE_FPLOAD_U:
23394 case TYPE_FPLOAD_UX:
23395 case TYPE_FPSTORE_U:
23396 case TYPE_FPSTORE_UX:
23402 case PROCESSOR_POWER7:
23403 type = get_attr_type (insn);
23407 case TYPE_CR_LOGICAL:
23414 case TYPE_DELAYED_COMPARE:
23415 case TYPE_VAR_DELAYED_COMPARE:
23421 case TYPE_LOAD_EXT:
23422 case TYPE_LOAD_EXT_U:
23423 case TYPE_LOAD_EXT_UX:
23425 case TYPE_STORE_UX:
23426 case TYPE_FPLOAD_U:
23427 case TYPE_FPLOAD_UX:
23428 case TYPE_FPSTORE_U:
23429 case TYPE_FPSTORE_UX:
23445 insn_must_be_last_in_group (rtx insn)
23447 enum attr_type type;
23450 || GET_CODE (insn) == NOTE
23451 || DEBUG_INSN_P (insn)
23452 || GET_CODE (PATTERN (insn)) == USE
23453 || GET_CODE (PATTERN (insn)) == CLOBBER)
23456 switch (rs6000_cpu) {
23457 case PROCESSOR_POWER4:
23458 case PROCESSOR_POWER5:
23459 if (is_microcoded_insn (insn))
23462 if (is_branch_slot_insn (insn))
23466 case PROCESSOR_POWER6:
23467 type = get_attr_type (insn);
23474 case TYPE_VAR_SHIFT_ROTATE:
23481 case TYPE_DELAYED_COMPARE:
23482 case TYPE_IMUL_COMPARE:
23483 case TYPE_LMUL_COMPARE:
23484 case TYPE_FPCOMPARE:
23498 case PROCESSOR_POWER7:
23499 type = get_attr_type (insn);
23507 case TYPE_LOAD_EXT_U:
23508 case TYPE_LOAD_EXT_UX:
23509 case TYPE_STORE_UX:
23522 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23523 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23526 is_costly_group (rtx *group_insns, rtx next_insn)
23529 int issue_rate = rs6000_issue_rate ();
23531 for (i = 0; i < issue_rate; i++)
23533 sd_iterator_def sd_it;
23535 rtx insn = group_insns[i];
23540 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23542 rtx next = DEP_CON (dep);
23544 if (next == next_insn
23545 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23553 /* Utility of the function redefine_groups.
23554 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23555 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23556 to keep it "far" (in a separate group) from GROUP_INSNS, following
23557 one of the following schemes, depending on the value of the flag
23558 -minsert_sched_nops = X:
23559 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23560 in order to force NEXT_INSN into a separate group.
23561 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23562 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23563 insertion (has a group just ended, how many vacant issue slots remain in the
23564 last group, and how many dispatch groups were encountered so far). */
23567 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23568 rtx next_insn, bool *group_end, int can_issue_more,
23573 int issue_rate = rs6000_issue_rate ();
23574 bool end = *group_end;
23577 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23578 return can_issue_more;
23580 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23581 return can_issue_more;
23583 force = is_costly_group (group_insns, next_insn);
23585 return can_issue_more;
23587 if (sched_verbose > 6)
23588 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23589 *group_count ,can_issue_more);
23591 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23594 can_issue_more = 0;
23596 /* Since only a branch can be issued in the last issue_slot, it is
23597 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23598 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23599 in this case the last nop will start a new group and the branch
23600 will be forced to the new group. */
23601 if (can_issue_more && !is_branch_slot_insn (next_insn))
23604 while (can_issue_more > 0)
23607 emit_insn_before (nop, next_insn);
23615 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23617 int n_nops = rs6000_sched_insert_nops;
23619 /* Nops can't be issued from the branch slot, so the effective
23620 issue_rate for nops is 'issue_rate - 1'. */
23621 if (can_issue_more == 0)
23622 can_issue_more = issue_rate;
23624 if (can_issue_more == 0)
23626 can_issue_more = issue_rate - 1;
23629 for (i = 0; i < issue_rate; i++)
23631 group_insns[i] = 0;
23638 emit_insn_before (nop, next_insn);
23639 if (can_issue_more == issue_rate - 1) /* new group begins */
23642 if (can_issue_more == 0)
23644 can_issue_more = issue_rate - 1;
23647 for (i = 0; i < issue_rate; i++)
23649 group_insns[i] = 0;
23655 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23658 /* Is next_insn going to start a new group? */
23661 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23662 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23663 || (can_issue_more < issue_rate &&
23664 insn_terminates_group_p (next_insn, previous_group)));
23665 if (*group_end && end)
23668 if (sched_verbose > 6)
23669 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23670 *group_count, can_issue_more);
23671 return can_issue_more;
23674 return can_issue_more;
23677 /* This function tries to synch the dispatch groups that the compiler "sees"
23678 with the dispatch groups that the processor dispatcher is expected to
23679 form in practice. It tries to achieve this synchronization by forcing the
23680 estimated processor grouping on the compiler (as opposed to the function
23681 'pad_goups' which tries to force the scheduler's grouping on the processor).
23683 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23684 examines the (estimated) dispatch groups that will be formed by the processor
23685 dispatcher. It marks these group boundaries to reflect the estimated
23686 processor grouping, overriding the grouping that the scheduler had marked.
23687 Depending on the value of the flag '-minsert-sched-nops' this function can
23688 force certain insns into separate groups or force a certain distance between
23689 them by inserting nops, for example, if there exists a "costly dependence"
23692 The function estimates the group boundaries that the processor will form as
23693 follows: It keeps track of how many vacant issue slots are available after
23694 each insn. A subsequent insn will start a new group if one of the following
23696 - no more vacant issue slots remain in the current dispatch group.
23697 - only the last issue slot, which is the branch slot, is vacant, but the next
23698 insn is not a branch.
23699 - only the last 2 or less issue slots, including the branch slot, are vacant,
23700 which means that a cracked insn (which occupies two issue slots) can't be
23701 issued in this group.
23702 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23703 start a new group. */
23706 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23708 rtx insn, next_insn;
23710 int can_issue_more;
23713 int group_count = 0;
23717 issue_rate = rs6000_issue_rate ();
23718 group_insns = XALLOCAVEC (rtx, issue_rate);
23719 for (i = 0; i < issue_rate; i++)
23721 group_insns[i] = 0;
23723 can_issue_more = issue_rate;
23725 insn = get_next_active_insn (prev_head_insn, tail);
23728 while (insn != NULL_RTX)
23730 slot = (issue_rate - can_issue_more);
23731 group_insns[slot] = insn;
23733 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23734 if (insn_terminates_group_p (insn, current_group))
23735 can_issue_more = 0;
23737 next_insn = get_next_active_insn (insn, tail);
23738 if (next_insn == NULL_RTX)
23739 return group_count + 1;
23741 /* Is next_insn going to start a new group? */
23743 = (can_issue_more == 0
23744 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23745 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23746 || (can_issue_more < issue_rate &&
23747 insn_terminates_group_p (next_insn, previous_group)));
23749 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23750 next_insn, &group_end, can_issue_more,
23756 can_issue_more = 0;
23757 for (i = 0; i < issue_rate; i++)
23759 group_insns[i] = 0;
23763 if (GET_MODE (next_insn) == TImode && can_issue_more)
23764 PUT_MODE (next_insn, VOIDmode);
23765 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23766 PUT_MODE (next_insn, TImode);
23769 if (can_issue_more == 0)
23770 can_issue_more = issue_rate;
23773 return group_count;
23776 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23777 dispatch group boundaries that the scheduler had marked. Pad with nops
23778 any dispatch groups which have vacant issue slots, in order to force the
23779 scheduler's grouping on the processor dispatcher. The function
23780 returns the number of dispatch groups found. */
23783 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23785 rtx insn, next_insn;
23788 int can_issue_more;
23790 int group_count = 0;
23792 /* Initialize issue_rate. */
23793 issue_rate = rs6000_issue_rate ();
23794 can_issue_more = issue_rate;
23796 insn = get_next_active_insn (prev_head_insn, tail);
23797 next_insn = get_next_active_insn (insn, tail);
23799 while (insn != NULL_RTX)
23802 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23804 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23806 if (next_insn == NULL_RTX)
23811 /* If the scheduler had marked group termination at this location
23812 (between insn and next_insn), and neither insn nor next_insn will
23813 force group termination, pad the group with nops to force group
23816 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23817 && !insn_terminates_group_p (insn, current_group)
23818 && !insn_terminates_group_p (next_insn, previous_group))
23820 if (!is_branch_slot_insn (next_insn))
23823 while (can_issue_more)
23826 emit_insn_before (nop, next_insn);
23831 can_issue_more = issue_rate;
23836 next_insn = get_next_active_insn (insn, tail);
23839 return group_count;
23842 /* We're beginning a new block. Initialize data structures as necessary. */
23845 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23846 int sched_verbose ATTRIBUTE_UNUSED,
23847 int max_ready ATTRIBUTE_UNUSED)
23849 last_scheduled_insn = NULL_RTX;
23850 load_store_pendulum = 0;
23853 /* The following function is called at the end of scheduling BB.
23854 After reload, it inserts nops at insn group bundling. */
23857 rs6000_sched_finish (FILE *dump, int sched_verbose)
23862 fprintf (dump, "=== Finishing schedule.\n");
23864 if (reload_completed && rs6000_sched_groups)
23866 /* Do not run sched_finish hook when selective scheduling enabled. */
23867 if (sel_sched_p ())
23870 if (rs6000_sched_insert_nops == sched_finish_none)
23873 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23874 n_groups = pad_groups (dump, sched_verbose,
23875 current_sched_info->prev_head,
23876 current_sched_info->next_tail);
23878 n_groups = redefine_groups (dump, sched_verbose,
23879 current_sched_info->prev_head,
23880 current_sched_info->next_tail);
23882 if (sched_verbose >= 6)
23884 fprintf (dump, "ngroups = %d\n", n_groups);
23885 print_rtl (dump, current_sched_info->prev_head);
23886 fprintf (dump, "Done finish_sched\n");
23891 struct _rs6000_sched_context
23893 short cached_can_issue_more;
23894 rtx last_scheduled_insn;
23895 int load_store_pendulum;
23898 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23899 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23901 /* Allocate store for new scheduling context. */
23903 rs6000_alloc_sched_context (void)
23905 return xmalloc (sizeof (rs6000_sched_context_def));
23908 /* If CLEAN_P is true then initializes _SC with clean data,
23909 and from the global context otherwise. */
23911 rs6000_init_sched_context (void *_sc, bool clean_p)
23913 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23917 sc->cached_can_issue_more = 0;
23918 sc->last_scheduled_insn = NULL_RTX;
23919 sc->load_store_pendulum = 0;
23923 sc->cached_can_issue_more = cached_can_issue_more;
23924 sc->last_scheduled_insn = last_scheduled_insn;
23925 sc->load_store_pendulum = load_store_pendulum;
23929 /* Sets the global scheduling context to the one pointed to by _SC. */
23931 rs6000_set_sched_context (void *_sc)
23933 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23935 gcc_assert (sc != NULL);
23937 cached_can_issue_more = sc->cached_can_issue_more;
23938 last_scheduled_insn = sc->last_scheduled_insn;
23939 load_store_pendulum = sc->load_store_pendulum;
23944 rs6000_free_sched_context (void *_sc)
23946 gcc_assert (_sc != NULL);
23952 /* Length in units of the trampoline for entering a nested function. */
23955 rs6000_trampoline_size (void)
23959 switch (DEFAULT_ABI)
23962 gcc_unreachable ();
23965 ret = (TARGET_32BIT) ? 12 : 24;
23970 ret = (TARGET_32BIT) ? 40 : 48;
23977 /* Emit RTL insns to initialize the variable parts of a trampoline.
23978 FNADDR is an RTX for the address of the function's pure code.
23979 CXT is an RTX for the static chain value for the function. */
23982 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23984 int regsize = (TARGET_32BIT) ? 4 : 8;
23985 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23986 rtx ctx_reg = force_reg (Pmode, cxt);
23987 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23989 switch (DEFAULT_ABI)
23992 gcc_unreachable ();
23994 /* Under AIX, just build the 3 word function descriptor */
23997 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23998 rtx fn_reg = gen_reg_rtx (Pmode);
23999 rtx toc_reg = gen_reg_rtx (Pmode);
24001 /* Macro to shorten the code expansions below. */
24002 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24004 m_tramp = replace_equiv_address (m_tramp, addr);
24006 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24007 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24008 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24009 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24010 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24016 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24019 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24020 LCT_NORMAL, VOIDmode, 4,
24022 GEN_INT (rs6000_trampoline_size ()), SImode,
24030 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24031 identifier as an argument, so the front end shouldn't look it up. */
24034 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24036 return is_attribute_p ("altivec", attr_id);
24039 /* Handle the "altivec" attribute. The attribute may have
24040 arguments as follows:
24042 __attribute__((altivec(vector__)))
24043 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24044 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24046 and may appear more than once (e.g., 'vector bool char') in a
24047 given declaration. */
24050 rs6000_handle_altivec_attribute (tree *node,
24051 tree name ATTRIBUTE_UNUSED,
24053 int flags ATTRIBUTE_UNUSED,
24054 bool *no_add_attrs)
24056 tree type = *node, result = NULL_TREE;
24057 enum machine_mode mode;
24060 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24061 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24062 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24065 while (POINTER_TYPE_P (type)
24066 || TREE_CODE (type) == FUNCTION_TYPE
24067 || TREE_CODE (type) == METHOD_TYPE
24068 || TREE_CODE (type) == ARRAY_TYPE)
24069 type = TREE_TYPE (type);
24071 mode = TYPE_MODE (type);
24073 /* Check for invalid AltiVec type qualifiers. */
24074 if (type == long_double_type_node)
24075 error ("use of %<long double%> in AltiVec types is invalid");
24076 else if (type == boolean_type_node)
24077 error ("use of boolean types in AltiVec types is invalid");
24078 else if (TREE_CODE (type) == COMPLEX_TYPE)
24079 error ("use of %<complex%> in AltiVec types is invalid");
24080 else if (DECIMAL_FLOAT_MODE_P (mode))
24081 error ("use of decimal floating point types in AltiVec types is invalid");
24082 else if (!TARGET_VSX)
24084 if (type == long_unsigned_type_node || type == long_integer_type_node)
24087 error ("use of %<long%> in AltiVec types is invalid for "
24088 "64-bit code without -mvsx");
24089 else if (rs6000_warn_altivec_long)
24090 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24093 else if (type == long_long_unsigned_type_node
24094 || type == long_long_integer_type_node)
24095 error ("use of %<long long%> in AltiVec types is invalid without "
24097 else if (type == double_type_node)
24098 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24101 switch (altivec_type)
24104 unsigned_p = TYPE_UNSIGNED (type);
24108 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24111 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24114 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24117 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24119 case SFmode: result = V4SF_type_node; break;
24120 case DFmode: result = V2DF_type_node; break;
24121 /* If the user says 'vector int bool', we may be handed the 'bool'
24122 attribute _before_ the 'vector' attribute, and so select the
24123 proper type in the 'b' case below. */
24124 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24125 case V2DImode: case V2DFmode:
24133 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24134 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24135 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24136 case QImode: case V16QImode: result = bool_V16QI_type_node;
24143 case V8HImode: result = pixel_V8HI_type_node;
24149 /* Propagate qualifiers attached to the element type
24150 onto the vector type. */
24151 if (result && result != type && TYPE_QUALS (type))
24152 result = build_qualified_type (result, TYPE_QUALS (type));
24154 *no_add_attrs = true; /* No need to hang on to the attribute. */
24157 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24162 /* AltiVec defines four built-in scalar types that serve as vector
24163 elements; we must teach the compiler how to mangle them. */
24165 static const char *
24166 rs6000_mangle_type (const_tree type)
24168 type = TYPE_MAIN_VARIANT (type);
24170 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24171 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24174 if (type == bool_char_type_node) return "U6__boolc";
24175 if (type == bool_short_type_node) return "U6__bools";
24176 if (type == pixel_type_node) return "u7__pixel";
24177 if (type == bool_int_type_node) return "U6__booli";
24178 if (type == bool_long_type_node) return "U6__booll";
24180 /* Mangle IBM extended float long double as `g' (__float128) on
24181 powerpc*-linux where long-double-64 previously was the default. */
24182 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24184 && TARGET_LONG_DOUBLE_128
24185 && !TARGET_IEEEQUAD)
24188 /* For all other types, use normal C++ mangling. */
24192 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24193 struct attribute_spec.handler. */
24196 rs6000_handle_longcall_attribute (tree *node, tree name,
24197 tree args ATTRIBUTE_UNUSED,
24198 int flags ATTRIBUTE_UNUSED,
24199 bool *no_add_attrs)
24201 if (TREE_CODE (*node) != FUNCTION_TYPE
24202 && TREE_CODE (*node) != FIELD_DECL
24203 && TREE_CODE (*node) != TYPE_DECL)
24205 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24207 *no_add_attrs = true;
24213 /* Set longcall attributes on all functions declared when
24214 rs6000_default_long_calls is true. */
24216 rs6000_set_default_type_attributes (tree type)
24218 if (rs6000_default_long_calls
24219 && (TREE_CODE (type) == FUNCTION_TYPE
24220 || TREE_CODE (type) == METHOD_TYPE))
24221 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24223 TYPE_ATTRIBUTES (type));
24226 darwin_set_default_type_attributes (type);
24230 /* Return a reference suitable for calling a function with the
24231 longcall attribute. */
24234 rs6000_longcall_ref (rtx call_ref)
24236 const char *call_name;
24239 if (GET_CODE (call_ref) != SYMBOL_REF)
24242 /* System V adds '.' to the internal name, so skip them. */
24243 call_name = XSTR (call_ref, 0);
24244 if (*call_name == '.')
24246 while (*call_name == '.')
24249 node = get_identifier (call_name);
24250 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24253 return force_reg (Pmode, call_ref);
24256 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24257 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24260 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24261 struct attribute_spec.handler. */
24263 rs6000_handle_struct_attribute (tree *node, tree name,
24264 tree args ATTRIBUTE_UNUSED,
24265 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24268 if (DECL_P (*node))
24270 if (TREE_CODE (*node) == TYPE_DECL)
24271 type = &TREE_TYPE (*node);
24276 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24277 || TREE_CODE (*type) == UNION_TYPE)))
24279 warning (OPT_Wattributes, "%qE attribute ignored", name);
24280 *no_add_attrs = true;
24283 else if ((is_attribute_p ("ms_struct", name)
24284 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24285 || ((is_attribute_p ("gcc_struct", name)
24286 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24288 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24290 *no_add_attrs = true;
24297 rs6000_ms_bitfield_layout_p (const_tree record_type)
24299 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24300 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24301 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24304 #ifdef USING_ELFOS_H
24306 /* A get_unnamed_section callback, used for switching to toc_section. */
24309 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24311 if (DEFAULT_ABI == ABI_AIX
24312 && TARGET_MINIMAL_TOC
24313 && !TARGET_RELOCATABLE)
24315 if (!toc_initialized)
24317 toc_initialized = 1;
24318 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24319 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24320 fprintf (asm_out_file, "\t.tc ");
24321 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24322 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24323 fprintf (asm_out_file, "\n");
24325 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24326 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24327 fprintf (asm_out_file, " = .+32768\n");
24330 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24332 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24333 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24336 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24337 if (!toc_initialized)
24339 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24340 fprintf (asm_out_file, " = .+32768\n");
24341 toc_initialized = 1;
24346 /* Implement TARGET_ASM_INIT_SECTIONS. */
24349 rs6000_elf_asm_init_sections (void)
24352 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24355 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24356 SDATA2_SECTION_ASM_OP);
24359 /* Implement TARGET_SELECT_RTX_SECTION. */
24362 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24363 unsigned HOST_WIDE_INT align)
24365 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24366 return toc_section;
24368 return default_elf_select_rtx_section (mode, x, align);
24371 /* For a SYMBOL_REF, set generic flags and then perform some
24372 target-specific processing.
24374 When the AIX ABI is requested on a non-AIX system, replace the
24375 function name with the real name (with a leading .) rather than the
24376 function descriptor name. This saves a lot of overriding code to
24377 read the prefixes. */
24380 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24382 default_encode_section_info (decl, rtl, first);
24385 && TREE_CODE (decl) == FUNCTION_DECL
24387 && DEFAULT_ABI == ABI_AIX)
24389 rtx sym_ref = XEXP (rtl, 0);
24390 size_t len = strlen (XSTR (sym_ref, 0));
24391 char *str = XALLOCAVEC (char, len + 2);
24393 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24394 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24399 compare_section_name (const char *section, const char *templ)
24403 len = strlen (templ);
24404 return (strncmp (section, templ, len) == 0
24405 && (section[len] == 0 || section[len] == '.'));
24409 rs6000_elf_in_small_data_p (const_tree decl)
24411 if (rs6000_sdata == SDATA_NONE)
24414 /* We want to merge strings, so we never consider them small data. */
24415 if (TREE_CODE (decl) == STRING_CST)
24418 /* Functions are never in the small data area. */
24419 if (TREE_CODE (decl) == FUNCTION_DECL)
24422 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24424 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24425 if (compare_section_name (section, ".sdata")
24426 || compare_section_name (section, ".sdata2")
24427 || compare_section_name (section, ".gnu.linkonce.s")
24428 || compare_section_name (section, ".sbss")
24429 || compare_section_name (section, ".sbss2")
24430 || compare_section_name (section, ".gnu.linkonce.sb")
24431 || strcmp (section, ".PPC.EMB.sdata0") == 0
24432 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24437 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24440 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24441 /* If it's not public, and we're not going to reference it there,
24442 there's no need to put it in the small data section. */
24443 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24450 #endif /* USING_ELFOS_H */
24452 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24455 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24457 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24460 /* Return a REG that occurs in ADDR with coefficient 1.
24461 ADDR can be effectively incremented by incrementing REG.
24463 r0 is special and we must not select it as an address
24464 register by this routine since our caller will try to
24465 increment the returned register via an "la" instruction. */
24468 find_addr_reg (rtx addr)
24470 while (GET_CODE (addr) == PLUS)
24472 if (GET_CODE (XEXP (addr, 0)) == REG
24473 && REGNO (XEXP (addr, 0)) != 0)
24474 addr = XEXP (addr, 0);
24475 else if (GET_CODE (XEXP (addr, 1)) == REG
24476 && REGNO (XEXP (addr, 1)) != 0)
24477 addr = XEXP (addr, 1);
24478 else if (CONSTANT_P (XEXP (addr, 0)))
24479 addr = XEXP (addr, 1);
24480 else if (CONSTANT_P (XEXP (addr, 1)))
24481 addr = XEXP (addr, 0);
24483 gcc_unreachable ();
24485 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24490 rs6000_fatal_bad_address (rtx op)
24492 fatal_insn ("bad address", op);
24497 static tree branch_island_list = 0;
24499 /* Remember to generate a branch island for far calls to the given
24503 add_compiler_branch_island (tree label_name, tree function_name,
24506 tree branch_island = build_tree_list (function_name, label_name);
24507 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24508 TREE_CHAIN (branch_island) = branch_island_list;
24509 branch_island_list = branch_island;
24512 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24513 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24514 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24515 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24517 /* Generate far-jump branch islands for everything on the
24518 branch_island_list. Invoked immediately after the last instruction
24519 of the epilogue has been emitted; the branch-islands must be
24520 appended to, and contiguous with, the function body. Mach-O stubs
24521 are generated in machopic_output_stub(). */
24524 macho_branch_islands (void)
24527 tree branch_island;
24529 for (branch_island = branch_island_list;
24531 branch_island = TREE_CHAIN (branch_island))
24533 const char *label =
24534 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24536 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24537 char name_buf[512];
24538 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24539 if (name[0] == '*' || name[0] == '&')
24540 strcpy (name_buf, name+1);
24544 strcpy (name_buf+1, name);
24546 strcpy (tmp_buf, "\n");
24547 strcat (tmp_buf, label);
24548 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24549 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24550 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24551 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24554 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24555 strcat (tmp_buf, label);
24556 strcat (tmp_buf, "_pic\n");
24557 strcat (tmp_buf, label);
24558 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24560 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24561 strcat (tmp_buf, name_buf);
24562 strcat (tmp_buf, " - ");
24563 strcat (tmp_buf, label);
24564 strcat (tmp_buf, "_pic)\n");
24566 strcat (tmp_buf, "\tmtlr r0\n");
24568 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24569 strcat (tmp_buf, name_buf);
24570 strcat (tmp_buf, " - ");
24571 strcat (tmp_buf, label);
24572 strcat (tmp_buf, "_pic)\n");
24574 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24578 strcat (tmp_buf, ":\nlis r12,hi16(");
24579 strcat (tmp_buf, name_buf);
24580 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24581 strcat (tmp_buf, name_buf);
24582 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24584 output_asm_insn (tmp_buf, 0);
24585 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24586 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24587 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24588 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24591 branch_island_list = 0;
24594 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24595 already there or not. */
24598 no_previous_def (tree function_name)
24600 tree branch_island;
24601 for (branch_island = branch_island_list;
24603 branch_island = TREE_CHAIN (branch_island))
24604 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24609 /* GET_PREV_LABEL gets the label name from the previous definition of
24613 get_prev_label (tree function_name)
24615 tree branch_island;
24616 for (branch_island = branch_island_list;
24618 branch_island = TREE_CHAIN (branch_island))
24619 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24620 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24624 /* INSN is either a function call or a millicode call. It may have an
24625 unconditional jump in its delay slot.
24627 CALL_DEST is the routine we are calling. */
24630 output_call (rtx insn, rtx *operands, int dest_operand_number,
24631 int cookie_operand_number)
24633 static char buf[256];
24634 if (darwin_emit_branch_islands
24635 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24636 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24639 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24641 if (no_previous_def (funname))
24643 rtx label_rtx = gen_label_rtx ();
24644 char *label_buf, temp_buf[256];
24645 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24646 CODE_LABEL_NUMBER (label_rtx));
24647 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24648 labelname = get_identifier (label_buf);
24649 add_compiler_branch_island (labelname, funname, insn_line (insn));
24652 labelname = get_prev_label (funname);
24654 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24655 instruction will reach 'foo', otherwise link as 'bl L42'".
24656 "L42" should be a 'branch island', that will do a far jump to
24657 'foo'. Branch islands are generated in
24658 macho_branch_islands(). */
24659 sprintf (buf, "jbsr %%z%d,%.246s",
24660 dest_operand_number, IDENTIFIER_POINTER (labelname));
24663 sprintf (buf, "bl %%z%d", dest_operand_number);
24667 /* Generate PIC and indirect symbol stubs. */
24670 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24672 unsigned int length;
24673 char *symbol_name, *lazy_ptr_name;
24674 char *local_label_0;
24675 static int label = 0;
24677 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24678 symb = (*targetm.strip_name_encoding) (symb);
24681 length = strlen (symb);
24682 symbol_name = XALLOCAVEC (char, length + 32);
24683 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24685 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24686 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24689 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24691 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24695 fprintf (file, "\t.align 5\n");
24697 fprintf (file, "%s:\n", stub);
24698 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24701 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24702 sprintf (local_label_0, "\"L%011d$spb\"", label);
24704 fprintf (file, "\tmflr r0\n");
24705 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24706 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24707 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24708 lazy_ptr_name, local_label_0);
24709 fprintf (file, "\tmtlr r0\n");
24710 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24711 (TARGET_64BIT ? "ldu" : "lwzu"),
24712 lazy_ptr_name, local_label_0);
24713 fprintf (file, "\tmtctr r12\n");
24714 fprintf (file, "\tbctr\n");
24718 fprintf (file, "\t.align 4\n");
24720 fprintf (file, "%s:\n", stub);
24721 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24723 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24724 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24725 (TARGET_64BIT ? "ldu" : "lwzu"),
24727 fprintf (file, "\tmtctr r12\n");
24728 fprintf (file, "\tbctr\n");
24731 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24732 fprintf (file, "%s:\n", lazy_ptr_name);
24733 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24734 fprintf (file, "%sdyld_stub_binding_helper\n",
24735 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24738 /* Legitimize PIC addresses. If the address is already
24739 position-independent, we return ORIG. Newly generated
24740 position-independent addresses go into a reg. This is REG if non
24741 zero, otherwise we allocate register(s) as necessary. */
24743 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24746 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24751 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24752 reg = gen_reg_rtx (Pmode);
24754 if (GET_CODE (orig) == CONST)
24758 if (GET_CODE (XEXP (orig, 0)) == PLUS
24759 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24762 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24764 /* Use a different reg for the intermediate value, as
24765 it will be marked UNCHANGING. */
24766 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24767 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24770 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24773 if (GET_CODE (offset) == CONST_INT)
24775 if (SMALL_INT (offset))
24776 return plus_constant (base, INTVAL (offset));
24777 else if (! reload_in_progress && ! reload_completed)
24778 offset = force_reg (Pmode, offset);
24781 rtx mem = force_const_mem (Pmode, orig);
24782 return machopic_legitimize_pic_address (mem, Pmode, reg);
24785 return gen_rtx_PLUS (Pmode, base, offset);
24788 /* Fall back on generic machopic code. */
24789 return machopic_legitimize_pic_address (orig, mode, reg);
24792 /* Output a .machine directive for the Darwin assembler, and call
24793 the generic start_file routine. */
24796 rs6000_darwin_file_start (void)
24798 static const struct
24804 { "ppc64", "ppc64", MASK_64BIT },
24805 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24806 { "power4", "ppc970", 0 },
24807 { "G5", "ppc970", 0 },
24808 { "7450", "ppc7450", 0 },
24809 { "7400", "ppc7400", MASK_ALTIVEC },
24810 { "G4", "ppc7400", 0 },
24811 { "750", "ppc750", 0 },
24812 { "740", "ppc750", 0 },
24813 { "G3", "ppc750", 0 },
24814 { "604e", "ppc604e", 0 },
24815 { "604", "ppc604", 0 },
24816 { "603e", "ppc603", 0 },
24817 { "603", "ppc603", 0 },
24818 { "601", "ppc601", 0 },
24819 { NULL, "ppc", 0 } };
24820 const char *cpu_id = "";
24823 rs6000_file_start ();
24824 darwin_file_start ();
24826 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24827 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24828 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24829 && rs6000_select[i].string[0] != '\0')
24830 cpu_id = rs6000_select[i].string;
24832 /* Look through the mapping array. Pick the first name that either
24833 matches the argument, has a bit set in IF_SET that is also set
24834 in the target flags, or has a NULL name. */
24837 while (mapping[i].arg != NULL
24838 && strcmp (mapping[i].arg, cpu_id) != 0
24839 && (mapping[i].if_set & target_flags) == 0)
24842 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24845 #endif /* TARGET_MACHO */
24849 rs6000_elf_reloc_rw_mask (void)
24853 else if (DEFAULT_ABI == ABI_AIX)
24859 /* Record an element in the table of global constructors. SYMBOL is
24860 a SYMBOL_REF of the function to be called; PRIORITY is a number
24861 between 0 and MAX_INIT_PRIORITY.
24863 This differs from default_named_section_asm_out_constructor in
24864 that we have special handling for -mrelocatable. */
24867 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24869 const char *section = ".ctors";
24872 if (priority != DEFAULT_INIT_PRIORITY)
24874 sprintf (buf, ".ctors.%.5u",
24875 /* Invert the numbering so the linker puts us in the proper
24876 order; constructors are run from right to left, and the
24877 linker sorts in increasing order. */
24878 MAX_INIT_PRIORITY - priority);
24882 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24883 assemble_align (POINTER_SIZE);
24885 if (TARGET_RELOCATABLE)
24887 fputs ("\t.long (", asm_out_file);
24888 output_addr_const (asm_out_file, symbol);
24889 fputs (")@fixup\n", asm_out_file);
24892 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24896 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24898 const char *section = ".dtors";
24901 if (priority != DEFAULT_INIT_PRIORITY)
24903 sprintf (buf, ".dtors.%.5u",
24904 /* Invert the numbering so the linker puts us in the proper
24905 order; constructors are run from right to left, and the
24906 linker sorts in increasing order. */
24907 MAX_INIT_PRIORITY - priority);
24911 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24912 assemble_align (POINTER_SIZE);
24914 if (TARGET_RELOCATABLE)
24916 fputs ("\t.long (", asm_out_file);
24917 output_addr_const (asm_out_file, symbol);
24918 fputs (")@fixup\n", asm_out_file);
24921 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24925 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24929 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24930 ASM_OUTPUT_LABEL (file, name);
24931 fputs (DOUBLE_INT_ASM_OP, file);
24932 rs6000_output_function_entry (file, name);
24933 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24936 fputs ("\t.size\t", file);
24937 assemble_name (file, name);
24938 fputs (",24\n\t.type\t.", file);
24939 assemble_name (file, name);
24940 fputs (",@function\n", file);
24941 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24943 fputs ("\t.globl\t.", file);
24944 assemble_name (file, name);
24949 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24950 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24951 rs6000_output_function_entry (file, name);
24952 fputs (":\n", file);
24956 if (TARGET_RELOCATABLE
24957 && !TARGET_SECURE_PLT
24958 && (get_pool_size () != 0 || crtl->profile)
24963 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24965 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24966 fprintf (file, "\t.long ");
24967 assemble_name (file, buf);
24969 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24970 assemble_name (file, buf);
24974 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24975 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24977 if (DEFAULT_ABI == ABI_AIX)
24979 const char *desc_name, *orig_name;
24981 orig_name = (*targetm.strip_name_encoding) (name);
24982 desc_name = orig_name;
24983 while (*desc_name == '.')
24986 if (TREE_PUBLIC (decl))
24987 fprintf (file, "\t.globl %s\n", desc_name);
24989 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24990 fprintf (file, "%s:\n", desc_name);
24991 fprintf (file, "\t.long %s\n", orig_name);
24992 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24993 if (DEFAULT_ABI == ABI_AIX)
24994 fputs ("\t.long 0\n", file);
24995 fprintf (file, "\t.previous\n");
24997 ASM_OUTPUT_LABEL (file, name);
25001 rs6000_elf_end_indicate_exec_stack (void)
25004 file_end_indicate_exec_stack ();
25010 rs6000_xcoff_asm_output_anchor (rtx symbol)
25014 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25015 SYMBOL_REF_BLOCK_OFFSET (symbol));
25016 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25020 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25022 fputs (GLOBAL_ASM_OP, stream);
25023 RS6000_OUTPUT_BASENAME (stream, name);
25024 putc ('\n', stream);
25027 /* A get_unnamed_decl callback, used for read-only sections. PTR
25028 points to the section string variable. */
25031 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25033 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25034 *(const char *const *) directive,
25035 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25038 /* Likewise for read-write sections. */
25041 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25043 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25044 *(const char *const *) directive,
25045 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25048 /* A get_unnamed_section callback, used for switching to toc_section. */
25051 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25053 if (TARGET_MINIMAL_TOC)
25055 /* toc_section is always selected at least once from
25056 rs6000_xcoff_file_start, so this is guaranteed to
25057 always be defined once and only once in each file. */
25058 if (!toc_initialized)
25060 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25061 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25062 toc_initialized = 1;
25064 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25065 (TARGET_32BIT ? "" : ",3"));
25068 fputs ("\t.toc\n", asm_out_file);
25071 /* Implement TARGET_ASM_INIT_SECTIONS. */
25074 rs6000_xcoff_asm_init_sections (void)
25076 read_only_data_section
25077 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25078 &xcoff_read_only_section_name);
25080 private_data_section
25081 = get_unnamed_section (SECTION_WRITE,
25082 rs6000_xcoff_output_readwrite_section_asm_op,
25083 &xcoff_private_data_section_name);
25085 read_only_private_data_section
25086 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25087 &xcoff_private_data_section_name);
25090 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25092 readonly_data_section = read_only_data_section;
25093 exception_section = data_section;
25097 rs6000_xcoff_reloc_rw_mask (void)
25103 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25104 tree decl ATTRIBUTE_UNUSED)
25107 static const char * const suffix[3] = { "PR", "RO", "RW" };
25109 if (flags & SECTION_CODE)
25111 else if (flags & SECTION_WRITE)
25116 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25117 (flags & SECTION_CODE) ? "." : "",
25118 name, suffix[smclass], flags & SECTION_ENTSIZE);
25122 rs6000_xcoff_select_section (tree decl, int reloc,
25123 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25125 if (decl_readonly_section (decl, reloc))
25127 if (TREE_PUBLIC (decl))
25128 return read_only_data_section;
25130 return read_only_private_data_section;
25134 if (TREE_PUBLIC (decl))
25135 return data_section;
25137 return private_data_section;
25142 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25146 /* Use select_section for private and uninitialized data. */
25147 if (!TREE_PUBLIC (decl)
25148 || DECL_COMMON (decl)
25149 || DECL_INITIAL (decl) == NULL_TREE
25150 || DECL_INITIAL (decl) == error_mark_node
25151 || (flag_zero_initialized_in_bss
25152 && initializer_zerop (DECL_INITIAL (decl))))
25155 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25156 name = (*targetm.strip_name_encoding) (name);
25157 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25160 /* Select section for constant in constant pool.
25162 On RS/6000, all constants are in the private read-only data area.
25163 However, if this is being placed in the TOC it must be output as a
25167 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25168 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25170 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25171 return toc_section;
25173 return read_only_private_data_section;
25176 /* Remove any trailing [DS] or the like from the symbol name. */
25178 static const char *
25179 rs6000_xcoff_strip_name_encoding (const char *name)
25184 len = strlen (name);
25185 if (name[len - 1] == ']')
25186 return ggc_alloc_string (name, len - 4);
25191 /* Section attributes. AIX is always PIC. */
25193 static unsigned int
25194 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25196 unsigned int align;
25197 unsigned int flags = default_section_type_flags (decl, name, reloc);
25199 /* Align to at least UNIT size. */
25200 if (flags & SECTION_CODE)
25201 align = MIN_UNITS_PER_WORD;
25203 /* Increase alignment of large objects if not already stricter. */
25204 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25205 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25206 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25208 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25211 /* Output at beginning of assembler file.
25213 Initialize the section names for the RS/6000 at this point.
25215 Specify filename, including full path, to assembler.
25217 We want to go into the TOC section so at least one .toc will be emitted.
25218 Also, in order to output proper .bs/.es pairs, we need at least one static
25219 [RW] section emitted.
25221 Finally, declare mcount when profiling to make the assembler happy. */
25224 rs6000_xcoff_file_start (void)
25226 rs6000_gen_section_name (&xcoff_bss_section_name,
25227 main_input_filename, ".bss_");
25228 rs6000_gen_section_name (&xcoff_private_data_section_name,
25229 main_input_filename, ".rw_");
25230 rs6000_gen_section_name (&xcoff_read_only_section_name,
25231 main_input_filename, ".ro_");
25233 fputs ("\t.file\t", asm_out_file);
25234 output_quoted_string (asm_out_file, main_input_filename);
25235 fputc ('\n', asm_out_file);
25236 if (write_symbols != NO_DEBUG)
25237 switch_to_section (private_data_section);
25238 switch_to_section (text_section);
25240 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25241 rs6000_file_start ();
25244 /* Output at end of assembler file.
25245 On the RS/6000, referencing data should automatically pull in text. */
25248 rs6000_xcoff_file_end (void)
25250 switch_to_section (text_section);
25251 fputs ("_section_.text:\n", asm_out_file);
25252 switch_to_section (data_section);
25253 fputs (TARGET_32BIT
25254 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25257 #endif /* TARGET_XCOFF */
25259 /* Compute a (partial) cost for rtx X. Return true if the complete
25260 cost has been computed, and false if subexpressions should be
25261 scanned. In either case, *TOTAL contains the cost result. */
25264 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25267 enum machine_mode mode = GET_MODE (x);
25271 /* On the RS/6000, if it is valid in the insn, it is free. */
25273 if (((outer_code == SET
25274 || outer_code == PLUS
25275 || outer_code == MINUS)
25276 && (satisfies_constraint_I (x)
25277 || satisfies_constraint_L (x)))
25278 || (outer_code == AND
25279 && (satisfies_constraint_K (x)
25281 ? satisfies_constraint_L (x)
25282 : satisfies_constraint_J (x))
25283 || mask_operand (x, mode)
25285 && mask64_operand (x, DImode))))
25286 || ((outer_code == IOR || outer_code == XOR)
25287 && (satisfies_constraint_K (x)
25289 ? satisfies_constraint_L (x)
25290 : satisfies_constraint_J (x))))
25291 || outer_code == ASHIFT
25292 || outer_code == ASHIFTRT
25293 || outer_code == LSHIFTRT
25294 || outer_code == ROTATE
25295 || outer_code == ROTATERT
25296 || outer_code == ZERO_EXTRACT
25297 || (outer_code == MULT
25298 && satisfies_constraint_I (x))
25299 || ((outer_code == DIV || outer_code == UDIV
25300 || outer_code == MOD || outer_code == UMOD)
25301 && exact_log2 (INTVAL (x)) >= 0)
25302 || (outer_code == COMPARE
25303 && (satisfies_constraint_I (x)
25304 || satisfies_constraint_K (x)))
25305 || (outer_code == EQ
25306 && (satisfies_constraint_I (x)
25307 || satisfies_constraint_K (x)
25309 ? satisfies_constraint_L (x)
25310 : satisfies_constraint_J (x))))
25311 || (outer_code == GTU
25312 && satisfies_constraint_I (x))
25313 || (outer_code == LTU
25314 && satisfies_constraint_P (x)))
25319 else if ((outer_code == PLUS
25320 && reg_or_add_cint_operand (x, VOIDmode))
25321 || (outer_code == MINUS
25322 && reg_or_sub_cint_operand (x, VOIDmode))
25323 || ((outer_code == SET
25324 || outer_code == IOR
25325 || outer_code == XOR)
25327 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25329 *total = COSTS_N_INSNS (1);
25335 if (mode == DImode && code == CONST_DOUBLE)
25337 if ((outer_code == IOR || outer_code == XOR)
25338 && CONST_DOUBLE_HIGH (x) == 0
25339 && (CONST_DOUBLE_LOW (x)
25340 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25345 else if ((outer_code == AND && and64_2_operand (x, DImode))
25346 || ((outer_code == SET
25347 || outer_code == IOR
25348 || outer_code == XOR)
25349 && CONST_DOUBLE_HIGH (x) == 0))
25351 *total = COSTS_N_INSNS (1);
25361 /* When optimizing for size, MEM should be slightly more expensive
25362 than generating address, e.g., (plus (reg) (const)).
25363 L1 cache latency is about two instructions. */
25364 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25372 if (mode == DFmode)
25374 if (GET_CODE (XEXP (x, 0)) == MULT)
25376 /* FNMA accounted in outer NEG. */
25377 if (outer_code == NEG)
25378 *total = rs6000_cost->dmul - rs6000_cost->fp;
25380 *total = rs6000_cost->dmul;
25383 *total = rs6000_cost->fp;
25385 else if (mode == SFmode)
25387 /* FNMA accounted in outer NEG. */
25388 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25391 *total = rs6000_cost->fp;
25394 *total = COSTS_N_INSNS (1);
25398 if (mode == DFmode)
25400 if (GET_CODE (XEXP (x, 0)) == MULT
25401 || GET_CODE (XEXP (x, 1)) == MULT)
25403 /* FNMA accounted in outer NEG. */
25404 if (outer_code == NEG)
25405 *total = rs6000_cost->dmul - rs6000_cost->fp;
25407 *total = rs6000_cost->dmul;
25410 *total = rs6000_cost->fp;
25412 else if (mode == SFmode)
25414 /* FNMA accounted in outer NEG. */
25415 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25418 *total = rs6000_cost->fp;
25421 *total = COSTS_N_INSNS (1);
25425 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25426 && satisfies_constraint_I (XEXP (x, 1)))
25428 if (INTVAL (XEXP (x, 1)) >= -256
25429 && INTVAL (XEXP (x, 1)) <= 255)
25430 *total = rs6000_cost->mulsi_const9;
25432 *total = rs6000_cost->mulsi_const;
25434 /* FMA accounted in outer PLUS/MINUS. */
25435 else if ((mode == DFmode || mode == SFmode)
25436 && (outer_code == PLUS || outer_code == MINUS))
25438 else if (mode == DFmode)
25439 *total = rs6000_cost->dmul;
25440 else if (mode == SFmode)
25441 *total = rs6000_cost->fp;
25442 else if (mode == DImode)
25443 *total = rs6000_cost->muldi;
25445 *total = rs6000_cost->mulsi;
25450 if (FLOAT_MODE_P (mode))
25452 *total = mode == DFmode ? rs6000_cost->ddiv
25453 : rs6000_cost->sdiv;
25460 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25461 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25463 if (code == DIV || code == MOD)
25465 *total = COSTS_N_INSNS (2);
25468 *total = COSTS_N_INSNS (1);
25472 if (GET_MODE (XEXP (x, 1)) == DImode)
25473 *total = rs6000_cost->divdi;
25475 *total = rs6000_cost->divsi;
25477 /* Add in shift and subtract for MOD. */
25478 if (code == MOD || code == UMOD)
25479 *total += COSTS_N_INSNS (2);
25484 *total = COSTS_N_INSNS (4);
25488 *total = COSTS_N_INSNS (6);
25492 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25504 *total = COSTS_N_INSNS (1);
25512 /* Handle mul_highpart. */
25513 if (outer_code == TRUNCATE
25514 && GET_CODE (XEXP (x, 0)) == MULT)
25516 if (mode == DImode)
25517 *total = rs6000_cost->muldi;
25519 *total = rs6000_cost->mulsi;
25522 else if (outer_code == AND)
25525 *total = COSTS_N_INSNS (1);
25530 if (GET_CODE (XEXP (x, 0)) == MEM)
25533 *total = COSTS_N_INSNS (1);
25539 if (!FLOAT_MODE_P (mode))
25541 *total = COSTS_N_INSNS (1);
25547 case UNSIGNED_FLOAT:
25550 case FLOAT_TRUNCATE:
25551 *total = rs6000_cost->fp;
25555 if (mode == DFmode)
25558 *total = rs6000_cost->fp;
25562 switch (XINT (x, 1))
25565 *total = rs6000_cost->fp;
25577 *total = COSTS_N_INSNS (1);
25580 else if (FLOAT_MODE_P (mode)
25581 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25583 *total = rs6000_cost->fp;
25591 /* Carry bit requires mode == Pmode.
25592 NEG or PLUS already counted so only add one. */
25594 && (outer_code == NEG || outer_code == PLUS))
25596 *total = COSTS_N_INSNS (1);
25599 if (outer_code == SET)
25601 if (XEXP (x, 1) == const0_rtx)
25603 if (TARGET_ISEL && !TARGET_MFCRF)
25604 *total = COSTS_N_INSNS (8);
25606 *total = COSTS_N_INSNS (2);
25609 else if (mode == Pmode)
25611 *total = COSTS_N_INSNS (3);
25620 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25622 if (TARGET_ISEL && !TARGET_MFCRF)
25623 *total = COSTS_N_INSNS (8);
25625 *total = COSTS_N_INSNS (2);
25629 if (outer_code == COMPARE)
25643 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25646 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25649 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25652 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25653 "total = %d, speed = %s, x:\n",
25654 ret ? "complete" : "scan inner",
25655 GET_RTX_NAME (code),
25656 GET_RTX_NAME (outer_code),
25658 speed ? "true" : "false");
25665 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25668 rs6000_debug_address_cost (rtx x, bool speed)
25670 int ret = TARGET_ADDRESS_COST (x, speed);
25672 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25673 ret, speed ? "true" : "false");
25680 /* A C expression returning the cost of moving data from a register of class
25681 CLASS1 to one of CLASS2. */
25684 rs6000_register_move_cost (enum machine_mode mode,
25685 reg_class_t from, reg_class_t to)
25689 /* Moves from/to GENERAL_REGS. */
25690 if (reg_classes_intersect_p (to, GENERAL_REGS)
25691 || reg_classes_intersect_p (from, GENERAL_REGS))
25693 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25696 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25697 ret = (rs6000_memory_move_cost (mode, from, false)
25698 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
25700 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25702 else if (from == CR_REGS)
25705 /* Power6 has slower LR/CTR moves so make them more expensive than
25706 memory in order to bias spills to memory .*/
25707 else if (rs6000_cpu == PROCESSOR_POWER6
25708 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25709 ret = 6 * hard_regno_nregs[0][mode];
25712 /* A move will cost one instruction per GPR moved. */
25713 ret = 2 * hard_regno_nregs[0][mode];
25716 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25717 else if (VECTOR_UNIT_VSX_P (mode)
25718 && reg_classes_intersect_p (to, VSX_REGS)
25719 && reg_classes_intersect_p (from, VSX_REGS))
25720 ret = 2 * hard_regno_nregs[32][mode];
25722 /* Moving between two similar registers is just one instruction. */
25723 else if (reg_classes_intersect_p (to, from))
25724 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25726 /* Everything else has to go through GENERAL_REGS. */
25728 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25729 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25731 if (TARGET_DEBUG_COST)
25733 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25734 ret, GET_MODE_NAME (mode), reg_class_names[from],
25735 reg_class_names[to]);
25740 /* A C expressions returning the cost of moving data of MODE from a register to
25744 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
25745 bool in ATTRIBUTE_UNUSED)
25749 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25750 ret = 4 * hard_regno_nregs[0][mode];
25751 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25752 ret = 4 * hard_regno_nregs[32][mode];
25753 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25754 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25756 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25758 if (TARGET_DEBUG_COST)
25760 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25761 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25766 /* Returns a code for a target-specific builtin that implements
25767 reciprocal of the function, or NULL_TREE if not available. */
25770 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25771 bool sqrt ATTRIBUTE_UNUSED)
25773 if (optimize_insn_for_size_p ())
25779 case VSX_BUILTIN_XVSQRTDP:
25780 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25783 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25785 case VSX_BUILTIN_XVSQRTSP:
25786 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25789 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25798 case BUILT_IN_SQRT:
25799 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25802 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25804 case BUILT_IN_SQRTF:
25805 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25808 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25815 /* Load up a constant. If the mode is a vector mode, splat the value across
25816 all of the vector elements. */
25819 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25823 if (mode == SFmode || mode == DFmode)
25825 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25826 reg = force_reg (mode, d);
25828 else if (mode == V4SFmode)
25830 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25831 rtvec v = gen_rtvec (4, d, d, d, d);
25832 reg = gen_reg_rtx (mode);
25833 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25835 else if (mode == V2DFmode)
25837 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25838 rtvec v = gen_rtvec (2, d, d);
25839 reg = gen_reg_rtx (mode);
25840 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25843 gcc_unreachable ();
25848 /* Generate a FMADD instruction:
25849 dst = (m1 * m2) + a
25851 generating different RTL based on the fused multiply/add switch. */
25854 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25856 enum machine_mode mode = GET_MODE (dst);
25858 if (!TARGET_FUSED_MADD)
25860 /* For the simple ops, use the generator function, rather than assuming
25861 that the RTL is standard. */
25862 enum insn_code mcode = optab_handler (smul_optab, mode);
25863 enum insn_code acode = optab_handler (add_optab, mode);
25864 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25865 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25866 rtx mreg = gen_reg_rtx (mode);
25868 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25869 emit_insn (gen_mul (mreg, m1, m2));
25870 emit_insn (gen_add (dst, mreg, a));
25874 emit_insn (gen_rtx_SET (VOIDmode, dst,
25875 gen_rtx_PLUS (mode,
25876 gen_rtx_MULT (mode, m1, m2),
25880 /* Generate a FMSUB instruction:
25881 dst = (m1 * m2) - a
25883 generating different RTL based on the fused multiply/add switch. */
25886 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25888 enum machine_mode mode = GET_MODE (dst);
25890 if (!TARGET_FUSED_MADD
25891 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25893 /* For the simple ops, use the generator function, rather than assuming
25894 that the RTL is standard. */
25895 enum insn_code mcode = optab_handler (smul_optab, mode);
25896 enum insn_code scode = optab_handler (add_optab, mode);
25897 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25898 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25899 rtx mreg = gen_reg_rtx (mode);
25901 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25902 emit_insn (gen_mul (mreg, m1, m2));
25903 emit_insn (gen_sub (dst, mreg, a));
25907 emit_insn (gen_rtx_SET (VOIDmode, dst,
25908 gen_rtx_MINUS (mode,
25909 gen_rtx_MULT (mode, m1, m2),
25913 /* Generate a FNMSUB instruction:
25914 dst = - ((m1 * m2) - a)
25916 Which is equivalent to (except in the prescence of -0.0):
25917 dst = a - (m1 * m2)
25919 generating different RTL based on the fast-math and fused multiply/add
25923 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25925 enum machine_mode mode = GET_MODE (dst);
25927 if (!TARGET_FUSED_MADD)
25929 /* For the simple ops, use the generator function, rather than assuming
25930 that the RTL is standard. */
25931 enum insn_code mcode = optab_handler (smul_optab, mode);
25932 enum insn_code scode = optab_handler (sub_optab, mode);
25933 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25934 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25935 rtx mreg = gen_reg_rtx (mode);
25937 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25938 emit_insn (gen_mul (mreg, m1, m2));
25939 emit_insn (gen_sub (dst, a, mreg));
25944 rtx m = gen_rtx_MULT (mode, m1, m2);
25946 if (!HONOR_SIGNED_ZEROS (mode))
25947 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25950 emit_insn (gen_rtx_SET (VOIDmode, dst,
25952 gen_rtx_MINUS (mode, m, a))));
25956 /* Newton-Raphson approximation of floating point divide with just 2 passes
25957 (either single precision floating point, or newer machines with higher
25958 accuracy estimates). Support both scalar and vector divide. Assumes no
25959 trapping math and finite arguments. */
25962 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25964 enum machine_mode mode = GET_MODE (dst);
25965 rtx x0, e0, e1, y1, u0, v0;
25966 enum insn_code code = optab_handler (smul_optab, mode);
25967 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25968 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25970 gcc_assert (code != CODE_FOR_nothing);
25972 /* x0 = 1./d estimate */
25973 x0 = gen_reg_rtx (mode);
25974 emit_insn (gen_rtx_SET (VOIDmode, x0,
25975 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25978 e0 = gen_reg_rtx (mode);
25979 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25981 e1 = gen_reg_rtx (mode);
25982 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25984 y1 = gen_reg_rtx (mode);
25985 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25987 u0 = gen_reg_rtx (mode);
25988 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25990 v0 = gen_reg_rtx (mode);
25991 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25993 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25996 /* Newton-Raphson approximation of floating point divide that has a low
25997 precision estimate. Assumes no trapping math and finite arguments. */
26000 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26002 enum machine_mode mode = GET_MODE (dst);
26003 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26004 enum insn_code code = optab_handler (smul_optab, mode);
26005 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26007 gcc_assert (code != CODE_FOR_nothing);
26009 one = rs6000_load_constant_and_splat (mode, dconst1);
26011 /* x0 = 1./d estimate */
26012 x0 = gen_reg_rtx (mode);
26013 emit_insn (gen_rtx_SET (VOIDmode, x0,
26014 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26017 e0 = gen_reg_rtx (mode);
26018 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26020 y1 = gen_reg_rtx (mode);
26021 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26023 e1 = gen_reg_rtx (mode);
26024 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26026 y2 = gen_reg_rtx (mode);
26027 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26029 e2 = gen_reg_rtx (mode);
26030 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26032 y3 = gen_reg_rtx (mode);
26033 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26035 u0 = gen_reg_rtx (mode);
26036 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26038 v0 = gen_reg_rtx (mode);
26039 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26041 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26044 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26045 add a reg_note saying that this was a division. Support both scalar and
26046 vector divide. Assumes no trapping math and finite arguments. */
26049 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26051 enum machine_mode mode = GET_MODE (dst);
26053 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26054 rs6000_emit_swdiv_high_precision (dst, n, d);
26056 rs6000_emit_swdiv_low_precision (dst, n, d);
26059 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26062 /* Newton-Raphson approximation of single/double-precision floating point
26063 rsqrt. Assumes no trapping math and finite arguments. */
26066 rs6000_emit_swrsqrt (rtx dst, rtx src)
26068 enum machine_mode mode = GET_MODE (src);
26069 rtx x0 = gen_reg_rtx (mode);
26070 rtx y = gen_reg_rtx (mode);
26071 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26072 REAL_VALUE_TYPE dconst3_2;
26075 enum insn_code code = optab_handler (smul_optab, mode);
26076 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26078 gcc_assert (code != CODE_FOR_nothing);
26080 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26081 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26082 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26084 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26086 /* x0 = rsqrt estimate */
26087 emit_insn (gen_rtx_SET (VOIDmode, x0,
26088 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26091 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26092 rs6000_emit_msub (y, src, halfthree, src);
26094 for (i = 0; i < passes; i++)
26096 rtx x1 = gen_reg_rtx (mode);
26097 rtx u = gen_reg_rtx (mode);
26098 rtx v = gen_reg_rtx (mode);
26100 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26101 emit_insn (gen_mul (u, x0, x0));
26102 rs6000_emit_nmsub (v, y, u, halfthree);
26103 emit_insn (gen_mul (x1, x0, v));
26107 emit_move_insn (dst, x0);
26111 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26112 (Power7) targets. DST is the target, and SRC is the argument operand. */
26115 rs6000_emit_popcount (rtx dst, rtx src)
26117 enum machine_mode mode = GET_MODE (dst);
26120 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26121 if (TARGET_POPCNTD)
26123 if (mode == SImode)
26124 emit_insn (gen_popcntwsi2 (dst, src));
26126 emit_insn (gen_popcntddi2 (dst, src));
26130 tmp1 = gen_reg_rtx (mode);
26132 if (mode == SImode)
26134 emit_insn (gen_popcntbsi2 (tmp1, src));
26135 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26137 tmp2 = force_reg (SImode, tmp2);
26138 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26142 emit_insn (gen_popcntbdi2 (tmp1, src));
26143 tmp2 = expand_mult (DImode, tmp1,
26144 GEN_INT ((HOST_WIDE_INT)
26145 0x01010101 << 32 | 0x01010101),
26147 tmp2 = force_reg (DImode, tmp2);
26148 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26153 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26154 target, and SRC is the argument operand. */
26157 rs6000_emit_parity (rtx dst, rtx src)
26159 enum machine_mode mode = GET_MODE (dst);
26162 tmp = gen_reg_rtx (mode);
26163 if (mode == SImode)
26165 /* Is mult+shift >= shift+xor+shift+xor? */
26166 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26168 rtx tmp1, tmp2, tmp3, tmp4;
26170 tmp1 = gen_reg_rtx (SImode);
26171 emit_insn (gen_popcntbsi2 (tmp1, src));
26173 tmp2 = gen_reg_rtx (SImode);
26174 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26175 tmp3 = gen_reg_rtx (SImode);
26176 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26178 tmp4 = gen_reg_rtx (SImode);
26179 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26180 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26183 rs6000_emit_popcount (tmp, src);
26184 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26188 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26189 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26191 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26193 tmp1 = gen_reg_rtx (DImode);
26194 emit_insn (gen_popcntbdi2 (tmp1, src));
26196 tmp2 = gen_reg_rtx (DImode);
26197 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26198 tmp3 = gen_reg_rtx (DImode);
26199 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26201 tmp4 = gen_reg_rtx (DImode);
26202 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26203 tmp5 = gen_reg_rtx (DImode);
26204 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26206 tmp6 = gen_reg_rtx (DImode);
26207 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26208 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26211 rs6000_emit_popcount (tmp, src);
26212 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26216 /* Return an RTX representing where to find the function value of a
26217 function returning MODE. */
26219 rs6000_complex_function_value (enum machine_mode mode)
26221 unsigned int regno;
26223 enum machine_mode inner = GET_MODE_INNER (mode);
26224 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26226 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26227 regno = FP_ARG_RETURN;
26230 regno = GP_ARG_RETURN;
26232 /* 32-bit is OK since it'll go in r3/r4. */
26233 if (TARGET_32BIT && inner_bytes >= 4)
26234 return gen_rtx_REG (mode, regno);
26237 if (inner_bytes >= 8)
26238 return gen_rtx_REG (mode, regno);
26240 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26242 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26243 GEN_INT (inner_bytes));
26244 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26247 /* Target hook for TARGET_FUNCTION_VALUE.
26249 On the SPE, both FPs and vectors are returned in r3.
26251 On RS/6000 an integer value is in r3 and a floating-point value is in
26252 fp1, unless -msoft-float. */
26255 rs6000_function_value (const_tree valtype,
26256 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26257 bool outgoing ATTRIBUTE_UNUSED)
26259 enum machine_mode mode;
26260 unsigned int regno;
26262 /* Special handling for structs in darwin64. */
26264 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26266 CUMULATIVE_ARGS valcum;
26270 valcum.fregno = FP_ARG_MIN_REG;
26271 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26272 /* Do a trial code generation as if this were going to be passed as
26273 an argument; if any part goes in memory, we return NULL. */
26274 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
26277 /* Otherwise fall through to standard ABI rules. */
26280 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26282 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26283 return gen_rtx_PARALLEL (DImode,
26285 gen_rtx_EXPR_LIST (VOIDmode,
26286 gen_rtx_REG (SImode, GP_ARG_RETURN),
26288 gen_rtx_EXPR_LIST (VOIDmode,
26289 gen_rtx_REG (SImode,
26290 GP_ARG_RETURN + 1),
26293 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26295 return gen_rtx_PARALLEL (DCmode,
26297 gen_rtx_EXPR_LIST (VOIDmode,
26298 gen_rtx_REG (SImode, GP_ARG_RETURN),
26300 gen_rtx_EXPR_LIST (VOIDmode,
26301 gen_rtx_REG (SImode,
26302 GP_ARG_RETURN + 1),
26304 gen_rtx_EXPR_LIST (VOIDmode,
26305 gen_rtx_REG (SImode,
26306 GP_ARG_RETURN + 2),
26308 gen_rtx_EXPR_LIST (VOIDmode,
26309 gen_rtx_REG (SImode,
26310 GP_ARG_RETURN + 3),
26314 mode = TYPE_MODE (valtype);
26315 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26316 || POINTER_TYPE_P (valtype))
26317 mode = TARGET_32BIT ? SImode : DImode;
26319 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26320 /* _Decimal128 must use an even/odd register pair. */
26321 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26322 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26323 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26324 regno = FP_ARG_RETURN;
26325 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26326 && targetm.calls.split_complex_arg)
26327 return rs6000_complex_function_value (mode);
26328 else if (TREE_CODE (valtype) == VECTOR_TYPE
26329 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26330 && ALTIVEC_VECTOR_MODE (mode))
26331 regno = ALTIVEC_ARG_RETURN;
26332 else if (TREE_CODE (valtype) == VECTOR_TYPE
26333 && TARGET_VSX && TARGET_ALTIVEC_ABI
26334 && VSX_VECTOR_MODE (mode))
26335 regno = ALTIVEC_ARG_RETURN;
26336 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26337 && (mode == DFmode || mode == DCmode
26338 || mode == TFmode || mode == TCmode))
26339 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26341 regno = GP_ARG_RETURN;
26343 return gen_rtx_REG (mode, regno);
26346 /* Define how to find the value returned by a library function
26347 assuming the value has mode MODE. */
26349 rs6000_libcall_value (enum machine_mode mode)
26351 unsigned int regno;
26353 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26355 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26356 return gen_rtx_PARALLEL (DImode,
26358 gen_rtx_EXPR_LIST (VOIDmode,
26359 gen_rtx_REG (SImode, GP_ARG_RETURN),
26361 gen_rtx_EXPR_LIST (VOIDmode,
26362 gen_rtx_REG (SImode,
26363 GP_ARG_RETURN + 1),
26367 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26368 /* _Decimal128 must use an even/odd register pair. */
26369 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26370 else if (SCALAR_FLOAT_MODE_P (mode)
26371 && TARGET_HARD_FLOAT && TARGET_FPRS
26372 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26373 regno = FP_ARG_RETURN;
26374 else if (ALTIVEC_VECTOR_MODE (mode)
26375 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26376 regno = ALTIVEC_ARG_RETURN;
26377 else if (VSX_VECTOR_MODE (mode)
26378 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26379 regno = ALTIVEC_ARG_RETURN;
26380 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26381 return rs6000_complex_function_value (mode);
26382 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26383 && (mode == DFmode || mode == DCmode
26384 || mode == TFmode || mode == TCmode))
26385 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26387 regno = GP_ARG_RETURN;
26389 return gen_rtx_REG (mode, regno);
26393 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26394 Frame pointer elimination is automatically handled.
26396 For the RS/6000, if frame pointer elimination is being done, we would like
26397 to convert ap into fp, not sp.
26399 We need r30 if -mminimal-toc was specified, and there are constant pool
26403 rs6000_can_eliminate (const int from, const int to)
26405 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26406 ? ! frame_pointer_needed
26407 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26408 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26412 /* Define the offset between two registers, FROM to be eliminated and its
26413 replacement TO, at the start of a routine. */
26415 rs6000_initial_elimination_offset (int from, int to)
26417 rs6000_stack_t *info = rs6000_stack_info ();
26418 HOST_WIDE_INT offset;
26420 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26421 offset = info->push_p ? 0 : -info->total_size;
26422 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26424 offset = info->push_p ? 0 : -info->total_size;
26425 if (FRAME_GROWS_DOWNWARD)
26426 offset += info->fixed_size + info->vars_size + info->parm_size;
26428 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26429 offset = FRAME_GROWS_DOWNWARD
26430 ? info->fixed_size + info->vars_size + info->parm_size
26432 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26433 offset = info->total_size;
26434 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26435 offset = info->push_p ? info->total_size : 0;
26436 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26439 gcc_unreachable ();
26445 rs6000_dwarf_register_span (rtx reg)
26449 unsigned regno = REGNO (reg);
26450 enum machine_mode mode = GET_MODE (reg);
26454 && (SPE_VECTOR_MODE (GET_MODE (reg))
26455 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26456 && mode != SFmode && mode != SDmode && mode != SCmode)))
26461 regno = REGNO (reg);
26463 /* The duality of the SPE register size wreaks all kinds of havoc.
26464 This is a way of distinguishing r0 in 32-bits from r0 in
26466 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26467 gcc_assert (words <= 4);
26468 for (i = 0; i < words; i++, regno++)
26470 if (BYTES_BIG_ENDIAN)
26472 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26473 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26477 parts[2 * i] = gen_rtx_REG (SImode, regno);
26478 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26482 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26485 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26488 rs6000_init_dwarf_reg_sizes_extra (tree address)
26493 enum machine_mode mode = TYPE_MODE (char_type_node);
26494 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26495 rtx mem = gen_rtx_MEM (BLKmode, addr);
26496 rtx value = gen_int_mode (4, mode);
26498 for (i = 1201; i < 1232; i++)
26500 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26501 HOST_WIDE_INT offset
26502 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26504 emit_move_insn (adjust_address (mem, mode, offset), value);
26509 /* Map internal gcc register numbers to DWARF2 register numbers. */
26512 rs6000_dbx_register_number (unsigned int regno)
26514 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26516 if (regno == MQ_REGNO)
26518 if (regno == LR_REGNO)
26520 if (regno == CTR_REGNO)
26522 if (CR_REGNO_P (regno))
26523 return regno - CR0_REGNO + 86;
26524 if (regno == CA_REGNO)
26525 return 101; /* XER */
26526 if (ALTIVEC_REGNO_P (regno))
26527 return regno - FIRST_ALTIVEC_REGNO + 1124;
26528 if (regno == VRSAVE_REGNO)
26530 if (regno == VSCR_REGNO)
26532 if (regno == SPE_ACC_REGNO)
26534 if (regno == SPEFSCR_REGNO)
26536 /* SPE high reg number. We get these values of regno from
26537 rs6000_dwarf_register_span. */
26538 gcc_assert (regno >= 1200 && regno < 1232);
26542 /* target hook eh_return_filter_mode */
26543 static enum machine_mode
26544 rs6000_eh_return_filter_mode (void)
26546 return TARGET_32BIT ? SImode : word_mode;
26549 /* Target hook for scalar_mode_supported_p. */
26551 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26553 if (DECIMAL_FLOAT_MODE_P (mode))
26554 return default_decimal_float_supported_p ();
26556 return default_scalar_mode_supported_p (mode);
26559 /* Target hook for vector_mode_supported_p. */
26561 rs6000_vector_mode_supported_p (enum machine_mode mode)
26564 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26567 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26570 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26577 /* Target hook for invalid_arg_for_unprototyped_fn. */
26578 static const char *
26579 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26581 return (!rs6000_darwin64_abi
26583 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26584 && (funcdecl == NULL_TREE
26585 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26586 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26587 ? N_("AltiVec argument passed to unprototyped function")
26591 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26592 setup by using __stack_chk_fail_local hidden function instead of
26593 calling __stack_chk_fail directly. Otherwise it is better to call
26594 __stack_chk_fail directly. */
26597 rs6000_stack_protect_fail (void)
26599 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26600 ? default_hidden_stack_protect_fail ()
26601 : default_external_stack_protect_fail ();
26605 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26606 int num_operands ATTRIBUTE_UNUSED)
26608 if (rs6000_warn_cell_microcode)
26611 int insn_code_number = recog_memoized (insn);
26612 location_t location = locator_location (INSN_LOCATOR (insn));
26614 /* Punt on insns we cannot recognize. */
26615 if (insn_code_number < 0)
26618 temp = get_insn_template (insn_code_number, insn);
26620 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26621 warning_at (location, OPT_mwarn_cell_microcode,
26622 "emitting microcode insn %s\t[%s] #%d",
26623 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26624 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26625 warning_at (location, OPT_mwarn_cell_microcode,
26626 "emitting conditional microcode insn %s\t[%s] #%d",
26627 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26631 #include "gt-rs6000.h"