1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
56 #include "tree-flow.h"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack {
76 int first_gp_reg_save; /* first callee saved GP register used */
77 int first_fp_reg_save; /* first callee saved FP register used */
78 int first_altivec_reg_save; /* first callee saved AltiVec register used */
79 int lr_save_p; /* true if the link reg needs to be saved */
80 int cr_save_p; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask; /* mask of vec registers to save */
82 int push_p; /* true if we need to allocate stack space */
83 int calls_p; /* true if the function makes any calls */
84 int world_save_p; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi; /* which ABI to use */
87 int gp_save_offset; /* offset to save GP regs from initial SP */
88 int fp_save_offset; /* offset to save FP regs from initial SP */
89 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset; /* offset to save LR from initial SP */
91 int cr_save_offset; /* offset to save CR from initial SP */
92 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset; /* offset to save the varargs registers */
95 int ehrd_offset; /* offset to EH return data */
96 int reg_size; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size; /* variable save area size */
98 int parm_size; /* outgoing parameter size */
99 int save_size; /* save area size */
100 int fixed_size; /* fixed size of stack frame */
101 int gp_size; /* size of saved GP registers */
102 int fp_size; /* size of saved FP registers */
103 int altivec_size; /* size of saved AltiVec registers */
104 int cr_size; /* size to hold CR if not in save_size */
105 int vrsave_size; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size; /* size of altivec alignment padding if
108 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size;
110 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
111 int spe_64bit_regs_used;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct GTY(()) machine_function
118 /* Some local-dynamic symbol. */
119 const char *some_ld_name;
120 /* Whether the instruction chain has been scanned already. */
121 int insn_chain_scanned_p;
122 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
123 int ra_needs_full_frame;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Cache lr_save_p after expansion of builtin_eh_return. */
128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
129 varargs save area. */
130 HOST_WIDE_INT varargs_save_offset;
131 /* Temporary stack slot to use for SDmode copies. This slot is
132 64-bits wide and is allocated early enough so that the offset
133 does not overflow the 16-bit load/store offset field. */
134 rtx sdmode_stack_slot;
137 /* Target cpu type */
139 enum processor_type rs6000_cpu;
140 struct rs6000_cpu_select rs6000_select[3] =
142 /* switch name, tune arch */
143 { (const char *)0, "--with-cpu=", 1, 1 },
144 { (const char *)0, "-mcpu=", 1, 1 },
145 { (const char *)0, "-mtune=", 1, 0 },
148 /* Always emit branch hint bits. */
149 static GTY(()) bool rs6000_always_hint;
151 /* Schedule instructions for group formation. */
152 static GTY(()) bool rs6000_sched_groups;
154 /* Align branch targets. */
155 static GTY(()) bool rs6000_align_branch_targets;
157 /* Support for -msched-costly-dep option. */
158 const char *rs6000_sched_costly_dep_str;
159 enum rs6000_dependence_cost rs6000_sched_costly_dep;
161 /* Support for -minsert-sched-nops option. */
162 const char *rs6000_sched_insert_nops_str;
163 enum rs6000_nop_insertion rs6000_sched_insert_nops;
165 /* Support targetm.vectorize.builtin_mask_for_load. */
166 static GTY(()) tree altivec_builtin_mask_for_load;
168 /* Size of long double. */
169 int rs6000_long_double_type_size;
171 /* IEEE quad extended precision long double. */
174 /* Nonzero to use AltiVec ABI. */
175 int rs6000_altivec_abi;
177 /* Nonzero if we want SPE SIMD instructions. */
180 /* Nonzero if we want SPE ABI extensions. */
183 /* Nonzero if floating point operations are done in the GPRs. */
184 int rs6000_float_gprs = 0;
186 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
187 int rs6000_darwin64_abi;
189 /* Set to nonzero once AIX common-mode calls have been defined. */
190 static GTY(()) int common_mode_defined;
192 /* Label number of label created for -mrelocatable, to call to so we can
193 get the address of the GOT section */
194 int rs6000_pic_labelno;
197 /* Which abi to adhere to */
198 const char *rs6000_abi_name;
200 /* Semantics of the small data area */
201 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
203 /* Which small data model to use */
204 const char *rs6000_sdata_name = (char *)0;
206 /* Counter for labels which are to be placed in .fixup. */
207 int fixuplabelno = 0;
210 /* Bit size of immediate TLS offsets and string from which it is decoded. */
211 int rs6000_tls_size = 32;
212 const char *rs6000_tls_size_string;
214 /* ABI enumeration available for subtarget to use. */
215 enum rs6000_abi rs6000_current_abi;
217 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
221 const char *rs6000_debug_name;
222 int rs6000_debug_stack; /* debug stack applications */
223 int rs6000_debug_arg; /* debug argument handling */
224 int rs6000_debug_reg; /* debug register classes */
225 int rs6000_debug_addr; /* debug memory addressing */
226 int rs6000_debug_cost; /* debug rtx_costs */
228 /* Specify the machine mode that pointers have. After generation of rtl, the
229 compiler makes no further distinction between pointers and any other objects
230 of this machine mode. The type is unsigned since not all things that
231 include rs6000.h also include machmode.h. */
232 unsigned rs6000_pmode;
234 /* Width in bits of a pointer. */
235 unsigned rs6000_pointer_size;
238 /* Value is TRUE if register/mode pair is acceptable. */
239 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
241 /* Maximum number of registers needed for a given register class and mode. */
242 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
244 /* How many registers are needed for a given register and mode. */
245 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
247 /* Map register number to register class. */
248 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
250 /* Reload functions based on the type and the vector unit. */
251 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
253 /* Built in types. */
254 tree rs6000_builtin_types[RS6000_BTI_MAX];
255 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
257 const char *rs6000_traceback_name;
259 traceback_default = 0,
265 /* Flag to say the TOC is initialized */
267 char toc_label_name[10];
269 /* Cached value of rs6000_variable_issue. This is cached in
270 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
271 static short cached_can_issue_more;
273 static GTY(()) section *read_only_data_section;
274 static GTY(()) section *private_data_section;
275 static GTY(()) section *read_only_private_data_section;
276 static GTY(()) section *sdata2_section;
277 static GTY(()) section *toc_section;
279 /* Control alignment for fields within structures. */
280 /* String from -malign-XXXXX. */
281 int rs6000_alignment_flags;
283 /* Code model for 64-bit linux. */
284 enum rs6000_cmodel cmodel;
286 /* True for any options that were explicitly set. */
288 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
289 bool alignment; /* True if -malign- was used. */
290 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
291 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
292 bool spe; /* True if -mspe= was used. */
293 bool float_gprs; /* True if -mfloat-gprs= was used. */
294 bool long_double; /* True if -mlong-double- was used. */
295 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
296 bool vrsave; /* True if -mvrsave was used. */
297 bool cmodel; /* True if -mcmodel was used. */
298 } rs6000_explicit_options;
300 struct builtin_description
302 /* mask is not const because we're going to alter it below. This
303 nonsense will go away when we rewrite the -march infrastructure
304 to give us more target flag bits. */
306 const enum insn_code icode;
307 const char *const name;
308 const enum rs6000_builtins code;
311 /* Describe the vector unit used for modes. */
312 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
313 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
315 /* Register classes for various constraints that are based on the target
317 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
319 /* Describe the alignment of a vector. */
320 int rs6000_vector_align[NUM_MACHINE_MODES];
322 /* Map selected modes to types for builtins. */
323 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
325 /* What modes to automatically generate reciprocal divide estimate (fre) and
326 reciprocal sqrt (frsqrte) for. */
327 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
329 /* Masks to determine which reciprocal esitmate instructions to generate
331 enum rs6000_recip_mask {
332 RECIP_SF_DIV = 0x001, /* Use divide estimate */
333 RECIP_DF_DIV = 0x002,
334 RECIP_V4SF_DIV = 0x004,
335 RECIP_V2DF_DIV = 0x008,
337 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
338 RECIP_DF_RSQRT = 0x020,
339 RECIP_V4SF_RSQRT = 0x040,
340 RECIP_V2DF_RSQRT = 0x080,
342 /* Various combination of flags for -mrecip=xxx. */
344 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
345 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
346 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
348 RECIP_HIGH_PRECISION = RECIP_ALL,
350 /* On low precision machines like the power5, don't enable double precision
351 reciprocal square root estimate, since it isn't accurate enough. */
352 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
355 static unsigned int rs6000_recip_control;
356 static const char *rs6000_recip_name;
358 /* -mrecip options. */
361 const char *string; /* option name */
362 unsigned int mask; /* mask bits to set */
363 } recip_options[] = {
364 { "all", RECIP_ALL },
365 { "none", RECIP_NONE },
366 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
368 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
369 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
370 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
371 | RECIP_V2DF_RSQRT) },
372 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
373 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
376 /* 2 argument gen function typedef. */
377 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
380 /* Target cpu costs. */
382 struct processor_costs {
383 const int mulsi; /* cost of SImode multiplication. */
384 const int mulsi_const; /* cost of SImode multiplication by constant. */
385 const int mulsi_const9; /* cost of SImode mult by short constant. */
386 const int muldi; /* cost of DImode multiplication. */
387 const int divsi; /* cost of SImode division. */
388 const int divdi; /* cost of DImode division. */
389 const int fp; /* cost of simple SFmode and DFmode insns. */
390 const int dmul; /* cost of DFmode multiplication (and fmadd). */
391 const int sdiv; /* cost of SFmode division (fdivs). */
392 const int ddiv; /* cost of DFmode division (fdiv). */
393 const int cache_line_size; /* cache line size in bytes. */
394 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
395 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
396 const int simultaneous_prefetches; /* number of parallel prefetch
400 const struct processor_costs *rs6000_cost;
402 /* Processor costs (relative to an add) */
404 /* Instruction size costs on 32bit processors. */
406 struct processor_costs size32_cost = {
407 COSTS_N_INSNS (1), /* mulsi */
408 COSTS_N_INSNS (1), /* mulsi_const */
409 COSTS_N_INSNS (1), /* mulsi_const9 */
410 COSTS_N_INSNS (1), /* muldi */
411 COSTS_N_INSNS (1), /* divsi */
412 COSTS_N_INSNS (1), /* divdi */
413 COSTS_N_INSNS (1), /* fp */
414 COSTS_N_INSNS (1), /* dmul */
415 COSTS_N_INSNS (1), /* sdiv */
416 COSTS_N_INSNS (1), /* ddiv */
423 /* Instruction size costs on 64bit processors. */
425 struct processor_costs size64_cost = {
426 COSTS_N_INSNS (1), /* mulsi */
427 COSTS_N_INSNS (1), /* mulsi_const */
428 COSTS_N_INSNS (1), /* mulsi_const9 */
429 COSTS_N_INSNS (1), /* muldi */
430 COSTS_N_INSNS (1), /* divsi */
431 COSTS_N_INSNS (1), /* divdi */
432 COSTS_N_INSNS (1), /* fp */
433 COSTS_N_INSNS (1), /* dmul */
434 COSTS_N_INSNS (1), /* sdiv */
435 COSTS_N_INSNS (1), /* ddiv */
442 /* Instruction costs on RIOS1 processors. */
444 struct processor_costs rios1_cost = {
445 COSTS_N_INSNS (5), /* mulsi */
446 COSTS_N_INSNS (4), /* mulsi_const */
447 COSTS_N_INSNS (3), /* mulsi_const9 */
448 COSTS_N_INSNS (5), /* muldi */
449 COSTS_N_INSNS (19), /* divsi */
450 COSTS_N_INSNS (19), /* divdi */
451 COSTS_N_INSNS (2), /* fp */
452 COSTS_N_INSNS (2), /* dmul */
453 COSTS_N_INSNS (19), /* sdiv */
454 COSTS_N_INSNS (19), /* ddiv */
455 128, /* cache line size */
461 /* Instruction costs on RIOS2 processors. */
463 struct processor_costs rios2_cost = {
464 COSTS_N_INSNS (2), /* mulsi */
465 COSTS_N_INSNS (2), /* mulsi_const */
466 COSTS_N_INSNS (2), /* mulsi_const9 */
467 COSTS_N_INSNS (2), /* muldi */
468 COSTS_N_INSNS (13), /* divsi */
469 COSTS_N_INSNS (13), /* divdi */
470 COSTS_N_INSNS (2), /* fp */
471 COSTS_N_INSNS (2), /* dmul */
472 COSTS_N_INSNS (17), /* sdiv */
473 COSTS_N_INSNS (17), /* ddiv */
474 256, /* cache line size */
480 /* Instruction costs on RS64A processors. */
482 struct processor_costs rs64a_cost = {
483 COSTS_N_INSNS (20), /* mulsi */
484 COSTS_N_INSNS (12), /* mulsi_const */
485 COSTS_N_INSNS (8), /* mulsi_const9 */
486 COSTS_N_INSNS (34), /* muldi */
487 COSTS_N_INSNS (65), /* divsi */
488 COSTS_N_INSNS (67), /* divdi */
489 COSTS_N_INSNS (4), /* fp */
490 COSTS_N_INSNS (4), /* dmul */
491 COSTS_N_INSNS (31), /* sdiv */
492 COSTS_N_INSNS (31), /* ddiv */
493 128, /* cache line size */
499 /* Instruction costs on MPCCORE processors. */
501 struct processor_costs mpccore_cost = {
502 COSTS_N_INSNS (2), /* mulsi */
503 COSTS_N_INSNS (2), /* mulsi_const */
504 COSTS_N_INSNS (2), /* mulsi_const9 */
505 COSTS_N_INSNS (2), /* muldi */
506 COSTS_N_INSNS (6), /* divsi */
507 COSTS_N_INSNS (6), /* divdi */
508 COSTS_N_INSNS (4), /* fp */
509 COSTS_N_INSNS (5), /* dmul */
510 COSTS_N_INSNS (10), /* sdiv */
511 COSTS_N_INSNS (17), /* ddiv */
512 32, /* cache line size */
518 /* Instruction costs on PPC403 processors. */
520 struct processor_costs ppc403_cost = {
521 COSTS_N_INSNS (4), /* mulsi */
522 COSTS_N_INSNS (4), /* mulsi_const */
523 COSTS_N_INSNS (4), /* mulsi_const9 */
524 COSTS_N_INSNS (4), /* muldi */
525 COSTS_N_INSNS (33), /* divsi */
526 COSTS_N_INSNS (33), /* divdi */
527 COSTS_N_INSNS (11), /* fp */
528 COSTS_N_INSNS (11), /* dmul */
529 COSTS_N_INSNS (11), /* sdiv */
530 COSTS_N_INSNS (11), /* ddiv */
531 32, /* cache line size */
537 /* Instruction costs on PPC405 processors. */
539 struct processor_costs ppc405_cost = {
540 COSTS_N_INSNS (5), /* mulsi */
541 COSTS_N_INSNS (4), /* mulsi_const */
542 COSTS_N_INSNS (3), /* mulsi_const9 */
543 COSTS_N_INSNS (5), /* muldi */
544 COSTS_N_INSNS (35), /* divsi */
545 COSTS_N_INSNS (35), /* divdi */
546 COSTS_N_INSNS (11), /* fp */
547 COSTS_N_INSNS (11), /* dmul */
548 COSTS_N_INSNS (11), /* sdiv */
549 COSTS_N_INSNS (11), /* ddiv */
550 32, /* cache line size */
556 /* Instruction costs on PPC440 processors. */
558 struct processor_costs ppc440_cost = {
559 COSTS_N_INSNS (3), /* mulsi */
560 COSTS_N_INSNS (2), /* mulsi_const */
561 COSTS_N_INSNS (2), /* mulsi_const9 */
562 COSTS_N_INSNS (3), /* muldi */
563 COSTS_N_INSNS (34), /* divsi */
564 COSTS_N_INSNS (34), /* divdi */
565 COSTS_N_INSNS (5), /* fp */
566 COSTS_N_INSNS (5), /* dmul */
567 COSTS_N_INSNS (19), /* sdiv */
568 COSTS_N_INSNS (33), /* ddiv */
569 32, /* cache line size */
575 /* Instruction costs on PPC476 processors. */
577 struct processor_costs ppc476_cost = {
578 COSTS_N_INSNS (4), /* mulsi */
579 COSTS_N_INSNS (4), /* mulsi_const */
580 COSTS_N_INSNS (4), /* mulsi_const9 */
581 COSTS_N_INSNS (4), /* muldi */
582 COSTS_N_INSNS (11), /* divsi */
583 COSTS_N_INSNS (11), /* divdi */
584 COSTS_N_INSNS (6), /* fp */
585 COSTS_N_INSNS (6), /* dmul */
586 COSTS_N_INSNS (19), /* sdiv */
587 COSTS_N_INSNS (33), /* ddiv */
588 32, /* l1 cache line size */
594 /* Instruction costs on PPC601 processors. */
596 struct processor_costs ppc601_cost = {
597 COSTS_N_INSNS (5), /* mulsi */
598 COSTS_N_INSNS (5), /* mulsi_const */
599 COSTS_N_INSNS (5), /* mulsi_const9 */
600 COSTS_N_INSNS (5), /* muldi */
601 COSTS_N_INSNS (36), /* divsi */
602 COSTS_N_INSNS (36), /* divdi */
603 COSTS_N_INSNS (4), /* fp */
604 COSTS_N_INSNS (5), /* dmul */
605 COSTS_N_INSNS (17), /* sdiv */
606 COSTS_N_INSNS (31), /* ddiv */
607 32, /* cache line size */
613 /* Instruction costs on PPC603 processors. */
615 struct processor_costs ppc603_cost = {
616 COSTS_N_INSNS (5), /* mulsi */
617 COSTS_N_INSNS (3), /* mulsi_const */
618 COSTS_N_INSNS (2), /* mulsi_const9 */
619 COSTS_N_INSNS (5), /* muldi */
620 COSTS_N_INSNS (37), /* divsi */
621 COSTS_N_INSNS (37), /* divdi */
622 COSTS_N_INSNS (3), /* fp */
623 COSTS_N_INSNS (4), /* dmul */
624 COSTS_N_INSNS (18), /* sdiv */
625 COSTS_N_INSNS (33), /* ddiv */
626 32, /* cache line size */
632 /* Instruction costs on PPC604 processors. */
634 struct processor_costs ppc604_cost = {
635 COSTS_N_INSNS (4), /* mulsi */
636 COSTS_N_INSNS (4), /* mulsi_const */
637 COSTS_N_INSNS (4), /* mulsi_const9 */
638 COSTS_N_INSNS (4), /* muldi */
639 COSTS_N_INSNS (20), /* divsi */
640 COSTS_N_INSNS (20), /* divdi */
641 COSTS_N_INSNS (3), /* fp */
642 COSTS_N_INSNS (3), /* dmul */
643 COSTS_N_INSNS (18), /* sdiv */
644 COSTS_N_INSNS (32), /* ddiv */
645 32, /* cache line size */
651 /* Instruction costs on PPC604e processors. */
653 struct processor_costs ppc604e_cost = {
654 COSTS_N_INSNS (2), /* mulsi */
655 COSTS_N_INSNS (2), /* mulsi_const */
656 COSTS_N_INSNS (2), /* mulsi_const9 */
657 COSTS_N_INSNS (2), /* muldi */
658 COSTS_N_INSNS (20), /* divsi */
659 COSTS_N_INSNS (20), /* divdi */
660 COSTS_N_INSNS (3), /* fp */
661 COSTS_N_INSNS (3), /* dmul */
662 COSTS_N_INSNS (18), /* sdiv */
663 COSTS_N_INSNS (32), /* ddiv */
664 32, /* cache line size */
670 /* Instruction costs on PPC620 processors. */
672 struct processor_costs ppc620_cost = {
673 COSTS_N_INSNS (5), /* mulsi */
674 COSTS_N_INSNS (4), /* mulsi_const */
675 COSTS_N_INSNS (3), /* mulsi_const9 */
676 COSTS_N_INSNS (7), /* muldi */
677 COSTS_N_INSNS (21), /* divsi */
678 COSTS_N_INSNS (37), /* divdi */
679 COSTS_N_INSNS (3), /* fp */
680 COSTS_N_INSNS (3), /* dmul */
681 COSTS_N_INSNS (18), /* sdiv */
682 COSTS_N_INSNS (32), /* ddiv */
683 128, /* cache line size */
689 /* Instruction costs on PPC630 processors. */
691 struct processor_costs ppc630_cost = {
692 COSTS_N_INSNS (5), /* mulsi */
693 COSTS_N_INSNS (4), /* mulsi_const */
694 COSTS_N_INSNS (3), /* mulsi_const9 */
695 COSTS_N_INSNS (7), /* muldi */
696 COSTS_N_INSNS (21), /* divsi */
697 COSTS_N_INSNS (37), /* divdi */
698 COSTS_N_INSNS (3), /* fp */
699 COSTS_N_INSNS (3), /* dmul */
700 COSTS_N_INSNS (17), /* sdiv */
701 COSTS_N_INSNS (21), /* ddiv */
702 128, /* cache line size */
708 /* Instruction costs on Cell processor. */
709 /* COSTS_N_INSNS (1) ~ one add. */
711 struct processor_costs ppccell_cost = {
712 COSTS_N_INSNS (9/2)+2, /* mulsi */
713 COSTS_N_INSNS (6/2), /* mulsi_const */
714 COSTS_N_INSNS (6/2), /* mulsi_const9 */
715 COSTS_N_INSNS (15/2)+2, /* muldi */
716 COSTS_N_INSNS (38/2), /* divsi */
717 COSTS_N_INSNS (70/2), /* divdi */
718 COSTS_N_INSNS (10/2), /* fp */
719 COSTS_N_INSNS (10/2), /* dmul */
720 COSTS_N_INSNS (74/2), /* sdiv */
721 COSTS_N_INSNS (74/2), /* ddiv */
722 128, /* cache line size */
728 /* Instruction costs on PPC750 and PPC7400 processors. */
730 struct processor_costs ppc750_cost = {
731 COSTS_N_INSNS (5), /* mulsi */
732 COSTS_N_INSNS (3), /* mulsi_const */
733 COSTS_N_INSNS (2), /* mulsi_const9 */
734 COSTS_N_INSNS (5), /* muldi */
735 COSTS_N_INSNS (17), /* divsi */
736 COSTS_N_INSNS (17), /* divdi */
737 COSTS_N_INSNS (3), /* fp */
738 COSTS_N_INSNS (3), /* dmul */
739 COSTS_N_INSNS (17), /* sdiv */
740 COSTS_N_INSNS (31), /* ddiv */
741 32, /* cache line size */
747 /* Instruction costs on PPC7450 processors. */
749 struct processor_costs ppc7450_cost = {
750 COSTS_N_INSNS (4), /* mulsi */
751 COSTS_N_INSNS (3), /* mulsi_const */
752 COSTS_N_INSNS (3), /* mulsi_const9 */
753 COSTS_N_INSNS (4), /* muldi */
754 COSTS_N_INSNS (23), /* divsi */
755 COSTS_N_INSNS (23), /* divdi */
756 COSTS_N_INSNS (5), /* fp */
757 COSTS_N_INSNS (5), /* dmul */
758 COSTS_N_INSNS (21), /* sdiv */
759 COSTS_N_INSNS (35), /* ddiv */
760 32, /* cache line size */
766 /* Instruction costs on PPC8540 processors. */
768 struct processor_costs ppc8540_cost = {
769 COSTS_N_INSNS (4), /* mulsi */
770 COSTS_N_INSNS (4), /* mulsi_const */
771 COSTS_N_INSNS (4), /* mulsi_const9 */
772 COSTS_N_INSNS (4), /* muldi */
773 COSTS_N_INSNS (19), /* divsi */
774 COSTS_N_INSNS (19), /* divdi */
775 COSTS_N_INSNS (4), /* fp */
776 COSTS_N_INSNS (4), /* dmul */
777 COSTS_N_INSNS (29), /* sdiv */
778 COSTS_N_INSNS (29), /* ddiv */
779 32, /* cache line size */
782 1, /* prefetch streams /*/
785 /* Instruction costs on E300C2 and E300C3 cores. */
787 struct processor_costs ppce300c2c3_cost = {
788 COSTS_N_INSNS (4), /* mulsi */
789 COSTS_N_INSNS (4), /* mulsi_const */
790 COSTS_N_INSNS (4), /* mulsi_const9 */
791 COSTS_N_INSNS (4), /* muldi */
792 COSTS_N_INSNS (19), /* divsi */
793 COSTS_N_INSNS (19), /* divdi */
794 COSTS_N_INSNS (3), /* fp */
795 COSTS_N_INSNS (4), /* dmul */
796 COSTS_N_INSNS (18), /* sdiv */
797 COSTS_N_INSNS (33), /* ddiv */
801 1, /* prefetch streams /*/
804 /* Instruction costs on PPCE500MC processors. */
806 struct processor_costs ppce500mc_cost = {
807 COSTS_N_INSNS (4), /* mulsi */
808 COSTS_N_INSNS (4), /* mulsi_const */
809 COSTS_N_INSNS (4), /* mulsi_const9 */
810 COSTS_N_INSNS (4), /* muldi */
811 COSTS_N_INSNS (14), /* divsi */
812 COSTS_N_INSNS (14), /* divdi */
813 COSTS_N_INSNS (8), /* fp */
814 COSTS_N_INSNS (10), /* dmul */
815 COSTS_N_INSNS (36), /* sdiv */
816 COSTS_N_INSNS (66), /* ddiv */
817 64, /* cache line size */
820 1, /* prefetch streams /*/
823 /* Instruction costs on PPCE500MC64 processors. */
825 struct processor_costs ppce500mc64_cost = {
826 COSTS_N_INSNS (4), /* mulsi */
827 COSTS_N_INSNS (4), /* mulsi_const */
828 COSTS_N_INSNS (4), /* mulsi_const9 */
829 COSTS_N_INSNS (4), /* muldi */
830 COSTS_N_INSNS (14), /* divsi */
831 COSTS_N_INSNS (14), /* divdi */
832 COSTS_N_INSNS (4), /* fp */
833 COSTS_N_INSNS (10), /* dmul */
834 COSTS_N_INSNS (36), /* sdiv */
835 COSTS_N_INSNS (66), /* ddiv */
836 64, /* cache line size */
839 1, /* prefetch streams /*/
842 /* Instruction costs on AppliedMicro Titan processors. */
844 struct processor_costs titan_cost = {
845 COSTS_N_INSNS (5), /* mulsi */
846 COSTS_N_INSNS (5), /* mulsi_const */
847 COSTS_N_INSNS (5), /* mulsi_const9 */
848 COSTS_N_INSNS (5), /* muldi */
849 COSTS_N_INSNS (18), /* divsi */
850 COSTS_N_INSNS (18), /* divdi */
851 COSTS_N_INSNS (10), /* fp */
852 COSTS_N_INSNS (10), /* dmul */
853 COSTS_N_INSNS (46), /* sdiv */
854 COSTS_N_INSNS (72), /* ddiv */
855 32, /* cache line size */
858 1, /* prefetch streams /*/
861 /* Instruction costs on POWER4 and POWER5 processors. */
863 struct processor_costs power4_cost = {
864 COSTS_N_INSNS (3), /* mulsi */
865 COSTS_N_INSNS (2), /* mulsi_const */
866 COSTS_N_INSNS (2), /* mulsi_const9 */
867 COSTS_N_INSNS (4), /* muldi */
868 COSTS_N_INSNS (18), /* divsi */
869 COSTS_N_INSNS (34), /* divdi */
870 COSTS_N_INSNS (3), /* fp */
871 COSTS_N_INSNS (3), /* dmul */
872 COSTS_N_INSNS (17), /* sdiv */
873 COSTS_N_INSNS (17), /* ddiv */
874 128, /* cache line size */
877 8, /* prefetch streams /*/
880 /* Instruction costs on POWER6 processors. */
882 struct processor_costs power6_cost = {
883 COSTS_N_INSNS (8), /* mulsi */
884 COSTS_N_INSNS (8), /* mulsi_const */
885 COSTS_N_INSNS (8), /* mulsi_const9 */
886 COSTS_N_INSNS (8), /* muldi */
887 COSTS_N_INSNS (22), /* divsi */
888 COSTS_N_INSNS (28), /* divdi */
889 COSTS_N_INSNS (3), /* fp */
890 COSTS_N_INSNS (3), /* dmul */
891 COSTS_N_INSNS (13), /* sdiv */
892 COSTS_N_INSNS (16), /* ddiv */
893 128, /* cache line size */
896 16, /* prefetch streams */
899 /* Instruction costs on POWER7 processors. */
901 struct processor_costs power7_cost = {
902 COSTS_N_INSNS (2), /* mulsi */
903 COSTS_N_INSNS (2), /* mulsi_const */
904 COSTS_N_INSNS (2), /* mulsi_const9 */
905 COSTS_N_INSNS (2), /* muldi */
906 COSTS_N_INSNS (18), /* divsi */
907 COSTS_N_INSNS (34), /* divdi */
908 COSTS_N_INSNS (3), /* fp */
909 COSTS_N_INSNS (3), /* dmul */
910 COSTS_N_INSNS (13), /* sdiv */
911 COSTS_N_INSNS (16), /* ddiv */
912 128, /* cache line size */
915 12, /* prefetch streams */
918 /* Instruction costs on POWER A2 processors. */
920 struct processor_costs ppca2_cost = {
921 COSTS_N_INSNS (16), /* mulsi */
922 COSTS_N_INSNS (16), /* mulsi_const */
923 COSTS_N_INSNS (16), /* mulsi_const9 */
924 COSTS_N_INSNS (16), /* muldi */
925 COSTS_N_INSNS (22), /* divsi */
926 COSTS_N_INSNS (28), /* divdi */
927 COSTS_N_INSNS (3), /* fp */
928 COSTS_N_INSNS (3), /* dmul */
929 COSTS_N_INSNS (59), /* sdiv */
930 COSTS_N_INSNS (72), /* ddiv */
934 16, /* prefetch streams */
938 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
939 #undef RS6000_BUILTIN
940 #undef RS6000_BUILTIN_EQUATE
941 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
942 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
944 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
946 #include "rs6000-builtin.def"
949 #undef RS6000_BUILTIN
950 #undef RS6000_BUILTIN_EQUATE
952 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
953 static tree (*rs6000_veclib_handler) (tree, tree, tree);
956 static bool rs6000_function_ok_for_sibcall (tree, tree);
957 static const char *rs6000_invalid_within_doloop (const_rtx);
958 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
959 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
960 static rtx rs6000_generate_compare (rtx, enum machine_mode);
961 static void rs6000_emit_stack_tie (void);
962 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
963 static bool spe_func_has_64bit_regs_p (void);
964 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
966 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
967 static unsigned rs6000_hash_constant (rtx);
968 static unsigned toc_hash_function (const void *);
969 static int toc_hash_eq (const void *, const void *);
970 static bool reg_offset_addressing_ok_p (enum machine_mode);
971 static bool virtual_stack_registers_memory_p (rtx);
972 static bool constant_pool_expr_p (rtx);
973 static bool legitimate_small_data_p (enum machine_mode, rtx);
974 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
975 static struct machine_function * rs6000_init_machine_status (void);
976 static bool rs6000_assemble_integer (rtx, unsigned int, int);
977 static bool no_global_regs_above (int, bool);
978 #ifdef HAVE_GAS_HIDDEN
979 static void rs6000_assemble_visibility (tree, int);
981 static int rs6000_ra_ever_killed (void);
982 static bool rs6000_attribute_takes_identifier_p (const_tree);
983 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
984 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
985 static bool rs6000_ms_bitfield_layout_p (const_tree);
986 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
987 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
988 static const char *rs6000_mangle_type (const_tree);
989 static void rs6000_set_default_type_attributes (tree);
990 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
991 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
992 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
993 enum machine_mode, bool, bool, bool);
994 static bool rs6000_reg_live_or_pic_offset_p (int);
995 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
996 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
997 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
998 static void rs6000_restore_saved_cr (rtx, int);
999 static bool rs6000_output_addr_const_extra (FILE *, rtx);
1000 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
1001 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
1002 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
1004 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1005 static bool rs6000_return_in_memory (const_tree, const_tree);
1006 static rtx rs6000_function_value (const_tree, const_tree, bool);
1007 static void rs6000_file_start (void);
1009 static int rs6000_elf_reloc_rw_mask (void);
1010 static void rs6000_elf_asm_out_constructor (rtx, int);
1011 static void rs6000_elf_asm_out_destructor (rtx, int);
1012 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1013 static void rs6000_elf_asm_init_sections (void);
1014 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1015 unsigned HOST_WIDE_INT);
1016 static void rs6000_elf_encode_section_info (tree, rtx, int)
1019 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1020 static void rs6000_alloc_sdmode_stack_slot (void);
1021 static void rs6000_instantiate_decls (void);
1023 static void rs6000_xcoff_asm_output_anchor (rtx);
1024 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1025 static void rs6000_xcoff_asm_init_sections (void);
1026 static int rs6000_xcoff_reloc_rw_mask (void);
1027 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1028 static section *rs6000_xcoff_select_section (tree, int,
1029 unsigned HOST_WIDE_INT);
1030 static void rs6000_xcoff_unique_section (tree, int);
1031 static section *rs6000_xcoff_select_rtx_section
1032 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1033 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1034 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1035 static void rs6000_xcoff_file_start (void);
1036 static void rs6000_xcoff_file_end (void);
1038 static int rs6000_variable_issue (FILE *, int, rtx, int);
1039 static int rs6000_register_move_cost (enum machine_mode,
1040 reg_class_t, reg_class_t);
1041 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1042 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1043 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1044 static int rs6000_debug_address_cost (rtx, bool);
1045 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1046 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1047 static void rs6000_sched_init (FILE *, int, int);
1048 static bool is_microcoded_insn (rtx);
1049 static bool is_nonpipeline_insn (rtx);
1050 static bool is_cracked_insn (rtx);
1051 static bool is_branch_slot_insn (rtx);
1052 static bool is_load_insn (rtx);
1053 static rtx get_store_dest (rtx pat);
1054 static bool is_store_insn (rtx);
1055 static bool set_to_load_agen (rtx,rtx);
1056 static bool adjacent_mem_locations (rtx,rtx);
1057 static int rs6000_adjust_priority (rtx, int);
1058 static int rs6000_issue_rate (void);
1059 static bool rs6000_is_costly_dependence (dep_t, int, int);
1060 static rtx get_next_active_insn (rtx, rtx);
1061 static bool insn_terminates_group_p (rtx , enum group_termination);
1062 static bool insn_must_be_first_in_group (rtx);
1063 static bool insn_must_be_last_in_group (rtx);
1064 static bool is_costly_group (rtx *, rtx);
1065 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1066 static int redefine_groups (FILE *, int, rtx, rtx);
1067 static int pad_groups (FILE *, int, rtx, rtx);
1068 static void rs6000_sched_finish (FILE *, int);
1069 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1070 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1071 static int rs6000_use_sched_lookahead (void);
1072 static int rs6000_use_sched_lookahead_guard (rtx);
1073 static void * rs6000_alloc_sched_context (void);
1074 static void rs6000_init_sched_context (void *, bool);
1075 static void rs6000_set_sched_context (void *);
1076 static void rs6000_free_sched_context (void *);
1077 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1078 static tree rs6000_builtin_mask_for_load (void);
1079 static tree rs6000_builtin_mul_widen_even (tree);
1080 static tree rs6000_builtin_mul_widen_odd (tree);
1081 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1082 static tree rs6000_builtin_vec_perm (tree, tree *);
1083 static bool rs6000_builtin_support_vector_misalignment (enum
1087 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1089 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1091 static void def_builtin (int, const char *, tree, int);
1092 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1093 static void rs6000_init_builtins (void);
1094 static tree rs6000_builtin_decl (unsigned, bool);
1096 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1097 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1098 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1099 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1100 static void altivec_init_builtins (void);
1101 static unsigned builtin_hash_function (const void *);
1102 static int builtin_hash_eq (const void *, const void *);
1103 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1104 enum machine_mode, enum machine_mode,
1105 enum rs6000_builtins, const char *name);
1106 static void rs6000_common_init_builtins (void);
1107 static void rs6000_init_libfuncs (void);
1109 static void paired_init_builtins (void);
1110 static rtx paired_expand_builtin (tree, rtx, bool *);
1111 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1112 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1113 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1115 static void enable_mask_for_builtins (struct builtin_description *, int,
1116 enum rs6000_builtins,
1117 enum rs6000_builtins);
1118 static void spe_init_builtins (void);
1119 static rtx spe_expand_builtin (tree, rtx, bool *);
1120 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1121 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1122 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1123 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1124 static rs6000_stack_t *rs6000_stack_info (void);
1125 static void debug_stack_info (rs6000_stack_t *);
1127 static rtx altivec_expand_builtin (tree, rtx, bool *);
1128 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1129 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1130 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1131 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1132 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1133 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1134 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1135 static rtx altivec_expand_vec_set_builtin (tree);
1136 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1137 static int get_element_number (tree, tree);
1138 static void rs6000_option_override (void);
1139 static void rs6000_option_optimization (int, int);
1140 static void rs6000_option_default_params (void);
1141 static bool rs6000_handle_option (size_t, const char *, int);
1142 static void rs6000_parse_tls_size_option (void);
1143 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1144 static int first_altivec_reg_to_save (void);
1145 static unsigned int compute_vrsave_mask (void);
1146 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1147 static void is_altivec_return_reg (rtx, void *);
1148 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1149 int easy_vector_constant (rtx, enum machine_mode);
1150 static rtx rs6000_dwarf_register_span (rtx);
1151 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1152 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1153 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1154 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1155 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1156 static rtx rs6000_delegitimize_address (rtx);
1157 static rtx rs6000_tls_get_addr (void);
1158 static rtx rs6000_got_sym (void);
1159 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1160 static const char *rs6000_get_some_local_dynamic_name (void);
1161 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1162 static rtx rs6000_complex_function_value (enum machine_mode);
1163 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1164 enum machine_mode, const_tree);
1165 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1166 HOST_WIDE_INT, int);
1167 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1170 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1173 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1174 const_tree, HOST_WIDE_INT,
1176 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1177 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1178 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1180 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1182 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1183 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1184 enum machine_mode, tree,
1186 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1188 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1190 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1192 static void macho_branch_islands (void);
1193 static int no_previous_def (tree function_name);
1194 static tree get_prev_label (tree function_name);
1195 static void rs6000_darwin_file_start (void);
1198 static tree rs6000_build_builtin_va_list (void);
1199 static void rs6000_va_start (tree, rtx);
1200 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1201 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1202 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1203 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1204 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1205 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1207 static tree rs6000_stack_protect_fail (void);
1209 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1212 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1215 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1217 = rs6000_legitimize_reload_address;
1219 static bool rs6000_mode_dependent_address_p (const_rtx);
1220 static bool rs6000_mode_dependent_address (const_rtx);
1221 static bool rs6000_debug_mode_dependent_address (const_rtx);
1222 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1223 = rs6000_mode_dependent_address;
1225 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1226 enum machine_mode, rtx);
1227 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1230 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1231 enum machine_mode, rtx)
1232 = rs6000_secondary_reload_class;
1234 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1235 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1237 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1238 = rs6000_preferred_reload_class;
1240 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1243 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1247 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1249 = rs6000_secondary_memory_needed;
1251 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1254 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1258 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1261 = rs6000_cannot_change_mode_class;
1263 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1265 struct secondary_reload_info *);
1267 static const reg_class_t *rs6000_ira_cover_classes (void);
1269 const int INSN_NOT_AVAILABLE = -1;
1270 static enum machine_mode rs6000_eh_return_filter_mode (void);
1271 static bool rs6000_can_eliminate (const int, const int);
1272 static void rs6000_trampoline_init (rtx, tree, rtx);
1274 /* Hash table stuff for keeping track of TOC entries. */
1276 struct GTY(()) toc_hash_struct
1278 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1279 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1281 enum machine_mode key_mode;
1285 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1287 /* Hash table to keep track of the argument types for builtin functions. */
1289 struct GTY(()) builtin_hash_struct
1292 enum machine_mode mode[4]; /* return value + 3 arguments. */
1293 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1296 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1298 /* Default register names. */
1299 char rs6000_reg_names[][8] =
1301 "0", "1", "2", "3", "4", "5", "6", "7",
1302 "8", "9", "10", "11", "12", "13", "14", "15",
1303 "16", "17", "18", "19", "20", "21", "22", "23",
1304 "24", "25", "26", "27", "28", "29", "30", "31",
1305 "0", "1", "2", "3", "4", "5", "6", "7",
1306 "8", "9", "10", "11", "12", "13", "14", "15",
1307 "16", "17", "18", "19", "20", "21", "22", "23",
1308 "24", "25", "26", "27", "28", "29", "30", "31",
1309 "mq", "lr", "ctr","ap",
1310 "0", "1", "2", "3", "4", "5", "6", "7",
1312 /* AltiVec registers. */
1313 "0", "1", "2", "3", "4", "5", "6", "7",
1314 "8", "9", "10", "11", "12", "13", "14", "15",
1315 "16", "17", "18", "19", "20", "21", "22", "23",
1316 "24", "25", "26", "27", "28", "29", "30", "31",
1318 /* SPE registers. */
1319 "spe_acc", "spefscr",
1320 /* Soft frame pointer. */
1324 #ifdef TARGET_REGNAMES
1325 static const char alt_reg_names[][8] =
1327 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1328 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1329 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1330 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1331 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1332 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1333 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1334 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1335 "mq", "lr", "ctr", "ap",
1336 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1338 /* AltiVec registers. */
1339 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1340 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1341 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1342 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1344 /* SPE registers. */
1345 "spe_acc", "spefscr",
1346 /* Soft frame pointer. */
1351 /* Table of valid machine attributes. */
1353 static const struct attribute_spec rs6000_attribute_table[] =
1355 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1356 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1357 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1358 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1359 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1360 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1361 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1362 SUBTARGET_ATTRIBUTE_TABLE,
1364 { NULL, 0, 0, false, false, false, NULL }
1367 #ifndef MASK_STRICT_ALIGN
1368 #define MASK_STRICT_ALIGN 0
1370 #ifndef TARGET_PROFILE_KERNEL
1371 #define TARGET_PROFILE_KERNEL 0
1374 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1375 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1377 /* Initialize the GCC target structure. */
1378 #undef TARGET_ATTRIBUTE_TABLE
1379 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1380 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1381 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1382 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1383 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1385 #undef TARGET_ASM_ALIGNED_DI_OP
1386 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1388 /* Default unaligned ops are only provided for ELF. Find the ops needed
1389 for non-ELF systems. */
1390 #ifndef OBJECT_FORMAT_ELF
1392 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1394 #undef TARGET_ASM_UNALIGNED_HI_OP
1395 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1396 #undef TARGET_ASM_UNALIGNED_SI_OP
1397 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1398 #undef TARGET_ASM_UNALIGNED_DI_OP
1399 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1402 #undef TARGET_ASM_UNALIGNED_HI_OP
1403 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1404 #undef TARGET_ASM_UNALIGNED_SI_OP
1405 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1406 #undef TARGET_ASM_UNALIGNED_DI_OP
1407 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1408 #undef TARGET_ASM_ALIGNED_DI_OP
1409 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1413 /* This hook deals with fixups for relocatable code and DI-mode objects
1415 #undef TARGET_ASM_INTEGER
1416 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1418 #ifdef HAVE_GAS_HIDDEN
1419 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1420 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1423 #undef TARGET_HAVE_TLS
1424 #define TARGET_HAVE_TLS HAVE_AS_TLS
1426 #undef TARGET_CANNOT_FORCE_CONST_MEM
1427 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1429 #undef TARGET_DELEGITIMIZE_ADDRESS
1430 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1432 #undef TARGET_ASM_FUNCTION_PROLOGUE
1433 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1434 #undef TARGET_ASM_FUNCTION_EPILOGUE
1435 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1437 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1438 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1440 #undef TARGET_LEGITIMIZE_ADDRESS
1441 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1443 #undef TARGET_SCHED_VARIABLE_ISSUE
1444 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1446 #undef TARGET_SCHED_ISSUE_RATE
1447 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1448 #undef TARGET_SCHED_ADJUST_COST
1449 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1450 #undef TARGET_SCHED_ADJUST_PRIORITY
1451 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1452 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1453 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1454 #undef TARGET_SCHED_INIT
1455 #define TARGET_SCHED_INIT rs6000_sched_init
1456 #undef TARGET_SCHED_FINISH
1457 #define TARGET_SCHED_FINISH rs6000_sched_finish
1458 #undef TARGET_SCHED_REORDER
1459 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1460 #undef TARGET_SCHED_REORDER2
1461 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1463 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1464 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1466 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1467 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1469 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1470 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1471 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1472 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1473 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1474 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1475 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1476 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1478 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1479 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1480 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1481 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1482 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1483 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1484 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1485 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1486 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1487 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1488 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1489 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1490 rs6000_builtin_support_vector_misalignment
1491 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1492 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1493 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1494 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1495 rs6000_builtin_vectorization_cost
1496 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1497 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1498 rs6000_preferred_simd_mode
1500 #undef TARGET_INIT_BUILTINS
1501 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1502 #undef TARGET_BUILTIN_DECL
1503 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1505 #undef TARGET_EXPAND_BUILTIN
1506 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1508 #undef TARGET_MANGLE_TYPE
1509 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1511 #undef TARGET_INIT_LIBFUNCS
1512 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1515 #undef TARGET_BINDS_LOCAL_P
1516 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1519 #undef TARGET_MS_BITFIELD_LAYOUT_P
1520 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1522 #undef TARGET_ASM_OUTPUT_MI_THUNK
1523 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1525 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1526 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1528 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1529 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1531 #undef TARGET_INVALID_WITHIN_DOLOOP
1532 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1534 #undef TARGET_REGISTER_MOVE_COST
1535 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1536 #undef TARGET_MEMORY_MOVE_COST
1537 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1538 #undef TARGET_RTX_COSTS
1539 #define TARGET_RTX_COSTS rs6000_rtx_costs
1540 #undef TARGET_ADDRESS_COST
1541 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1543 #undef TARGET_DWARF_REGISTER_SPAN
1544 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1546 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1547 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1549 /* On rs6000, function arguments are promoted, as are function return
1551 #undef TARGET_PROMOTE_FUNCTION_MODE
1552 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1554 #undef TARGET_RETURN_IN_MEMORY
1555 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1557 #undef TARGET_SETUP_INCOMING_VARARGS
1558 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1560 /* Always strict argument naming on rs6000. */
1561 #undef TARGET_STRICT_ARGUMENT_NAMING
1562 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1563 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1564 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1565 #undef TARGET_SPLIT_COMPLEX_ARG
1566 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1567 #undef TARGET_MUST_PASS_IN_STACK
1568 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1569 #undef TARGET_PASS_BY_REFERENCE
1570 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1571 #undef TARGET_ARG_PARTIAL_BYTES
1572 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1573 #undef TARGET_FUNCTION_ARG_ADVANCE
1574 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1575 #undef TARGET_FUNCTION_ARG
1576 #define TARGET_FUNCTION_ARG rs6000_function_arg
1578 #undef TARGET_BUILD_BUILTIN_VA_LIST
1579 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1581 #undef TARGET_EXPAND_BUILTIN_VA_START
1582 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1584 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1585 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1587 #undef TARGET_EH_RETURN_FILTER_MODE
1588 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1590 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1591 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1593 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1594 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1596 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1597 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1599 #undef TARGET_HANDLE_OPTION
1600 #define TARGET_HANDLE_OPTION rs6000_handle_option
1602 #undef TARGET_OPTION_OVERRIDE
1603 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1605 #undef TARGET_OPTION_OPTIMIZATION
1606 #define TARGET_OPTION_OPTIMIZATION rs6000_option_optimization
1608 #undef TARGET_OPTION_DEFAULT_PARAMS
1609 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1611 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1612 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1613 rs6000_builtin_vectorized_function
1615 #undef TARGET_DEFAULT_TARGET_FLAGS
1616 #define TARGET_DEFAULT_TARGET_FLAGS \
1619 #undef TARGET_STACK_PROTECT_FAIL
1620 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1622 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1623 The PowerPC architecture requires only weak consistency among
1624 processors--that is, memory accesses between processors need not be
1625 sequentially consistent and memory accesses among processors can occur
1626 in any order. The ability to order memory accesses weakly provides
1627 opportunities for more efficient use of the system bus. Unless a
1628 dependency exists, the 604e allows read operations to precede store
1630 #undef TARGET_RELAXED_ORDERING
1631 #define TARGET_RELAXED_ORDERING true
1634 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1635 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1638 /* Use a 32-bit anchor range. This leads to sequences like:
1640 addis tmp,anchor,high
1643 where tmp itself acts as an anchor, and can be shared between
1644 accesses to the same 64k page. */
1645 #undef TARGET_MIN_ANCHOR_OFFSET
1646 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1647 #undef TARGET_MAX_ANCHOR_OFFSET
1648 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1649 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1650 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1652 #undef TARGET_BUILTIN_RECIPROCAL
1653 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1655 #undef TARGET_EXPAND_TO_RTL_HOOK
1656 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1658 #undef TARGET_INSTANTIATE_DECLS
1659 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1661 #undef TARGET_SECONDARY_RELOAD
1662 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1664 #undef TARGET_IRA_COVER_CLASSES
1665 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1667 #undef TARGET_LEGITIMATE_ADDRESS_P
1668 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1670 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1671 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1673 #undef TARGET_CAN_ELIMINATE
1674 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1676 #undef TARGET_TRAMPOLINE_INIT
1677 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1679 #undef TARGET_FUNCTION_VALUE
1680 #define TARGET_FUNCTION_VALUE rs6000_function_value
1682 struct gcc_target targetm = TARGET_INITIALIZER;
1684 /* Return number of consecutive hard regs needed starting at reg REGNO
1685 to hold something of mode MODE.
1686 This is ordinarily the length in words of a value of mode MODE
1687 but can be less for certain modes in special long registers.
1689 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1690 scalar instructions. The upper 32 bits are only available to the
1693 POWER and PowerPC GPRs hold 32 bits worth;
1694 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1697 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1699 unsigned HOST_WIDE_INT reg_size;
1701 if (FP_REGNO_P (regno))
1702 reg_size = (VECTOR_MEM_VSX_P (mode)
1703 ? UNITS_PER_VSX_WORD
1704 : UNITS_PER_FP_WORD);
1706 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1707 reg_size = UNITS_PER_SPE_WORD;
1709 else if (ALTIVEC_REGNO_P (regno))
1710 reg_size = UNITS_PER_ALTIVEC_WORD;
1712 /* The value returned for SCmode in the E500 double case is 2 for
1713 ABI compatibility; storing an SCmode value in a single register
1714 would require function_arg and rs6000_spe_function_arg to handle
1715 SCmode so as to pass the value correctly in a pair of
1717 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1718 && !DECIMAL_FLOAT_MODE_P (mode))
1719 reg_size = UNITS_PER_FP_WORD;
1722 reg_size = UNITS_PER_WORD;
1724 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1727 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1730 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1732 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1734 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1735 implementations. Don't allow an item to be split between a FP register
1736 and an Altivec register. */
1737 if (VECTOR_MEM_VSX_P (mode))
1739 if (FP_REGNO_P (regno))
1740 return FP_REGNO_P (last_regno);
1742 if (ALTIVEC_REGNO_P (regno))
1743 return ALTIVEC_REGNO_P (last_regno);
1746 /* The GPRs can hold any mode, but values bigger than one register
1747 cannot go past R31. */
1748 if (INT_REGNO_P (regno))
1749 return INT_REGNO_P (last_regno);
1751 /* The float registers (except for VSX vector modes) can only hold floating
1752 modes and DImode. This excludes the 32-bit decimal float mode for
1754 if (FP_REGNO_P (regno))
1756 if (SCALAR_FLOAT_MODE_P (mode)
1757 && (mode != TDmode || (regno % 2) == 0)
1758 && FP_REGNO_P (last_regno))
1761 if (GET_MODE_CLASS (mode) == MODE_INT
1762 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1765 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1766 && PAIRED_VECTOR_MODE (mode))
1772 /* The CR register can only hold CC modes. */
1773 if (CR_REGNO_P (regno))
1774 return GET_MODE_CLASS (mode) == MODE_CC;
1776 if (CA_REGNO_P (regno))
1777 return mode == BImode;
1779 /* AltiVec only in AldyVec registers. */
1780 if (ALTIVEC_REGNO_P (regno))
1781 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1783 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1784 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1787 /* We cannot put TImode anywhere except general register and it must be able
1788 to fit within the register set. In the future, allow TImode in the
1789 Altivec or VSX registers. */
1791 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1794 /* Print interesting facts about registers. */
1796 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1800 for (r = first_regno; r <= last_regno; ++r)
1802 const char *comma = "";
1805 if (first_regno == last_regno)
1806 fprintf (stderr, "%s:\t", reg_name);
1808 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1811 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1812 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1816 fprintf (stderr, ",\n\t");
1821 if (rs6000_hard_regno_nregs[m][r] > 1)
1822 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1823 rs6000_hard_regno_nregs[m][r]);
1825 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1830 if (call_used_regs[r])
1834 fprintf (stderr, ",\n\t");
1839 len += fprintf (stderr, "%s%s", comma, "call-used");
1847 fprintf (stderr, ",\n\t");
1852 len += fprintf (stderr, "%s%s", comma, "fixed");
1858 fprintf (stderr, ",\n\t");
1862 fprintf (stderr, "%sregno = %d\n", comma, r);
1866 /* Print various interesting information with -mdebug=reg. */
1868 rs6000_debug_reg_global (void)
1870 const char *nl = (const char *)0;
1872 char costly_num[20];
1874 const char *costly_str;
1875 const char *nop_str;
1877 /* Map enum rs6000_vector to string. */
1878 static const char *rs6000_debug_vector_unit[] = {
1887 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1888 LAST_VIRTUAL_REGISTER);
1889 rs6000_debug_reg_print (0, 31, "gr");
1890 rs6000_debug_reg_print (32, 63, "fp");
1891 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1894 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1895 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1896 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1897 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1898 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1899 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1900 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1901 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1902 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1906 "d reg_class = %s\n"
1907 "f reg_class = %s\n"
1908 "v reg_class = %s\n"
1909 "wa reg_class = %s\n"
1910 "wd reg_class = %s\n"
1911 "wf reg_class = %s\n"
1912 "ws reg_class = %s\n\n",
1913 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1914 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1915 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1916 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1917 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1918 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1919 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1921 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1922 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1925 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1927 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1928 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1934 if (rs6000_recip_control)
1936 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1938 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1939 if (rs6000_recip_bits[m])
1942 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1944 (RS6000_RECIP_AUTO_RE_P (m)
1946 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1947 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1949 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1952 fputs ("\n", stderr);
1955 switch (rs6000_sched_costly_dep)
1957 case max_dep_latency:
1958 costly_str = "max_dep_latency";
1962 costly_str = "no_dep_costly";
1965 case all_deps_costly:
1966 costly_str = "all_deps_costly";
1969 case true_store_to_load_dep_costly:
1970 costly_str = "true_store_to_load_dep_costly";
1973 case store_to_load_dep_costly:
1974 costly_str = "store_to_load_dep_costly";
1978 costly_str = costly_num;
1979 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1983 switch (rs6000_sched_insert_nops)
1985 case sched_finish_regroup_exact:
1986 nop_str = "sched_finish_regroup_exact";
1989 case sched_finish_pad_groups:
1990 nop_str = "sched_finish_pad_groups";
1993 case sched_finish_none:
1994 nop_str = "sched_finish_none";
1999 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2004 "always_hint = %s\n"
2005 "align_branch_targets = %s\n"
2006 "sched_restricted_insns_priority = %d\n"
2007 "sched_costly_dep = %s\n"
2008 "sched_insert_nops = %s\n\n",
2009 rs6000_always_hint ? "true" : "false",
2010 rs6000_align_branch_targets ? "true" : "false",
2011 (int)rs6000_sched_restricted_insns_priority,
2012 costly_str, nop_str);
2015 /* Initialize the various global tables that are based on register size. */
2017 rs6000_init_hard_regno_mode_ok (void)
2023 /* Precalculate REGNO_REG_CLASS. */
2024 rs6000_regno_regclass[0] = GENERAL_REGS;
2025 for (r = 1; r < 32; ++r)
2026 rs6000_regno_regclass[r] = BASE_REGS;
2028 for (r = 32; r < 64; ++r)
2029 rs6000_regno_regclass[r] = FLOAT_REGS;
2031 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2032 rs6000_regno_regclass[r] = NO_REGS;
2034 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2035 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2037 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2038 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2039 rs6000_regno_regclass[r] = CR_REGS;
2041 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2042 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2043 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2044 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2045 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2046 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2047 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2048 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2049 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2050 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2052 /* Precalculate vector information, this must be set up before the
2053 rs6000_hard_regno_nregs_internal below. */
2054 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2056 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2057 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2058 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2061 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2062 rs6000_constraints[c] = NO_REGS;
2064 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2065 believes it can use native alignment or still uses 128-bit alignment. */
2066 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2077 /* V2DF mode, VSX only. */
2080 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2081 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2082 rs6000_vector_align[V2DFmode] = align64;
2085 /* V4SF mode, either VSX or Altivec. */
2088 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2089 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2090 rs6000_vector_align[V4SFmode] = align32;
2092 else if (TARGET_ALTIVEC)
2094 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2095 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2096 rs6000_vector_align[V4SFmode] = align32;
2099 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2103 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2104 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2105 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2106 rs6000_vector_align[V4SImode] = align32;
2107 rs6000_vector_align[V8HImode] = align32;
2108 rs6000_vector_align[V16QImode] = align32;
2112 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2113 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2114 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2118 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2119 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2120 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2124 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2125 Altivec doesn't have 64-bit support. */
2128 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2129 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2130 rs6000_vector_align[V2DImode] = align64;
2133 /* DFmode, see if we want to use the VSX unit. */
2134 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2136 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2137 rs6000_vector_mem[DFmode]
2138 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2139 rs6000_vector_align[DFmode] = align64;
2142 /* TODO add SPE and paired floating point vector support. */
2144 /* Register class constaints for the constraints that depend on compile
2146 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2147 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2149 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2150 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2154 /* At present, we just use VSX_REGS, but we have different constraints
2155 based on the use, in case we want to fine tune the default register
2156 class used. wa = any VSX register, wf = register class to use for
2157 V4SF, wd = register class to use for V2DF, and ws = register classs to
2158 use for DF scalars. */
2159 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2160 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2161 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2162 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2168 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2170 /* Set up the reload helper functions. */
2171 if (TARGET_VSX || TARGET_ALTIVEC)
2175 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2176 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2177 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2178 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2179 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2180 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2181 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2182 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2183 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2184 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2185 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2186 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2190 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2191 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2192 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2193 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2194 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2195 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2196 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2197 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2198 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2199 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2200 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2201 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2205 /* Precalculate HARD_REGNO_NREGS. */
2206 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2207 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2208 rs6000_hard_regno_nregs[m][r]
2209 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2211 /* Precalculate HARD_REGNO_MODE_OK. */
2212 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2213 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2214 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2215 rs6000_hard_regno_mode_ok_p[m][r] = true;
2217 /* Precalculate CLASS_MAX_NREGS sizes. */
2218 for (c = 0; c < LIM_REG_CLASSES; ++c)
2222 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2223 reg_size = UNITS_PER_VSX_WORD;
2225 else if (c == ALTIVEC_REGS)
2226 reg_size = UNITS_PER_ALTIVEC_WORD;
2228 else if (c == FLOAT_REGS)
2229 reg_size = UNITS_PER_FP_WORD;
2232 reg_size = UNITS_PER_WORD;
2234 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2235 rs6000_class_max_nregs[m][c]
2236 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2239 if (TARGET_E500_DOUBLE)
2240 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2242 /* Calculate which modes to automatically generate code to use a the
2243 reciprocal divide and square root instructions. In the future, possibly
2244 automatically generate the instructions even if the user did not specify
2245 -mrecip. The older machines double precision reciprocal sqrt estimate is
2246 not accurate enough. */
2247 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2249 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2251 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2252 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2253 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2254 if (VECTOR_UNIT_VSX_P (V2DFmode))
2255 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2257 if (TARGET_FRSQRTES)
2258 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2260 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2261 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2262 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2263 if (VECTOR_UNIT_VSX_P (V2DFmode))
2264 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2266 if (rs6000_recip_control)
2268 if (!TARGET_FUSED_MADD)
2269 warning (0, "-mrecip requires -mfused-madd");
2270 if (!flag_finite_math_only)
2271 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2272 if (flag_trapping_math)
2273 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2274 if (!flag_reciprocal_math)
2275 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2276 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2277 && flag_reciprocal_math)
2279 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2280 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2281 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2283 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2284 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2285 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2287 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2288 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2289 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2291 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2292 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2293 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2295 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2296 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2297 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2299 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2300 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2301 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2303 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2304 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2305 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2307 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2308 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2309 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2313 if (TARGET_DEBUG_REG)
2314 rs6000_debug_reg_global ();
2316 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2318 "SImode variable mult cost = %d\n"
2319 "SImode constant mult cost = %d\n"
2320 "SImode short constant mult cost = %d\n"
2321 "DImode multipliciation cost = %d\n"
2322 "SImode division cost = %d\n"
2323 "DImode division cost = %d\n"
2324 "Simple fp operation cost = %d\n"
2325 "DFmode multiplication cost = %d\n"
2326 "SFmode division cost = %d\n"
2327 "DFmode division cost = %d\n"
2328 "cache line size = %d\n"
2329 "l1 cache size = %d\n"
2330 "l2 cache size = %d\n"
2331 "simultaneous prefetches = %d\n"
2334 rs6000_cost->mulsi_const,
2335 rs6000_cost->mulsi_const9,
2343 rs6000_cost->cache_line_size,
2344 rs6000_cost->l1_cache_size,
2345 rs6000_cost->l2_cache_size,
2346 rs6000_cost->simultaneous_prefetches);
2350 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2353 darwin_rs6000_override_options (void)
2355 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2357 rs6000_altivec_abi = 1;
2358 TARGET_ALTIVEC_VRSAVE = 1;
2359 if (DEFAULT_ABI == ABI_DARWIN)
2361 if (MACHO_DYNAMIC_NO_PIC_P)
2364 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2367 else if (flag_pic == 1)
2372 darwin_one_byte_bool = 1;
2374 if (TARGET_64BIT && ! TARGET_POWERPC64)
2376 target_flags |= MASK_POWERPC64;
2377 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2381 rs6000_default_long_calls = 1;
2382 target_flags |= MASK_SOFT_FLOAT;
2385 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2387 if (!flag_mkernel && !flag_apple_kext
2389 && ! (target_flags_explicit & MASK_ALTIVEC))
2390 target_flags |= MASK_ALTIVEC;
2392 /* Unless the user (not the configurer) has explicitly overridden
2393 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2394 G4 unless targetting the kernel. */
2397 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2398 && ! (target_flags_explicit & MASK_ALTIVEC)
2399 && ! rs6000_select[1].string)
2401 target_flags |= MASK_ALTIVEC;
2406 /* If not otherwise specified by a target, make 'long double' equivalent to
2409 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2410 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2413 /* Override command line options. Mostly we process the processor
2414 type and sometimes adjust other TARGET_ options. */
2417 rs6000_option_override_internal (const char *default_cpu)
2420 struct rs6000_cpu_select *ptr;
2423 /* Simplifications for entries below. */
2426 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2427 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2430 /* This table occasionally claims that a processor does not support
2431 a particular feature even though it does, but the feature is slower
2432 than the alternative. Thus, it shouldn't be relied on as a
2433 complete description of the processor's support.
2435 Please keep this list in order, and don't forget to update the
2436 documentation in invoke.texi when adding a new processor or
2440 const char *const name; /* Canonical processor name. */
2441 const enum processor_type processor; /* Processor type enum value. */
2442 const int target_enable; /* Target flags to enable. */
2443 } const processor_target_table[]
2444 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2445 {"403", PROCESSOR_PPC403,
2446 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2447 {"405", PROCESSOR_PPC405,
2448 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2449 {"405fp", PROCESSOR_PPC405,
2450 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2451 {"440", PROCESSOR_PPC440,
2452 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2453 {"440fp", PROCESSOR_PPC440,
2454 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2455 {"464", PROCESSOR_PPC440,
2456 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2457 {"464fp", PROCESSOR_PPC440,
2458 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2459 {"476", PROCESSOR_PPC476,
2460 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2461 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2462 {"476fp", PROCESSOR_PPC476,
2463 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2464 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2465 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2466 {"601", PROCESSOR_PPC601,
2467 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2468 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2469 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2470 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2471 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2472 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2473 {"620", PROCESSOR_PPC620,
2474 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2475 {"630", PROCESSOR_PPC630,
2476 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2477 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2478 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2479 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2480 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2481 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2482 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2483 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2484 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2486 /* 8548 has a dummy entry for now. */
2487 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2489 {"a2", PROCESSOR_PPCA2,
2490 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2491 | MASK_CMPB | MASK_NO_UPDATE },
2492 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2493 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2494 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2496 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2497 | MASK_PPC_GFXOPT | MASK_ISEL},
2498 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2499 {"970", PROCESSOR_POWER4,
2500 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2501 {"cell", PROCESSOR_CELL,
2502 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2503 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2504 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2505 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2506 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2507 {"G5", PROCESSOR_POWER4,
2508 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2509 {"titan", PROCESSOR_TITAN,
2510 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2511 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2512 {"power2", PROCESSOR_POWER,
2513 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2514 {"power3", PROCESSOR_PPC630,
2515 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2516 {"power4", PROCESSOR_POWER4,
2517 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2519 {"power5", PROCESSOR_POWER5,
2520 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2521 | MASK_MFCRF | MASK_POPCNTB},
2522 {"power5+", PROCESSOR_POWER5,
2523 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2524 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2525 {"power6", PROCESSOR_POWER6,
2526 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2527 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2528 | MASK_RECIP_PRECISION},
2529 {"power6x", PROCESSOR_POWER6,
2530 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2531 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2532 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2533 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
2534 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2535 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2536 | MASK_VSX | MASK_RECIP_PRECISION},
2537 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2538 {"powerpc64", PROCESSOR_POWERPC64,
2539 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2540 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2541 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2542 {"rios2", PROCESSOR_RIOS2,
2543 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2544 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2545 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2546 {"rs64", PROCESSOR_RS64A,
2547 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2550 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2552 /* Some OSs don't support saving the high part of 64-bit registers on
2553 context switch. Other OSs don't support saving Altivec registers.
2554 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2555 settings; if the user wants either, the user must explicitly specify
2556 them and we won't interfere with the user's specification. */
2559 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2560 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2561 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2562 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2563 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2564 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2565 | MASK_RECIP_PRECISION)
2568 /* Masks for instructions set at various powerpc ISAs. */
2570 ISA_2_1_MASKS = MASK_MFCRF,
2571 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2573 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2574 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2575 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2576 masks by server and embedded. */
2577 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2578 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2579 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2581 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2582 altivec is a win so enable it. */
2583 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2584 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2588 /* Numerous experiment shows that IRA based loop pressure
2589 calculation works better for RTL loop invariant motion on targets
2590 with enough (>= 32) registers. It is an expensive optimization.
2591 So it is on only for peak performance. */
2593 flag_ira_loop_pressure = 1;
2595 /* Set the pointer size. */
2598 rs6000_pmode = (int)DImode;
2599 rs6000_pointer_size = 64;
2603 rs6000_pmode = (int)SImode;
2604 rs6000_pointer_size = 32;
2607 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2608 #ifdef OS_MISSING_POWERPC64
2609 if (OS_MISSING_POWERPC64)
2610 set_masks &= ~MASK_POWERPC64;
2612 #ifdef OS_MISSING_ALTIVEC
2613 if (OS_MISSING_ALTIVEC)
2614 set_masks &= ~MASK_ALTIVEC;
2617 /* Don't override by the processor default if given explicitly. */
2618 set_masks &= ~target_flags_explicit;
2620 /* Identify the processor type. */
2621 rs6000_select[0].string = default_cpu;
2622 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2624 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2626 ptr = &rs6000_select[i];
2627 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2629 for (j = 0; j < ptt_size; j++)
2630 if (! strcmp (ptr->string, processor_target_table[j].name))
2632 if (ptr->set_tune_p)
2633 rs6000_cpu = processor_target_table[j].processor;
2635 if (ptr->set_arch_p)
2637 target_flags &= ~set_masks;
2638 target_flags |= (processor_target_table[j].target_enable
2645 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2649 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2650 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2653 error ("AltiVec not supported in this target");
2655 error ("Spe not supported in this target");
2658 /* Disable Cell microcode if we are optimizing for the Cell
2659 and not optimizing for size. */
2660 if (rs6000_gen_cell_microcode == -1)
2661 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2664 /* If we are optimizing big endian systems for space and it's OK to
2665 use instructions that would be microcoded on the Cell, use the
2666 load/store multiple and string instructions. */
2667 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2668 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2670 /* Don't allow -mmultiple or -mstring on little endian systems
2671 unless the cpu is a 750, because the hardware doesn't support the
2672 instructions used in little endian mode, and causes an alignment
2673 trap. The 750 does not cause an alignment trap (except when the
2674 target is unaligned). */
2676 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2678 if (TARGET_MULTIPLE)
2680 target_flags &= ~MASK_MULTIPLE;
2681 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2682 warning (0, "-mmultiple is not supported on little endian systems");
2687 target_flags &= ~MASK_STRING;
2688 if ((target_flags_explicit & MASK_STRING) != 0)
2689 warning (0, "-mstring is not supported on little endian systems");
2693 /* Add some warnings for VSX. */
2696 const char *msg = NULL;
2697 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2698 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2700 if (target_flags_explicit & MASK_VSX)
2701 msg = N_("-mvsx requires hardware floating point");
2703 target_flags &= ~ MASK_VSX;
2705 else if (TARGET_PAIRED_FLOAT)
2706 msg = N_("-mvsx and -mpaired are incompatible");
2707 /* The hardware will allow VSX and little endian, but until we make sure
2708 things like vector select, etc. work don't allow VSX on little endian
2709 systems at this point. */
2710 else if (!BYTES_BIG_ENDIAN)
2711 msg = N_("-mvsx used with little endian code");
2712 else if (TARGET_AVOID_XFORM > 0)
2713 msg = N_("-mvsx needs indexed addressing");
2714 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2716 if (target_flags_explicit & MASK_VSX)
2717 msg = N_("-mvsx and -mno-altivec are incompatible");
2719 msg = N_("-mno-altivec disables vsx");
2725 target_flags &= ~ MASK_VSX;
2726 target_flags_explicit |= MASK_VSX;
2730 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2731 unless the user explicitly used the -mno-<option> to disable the code. */
2733 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2734 else if (TARGET_POPCNTD)
2735 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2736 else if (TARGET_DFP)
2737 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2738 else if (TARGET_CMPB)
2739 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2740 else if (TARGET_POPCNTB || TARGET_FPRND)
2741 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2742 else if (TARGET_ALTIVEC)
2743 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2745 /* E500mc does "better" if we inline more aggressively. Respect the
2746 user's opinion, though. */
2747 if (rs6000_block_move_inline_limit == 0
2748 && (rs6000_cpu == PROCESSOR_PPCE500MC
2749 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2750 rs6000_block_move_inline_limit = 128;
2752 /* store_one_arg depends on expand_block_move to handle at least the
2753 size of reg_parm_stack_space. */
2754 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2755 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2757 /* Set debug flags */
2758 if (rs6000_debug_name)
2760 if (! strcmp (rs6000_debug_name, "all"))
2761 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2762 = rs6000_debug_addr = rs6000_debug_cost = 1;
2763 else if (! strcmp (rs6000_debug_name, "stack"))
2764 rs6000_debug_stack = 1;
2765 else if (! strcmp (rs6000_debug_name, "arg"))
2766 rs6000_debug_arg = 1;
2767 else if (! strcmp (rs6000_debug_name, "reg"))
2768 rs6000_debug_reg = 1;
2769 else if (! strcmp (rs6000_debug_name, "addr"))
2770 rs6000_debug_addr = 1;
2771 else if (! strcmp (rs6000_debug_name, "cost"))
2772 rs6000_debug_cost = 1;
2774 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2776 /* If the appropriate debug option is enabled, replace the target hooks
2777 with debug versions that call the real version and then prints
2778 debugging information. */
2779 if (TARGET_DEBUG_COST)
2781 targetm.rtx_costs = rs6000_debug_rtx_costs;
2782 targetm.address_cost = rs6000_debug_address_cost;
2783 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2786 if (TARGET_DEBUG_ADDR)
2788 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2789 targetm.legitimize_address = rs6000_debug_legitimize_address;
2790 rs6000_secondary_reload_class_ptr
2791 = rs6000_debug_secondary_reload_class;
2792 rs6000_secondary_memory_needed_ptr
2793 = rs6000_debug_secondary_memory_needed;
2794 rs6000_cannot_change_mode_class_ptr
2795 = rs6000_debug_cannot_change_mode_class;
2796 rs6000_preferred_reload_class_ptr
2797 = rs6000_debug_preferred_reload_class;
2798 rs6000_legitimize_reload_address_ptr
2799 = rs6000_debug_legitimize_reload_address;
2800 rs6000_mode_dependent_address_ptr
2801 = rs6000_debug_mode_dependent_address;
2805 if (rs6000_traceback_name)
2807 if (! strncmp (rs6000_traceback_name, "full", 4))
2808 rs6000_traceback = traceback_full;
2809 else if (! strncmp (rs6000_traceback_name, "part", 4))
2810 rs6000_traceback = traceback_part;
2811 else if (! strncmp (rs6000_traceback_name, "no", 2))
2812 rs6000_traceback = traceback_none;
2814 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2815 rs6000_traceback_name);
2818 if (rs6000_veclibabi_name)
2820 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2821 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2823 error ("unknown vectorization library ABI type (%s) for "
2824 "-mveclibabi= switch", rs6000_veclibabi_name);
2827 if (!rs6000_explicit_options.long_double)
2828 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2830 #ifndef POWERPC_LINUX
2831 if (!rs6000_explicit_options.ieee)
2832 rs6000_ieeequad = 1;
2835 /* Enable Altivec ABI for AIX -maltivec. */
2836 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2837 rs6000_altivec_abi = 1;
2839 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2840 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2841 be explicitly overridden in either case. */
2844 if (!rs6000_explicit_options.altivec_abi
2845 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2846 rs6000_altivec_abi = 1;
2848 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2849 if (!rs6000_explicit_options.vrsave)
2850 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2853 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2854 So far, the only darwin64 targets are also MACH-O. */
2856 && DEFAULT_ABI == ABI_DARWIN
2859 rs6000_darwin64_abi = 1;
2860 /* Default to natural alignment, for better performance. */
2861 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2864 /* Place FP constants in the constant pool instead of TOC
2865 if section anchors enabled. */
2866 if (flag_section_anchors)
2867 TARGET_NO_FP_IN_TOC = 1;
2869 /* Handle -mtls-size option. */
2870 rs6000_parse_tls_size_option ();
2872 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2873 SUBTARGET_OVERRIDE_OPTIONS;
2875 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2876 SUBSUBTARGET_OVERRIDE_OPTIONS;
2878 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2879 SUB3TARGET_OVERRIDE_OPTIONS;
2882 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2883 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2885 /* The e500 and e500mc do not have string instructions, and we set
2886 MASK_STRING above when optimizing for size. */
2887 if ((target_flags & MASK_STRING) != 0)
2888 target_flags = target_flags & ~MASK_STRING;
2890 else if (rs6000_select[1].string != NULL)
2892 /* For the powerpc-eabispe configuration, we set all these by
2893 default, so let's unset them if we manually set another
2894 CPU that is not the E500. */
2895 if (!rs6000_explicit_options.spe_abi)
2897 if (!rs6000_explicit_options.spe)
2899 if (!rs6000_explicit_options.float_gprs)
2900 rs6000_float_gprs = 0;
2901 if (!(target_flags_explicit & MASK_ISEL))
2902 target_flags &= ~MASK_ISEL;
2905 /* Detect invalid option combinations with E500. */
2908 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2909 && rs6000_cpu != PROCESSOR_POWER5
2910 && rs6000_cpu != PROCESSOR_POWER6
2911 && rs6000_cpu != PROCESSOR_POWER7
2912 && rs6000_cpu != PROCESSOR_PPCA2
2913 && rs6000_cpu != PROCESSOR_CELL);
2914 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2915 || rs6000_cpu == PROCESSOR_POWER5
2916 || rs6000_cpu == PROCESSOR_POWER7);
2917 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2918 || rs6000_cpu == PROCESSOR_POWER5
2919 || rs6000_cpu == PROCESSOR_POWER6
2920 || rs6000_cpu == PROCESSOR_POWER7
2921 || rs6000_cpu == PROCESSOR_PPCE500MC
2922 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2924 /* Allow debug switches to override the above settings. */
2925 if (TARGET_ALWAYS_HINT > 0)
2926 rs6000_always_hint = TARGET_ALWAYS_HINT;
2928 if (TARGET_SCHED_GROUPS > 0)
2929 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2931 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2932 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2934 rs6000_sched_restricted_insns_priority
2935 = (rs6000_sched_groups ? 1 : 0);
2937 /* Handle -msched-costly-dep option. */
2938 rs6000_sched_costly_dep
2939 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2941 if (rs6000_sched_costly_dep_str)
2943 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2944 rs6000_sched_costly_dep = no_dep_costly;
2945 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2946 rs6000_sched_costly_dep = all_deps_costly;
2947 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2948 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2949 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2950 rs6000_sched_costly_dep = store_to_load_dep_costly;
2952 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2953 atoi (rs6000_sched_costly_dep_str));
2956 /* Handle -minsert-sched-nops option. */
2957 rs6000_sched_insert_nops
2958 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2960 if (rs6000_sched_insert_nops_str)
2962 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2963 rs6000_sched_insert_nops = sched_finish_none;
2964 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2965 rs6000_sched_insert_nops = sched_finish_pad_groups;
2966 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2967 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2969 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2970 atoi (rs6000_sched_insert_nops_str));
2973 #ifdef TARGET_REGNAMES
2974 /* If the user desires alternate register names, copy in the
2975 alternate names now. */
2976 if (TARGET_REGNAMES)
2977 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2980 /* Set aix_struct_return last, after the ABI is determined.
2981 If -maix-struct-return or -msvr4-struct-return was explicitly
2982 used, don't override with the ABI default. */
2983 if (!rs6000_explicit_options.aix_struct_ret)
2984 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2987 /* IBM XL compiler defaults to unsigned bitfields. */
2988 if (TARGET_XL_COMPAT)
2989 flag_signed_bitfields = 0;
2992 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2993 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2996 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2998 /* We can only guarantee the availability of DI pseudo-ops when
2999 assembling for 64-bit targets. */
3002 targetm.asm_out.aligned_op.di = NULL;
3003 targetm.asm_out.unaligned_op.di = NULL;
3006 /* Set branch target alignment, if not optimizing for size. */
3009 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3010 aligned 8byte to avoid misprediction by the branch predictor. */
3011 if (rs6000_cpu == PROCESSOR_TITAN
3012 || rs6000_cpu == PROCESSOR_CELL)
3014 if (align_functions <= 0)
3015 align_functions = 8;
3016 if (align_jumps <= 0)
3018 if (align_loops <= 0)
3021 if (rs6000_align_branch_targets)
3023 if (align_functions <= 0)
3024 align_functions = 16;
3025 if (align_jumps <= 0)
3027 if (align_loops <= 0)
3030 if (align_jumps_max_skip <= 0)
3031 align_jumps_max_skip = 15;
3032 if (align_loops_max_skip <= 0)
3033 align_loops_max_skip = 15;
3036 /* Arrange to save and restore machine status around nested functions. */
3037 init_machine_status = rs6000_init_machine_status;
3039 /* We should always be splitting complex arguments, but we can't break
3040 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3041 if (DEFAULT_ABI != ABI_AIX)
3042 targetm.calls.split_complex_arg = NULL;
3044 /* Initialize rs6000_cost with the appropriate target costs. */
3046 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3050 case PROCESSOR_RIOS1:
3051 rs6000_cost = &rios1_cost;
3054 case PROCESSOR_RIOS2:
3055 rs6000_cost = &rios2_cost;
3058 case PROCESSOR_RS64A:
3059 rs6000_cost = &rs64a_cost;
3062 case PROCESSOR_MPCCORE:
3063 rs6000_cost = &mpccore_cost;
3066 case PROCESSOR_PPC403:
3067 rs6000_cost = &ppc403_cost;
3070 case PROCESSOR_PPC405:
3071 rs6000_cost = &ppc405_cost;
3074 case PROCESSOR_PPC440:
3075 rs6000_cost = &ppc440_cost;
3078 case PROCESSOR_PPC476:
3079 rs6000_cost = &ppc476_cost;
3082 case PROCESSOR_PPC601:
3083 rs6000_cost = &ppc601_cost;
3086 case PROCESSOR_PPC603:
3087 rs6000_cost = &ppc603_cost;
3090 case PROCESSOR_PPC604:
3091 rs6000_cost = &ppc604_cost;
3094 case PROCESSOR_PPC604e:
3095 rs6000_cost = &ppc604e_cost;
3098 case PROCESSOR_PPC620:
3099 rs6000_cost = &ppc620_cost;
3102 case PROCESSOR_PPC630:
3103 rs6000_cost = &ppc630_cost;
3106 case PROCESSOR_CELL:
3107 rs6000_cost = &ppccell_cost;
3110 case PROCESSOR_PPC750:
3111 case PROCESSOR_PPC7400:
3112 rs6000_cost = &ppc750_cost;
3115 case PROCESSOR_PPC7450:
3116 rs6000_cost = &ppc7450_cost;
3119 case PROCESSOR_PPC8540:
3120 rs6000_cost = &ppc8540_cost;
3123 case PROCESSOR_PPCE300C2:
3124 case PROCESSOR_PPCE300C3:
3125 rs6000_cost = &ppce300c2c3_cost;
3128 case PROCESSOR_PPCE500MC:
3129 rs6000_cost = &ppce500mc_cost;
3132 case PROCESSOR_PPCE500MC64:
3133 rs6000_cost = &ppce500mc64_cost;
3136 case PROCESSOR_TITAN:
3137 rs6000_cost = &titan_cost;
3140 case PROCESSOR_POWER4:
3141 case PROCESSOR_POWER5:
3142 rs6000_cost = &power4_cost;
3145 case PROCESSOR_POWER6:
3146 rs6000_cost = &power6_cost;
3149 case PROCESSOR_POWER7:
3150 rs6000_cost = &power7_cost;
3153 case PROCESSOR_PPCA2:
3154 rs6000_cost = &ppca2_cost;
3161 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3162 rs6000_cost->simultaneous_prefetches,
3163 global_options.x_param_values,
3164 global_options_set.x_param_values);
3165 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3166 global_options.x_param_values,
3167 global_options_set.x_param_values);
3168 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3169 rs6000_cost->cache_line_size,
3170 global_options.x_param_values,
3171 global_options_set.x_param_values);
3172 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3173 global_options.x_param_values,
3174 global_options_set.x_param_values);
3176 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3177 can be optimized to ap = __builtin_next_arg (0). */
3178 if (DEFAULT_ABI != ABI_V4)
3179 targetm.expand_builtin_va_start = NULL;
3181 /* Set up single/double float flags.
3182 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3183 then set both flags. */
3184 if (TARGET_HARD_FLOAT && TARGET_FPRS
3185 && rs6000_single_float == 0 && rs6000_double_float == 0)
3186 rs6000_single_float = rs6000_double_float = 1;
3188 /* Reset single and double FP flags if target is E500. */
3191 rs6000_single_float = rs6000_double_float = 0;
3192 if (TARGET_E500_SINGLE)
3193 rs6000_single_float = 1;
3194 if (TARGET_E500_DOUBLE)
3195 rs6000_single_float = rs6000_double_float = 1;
3198 /* If not explicitly specified via option, decide whether to generate indexed
3199 load/store instructions. */
3200 if (TARGET_AVOID_XFORM == -1)
3201 /* Avoid indexed addressing when targeting Power6 in order to avoid
3202 the DERAT mispredict penalty. */
3203 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3205 /* Set the -mrecip options. */
3206 if (rs6000_recip_name)
3208 char *p = ASTRDUP (rs6000_recip_name);
3210 unsigned int mask, i;
3213 while ((q = strtok (p, ",")) != NULL)
3224 if (!strcmp (q, "default"))
3225 mask = ((TARGET_RECIP_PRECISION)
3226 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3229 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3230 if (!strcmp (q, recip_options[i].string))
3232 mask = recip_options[i].mask;
3236 if (i == ARRAY_SIZE (recip_options))
3238 error ("Unknown option for -mrecip=%s", q);
3245 rs6000_recip_control &= ~mask;
3247 rs6000_recip_control |= mask;
3251 rs6000_init_hard_regno_mode_ok ();
3254 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3255 define the target cpu type. */
3258 rs6000_option_override (void)
3260 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT);
3263 /* Implement targetm.vectorize.builtin_mask_for_load. */
3265 rs6000_builtin_mask_for_load (void)
3267 if (TARGET_ALTIVEC || TARGET_VSX)
3268 return altivec_builtin_mask_for_load;
3273 /* Implement targetm.vectorize.builtin_conversion.
3274 Returns a decl of a function that implements conversion of an integer vector
3275 into a floating-point vector, or vice-versa. DEST_TYPE is the
3276 destination type and SRC_TYPE the source type of the conversion.
3277 Return NULL_TREE if it is not available. */
3279 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3281 enum tree_code code = (enum tree_code) tcode;
3285 case FIX_TRUNC_EXPR:
3286 switch (TYPE_MODE (dest_type))
3289 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3292 return TYPE_UNSIGNED (dest_type)
3293 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3294 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3297 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3300 return TYPE_UNSIGNED (dest_type)
3301 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3302 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3309 switch (TYPE_MODE (src_type))
3312 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3315 return TYPE_UNSIGNED (src_type)
3316 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3317 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3320 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3323 return TYPE_UNSIGNED (src_type)
3324 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3325 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3336 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3338 rs6000_builtin_mul_widen_even (tree type)
3340 if (!TARGET_ALTIVEC)
3343 switch (TYPE_MODE (type))
3346 return TYPE_UNSIGNED (type)
3347 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3348 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3351 return TYPE_UNSIGNED (type)
3352 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3353 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3359 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3361 rs6000_builtin_mul_widen_odd (tree type)
3363 if (!TARGET_ALTIVEC)
3366 switch (TYPE_MODE (type))
3369 return TYPE_UNSIGNED (type)
3370 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3371 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3374 return TYPE_UNSIGNED (type)
3375 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3376 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3383 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3384 after applying N number of iterations. This routine does not determine
3385 how may iterations are required to reach desired alignment. */
3388 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3395 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3398 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3408 /* Assuming that all other types are naturally aligned. CHECKME! */
3413 /* Return true if the vector misalignment factor is supported by the
3416 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3423 /* Return if movmisalign pattern is not supported for this mode. */
3424 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3427 if (misalignment == -1)
3429 /* Misalignment factor is unknown at compile time but we know
3430 it's word aligned. */
3431 if (rs6000_vector_alignment_reachable (type, is_packed))
3433 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3435 if (element_size == 64 || element_size == 32)
3442 /* VSX supports word-aligned vector. */
3443 if (misalignment % 4 == 0)
3449 /* Implement targetm.vectorize.builtin_vec_perm. */
3451 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3453 tree inner_type = TREE_TYPE (type);
3454 bool uns_p = TYPE_UNSIGNED (inner_type);
3457 *mask_element_type = unsigned_char_type_node;
3459 switch (TYPE_MODE (type))
3463 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3464 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3469 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3470 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3475 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3476 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3480 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3484 if (!TARGET_ALLOW_DF_PERMUTE)
3487 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3491 if (!TARGET_ALLOW_DF_PERMUTE)
3495 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3496 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3508 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3510 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3511 tree vectype, int misalign)
3515 switch (type_of_cost)
3525 case cond_branch_not_taken:
3529 case cond_branch_taken:
3532 case unaligned_load:
3533 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3535 elements = TYPE_VECTOR_SUBPARTS (vectype);
3537 /* Double word aligned. */
3545 /* Double word aligned. */
3549 /* Unknown misalignment. */
3562 /* Misaligned loads are not supported. */
3567 case unaligned_store:
3568 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3570 elements = TYPE_VECTOR_SUBPARTS (vectype);
3572 /* Double word aligned. */
3580 /* Double word aligned. */
3584 /* Unknown misalignment. */
3597 /* Misaligned stores are not supported. */
3607 /* Implement targetm.vectorize.preferred_simd_mode. */
3609 static enum machine_mode
3610 rs6000_preferred_simd_mode (enum machine_mode mode)
3619 if (TARGET_ALTIVEC || TARGET_VSX)
3643 if (TARGET_PAIRED_FLOAT
3649 /* Handle generic options of the form -mfoo=yes/no.
3650 NAME is the option name.
3651 VALUE is the option value.
3652 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3653 whether the option value is 'yes' or 'no' respectively. */
3655 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3659 else if (!strcmp (value, "yes"))
3661 else if (!strcmp (value, "no"))
3664 error ("unknown -m%s= option specified: '%s'", name, value);
3667 /* Validate and record the size specified with the -mtls-size option. */
3670 rs6000_parse_tls_size_option (void)
3672 if (rs6000_tls_size_string == 0)
3674 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3675 rs6000_tls_size = 16;
3676 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3677 rs6000_tls_size = 32;
3678 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3679 rs6000_tls_size = 64;
3681 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3685 rs6000_option_optimization (int level ATTRIBUTE_UNUSED,
3686 int size ATTRIBUTE_UNUSED)
3688 if (DEFAULT_ABI == ABI_DARWIN)
3689 /* The Darwin libraries never set errno, so we might as well
3690 avoid calling them when that's the only reason we would. */
3691 flag_errno_math = 0;
3693 /* Enable section anchors by default.
3694 Skip section anchors for Objective C and Objective C++
3695 until front-ends fixed. */
3696 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3697 flag_section_anchors = 2;
3700 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3703 rs6000_option_default_params (void)
3705 /* Double growth factor to counter reduced min jump length. */
3706 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3709 static enum fpu_type_t
3710 rs6000_parse_fpu_option (const char *option)
3712 if (!strcmp("none", option)) return FPU_NONE;
3713 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3714 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3715 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3716 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3717 error("unknown value %s for -mfpu", option);
3722 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3723 library with vectorized intrinsics. */
3726 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3729 const char *suffix = NULL;
3730 tree fntype, new_fndecl, bdecl = NULL_TREE;
3733 enum machine_mode el_mode, in_mode;
3736 /* Libmass is suitable for unsafe math only as it does not correctly support
3737 parts of IEEE with the required precision such as denormals. Only support
3738 it if we have VSX to use the simd d2 or f4 functions.
3739 XXX: Add variable length support. */
3740 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3743 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3744 n = TYPE_VECTOR_SUBPARTS (type_out);
3745 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3746 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3747 if (el_mode != in_mode
3751 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3753 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3756 case BUILT_IN_ATAN2:
3757 case BUILT_IN_HYPOT:
3763 case BUILT_IN_ACOSH:
3765 case BUILT_IN_ASINH:
3767 case BUILT_IN_ATANH:
3775 case BUILT_IN_EXPM1:
3776 case BUILT_IN_LGAMMA:
3777 case BUILT_IN_LOG10:
3778 case BUILT_IN_LOG1P:
3786 bdecl = implicit_built_in_decls[fn];
3787 suffix = "d2"; /* pow -> powd2 */
3788 if (el_mode != DFmode
3793 case BUILT_IN_ATAN2F:
3794 case BUILT_IN_HYPOTF:
3799 case BUILT_IN_ACOSF:
3800 case BUILT_IN_ACOSHF:
3801 case BUILT_IN_ASINF:
3802 case BUILT_IN_ASINHF:
3803 case BUILT_IN_ATANF:
3804 case BUILT_IN_ATANHF:
3805 case BUILT_IN_CBRTF:
3807 case BUILT_IN_COSHF:
3809 case BUILT_IN_ERFCF:
3810 case BUILT_IN_EXP2F:
3812 case BUILT_IN_EXPM1F:
3813 case BUILT_IN_LGAMMAF:
3814 case BUILT_IN_LOG10F:
3815 case BUILT_IN_LOG1PF:
3816 case BUILT_IN_LOG2F:
3819 case BUILT_IN_SINHF:
3820 case BUILT_IN_SQRTF:
3822 case BUILT_IN_TANHF:
3823 bdecl = implicit_built_in_decls[fn];
3824 suffix = "4"; /* powf -> powf4 */
3825 if (el_mode != SFmode
3837 gcc_assert (suffix != NULL);
3838 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3839 strcpy (name, bname + sizeof ("__builtin_") - 1);
3840 strcat (name, suffix);
3843 fntype = build_function_type_list (type_out, type_in, NULL);
3844 else if (n_args == 2)
3845 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3849 /* Build a function declaration for the vectorized function. */
3850 new_fndecl = build_decl (BUILTINS_LOCATION,
3851 FUNCTION_DECL, get_identifier (name), fntype);
3852 TREE_PUBLIC (new_fndecl) = 1;
3853 DECL_EXTERNAL (new_fndecl) = 1;
3854 DECL_IS_NOVOPS (new_fndecl) = 1;
3855 TREE_READONLY (new_fndecl) = 1;
3860 /* Returns a function decl for a vectorized version of the builtin function
3861 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3862 if it is not available. */
3865 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3868 enum machine_mode in_mode, out_mode;
3871 if (TREE_CODE (type_out) != VECTOR_TYPE
3872 || TREE_CODE (type_in) != VECTOR_TYPE
3873 || !TARGET_VECTORIZE_BUILTINS)
3876 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3877 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3878 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3879 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3881 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3883 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3886 case BUILT_IN_COPYSIGN:
3887 if (VECTOR_UNIT_VSX_P (V2DFmode)
3888 && out_mode == DFmode && out_n == 2
3889 && in_mode == DFmode && in_n == 2)
3890 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3892 case BUILT_IN_COPYSIGNF:
3893 if (out_mode != SFmode || out_n != 4
3894 || in_mode != SFmode || in_n != 4)
3896 if (VECTOR_UNIT_VSX_P (V4SFmode))
3897 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3898 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3899 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3902 if (VECTOR_UNIT_VSX_P (V2DFmode)
3903 && out_mode == DFmode && out_n == 2
3904 && in_mode == DFmode && in_n == 2)
3905 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3907 case BUILT_IN_SQRTF:
3908 if (VECTOR_UNIT_VSX_P (V4SFmode)
3909 && out_mode == SFmode && out_n == 4
3910 && in_mode == SFmode && in_n == 4)
3911 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3914 if (VECTOR_UNIT_VSX_P (V2DFmode)
3915 && out_mode == DFmode && out_n == 2
3916 && in_mode == DFmode && in_n == 2)
3917 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3919 case BUILT_IN_CEILF:
3920 if (out_mode != SFmode || out_n != 4
3921 || in_mode != SFmode || in_n != 4)
3923 if (VECTOR_UNIT_VSX_P (V4SFmode))
3924 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3925 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3926 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3928 case BUILT_IN_FLOOR:
3929 if (VECTOR_UNIT_VSX_P (V2DFmode)
3930 && out_mode == DFmode && out_n == 2
3931 && in_mode == DFmode && in_n == 2)
3932 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3934 case BUILT_IN_FLOORF:
3935 if (out_mode != SFmode || out_n != 4
3936 || in_mode != SFmode || in_n != 4)
3938 if (VECTOR_UNIT_VSX_P (V4SFmode))
3939 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3940 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3941 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3943 case BUILT_IN_TRUNC:
3944 if (VECTOR_UNIT_VSX_P (V2DFmode)
3945 && out_mode == DFmode && out_n == 2
3946 && in_mode == DFmode && in_n == 2)
3947 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3949 case BUILT_IN_TRUNCF:
3950 if (out_mode != SFmode || out_n != 4
3951 || in_mode != SFmode || in_n != 4)
3953 if (VECTOR_UNIT_VSX_P (V4SFmode))
3954 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3955 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3956 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3958 case BUILT_IN_NEARBYINT:
3959 if (VECTOR_UNIT_VSX_P (V2DFmode)
3960 && flag_unsafe_math_optimizations
3961 && out_mode == DFmode && out_n == 2
3962 && in_mode == DFmode && in_n == 2)
3963 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3965 case BUILT_IN_NEARBYINTF:
3966 if (VECTOR_UNIT_VSX_P (V4SFmode)
3967 && flag_unsafe_math_optimizations
3968 && out_mode == SFmode && out_n == 4
3969 && in_mode == SFmode && in_n == 4)
3970 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3973 if (VECTOR_UNIT_VSX_P (V2DFmode)
3974 && !flag_trapping_math
3975 && out_mode == DFmode && out_n == 2
3976 && in_mode == DFmode && in_n == 2)
3977 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3979 case BUILT_IN_RINTF:
3980 if (VECTOR_UNIT_VSX_P (V4SFmode)
3981 && !flag_trapping_math
3982 && out_mode == SFmode && out_n == 4
3983 && in_mode == SFmode && in_n == 4)
3984 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3991 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3993 enum rs6000_builtins fn
3994 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3997 case RS6000_BUILTIN_RSQRTF:
3998 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3999 && out_mode == SFmode && out_n == 4
4000 && in_mode == SFmode && in_n == 4)
4001 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4003 case RS6000_BUILTIN_RSQRT:
4004 if (VECTOR_UNIT_VSX_P (V2DFmode)
4005 && out_mode == DFmode && out_n == 2
4006 && in_mode == DFmode && in_n == 2)
4007 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4009 case RS6000_BUILTIN_RECIPF:
4010 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4011 && out_mode == SFmode && out_n == 4
4012 && in_mode == SFmode && in_n == 4)
4013 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4015 case RS6000_BUILTIN_RECIP:
4016 if (VECTOR_UNIT_VSX_P (V2DFmode)
4017 && out_mode == DFmode && out_n == 2
4018 && in_mode == DFmode && in_n == 2)
4019 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4026 /* Generate calls to libmass if appropriate. */
4027 if (rs6000_veclib_handler)
4028 return rs6000_veclib_handler (fndecl, type_out, type_in);
4034 /* Implement TARGET_HANDLE_OPTION. */
4037 rs6000_handle_option (size_t code, const char *arg, int value)
4039 enum fpu_type_t fpu_type = FPU_NONE;
4045 target_flags &= ~(MASK_POWER | MASK_POWER2
4046 | MASK_MULTIPLE | MASK_STRING);
4047 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4048 | MASK_MULTIPLE | MASK_STRING);
4050 case OPT_mno_powerpc:
4051 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4052 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4053 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4054 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4057 target_flags &= ~MASK_MINIMAL_TOC;
4058 TARGET_NO_FP_IN_TOC = 0;
4059 TARGET_NO_SUM_IN_TOC = 0;
4060 target_flags_explicit |= MASK_MINIMAL_TOC;
4061 #ifdef TARGET_USES_SYSV4_OPT
4062 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4063 just the same as -mminimal-toc. */
4064 target_flags |= MASK_MINIMAL_TOC;
4065 target_flags_explicit |= MASK_MINIMAL_TOC;
4069 #ifdef TARGET_USES_SYSV4_OPT
4071 /* Make -mtoc behave like -mminimal-toc. */
4072 target_flags |= MASK_MINIMAL_TOC;
4073 target_flags_explicit |= MASK_MINIMAL_TOC;
4077 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4079 if (strcmp (arg, "small") == 0)
4080 cmodel = CMODEL_SMALL;
4081 else if (strcmp (arg, "medium") == 0)
4082 cmodel = CMODEL_MEDIUM;
4083 else if (strcmp (arg, "large") == 0)
4084 cmodel = CMODEL_LARGE;
4087 error ("invalid option for -mcmodel: '%s'", arg);
4090 rs6000_explicit_options.cmodel = true;
4093 #ifdef TARGET_USES_AIX64_OPT
4098 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4099 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4100 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4103 #ifdef TARGET_USES_AIX64_OPT
4108 target_flags &= ~MASK_POWERPC64;
4109 target_flags_explicit |= MASK_POWERPC64;
4112 case OPT_minsert_sched_nops_:
4113 rs6000_sched_insert_nops_str = arg;
4116 case OPT_mminimal_toc:
4119 TARGET_NO_FP_IN_TOC = 0;
4120 TARGET_NO_SUM_IN_TOC = 0;
4127 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4128 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4135 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4136 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4140 case OPT_mpowerpc_gpopt:
4141 case OPT_mpowerpc_gfxopt:
4144 target_flags |= MASK_POWERPC;
4145 target_flags_explicit |= MASK_POWERPC;
4149 case OPT_maix_struct_return:
4150 case OPT_msvr4_struct_return:
4151 rs6000_explicit_options.aix_struct_ret = true;
4155 rs6000_explicit_options.vrsave = true;
4156 TARGET_ALTIVEC_VRSAVE = value;
4160 rs6000_explicit_options.vrsave = true;
4161 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4165 target_flags_explicit |= MASK_ISEL;
4167 rs6000_parse_yes_no_option ("isel", arg, &isel);
4169 target_flags |= MASK_ISEL;
4171 target_flags &= ~MASK_ISEL;
4175 rs6000_explicit_options.spe = true;
4180 rs6000_explicit_options.spe = true;
4181 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4185 rs6000_debug_name = arg;
4188 #ifdef TARGET_USES_SYSV4_OPT
4190 rs6000_abi_name = arg;
4194 rs6000_sdata_name = arg;
4197 case OPT_mtls_size_:
4198 rs6000_tls_size_string = arg;
4201 case OPT_mrelocatable:
4204 target_flags |= MASK_MINIMAL_TOC;
4205 target_flags_explicit |= MASK_MINIMAL_TOC;
4206 TARGET_NO_FP_IN_TOC = 1;
4210 case OPT_mrelocatable_lib:
4213 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4214 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4215 TARGET_NO_FP_IN_TOC = 1;
4219 target_flags &= ~MASK_RELOCATABLE;
4220 target_flags_explicit |= MASK_RELOCATABLE;
4226 if (!strcmp (arg, "altivec"))
4228 rs6000_explicit_options.altivec_abi = true;
4229 rs6000_altivec_abi = 1;
4231 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4234 else if (! strcmp (arg, "no-altivec"))
4236 rs6000_explicit_options.altivec_abi = true;
4237 rs6000_altivec_abi = 0;
4239 else if (! strcmp (arg, "spe"))
4241 rs6000_explicit_options.spe_abi = true;
4243 rs6000_altivec_abi = 0;
4244 if (!TARGET_SPE_ABI)
4245 error ("not configured for ABI: '%s'", arg);
4247 else if (! strcmp (arg, "no-spe"))
4249 rs6000_explicit_options.spe_abi = true;
4253 /* These are here for testing during development only, do not
4254 document in the manual please. */
4255 else if (! strcmp (arg, "d64"))
4257 rs6000_darwin64_abi = 1;
4258 warning (0, "Using darwin64 ABI");
4260 else if (! strcmp (arg, "d32"))
4262 rs6000_darwin64_abi = 0;
4263 warning (0, "Using old darwin ABI");
4266 else if (! strcmp (arg, "ibmlongdouble"))
4268 rs6000_explicit_options.ieee = true;
4269 rs6000_ieeequad = 0;
4270 warning (0, "Using IBM extended precision long double");
4272 else if (! strcmp (arg, "ieeelongdouble"))
4274 rs6000_explicit_options.ieee = true;
4275 rs6000_ieeequad = 1;
4276 warning (0, "Using IEEE extended precision long double");
4281 error ("unknown ABI specified: '%s'", arg);
4287 rs6000_select[1].string = arg;
4291 rs6000_select[2].string = arg;
4294 case OPT_mtraceback_:
4295 rs6000_traceback_name = arg;
4298 case OPT_mfloat_gprs_:
4299 rs6000_explicit_options.float_gprs = true;
4300 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4301 rs6000_float_gprs = 1;
4302 else if (! strcmp (arg, "double"))
4303 rs6000_float_gprs = 2;
4304 else if (! strcmp (arg, "no"))
4305 rs6000_float_gprs = 0;
4308 error ("invalid option for -mfloat-gprs: '%s'", arg);
4313 case OPT_mlong_double_:
4314 rs6000_explicit_options.long_double = true;
4315 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4316 if (value != 64 && value != 128)
4318 error ("Unknown switch -mlong-double-%s", arg);
4319 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4323 rs6000_long_double_type_size = value;
4326 case OPT_msched_costly_dep_:
4327 rs6000_sched_costly_dep_str = arg;
4331 rs6000_explicit_options.alignment = true;
4332 if (! strcmp (arg, "power"))
4334 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4335 some C library functions, so warn about it. The flag may be
4336 useful for performance studies from time to time though, so
4337 don't disable it entirely. */
4338 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4339 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4340 " it is incompatible with the installed C and C++ libraries");
4341 rs6000_alignment_flags = MASK_ALIGN_POWER;
4343 else if (! strcmp (arg, "natural"))
4344 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4347 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4352 case OPT_msingle_float:
4353 if (!TARGET_SINGLE_FPU)
4354 warning (0, "-msingle-float option equivalent to -mhard-float");
4355 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4356 rs6000_double_float = 0;
4357 target_flags &= ~MASK_SOFT_FLOAT;
4358 target_flags_explicit |= MASK_SOFT_FLOAT;
4361 case OPT_mdouble_float:
4362 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4363 rs6000_single_float = 1;
4364 target_flags &= ~MASK_SOFT_FLOAT;
4365 target_flags_explicit |= MASK_SOFT_FLOAT;
4368 case OPT_msimple_fpu:
4369 if (!TARGET_SINGLE_FPU)
4370 warning (0, "-msimple-fpu option ignored");
4373 case OPT_mhard_float:
4374 /* -mhard_float implies -msingle-float and -mdouble-float. */
4375 rs6000_single_float = rs6000_double_float = 1;
4378 case OPT_msoft_float:
4379 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4380 rs6000_single_float = rs6000_double_float = 0;
4384 fpu_type = rs6000_parse_fpu_option(arg);
4385 if (fpu_type != FPU_NONE)
4386 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4388 target_flags &= ~MASK_SOFT_FLOAT;
4389 target_flags_explicit |= MASK_SOFT_FLOAT;
4390 rs6000_xilinx_fpu = 1;
4391 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4392 rs6000_single_float = 1;
4393 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4394 rs6000_single_float = rs6000_double_float = 1;
4395 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4396 rs6000_simple_fpu = 1;
4400 /* -mfpu=none is equivalent to -msoft-float */
4401 target_flags |= MASK_SOFT_FLOAT;
4402 target_flags_explicit |= MASK_SOFT_FLOAT;
4403 rs6000_single_float = rs6000_double_float = 0;
4407 rs6000_recip_name = (value) ? "default" : "none";
4411 rs6000_recip_name = arg;
4417 /* Do anything needed at the start of the asm file. */
4420 rs6000_file_start (void)
4424 const char *start = buffer;
4425 struct rs6000_cpu_select *ptr;
4426 const char *default_cpu = TARGET_CPU_DEFAULT;
4427 FILE *file = asm_out_file;
4429 default_file_start ();
4431 #ifdef TARGET_BI_ARCH
4432 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4436 if (flag_verbose_asm)
4438 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4439 rs6000_select[0].string = default_cpu;
4441 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4443 ptr = &rs6000_select[i];
4444 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4446 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4451 if (PPC405_ERRATUM77)
4453 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4457 #ifdef USING_ELFOS_H
4458 switch (rs6000_sdata)
4460 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4461 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4462 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4463 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4466 if (rs6000_sdata && g_switch_value)
4468 fprintf (file, "%s -G %d", start,
4478 #ifdef HAVE_AS_GNU_ATTRIBUTE
4479 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4481 fprintf (file, "\t.gnu_attribute 4, %d\n",
4482 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4483 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4485 fprintf (file, "\t.gnu_attribute 8, %d\n",
4486 (TARGET_ALTIVEC_ABI ? 2
4487 : TARGET_SPE_ABI ? 3
4489 fprintf (file, "\t.gnu_attribute 12, %d\n",
4490 aix_struct_return ? 2 : 1);
4495 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4497 switch_to_section (toc_section);
4498 switch_to_section (text_section);
4503 /* Return nonzero if this function is known to have a null epilogue. */
4506 direct_return (void)
4508 if (reload_completed)
4510 rs6000_stack_t *info = rs6000_stack_info ();
4512 if (info->first_gp_reg_save == 32
4513 && info->first_fp_reg_save == 64
4514 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4515 && ! info->lr_save_p
4516 && ! info->cr_save_p
4517 && info->vrsave_mask == 0
4525 /* Return the number of instructions it takes to form a constant in an
4526 integer register. */
4529 num_insns_constant_wide (HOST_WIDE_INT value)
4531 /* signed constant loadable with {cal|addi} */
4532 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4535 /* constant loadable with {cau|addis} */
4536 else if ((value & 0xffff) == 0
4537 && (value >> 31 == -1 || value >> 31 == 0))
4540 #if HOST_BITS_PER_WIDE_INT == 64
4541 else if (TARGET_POWERPC64)
4543 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4544 HOST_WIDE_INT high = value >> 31;
4546 if (high == 0 || high == -1)
4552 return num_insns_constant_wide (high) + 1;
4554 return num_insns_constant_wide (low) + 1;
4556 return (num_insns_constant_wide (high)
4557 + num_insns_constant_wide (low) + 1);
4566 num_insns_constant (rtx op, enum machine_mode mode)
4568 HOST_WIDE_INT low, high;
4570 switch (GET_CODE (op))
4573 #if HOST_BITS_PER_WIDE_INT == 64
4574 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4575 && mask64_operand (op, mode))
4579 return num_insns_constant_wide (INTVAL (op));
4582 if (mode == SFmode || mode == SDmode)
4587 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4588 if (DECIMAL_FLOAT_MODE_P (mode))
4589 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4591 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4592 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4595 if (mode == VOIDmode || mode == DImode)
4597 high = CONST_DOUBLE_HIGH (op);
4598 low = CONST_DOUBLE_LOW (op);
4605 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4606 if (DECIMAL_FLOAT_MODE_P (mode))
4607 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4609 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4610 high = l[WORDS_BIG_ENDIAN == 0];
4611 low = l[WORDS_BIG_ENDIAN != 0];
4615 return (num_insns_constant_wide (low)
4616 + num_insns_constant_wide (high));
4619 if ((high == 0 && low >= 0)
4620 || (high == -1 && low < 0))
4621 return num_insns_constant_wide (low);
4623 else if (mask64_operand (op, mode))
4627 return num_insns_constant_wide (high) + 1;
4630 return (num_insns_constant_wide (high)
4631 + num_insns_constant_wide (low) + 1);
4639 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4640 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4641 corresponding element of the vector, but for V4SFmode and V2SFmode,
4642 the corresponding "float" is interpreted as an SImode integer. */
4645 const_vector_elt_as_int (rtx op, unsigned int elt)
4647 rtx tmp = CONST_VECTOR_ELT (op, elt);
4648 if (GET_MODE (op) == V4SFmode
4649 || GET_MODE (op) == V2SFmode)
4650 tmp = gen_lowpart (SImode, tmp);
4651 return INTVAL (tmp);
4654 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4655 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4656 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4657 all items are set to the same value and contain COPIES replicas of the
4658 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4659 operand and the others are set to the value of the operand's msb. */
4662 vspltis_constant (rtx op, unsigned step, unsigned copies)
4664 enum machine_mode mode = GET_MODE (op);
4665 enum machine_mode inner = GET_MODE_INNER (mode);
4668 unsigned nunits = GET_MODE_NUNITS (mode);
4669 unsigned bitsize = GET_MODE_BITSIZE (inner);
4670 unsigned mask = GET_MODE_MASK (inner);
4672 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4673 HOST_WIDE_INT splat_val = val;
4674 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4676 /* Construct the value to be splatted, if possible. If not, return 0. */
4677 for (i = 2; i <= copies; i *= 2)
4679 HOST_WIDE_INT small_val;
4681 small_val = splat_val >> bitsize;
4683 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4685 splat_val = small_val;
4688 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4689 if (EASY_VECTOR_15 (splat_val))
4692 /* Also check if we can splat, and then add the result to itself. Do so if
4693 the value is positive, of if the splat instruction is using OP's mode;
4694 for splat_val < 0, the splat and the add should use the same mode. */
4695 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4696 && (splat_val >= 0 || (step == 1 && copies == 1)))
4699 /* Also check if are loading up the most significant bit which can be done by
4700 loading up -1 and shifting the value left by -1. */
4701 else if (EASY_VECTOR_MSB (splat_val, inner))
4707 /* Check if VAL is present in every STEP-th element, and the
4708 other elements are filled with its most significant bit. */
4709 for (i = 0; i < nunits - 1; ++i)
4711 HOST_WIDE_INT desired_val;
4712 if (((i + 1) & (step - 1)) == 0)
4715 desired_val = msb_val;
4717 if (desired_val != const_vector_elt_as_int (op, i))
4725 /* Return true if OP is of the given MODE and can be synthesized
4726 with a vspltisb, vspltish or vspltisw. */
4729 easy_altivec_constant (rtx op, enum machine_mode mode)
4731 unsigned step, copies;
4733 if (mode == VOIDmode)
4734 mode = GET_MODE (op);
4735 else if (mode != GET_MODE (op))
4738 /* Start with a vspltisw. */
4739 step = GET_MODE_NUNITS (mode) / 4;
4742 if (vspltis_constant (op, step, copies))
4745 /* Then try with a vspltish. */
4751 if (vspltis_constant (op, step, copies))
4754 /* And finally a vspltisb. */
4760 if (vspltis_constant (op, step, copies))
4766 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4767 result is OP. Abort if it is not possible. */
4770 gen_easy_altivec_constant (rtx op)
4772 enum machine_mode mode = GET_MODE (op);
4773 int nunits = GET_MODE_NUNITS (mode);
4774 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4775 unsigned step = nunits / 4;
4776 unsigned copies = 1;
4778 /* Start with a vspltisw. */
4779 if (vspltis_constant (op, step, copies))
4780 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4782 /* Then try with a vspltish. */
4788 if (vspltis_constant (op, step, copies))
4789 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4791 /* And finally a vspltisb. */
4797 if (vspltis_constant (op, step, copies))
4798 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4804 output_vec_const_move (rtx *operands)
4807 enum machine_mode mode;
4812 mode = GET_MODE (dest);
4814 if (TARGET_VSX && zero_constant (vec, mode))
4815 return "xxlxor %x0,%x0,%x0";
4820 if (zero_constant (vec, mode))
4821 return "vxor %0,%0,%0";
4823 splat_vec = gen_easy_altivec_constant (vec);
4824 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4825 operands[1] = XEXP (splat_vec, 0);
4826 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4829 switch (GET_MODE (splat_vec))
4832 return "vspltisw %0,%1";
4835 return "vspltish %0,%1";
4838 return "vspltisb %0,%1";
4845 gcc_assert (TARGET_SPE);
4847 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4848 pattern of V1DI, V4HI, and V2SF.
4850 FIXME: We should probably return # and add post reload
4851 splitters for these, but this way is so easy ;-). */
4852 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4853 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4854 operands[1] = CONST_VECTOR_ELT (vec, 0);
4855 operands[2] = CONST_VECTOR_ELT (vec, 1);
4857 return "li %0,%1\n\tevmergelo %0,%0,%0";
4859 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4862 /* Initialize TARGET of vector PAIRED to VALS. */
4865 paired_expand_vector_init (rtx target, rtx vals)
4867 enum machine_mode mode = GET_MODE (target);
4868 int n_elts = GET_MODE_NUNITS (mode);
4870 rtx x, new_rtx, tmp, constant_op, op1, op2;
4873 for (i = 0; i < n_elts; ++i)
4875 x = XVECEXP (vals, 0, i);
4876 if (!CONSTANT_P (x))
4881 /* Load from constant pool. */
4882 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4888 /* The vector is initialized only with non-constants. */
4889 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4890 XVECEXP (vals, 0, 1));
4892 emit_move_insn (target, new_rtx);
4896 /* One field is non-constant and the other one is a constant. Load the
4897 constant from the constant pool and use ps_merge instruction to
4898 construct the whole vector. */
4899 op1 = XVECEXP (vals, 0, 0);
4900 op2 = XVECEXP (vals, 0, 1);
4902 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4904 tmp = gen_reg_rtx (GET_MODE (constant_op));
4905 emit_move_insn (tmp, constant_op);
4907 if (CONSTANT_P (op1))
4908 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4910 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4912 emit_move_insn (target, new_rtx);
4916 paired_expand_vector_move (rtx operands[])
4918 rtx op0 = operands[0], op1 = operands[1];
4920 emit_move_insn (op0, op1);
4923 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4924 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4925 operands for the relation operation COND. This is a recursive
4929 paired_emit_vector_compare (enum rtx_code rcode,
4930 rtx dest, rtx op0, rtx op1,
4931 rtx cc_op0, rtx cc_op1)
4933 rtx tmp = gen_reg_rtx (V2SFmode);
4936 gcc_assert (TARGET_PAIRED_FLOAT);
4937 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4943 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4947 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4948 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4952 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4955 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4958 tmp1 = gen_reg_rtx (V2SFmode);
4959 max = gen_reg_rtx (V2SFmode);
4960 min = gen_reg_rtx (V2SFmode);
4961 gen_reg_rtx (V2SFmode);
4963 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4964 emit_insn (gen_selv2sf4
4965 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4966 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4967 emit_insn (gen_selv2sf4
4968 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4969 emit_insn (gen_subv2sf3 (tmp1, min, max));
4970 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4973 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4976 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4979 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4982 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4985 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4994 /* Emit vector conditional expression.
4995 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4996 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4999 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5000 rtx cond, rtx cc_op0, rtx cc_op1)
5002 enum rtx_code rcode = GET_CODE (cond);
5004 if (!TARGET_PAIRED_FLOAT)
5007 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5012 /* Initialize vector TARGET to VALS. */
5015 rs6000_expand_vector_init (rtx target, rtx vals)
5017 enum machine_mode mode = GET_MODE (target);
5018 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5019 int n_elts = GET_MODE_NUNITS (mode);
5020 int n_var = 0, one_var = -1;
5021 bool all_same = true, all_const_zero = true;
5025 for (i = 0; i < n_elts; ++i)
5027 x = XVECEXP (vals, 0, i);
5028 if (!CONSTANT_P (x))
5029 ++n_var, one_var = i;
5030 else if (x != CONST0_RTX (inner_mode))
5031 all_const_zero = false;
5033 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5039 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5040 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5041 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5043 /* Zero register. */
5044 emit_insn (gen_rtx_SET (VOIDmode, target,
5045 gen_rtx_XOR (mode, target, target)));
5048 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5050 /* Splat immediate. */
5051 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5056 /* Load from constant pool. */
5057 emit_move_insn (target, const_vec);
5062 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5063 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5067 rtx element = XVECEXP (vals, 0, 0);
5068 if (mode == V2DFmode)
5069 emit_insn (gen_vsx_splat_v2df (target, element));
5071 emit_insn (gen_vsx_splat_v2di (target, element));
5075 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5076 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5077 if (mode == V2DFmode)
5078 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5080 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5085 /* With single precision floating point on VSX, know that internally single
5086 precision is actually represented as a double, and either make 2 V2DF
5087 vectors, and convert these vectors to single precision, or do one
5088 conversion, and splat the result to the other elements. */
5089 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5093 rtx freg = gen_reg_rtx (V4SFmode);
5094 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5096 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5097 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5101 rtx dbl_even = gen_reg_rtx (V2DFmode);
5102 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5103 rtx flt_even = gen_reg_rtx (V4SFmode);
5104 rtx flt_odd = gen_reg_rtx (V4SFmode);
5106 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5107 copy_to_reg (XVECEXP (vals, 0, 0)),
5108 copy_to_reg (XVECEXP (vals, 0, 1))));
5109 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5110 copy_to_reg (XVECEXP (vals, 0, 2)),
5111 copy_to_reg (XVECEXP (vals, 0, 3))));
5112 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5113 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5114 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5119 /* Store value to stack temp. Load vector element. Splat. However, splat
5120 of 64-bit items is not supported on Altivec. */
5121 if (all_same && GET_MODE_SIZE (mode) <= 4)
5123 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5124 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5125 XVECEXP (vals, 0, 0));
5126 x = gen_rtx_UNSPEC (VOIDmode,
5127 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5128 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5130 gen_rtx_SET (VOIDmode,
5133 x = gen_rtx_VEC_SELECT (inner_mode, target,
5134 gen_rtx_PARALLEL (VOIDmode,
5135 gen_rtvec (1, const0_rtx)));
5136 emit_insn (gen_rtx_SET (VOIDmode, target,
5137 gen_rtx_VEC_DUPLICATE (mode, x)));
5141 /* One field is non-constant. Load constant then overwrite
5145 rtx copy = copy_rtx (vals);
5147 /* Load constant part of vector, substitute neighboring value for
5149 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5150 rs6000_expand_vector_init (target, copy);
5152 /* Insert variable. */
5153 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5157 /* Construct the vector in memory one field at a time
5158 and load the whole vector. */
5159 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5160 for (i = 0; i < n_elts; i++)
5161 emit_move_insn (adjust_address_nv (mem, inner_mode,
5162 i * GET_MODE_SIZE (inner_mode)),
5163 XVECEXP (vals, 0, i));
5164 emit_move_insn (target, mem);
5167 /* Set field ELT of TARGET to VAL. */
5170 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5172 enum machine_mode mode = GET_MODE (target);
5173 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5174 rtx reg = gen_reg_rtx (mode);
5176 int width = GET_MODE_SIZE (inner_mode);
5179 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5181 rtx (*set_func) (rtx, rtx, rtx, rtx)
5182 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5183 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5187 /* Load single variable value. */
5188 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5189 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5190 x = gen_rtx_UNSPEC (VOIDmode,
5191 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5192 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5194 gen_rtx_SET (VOIDmode,
5198 /* Linear sequence. */
5199 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5200 for (i = 0; i < 16; ++i)
5201 XVECEXP (mask, 0, i) = GEN_INT (i);
5203 /* Set permute mask to insert element into target. */
5204 for (i = 0; i < width; ++i)
5205 XVECEXP (mask, 0, elt*width + i)
5206 = GEN_INT (i + 0x10);
5207 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5208 x = gen_rtx_UNSPEC (mode,
5209 gen_rtvec (3, target, reg,
5210 force_reg (V16QImode, x)),
5212 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5215 /* Extract field ELT from VEC into TARGET. */
5218 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5220 enum machine_mode mode = GET_MODE (vec);
5221 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5224 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5226 rtx (*extract_func) (rtx, rtx, rtx)
5227 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5228 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5232 /* Allocate mode-sized buffer. */
5233 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5235 /* Add offset to field within buffer matching vector element. */
5236 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5238 /* Store single field into mode-sized buffer. */
5239 x = gen_rtx_UNSPEC (VOIDmode,
5240 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5241 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5243 gen_rtx_SET (VOIDmode,
5246 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5249 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5250 implement ANDing by the mask IN. */
5252 build_mask64_2_operands (rtx in, rtx *out)
5254 #if HOST_BITS_PER_WIDE_INT >= 64
5255 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5258 gcc_assert (GET_CODE (in) == CONST_INT);
5263 /* Assume c initially something like 0x00fff000000fffff. The idea
5264 is to rotate the word so that the middle ^^^^^^ group of zeros
5265 is at the MS end and can be cleared with an rldicl mask. We then
5266 rotate back and clear off the MS ^^ group of zeros with a
5268 c = ~c; /* c == 0xff000ffffff00000 */
5269 lsb = c & -c; /* lsb == 0x0000000000100000 */
5270 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5271 c = ~c; /* c == 0x00fff000000fffff */
5272 c &= -lsb; /* c == 0x00fff00000000000 */
5273 lsb = c & -c; /* lsb == 0x0000100000000000 */
5274 c = ~c; /* c == 0xff000fffffffffff */
5275 c &= -lsb; /* c == 0xff00000000000000 */
5277 while ((lsb >>= 1) != 0)
5278 shift++; /* shift == 44 on exit from loop */
5279 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5280 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5281 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5285 /* Assume c initially something like 0xff000f0000000000. The idea
5286 is to rotate the word so that the ^^^ middle group of zeros
5287 is at the LS end and can be cleared with an rldicr mask. We then
5288 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5290 lsb = c & -c; /* lsb == 0x0000010000000000 */
5291 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5292 c = ~c; /* c == 0x00fff0ffffffffff */
5293 c &= -lsb; /* c == 0x00fff00000000000 */
5294 lsb = c & -c; /* lsb == 0x0000100000000000 */
5295 c = ~c; /* c == 0xff000fffffffffff */
5296 c &= -lsb; /* c == 0xff00000000000000 */
5298 while ((lsb >>= 1) != 0)
5299 shift++; /* shift == 44 on exit from loop */
5300 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5301 m1 >>= shift; /* m1 == 0x0000000000000fff */
5302 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5305 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5306 masks will be all 1's. We are guaranteed more than one transition. */
5307 out[0] = GEN_INT (64 - shift);
5308 out[1] = GEN_INT (m1);
5309 out[2] = GEN_INT (shift);
5310 out[3] = GEN_INT (m2);
5318 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5321 invalid_e500_subreg (rtx op, enum machine_mode mode)
5323 if (TARGET_E500_DOUBLE)
5325 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5326 subreg:TI and reg:TF. Decimal float modes are like integer
5327 modes (only low part of each register used) for this
5329 if (GET_CODE (op) == SUBREG
5330 && (mode == SImode || mode == DImode || mode == TImode
5331 || mode == DDmode || mode == TDmode)
5332 && REG_P (SUBREG_REG (op))
5333 && (GET_MODE (SUBREG_REG (op)) == DFmode
5334 || GET_MODE (SUBREG_REG (op)) == TFmode))
5337 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5339 if (GET_CODE (op) == SUBREG
5340 && (mode == DFmode || mode == TFmode)
5341 && REG_P (SUBREG_REG (op))
5342 && (GET_MODE (SUBREG_REG (op)) == DImode
5343 || GET_MODE (SUBREG_REG (op)) == TImode
5344 || GET_MODE (SUBREG_REG (op)) == DDmode
5345 || GET_MODE (SUBREG_REG (op)) == TDmode))
5350 && GET_CODE (op) == SUBREG
5352 && REG_P (SUBREG_REG (op))
5353 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5359 /* AIX increases natural record alignment to doubleword if the first
5360 field is an FP double while the FP fields remain word aligned. */
5363 rs6000_special_round_type_align (tree type, unsigned int computed,
5364 unsigned int specified)
5366 unsigned int align = MAX (computed, specified);
5367 tree field = TYPE_FIELDS (type);
5369 /* Skip all non field decls */
5370 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5371 field = DECL_CHAIN (field);
5373 if (field != NULL && field != type)
5375 type = TREE_TYPE (field);
5376 while (TREE_CODE (type) == ARRAY_TYPE)
5377 type = TREE_TYPE (type);
5379 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5380 align = MAX (align, 64);
5386 /* Darwin increases record alignment to the natural alignment of
5390 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5391 unsigned int specified)
5393 unsigned int align = MAX (computed, specified);
5395 if (TYPE_PACKED (type))
5398 /* Find the first field, looking down into aggregates. */
5400 tree field = TYPE_FIELDS (type);
5401 /* Skip all non field decls */
5402 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5403 field = DECL_CHAIN (field);
5406 /* A packed field does not contribute any extra alignment. */
5407 if (DECL_PACKED (field))
5409 type = TREE_TYPE (field);
5410 while (TREE_CODE (type) == ARRAY_TYPE)
5411 type = TREE_TYPE (type);
5412 } while (AGGREGATE_TYPE_P (type));
5414 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5415 align = MAX (align, TYPE_ALIGN (type));
5420 /* Return 1 for an operand in small memory on V.4/eabi. */
5423 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5424 enum machine_mode mode ATTRIBUTE_UNUSED)
5429 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5432 if (DEFAULT_ABI != ABI_V4)
5435 /* Vector and float memory instructions have a limited offset on the
5436 SPE, so using a vector or float variable directly as an operand is
5439 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5442 if (GET_CODE (op) == SYMBOL_REF)
5445 else if (GET_CODE (op) != CONST
5446 || GET_CODE (XEXP (op, 0)) != PLUS
5447 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5448 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5453 rtx sum = XEXP (op, 0);
5454 HOST_WIDE_INT summand;
5456 /* We have to be careful here, because it is the referenced address
5457 that must be 32k from _SDA_BASE_, not just the symbol. */
5458 summand = INTVAL (XEXP (sum, 1));
5459 if (summand < 0 || summand > g_switch_value)
5462 sym_ref = XEXP (sum, 0);
5465 return SYMBOL_REF_SMALL_P (sym_ref);
5471 /* Return true if either operand is a general purpose register. */
5474 gpr_or_gpr_p (rtx op0, rtx op1)
5476 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5477 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5481 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5484 reg_offset_addressing_ok_p (enum machine_mode mode)
5494 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5495 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5503 /* Paired vector modes. Only reg+reg addressing is valid. */
5504 if (TARGET_PAIRED_FLOAT)
5516 virtual_stack_registers_memory_p (rtx op)
5520 if (GET_CODE (op) == REG)
5521 regnum = REGNO (op);
5523 else if (GET_CODE (op) == PLUS
5524 && GET_CODE (XEXP (op, 0)) == REG
5525 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5526 regnum = REGNO (XEXP (op, 0));
5531 return (regnum >= FIRST_VIRTUAL_REGISTER
5532 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5536 constant_pool_expr_p (rtx op)
5540 split_const (op, &base, &offset);
5541 return (GET_CODE (base) == SYMBOL_REF
5542 && CONSTANT_POOL_ADDRESS_P (base)
5543 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5546 static rtx tocrel_base, tocrel_offset;
5549 toc_relative_expr_p (rtx op)
5551 if (GET_CODE (op) != CONST)
5554 split_const (op, &tocrel_base, &tocrel_offset);
5555 return (GET_CODE (tocrel_base) == UNSPEC
5556 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5560 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5563 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5564 && GET_CODE (XEXP (x, 0)) == REG
5565 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5566 || ((TARGET_MINIMAL_TOC
5567 || TARGET_CMODEL != CMODEL_SMALL)
5568 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5569 && toc_relative_expr_p (XEXP (x, 1)));
5573 legitimate_small_data_p (enum machine_mode mode, rtx x)
5575 return (DEFAULT_ABI == ABI_V4
5576 && !flag_pic && !TARGET_TOC
5577 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5578 && small_data_operand (x, mode));
5581 /* SPE offset addressing is limited to 5-bits worth of double words. */
5582 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5585 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5587 unsigned HOST_WIDE_INT offset, extra;
5589 if (GET_CODE (x) != PLUS)
5591 if (GET_CODE (XEXP (x, 0)) != REG)
5593 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5595 if (!reg_offset_addressing_ok_p (mode))
5596 return virtual_stack_registers_memory_p (x);
5597 if (legitimate_constant_pool_address_p (x, strict))
5599 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5602 offset = INTVAL (XEXP (x, 1));
5610 /* SPE vector modes. */
5611 return SPE_CONST_OFFSET_OK (offset);
5614 if (TARGET_E500_DOUBLE)
5615 return SPE_CONST_OFFSET_OK (offset);
5617 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5619 if (VECTOR_MEM_VSX_P (DFmode))
5624 /* On e500v2, we may have:
5626 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5628 Which gets addressed with evldd instructions. */
5629 if (TARGET_E500_DOUBLE)
5630 return SPE_CONST_OFFSET_OK (offset);
5632 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5634 else if (offset & 3)
5639 if (TARGET_E500_DOUBLE)
5640 return (SPE_CONST_OFFSET_OK (offset)
5641 && SPE_CONST_OFFSET_OK (offset + 8));
5645 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5647 else if (offset & 3)
5658 return (offset < 0x10000) && (offset + extra < 0x10000);
5662 legitimate_indexed_address_p (rtx x, int strict)
5666 if (GET_CODE (x) != PLUS)
5672 /* Recognize the rtl generated by reload which we know will later be
5673 replaced with proper base and index regs. */
5675 && reload_in_progress
5676 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5680 return (REG_P (op0) && REG_P (op1)
5681 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5682 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5683 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5684 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5688 avoiding_indexed_address_p (enum machine_mode mode)
5690 /* Avoid indexed addressing for modes that have non-indexed
5691 load/store instruction forms. */
5692 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5696 legitimate_indirect_address_p (rtx x, int strict)
5698 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5702 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5704 if (!TARGET_MACHO || !flag_pic
5705 || mode != SImode || GET_CODE (x) != MEM)
5709 if (GET_CODE (x) != LO_SUM)
5711 if (GET_CODE (XEXP (x, 0)) != REG)
5713 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5717 return CONSTANT_P (x);
5721 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5723 if (GET_CODE (x) != LO_SUM)
5725 if (GET_CODE (XEXP (x, 0)) != REG)
5727 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5729 /* Restrict addressing for DI because of our SUBREG hackery. */
5730 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5731 || mode == DDmode || mode == TDmode
5736 if (TARGET_ELF || TARGET_MACHO)
5738 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5742 if (GET_MODE_NUNITS (mode) != 1)
5744 if (GET_MODE_BITSIZE (mode) > 64
5745 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5746 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5747 && (mode == DFmode || mode == DDmode))))
5750 return CONSTANT_P (x);
5757 /* Try machine-dependent ways of modifying an illegitimate address
5758 to be legitimate. If we find one, return the new, valid address.
5759 This is used from only one place: `memory_address' in explow.c.
5761 OLDX is the address as it was before break_out_memory_refs was
5762 called. In some cases it is useful to look at this to decide what
5765 It is always safe for this function to do nothing. It exists to
5766 recognize opportunities to optimize the output.
5768 On RS/6000, first check for the sum of a register with a constant
5769 integer that is out of range. If so, generate code to add the
5770 constant with the low-order 16 bits masked to the register and force
5771 this result into another register (this can be done with `cau').
5772 Then generate an address of REG+(CONST&0xffff), allowing for the
5773 possibility of bit 16 being a one.
5775 Then check for the sum of a register and something not constant, try to
5776 load the other things into a register and return the sum. */
5779 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5780 enum machine_mode mode)
5782 unsigned int extra = 0;
5784 if (!reg_offset_addressing_ok_p (mode))
5786 if (virtual_stack_registers_memory_p (x))
5789 /* In theory we should not be seeing addresses of the form reg+0,
5790 but just in case it is generated, optimize it away. */
5791 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5792 return force_reg (Pmode, XEXP (x, 0));
5794 /* Make sure both operands are registers. */
5795 else if (GET_CODE (x) == PLUS)
5796 return gen_rtx_PLUS (Pmode,
5797 force_reg (Pmode, XEXP (x, 0)),
5798 force_reg (Pmode, XEXP (x, 1)));
5800 return force_reg (Pmode, x);
5802 if (GET_CODE (x) == SYMBOL_REF)
5804 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5806 return rs6000_legitimize_tls_address (x, model);
5816 if (!TARGET_POWERPC64)
5824 extra = TARGET_POWERPC64 ? 8 : 12;
5830 if (GET_CODE (x) == PLUS
5831 && GET_CODE (XEXP (x, 0)) == REG
5832 && GET_CODE (XEXP (x, 1)) == CONST_INT
5833 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5835 && !((TARGET_POWERPC64
5836 && (mode == DImode || mode == TImode)
5837 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5838 || SPE_VECTOR_MODE (mode)
5839 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5840 || mode == DImode || mode == DDmode
5841 || mode == TDmode))))
5843 HOST_WIDE_INT high_int, low_int;
5845 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5846 if (low_int >= 0x8000 - extra)
5848 high_int = INTVAL (XEXP (x, 1)) - low_int;
5849 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5850 GEN_INT (high_int)), 0);
5851 return plus_constant (sum, low_int);
5853 else if (GET_CODE (x) == PLUS
5854 && GET_CODE (XEXP (x, 0)) == REG
5855 && GET_CODE (XEXP (x, 1)) != CONST_INT
5856 && GET_MODE_NUNITS (mode) == 1
5857 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5859 || ((mode != DImode && mode != DFmode && mode != DDmode)
5860 || (TARGET_E500_DOUBLE && mode != DDmode)))
5861 && (TARGET_POWERPC64 || mode != DImode)
5862 && !avoiding_indexed_address_p (mode)
5867 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5868 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5870 else if (SPE_VECTOR_MODE (mode)
5871 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5872 || mode == DDmode || mode == TDmode
5873 || mode == DImode)))
5877 /* We accept [reg + reg] and [reg + OFFSET]. */
5879 if (GET_CODE (x) == PLUS)
5881 rtx op1 = XEXP (x, 0);
5882 rtx op2 = XEXP (x, 1);
5885 op1 = force_reg (Pmode, op1);
5887 if (GET_CODE (op2) != REG
5888 && (GET_CODE (op2) != CONST_INT
5889 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5890 || (GET_MODE_SIZE (mode) > 8
5891 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5892 op2 = force_reg (Pmode, op2);
5894 /* We can't always do [reg + reg] for these, because [reg +
5895 reg + offset] is not a legitimate addressing mode. */
5896 y = gen_rtx_PLUS (Pmode, op1, op2);
5898 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5899 return force_reg (Pmode, y);
5904 return force_reg (Pmode, x);
5910 && GET_CODE (x) != CONST_INT
5911 && GET_CODE (x) != CONST_DOUBLE
5913 && GET_MODE_NUNITS (mode) == 1
5914 && (GET_MODE_BITSIZE (mode) <= 32
5915 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5916 && (mode == DFmode || mode == DDmode))))
5918 rtx reg = gen_reg_rtx (Pmode);
5919 emit_insn (gen_elf_high (reg, x));
5920 return gen_rtx_LO_SUM (Pmode, reg, x);
5922 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5925 && ! MACHO_DYNAMIC_NO_PIC_P
5927 && GET_CODE (x) != CONST_INT
5928 && GET_CODE (x) != CONST_DOUBLE
5930 && GET_MODE_NUNITS (mode) == 1
5931 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5932 || (mode != DFmode && mode != DDmode))
5936 rtx reg = gen_reg_rtx (Pmode);
5937 emit_insn (gen_macho_high (reg, x));
5938 return gen_rtx_LO_SUM (Pmode, reg, x);
5941 && GET_CODE (x) == SYMBOL_REF
5942 && constant_pool_expr_p (x)
5943 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5945 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5946 return create_TOC_reference (x, reg);
5952 /* Debug version of rs6000_legitimize_address. */
5954 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5960 ret = rs6000_legitimize_address (x, oldx, mode);
5961 insns = get_insns ();
5967 "\nrs6000_legitimize_address: mode %s, old code %s, "
5968 "new code %s, modified\n",
5969 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5970 GET_RTX_NAME (GET_CODE (ret)));
5972 fprintf (stderr, "Original address:\n");
5975 fprintf (stderr, "oldx:\n");
5978 fprintf (stderr, "New address:\n");
5983 fprintf (stderr, "Insns added:\n");
5984 debug_rtx_list (insns, 20);
5990 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5991 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6002 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6003 We need to emit DTP-relative relocations. */
6006 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6011 fputs ("\t.long\t", file);
6014 fputs (DOUBLE_INT_ASM_OP, file);
6019 output_addr_const (file, x);
6020 fputs ("@dtprel+0x8000", file);
6023 /* In the name of slightly smaller debug output, and to cater to
6024 general assembler lossage, recognize various UNSPEC sequences
6025 and turn them back into a direct symbol reference. */
6028 rs6000_delegitimize_address (rtx orig_x)
6032 orig_x = delegitimize_mem_from_attrs (orig_x);
6037 if ((GET_CODE (x) == PLUS
6038 || GET_CODE (x) == LO_SUM)
6039 && GET_CODE (XEXP (x, 0)) == REG
6040 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6041 || TARGET_MINIMAL_TOC
6042 || TARGET_CMODEL != CMODEL_SMALL)
6043 && GET_CODE (XEXP (x, 1)) == CONST)
6045 y = XEXP (XEXP (x, 1), 0);
6046 if (GET_CODE (y) == UNSPEC
6047 && XINT (y, 1) == UNSPEC_TOCREL)
6049 y = XVECEXP (y, 0, 0);
6050 if (!MEM_P (orig_x))
6053 return replace_equiv_address_nv (orig_x, y);
6058 && GET_CODE (orig_x) == LO_SUM
6059 && GET_CODE (XEXP (x, 1)) == CONST)
6061 y = XEXP (XEXP (x, 1), 0);
6062 if (GET_CODE (y) == UNSPEC
6063 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6064 return XVECEXP (y, 0, 0);
6070 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6072 static GTY(()) rtx rs6000_tls_symbol;
6074 rs6000_tls_get_addr (void)
6076 if (!rs6000_tls_symbol)
6077 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6079 return rs6000_tls_symbol;
6082 /* Construct the SYMBOL_REF for TLS GOT references. */
6084 static GTY(()) rtx rs6000_got_symbol;
6086 rs6000_got_sym (void)
6088 if (!rs6000_got_symbol)
6090 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6091 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6092 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6095 return rs6000_got_symbol;
6098 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6099 this (thread-local) address. */
6102 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6106 dest = gen_reg_rtx (Pmode);
6107 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6113 tlsreg = gen_rtx_REG (Pmode, 13);
6114 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6118 tlsreg = gen_rtx_REG (Pmode, 2);
6119 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6123 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6127 tmp = gen_reg_rtx (Pmode);
6130 tlsreg = gen_rtx_REG (Pmode, 13);
6131 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6135 tlsreg = gen_rtx_REG (Pmode, 2);
6136 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6140 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6142 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6147 rtx r3, got, tga, tmp1, tmp2, call_insn;
6149 /* We currently use relocations like @got@tlsgd for tls, which
6150 means the linker will handle allocation of tls entries, placing
6151 them in the .got section. So use a pointer to the .got section,
6152 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6153 or to secondary GOT sections used by 32-bit -fPIC. */
6155 got = gen_rtx_REG (Pmode, 2);
6159 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6162 rtx gsym = rs6000_got_sym ();
6163 got = gen_reg_rtx (Pmode);
6165 rs6000_emit_move (got, gsym, Pmode);
6170 tmp1 = gen_reg_rtx (Pmode);
6171 tmp2 = gen_reg_rtx (Pmode);
6172 mem = gen_const_mem (Pmode, tmp1);
6173 lab = gen_label_rtx ();
6174 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6175 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6176 emit_move_insn (tmp2, mem);
6177 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6178 set_unique_reg_note (last, REG_EQUAL, gsym);
6183 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6185 r3 = gen_rtx_REG (Pmode, 3);
6186 tga = rs6000_tls_get_addr ();
6187 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6189 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6190 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6191 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6192 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6193 else if (DEFAULT_ABI == ABI_V4)
6194 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6197 call_insn = last_call_insn ();
6198 PATTERN (call_insn) = insn;
6199 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6200 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6201 pic_offset_table_rtx);
6203 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6205 r3 = gen_rtx_REG (Pmode, 3);
6206 tga = rs6000_tls_get_addr ();
6207 tmp1 = gen_reg_rtx (Pmode);
6208 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6210 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6211 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6212 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6213 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6214 else if (DEFAULT_ABI == ABI_V4)
6215 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6218 call_insn = last_call_insn ();
6219 PATTERN (call_insn) = insn;
6220 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6221 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6222 pic_offset_table_rtx);
6224 if (rs6000_tls_size == 16)
6227 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6229 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6231 else if (rs6000_tls_size == 32)
6233 tmp2 = gen_reg_rtx (Pmode);
6235 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6237 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6240 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6242 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6246 tmp2 = gen_reg_rtx (Pmode);
6248 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6250 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6252 insn = gen_rtx_SET (Pmode, dest,
6253 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6259 /* IE, or 64-bit offset LE. */
6260 tmp2 = gen_reg_rtx (Pmode);
6262 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6264 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6267 insn = gen_tls_tls_64 (dest, tmp2, addr);
6269 insn = gen_tls_tls_32 (dest, tmp2, addr);
6277 /* Return 1 if X contains a thread-local symbol. */
6280 rs6000_tls_referenced_p (rtx x)
6282 if (! TARGET_HAVE_TLS)
6285 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6288 /* Return 1 if *X is a thread-local symbol. This is the same as
6289 rs6000_tls_symbol_ref except for the type of the unused argument. */
6292 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6294 return RS6000_SYMBOL_REF_TLS_P (*x);
6297 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6298 replace the input X, or the original X if no replacement is called for.
6299 The output parameter *WIN is 1 if the calling macro should goto WIN,
6302 For RS/6000, we wish to handle large displacements off a base
6303 register by splitting the addend across an addiu/addis and the mem insn.
6304 This cuts number of extra insns needed from 3 to 1.
6306 On Darwin, we use this to generate code for floating point constants.
6307 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6308 The Darwin code is inside #if TARGET_MACHO because only then are the
6309 machopic_* functions defined. */
6311 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6312 int opnum, int type,
6313 int ind_levels ATTRIBUTE_UNUSED, int *win)
6315 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6317 /* We must recognize output that we have already generated ourselves. */
6318 if (GET_CODE (x) == PLUS
6319 && GET_CODE (XEXP (x, 0)) == PLUS
6320 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6321 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6322 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6324 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6325 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6326 opnum, (enum reload_type)type);
6331 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6332 if (GET_CODE (x) == LO_SUM
6333 && GET_CODE (XEXP (x, 0)) == HIGH)
6335 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6336 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6337 opnum, (enum reload_type)type);
6343 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6344 && GET_CODE (x) == LO_SUM
6345 && GET_CODE (XEXP (x, 0)) == PLUS
6346 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6347 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6348 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6349 && machopic_operand_p (XEXP (x, 1)))
6351 /* Result of previous invocation of this function on Darwin
6352 floating point constant. */
6353 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6354 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6355 opnum, (enum reload_type)type);
6361 if (TARGET_CMODEL != CMODEL_SMALL
6362 && GET_CODE (x) == LO_SUM
6363 && GET_CODE (XEXP (x, 0)) == PLUS
6364 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6365 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6366 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6367 && GET_CODE (XEXP (x, 1)) == CONST
6368 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6369 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6370 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6372 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6373 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6374 opnum, (enum reload_type) type);
6379 /* Force ld/std non-word aligned offset into base register by wrapping
6381 if (GET_CODE (x) == PLUS
6382 && GET_CODE (XEXP (x, 0)) == REG
6383 && REGNO (XEXP (x, 0)) < 32
6384 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6385 && GET_CODE (XEXP (x, 1)) == CONST_INT
6387 && (INTVAL (XEXP (x, 1)) & 3) != 0
6388 && VECTOR_MEM_NONE_P (mode)
6389 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6390 && TARGET_POWERPC64)
6392 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6393 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6394 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6395 opnum, (enum reload_type) type);
6400 if (GET_CODE (x) == PLUS
6401 && GET_CODE (XEXP (x, 0)) == REG
6402 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6403 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6404 && GET_CODE (XEXP (x, 1)) == CONST_INT
6406 && !SPE_VECTOR_MODE (mode)
6407 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6408 || mode == DDmode || mode == TDmode
6410 && VECTOR_MEM_NONE_P (mode))
6412 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6413 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6415 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6417 /* Check for 32-bit overflow. */
6418 if (high + low != val)
6424 /* Reload the high part into a base reg; leave the low part
6425 in the mem directly. */
6427 x = gen_rtx_PLUS (GET_MODE (x),
6428 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6432 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6433 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6434 opnum, (enum reload_type)type);
6439 if (GET_CODE (x) == SYMBOL_REF
6441 && VECTOR_MEM_NONE_P (mode)
6442 && !SPE_VECTOR_MODE (mode)
6444 && DEFAULT_ABI == ABI_DARWIN
6445 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6447 && DEFAULT_ABI == ABI_V4
6450 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6451 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6455 && (mode != DImode || TARGET_POWERPC64)
6456 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6457 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6462 rtx offset = machopic_gen_offset (x);
6463 x = gen_rtx_LO_SUM (GET_MODE (x),
6464 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6465 gen_rtx_HIGH (Pmode, offset)), offset);
6469 x = gen_rtx_LO_SUM (GET_MODE (x),
6470 gen_rtx_HIGH (Pmode, x), x);
6472 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6473 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6474 opnum, (enum reload_type)type);
6479 /* Reload an offset address wrapped by an AND that represents the
6480 masking of the lower bits. Strip the outer AND and let reload
6481 convert the offset address into an indirect address. For VSX,
6482 force reload to create the address with an AND in a separate
6483 register, because we can't guarantee an altivec register will
6485 if (VECTOR_MEM_ALTIVEC_P (mode)
6486 && GET_CODE (x) == AND
6487 && GET_CODE (XEXP (x, 0)) == PLUS
6488 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6489 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6490 && GET_CODE (XEXP (x, 1)) == CONST_INT
6491 && INTVAL (XEXP (x, 1)) == -16)
6500 && GET_CODE (x) == SYMBOL_REF
6501 && constant_pool_expr_p (x)
6502 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6504 x = create_TOC_reference (x, NULL_RTX);
6505 if (TARGET_CMODEL != CMODEL_SMALL)
6506 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6507 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6508 opnum, (enum reload_type) type);
6516 /* Debug version of rs6000_legitimize_reload_address. */
6518 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6519 int opnum, int type,
6520 int ind_levels, int *win)
6522 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6525 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6526 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6527 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6531 fprintf (stderr, "Same address returned\n");
6533 fprintf (stderr, "NULL returned\n");
6536 fprintf (stderr, "New address:\n");
6543 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6544 that is a valid memory address for an instruction.
6545 The MODE argument is the machine mode for the MEM expression
6546 that wants to use this address.
6548 On the RS/6000, there are four valid address: a SYMBOL_REF that
6549 refers to a constant pool entry of an address (or the sum of it
6550 plus a constant), a short (16-bit signed) constant plus a register,
6551 the sum of two registers, or a register indirect, possibly with an
6552 auto-increment. For DFmode, DDmode and DImode with a constant plus
6553 register, we must ensure that both words are addressable or PowerPC64
6554 with offset word aligned.
6556 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6557 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6558 because adjacent memory cells are accessed by adding word-sized offsets
6559 during assembly output. */
6561 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6563 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6565 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6566 if (VECTOR_MEM_ALTIVEC_P (mode)
6567 && GET_CODE (x) == AND
6568 && GET_CODE (XEXP (x, 1)) == CONST_INT
6569 && INTVAL (XEXP (x, 1)) == -16)
6572 if (RS6000_SYMBOL_REF_TLS_P (x))
6574 if (legitimate_indirect_address_p (x, reg_ok_strict))
6576 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6577 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6578 && !SPE_VECTOR_MODE (mode)
6581 /* Restrict addressing for DI because of our SUBREG hackery. */
6582 && !(TARGET_E500_DOUBLE
6583 && (mode == DFmode || mode == DDmode || mode == DImode))
6585 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6587 if (virtual_stack_registers_memory_p (x))
6589 if (reg_offset_p && legitimate_small_data_p (mode, x))
6591 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6593 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6596 && GET_CODE (x) == PLUS
6597 && GET_CODE (XEXP (x, 0)) == REG
6598 && (XEXP (x, 0) == virtual_stack_vars_rtx
6599 || XEXP (x, 0) == arg_pointer_rtx)
6600 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6602 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6607 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6609 || (mode != DFmode && mode != DDmode)
6610 || (TARGET_E500_DOUBLE && mode != DDmode))
6611 && (TARGET_POWERPC64 || mode != DImode)
6612 && !avoiding_indexed_address_p (mode)
6613 && legitimate_indexed_address_p (x, reg_ok_strict))
6615 if (GET_CODE (x) == PRE_MODIFY
6619 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6621 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6622 && (TARGET_POWERPC64 || mode != DImode)
6623 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6624 && !SPE_VECTOR_MODE (mode)
6625 /* Restrict addressing for DI because of our SUBREG hackery. */
6626 && !(TARGET_E500_DOUBLE
6627 && (mode == DFmode || mode == DDmode || mode == DImode))
6629 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6630 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6631 || (!avoiding_indexed_address_p (mode)
6632 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6633 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6635 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6640 /* Debug version of rs6000_legitimate_address_p. */
6642 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6645 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6647 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6648 "strict = %d, code = %s\n",
6649 ret ? "true" : "false",
6650 GET_MODE_NAME (mode),
6652 GET_RTX_NAME (GET_CODE (x)));
6658 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6661 rs6000_mode_dependent_address_p (const_rtx addr)
6663 return rs6000_mode_dependent_address_ptr (addr);
6666 /* Go to LABEL if ADDR (a legitimate address expression)
6667 has an effect that depends on the machine mode it is used for.
6669 On the RS/6000 this is true of all integral offsets (since AltiVec
6670 and VSX modes don't allow them) or is a pre-increment or decrement.
6672 ??? Except that due to conceptual problems in offsettable_address_p
6673 we can't really report the problems of integral offsets. So leave
6674 this assuming that the adjustable offset must be valid for the
6675 sub-words of a TFmode operand, which is what we had before. */
6678 rs6000_mode_dependent_address (const_rtx addr)
6680 switch (GET_CODE (addr))
6683 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6684 is considered a legitimate address before reload, so there
6685 are no offset restrictions in that case. Note that this
6686 condition is safe in strict mode because any address involving
6687 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6688 been rejected as illegitimate. */
6689 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6690 && XEXP (addr, 0) != arg_pointer_rtx
6691 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6693 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6694 return val + 12 + 0x8000 >= 0x10000;
6699 /* Anything in the constant pool is sufficiently aligned that
6700 all bytes have the same high part address. */
6701 return !legitimate_constant_pool_address_p (addr, false);
6703 /* Auto-increment cases are now treated generically in recog.c. */
6705 return TARGET_UPDATE;
6707 /* AND is only allowed in Altivec loads. */
6718 /* Debug version of rs6000_mode_dependent_address. */
6720 rs6000_debug_mode_dependent_address (const_rtx addr)
6722 bool ret = rs6000_mode_dependent_address (addr);
6724 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6725 ret ? "true" : "false");
6731 /* Implement FIND_BASE_TERM. */
6734 rs6000_find_base_term (rtx op)
6738 split_const (op, &base, &offset);
6739 if (GET_CODE (base) == UNSPEC)
6740 switch (XINT (base, 1))
6743 case UNSPEC_MACHOPIC_OFFSET:
6744 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6745 for aliasing purposes. */
6746 return XVECEXP (base, 0, 0);
6752 /* More elaborate version of recog's offsettable_memref_p predicate
6753 that works around the ??? note of rs6000_mode_dependent_address.
6754 In particular it accepts
6756 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6758 in 32-bit mode, that the recog predicate rejects. */
6761 rs6000_offsettable_memref_p (rtx op)
6766 /* First mimic offsettable_memref_p. */
6767 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6770 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6771 the latter predicate knows nothing about the mode of the memory
6772 reference and, therefore, assumes that it is the largest supported
6773 mode (TFmode). As a consequence, legitimate offsettable memory
6774 references are rejected. rs6000_legitimate_offset_address_p contains
6775 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6776 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6779 /* Change register usage conditional on target flags. */
6781 rs6000_conditional_register_usage (void)
6785 /* Set MQ register fixed (already call_used) if not POWER
6786 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6791 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6793 fixed_regs[13] = call_used_regs[13]
6794 = call_really_used_regs[13] = 1;
6796 /* Conditionally disable FPRs. */
6797 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6798 for (i = 32; i < 64; i++)
6799 fixed_regs[i] = call_used_regs[i]
6800 = call_really_used_regs[i] = 1;
6802 /* The TOC register is not killed across calls in a way that is
6803 visible to the compiler. */
6804 if (DEFAULT_ABI == ABI_AIX)
6805 call_really_used_regs[2] = 0;
6807 if (DEFAULT_ABI == ABI_V4
6808 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6810 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6812 if (DEFAULT_ABI == ABI_V4
6813 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6815 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6816 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6817 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6819 if (DEFAULT_ABI == ABI_DARWIN
6820 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6821 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6822 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6823 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6825 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6826 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6827 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6831 global_regs[SPEFSCR_REGNO] = 1;
6832 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6833 registers in prologues and epilogues. We no longer use r14
6834 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6835 pool for link-compatibility with older versions of GCC. Once
6836 "old" code has died out, we can return r14 to the allocation
6839 = call_used_regs[14]
6840 = call_really_used_regs[14] = 1;
6843 if (!TARGET_ALTIVEC && !TARGET_VSX)
6845 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6846 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6847 call_really_used_regs[VRSAVE_REGNO] = 1;
6850 if (TARGET_ALTIVEC || TARGET_VSX)
6851 global_regs[VSCR_REGNO] = 1;
6853 if (TARGET_ALTIVEC_ABI)
6855 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6856 call_used_regs[i] = call_really_used_regs[i] = 1;
6858 /* AIX reserves VR20:31 in non-extended ABI mode. */
6860 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6861 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6865 /* Try to output insns to set TARGET equal to the constant C if it can
6866 be done in less than N insns. Do all computations in MODE.
6867 Returns the place where the output has been placed if it can be
6868 done and the insns have been emitted. If it would take more than N
6869 insns, zero is returned and no insns and emitted. */
6872 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6873 rtx source, int n ATTRIBUTE_UNUSED)
6875 rtx result, insn, set;
6876 HOST_WIDE_INT c0, c1;
6883 dest = gen_reg_rtx (mode);
6884 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6888 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6890 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6891 GEN_INT (INTVAL (source)
6892 & (~ (HOST_WIDE_INT) 0xffff))));
6893 emit_insn (gen_rtx_SET (VOIDmode, dest,
6894 gen_rtx_IOR (SImode, copy_rtx (result),
6895 GEN_INT (INTVAL (source) & 0xffff))));
6900 switch (GET_CODE (source))
6903 c0 = INTVAL (source);
6908 #if HOST_BITS_PER_WIDE_INT >= 64
6909 c0 = CONST_DOUBLE_LOW (source);
6912 c0 = CONST_DOUBLE_LOW (source);
6913 c1 = CONST_DOUBLE_HIGH (source);
6921 result = rs6000_emit_set_long_const (dest, c0, c1);
6928 insn = get_last_insn ();
6929 set = single_set (insn);
6930 if (! CONSTANT_P (SET_SRC (set)))
6931 set_unique_reg_note (insn, REG_EQUAL, source);
6936 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6937 fall back to a straight forward decomposition. We do this to avoid
6938 exponential run times encountered when looking for longer sequences
6939 with rs6000_emit_set_const. */
6941 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6943 if (!TARGET_POWERPC64)
6945 rtx operand1, operand2;
6947 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6949 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6951 emit_move_insn (operand1, GEN_INT (c1));
6952 emit_move_insn (operand2, GEN_INT (c2));
6956 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6959 ud2 = (c1 & 0xffff0000) >> 16;
6960 #if HOST_BITS_PER_WIDE_INT >= 64
6964 ud4 = (c2 & 0xffff0000) >> 16;
6966 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6967 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6970 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6972 emit_move_insn (dest, GEN_INT (ud1));
6975 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6976 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6979 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6982 emit_move_insn (dest, GEN_INT (ud2 << 16));
6984 emit_move_insn (copy_rtx (dest),
6985 gen_rtx_IOR (DImode, copy_rtx (dest),
6988 else if (ud3 == 0 && ud4 == 0)
6990 gcc_assert (ud2 & 0x8000);
6991 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6994 emit_move_insn (copy_rtx (dest),
6995 gen_rtx_IOR (DImode, copy_rtx (dest),
6997 emit_move_insn (copy_rtx (dest),
6998 gen_rtx_ZERO_EXTEND (DImode,
6999 gen_lowpart (SImode,
7002 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7003 || (ud4 == 0 && ! (ud3 & 0x8000)))
7006 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7009 emit_move_insn (dest, GEN_INT (ud3 << 16));
7012 emit_move_insn (copy_rtx (dest),
7013 gen_rtx_IOR (DImode, copy_rtx (dest),
7015 emit_move_insn (copy_rtx (dest),
7016 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7019 emit_move_insn (copy_rtx (dest),
7020 gen_rtx_IOR (DImode, copy_rtx (dest),
7026 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7029 emit_move_insn (dest, GEN_INT (ud4 << 16));
7032 emit_move_insn (copy_rtx (dest),
7033 gen_rtx_IOR (DImode, copy_rtx (dest),
7036 emit_move_insn (copy_rtx (dest),
7037 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7040 emit_move_insn (copy_rtx (dest),
7041 gen_rtx_IOR (DImode, copy_rtx (dest),
7042 GEN_INT (ud2 << 16)));
7044 emit_move_insn (copy_rtx (dest),
7045 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7051 /* Helper for the following. Get rid of [r+r] memory refs
7052 in cases where it won't work (TImode, TFmode, TDmode). */
7055 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7057 if (reload_in_progress)
7060 if (GET_CODE (operands[0]) == MEM
7061 && GET_CODE (XEXP (operands[0], 0)) != REG
7062 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7064 = replace_equiv_address (operands[0],
7065 copy_addr_to_reg (XEXP (operands[0], 0)));
7067 if (GET_CODE (operands[1]) == MEM
7068 && GET_CODE (XEXP (operands[1], 0)) != REG
7069 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7071 = replace_equiv_address (operands[1],
7072 copy_addr_to_reg (XEXP (operands[1], 0)));
7075 /* Return true if memory accesses to DECL are known to never straddle
7079 offsettable_ok_by_alignment (tree decl)
7081 unsigned HOST_WIDE_INT dsize, dalign;
7083 /* Presume any compiler generated symbol_ref is suitably aligned. */
7087 if (TREE_CODE (decl) != VAR_DECL
7088 && TREE_CODE (decl) != PARM_DECL
7089 && TREE_CODE (decl) != RESULT_DECL
7090 && TREE_CODE (decl) != FIELD_DECL)
7093 if (!DECL_SIZE_UNIT (decl))
7096 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7099 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7105 dalign = DECL_ALIGN_UNIT (decl);
7106 return dalign >= dsize;
7109 /* Emit a move from SOURCE to DEST in mode MODE. */
7111 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7115 operands[1] = source;
7117 if (TARGET_DEBUG_ADDR)
7120 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7121 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7122 GET_MODE_NAME (mode),
7125 can_create_pseudo_p ());
7127 fprintf (stderr, "source:\n");
7131 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7132 if (GET_CODE (operands[1]) == CONST_DOUBLE
7133 && ! FLOAT_MODE_P (mode)
7134 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7136 /* FIXME. This should never happen. */
7137 /* Since it seems that it does, do the safe thing and convert
7139 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7141 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7142 || FLOAT_MODE_P (mode)
7143 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7144 || CONST_DOUBLE_LOW (operands[1]) < 0)
7145 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7146 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7148 /* Check if GCC is setting up a block move that will end up using FP
7149 registers as temporaries. We must make sure this is acceptable. */
7150 if (GET_CODE (operands[0]) == MEM
7151 && GET_CODE (operands[1]) == MEM
7153 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7154 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7155 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7156 ? 32 : MEM_ALIGN (operands[0])))
7157 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7159 : MEM_ALIGN (operands[1]))))
7160 && ! MEM_VOLATILE_P (operands [0])
7161 && ! MEM_VOLATILE_P (operands [1]))
7163 emit_move_insn (adjust_address (operands[0], SImode, 0),
7164 adjust_address (operands[1], SImode, 0));
7165 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7166 adjust_address (copy_rtx (operands[1]), SImode, 4));
7170 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7171 && !gpc_reg_operand (operands[1], mode))
7172 operands[1] = force_reg (mode, operands[1]);
7174 if (mode == SFmode && ! TARGET_POWERPC
7175 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7176 && GET_CODE (operands[0]) == MEM)
7180 if (reload_in_progress || reload_completed)
7181 regnum = true_regnum (operands[1]);
7182 else if (GET_CODE (operands[1]) == REG)
7183 regnum = REGNO (operands[1]);
7187 /* If operands[1] is a register, on POWER it may have
7188 double-precision data in it, so truncate it to single
7190 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7193 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7194 : gen_reg_rtx (mode));
7195 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7196 operands[1] = newreg;
7200 /* Recognize the case where operand[1] is a reference to thread-local
7201 data and load its address to a register. */
7202 if (rs6000_tls_referenced_p (operands[1]))
7204 enum tls_model model;
7205 rtx tmp = operands[1];
7208 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7210 addend = XEXP (XEXP (tmp, 0), 1);
7211 tmp = XEXP (XEXP (tmp, 0), 0);
7214 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7215 model = SYMBOL_REF_TLS_MODEL (tmp);
7216 gcc_assert (model != 0);
7218 tmp = rs6000_legitimize_tls_address (tmp, model);
7221 tmp = gen_rtx_PLUS (mode, tmp, addend);
7222 tmp = force_operand (tmp, operands[0]);
7227 /* Handle the case where reload calls us with an invalid address. */
7228 if (reload_in_progress && mode == Pmode
7229 && (! general_operand (operands[1], mode)
7230 || ! nonimmediate_operand (operands[0], mode)))
7233 /* 128-bit constant floating-point values on Darwin should really be
7234 loaded as two parts. */
7235 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7236 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7238 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7239 know how to get a DFmode SUBREG of a TFmode. */
7240 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7241 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7242 simplify_gen_subreg (imode, operands[1], mode, 0),
7244 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7245 GET_MODE_SIZE (imode)),
7246 simplify_gen_subreg (imode, operands[1], mode,
7247 GET_MODE_SIZE (imode)),
7252 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7253 cfun->machine->sdmode_stack_slot =
7254 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7256 if (reload_in_progress
7258 && MEM_P (operands[0])
7259 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7260 && REG_P (operands[1]))
7262 if (FP_REGNO_P (REGNO (operands[1])))
7264 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7265 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7266 emit_insn (gen_movsd_store (mem, operands[1]));
7268 else if (INT_REGNO_P (REGNO (operands[1])))
7270 rtx mem = adjust_address_nv (operands[0], mode, 4);
7271 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7272 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7278 if (reload_in_progress
7280 && REG_P (operands[0])
7281 && MEM_P (operands[1])
7282 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7284 if (FP_REGNO_P (REGNO (operands[0])))
7286 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7287 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7288 emit_insn (gen_movsd_load (operands[0], mem));
7290 else if (INT_REGNO_P (REGNO (operands[0])))
7292 rtx mem = adjust_address_nv (operands[1], mode, 4);
7293 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7294 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7301 /* FIXME: In the long term, this switch statement should go away
7302 and be replaced by a sequence of tests based on things like
7308 if (CONSTANT_P (operands[1])
7309 && GET_CODE (operands[1]) != CONST_INT)
7310 operands[1] = force_const_mem (mode, operands[1]);
7315 rs6000_eliminate_indexed_memrefs (operands);
7322 if (CONSTANT_P (operands[1])
7323 && ! easy_fp_constant (operands[1], mode))
7324 operands[1] = force_const_mem (mode, operands[1]);
7337 if (CONSTANT_P (operands[1])
7338 && !easy_vector_constant (operands[1], mode))
7339 operands[1] = force_const_mem (mode, operands[1]);
7344 /* Use default pattern for address of ELF small data */
7347 && DEFAULT_ABI == ABI_V4
7348 && (GET_CODE (operands[1]) == SYMBOL_REF
7349 || GET_CODE (operands[1]) == CONST)
7350 && small_data_operand (operands[1], mode))
7352 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7356 if (DEFAULT_ABI == ABI_V4
7357 && mode == Pmode && mode == SImode
7358 && flag_pic == 1 && got_operand (operands[1], mode))
7360 emit_insn (gen_movsi_got (operands[0], operands[1]));
7364 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7368 && CONSTANT_P (operands[1])
7369 && GET_CODE (operands[1]) != HIGH
7370 && GET_CODE (operands[1]) != CONST_INT)
7372 rtx target = (!can_create_pseudo_p ()
7374 : gen_reg_rtx (mode));
7376 /* If this is a function address on -mcall-aixdesc,
7377 convert it to the address of the descriptor. */
7378 if (DEFAULT_ABI == ABI_AIX
7379 && GET_CODE (operands[1]) == SYMBOL_REF
7380 && XSTR (operands[1], 0)[0] == '.')
7382 const char *name = XSTR (operands[1], 0);
7384 while (*name == '.')
7386 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7387 CONSTANT_POOL_ADDRESS_P (new_ref)
7388 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7389 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7390 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7391 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7392 operands[1] = new_ref;
7395 if (DEFAULT_ABI == ABI_DARWIN)
7398 if (MACHO_DYNAMIC_NO_PIC_P)
7400 /* Take care of any required data indirection. */
7401 operands[1] = rs6000_machopic_legitimize_pic_address (
7402 operands[1], mode, operands[0]);
7403 if (operands[0] != operands[1])
7404 emit_insn (gen_rtx_SET (VOIDmode,
7405 operands[0], operands[1]));
7409 emit_insn (gen_macho_high (target, operands[1]));
7410 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7414 emit_insn (gen_elf_high (target, operands[1]));
7415 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7419 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7420 and we have put it in the TOC, we just need to make a TOC-relative
7423 && GET_CODE (operands[1]) == SYMBOL_REF
7424 && constant_pool_expr_p (operands[1])
7425 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7426 get_pool_mode (operands[1])))
7427 || (TARGET_CMODEL == CMODEL_MEDIUM
7428 && GET_CODE (operands[1]) == SYMBOL_REF
7429 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7430 && SYMBOL_REF_LOCAL_P (operands[1])
7431 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7434 if (TARGET_CMODEL != CMODEL_SMALL)
7436 if (can_create_pseudo_p ())
7437 reg = gen_reg_rtx (Pmode);
7441 operands[1] = create_TOC_reference (operands[1], reg);
7443 else if (mode == Pmode
7444 && CONSTANT_P (operands[1])
7445 && ((GET_CODE (operands[1]) != CONST_INT
7446 && ! easy_fp_constant (operands[1], mode))
7447 || (GET_CODE (operands[1]) == CONST_INT
7448 && (num_insns_constant (operands[1], mode)
7449 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7450 || (GET_CODE (operands[0]) == REG
7451 && FP_REGNO_P (REGNO (operands[0]))))
7452 && GET_CODE (operands[1]) != HIGH
7453 && ! legitimate_constant_pool_address_p (operands[1], false)
7454 && ! toc_relative_expr_p (operands[1])
7455 && (TARGET_CMODEL == CMODEL_SMALL
7456 || can_create_pseudo_p ()
7457 || (REG_P (operands[0])
7458 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7462 /* Darwin uses a special PIC legitimizer. */
7463 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7466 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7468 if (operands[0] != operands[1])
7469 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7474 /* If we are to limit the number of things we put in the TOC and
7475 this is a symbol plus a constant we can add in one insn,
7476 just put the symbol in the TOC and add the constant. Don't do
7477 this if reload is in progress. */
7478 if (GET_CODE (operands[1]) == CONST
7479 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7480 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7481 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7482 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7483 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7484 && ! side_effects_p (operands[0]))
7487 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7488 rtx other = XEXP (XEXP (operands[1], 0), 1);
7490 sym = force_reg (mode, sym);
7491 emit_insn (gen_add3_insn (operands[0], sym, other));
7495 operands[1] = force_const_mem (mode, operands[1]);
7498 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7499 && constant_pool_expr_p (XEXP (operands[1], 0))
7500 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7501 get_pool_constant (XEXP (operands[1], 0)),
7502 get_pool_mode (XEXP (operands[1], 0))))
7506 if (TARGET_CMODEL != CMODEL_SMALL)
7508 if (can_create_pseudo_p ())
7509 reg = gen_reg_rtx (Pmode);
7513 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7514 operands[1] = gen_const_mem (mode, tocref);
7515 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7521 rs6000_eliminate_indexed_memrefs (operands);
7525 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7527 gen_rtx_SET (VOIDmode,
7528 operands[0], operands[1]),
7529 gen_rtx_CLOBBER (VOIDmode,
7530 gen_rtx_SCRATCH (SImode)))));
7536 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7539 /* Above, we may have called force_const_mem which may have returned
7540 an invalid address. If we can, fix this up; otherwise, reload will
7541 have to deal with it. */
7542 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7543 operands[1] = validize_mem (operands[1]);
7546 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7549 /* Nonzero if we can use a floating-point register to pass this arg. */
7550 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7551 (SCALAR_FLOAT_MODE_P (MODE) \
7552 && (CUM)->fregno <= FP_ARG_MAX_REG \
7553 && TARGET_HARD_FLOAT && TARGET_FPRS)
7555 /* Nonzero if we can use an AltiVec register to pass this arg. */
7556 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7557 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7558 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7559 && TARGET_ALTIVEC_ABI \
7562 /* Return a nonzero value to say to return the function value in
7563 memory, just as large structures are always returned. TYPE will be
7564 the data type of the value, and FNTYPE will be the type of the
7565 function doing the returning, or @code{NULL} for libcalls.
7567 The AIX ABI for the RS/6000 specifies that all structures are
7568 returned in memory. The Darwin ABI does the same.
7570 For the Darwin 64 Bit ABI, a function result can be returned in
7571 registers or in memory, depending on the size of the return data
7572 type. If it is returned in registers, the value occupies the same
7573 registers as it would if it were the first and only function
7574 argument. Otherwise, the function places its result in memory at
7575 the location pointed to by GPR3.
7577 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7578 but a draft put them in memory, and GCC used to implement the draft
7579 instead of the final standard. Therefore, aix_struct_return
7580 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7581 compatibility can change DRAFT_V4_STRUCT_RET to override the
7582 default, and -m switches get the final word. See
7583 rs6000_option_override_internal for more details.
7585 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7586 long double support is enabled. These values are returned in memory.
7588 int_size_in_bytes returns -1 for variable size objects, which go in
7589 memory always. The cast to unsigned makes -1 > 8. */
7592 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7594 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7596 && rs6000_darwin64_abi
7597 && TREE_CODE (type) == RECORD_TYPE
7598 && int_size_in_bytes (type) > 0)
7600 CUMULATIVE_ARGS valcum;
7604 valcum.fregno = FP_ARG_MIN_REG;
7605 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7606 /* Do a trial code generation as if this were going to be passed
7607 as an argument; if any part goes in memory, we return NULL. */
7608 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7611 /* Otherwise fall through to more conventional ABI rules. */
7614 if (AGGREGATE_TYPE_P (type)
7615 && (aix_struct_return
7616 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7619 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7620 modes only exist for GCC vector types if -maltivec. */
7621 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7622 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7625 /* Return synthetic vectors in memory. */
7626 if (TREE_CODE (type) == VECTOR_TYPE
7627 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7629 static bool warned_for_return_big_vectors = false;
7630 if (!warned_for_return_big_vectors)
7632 warning (0, "GCC vector returned by reference: "
7633 "non-standard ABI extension with no compatibility guarantee");
7634 warned_for_return_big_vectors = true;
7639 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7645 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7646 for a call to a function whose data type is FNTYPE.
7647 For a library call, FNTYPE is 0.
7649 For incoming args we set the number of arguments in the prototype large
7650 so we never return a PARALLEL. */
7653 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7654 rtx libname ATTRIBUTE_UNUSED, int incoming,
7655 int libcall, int n_named_args)
7657 static CUMULATIVE_ARGS zero_cumulative;
7659 *cum = zero_cumulative;
7661 cum->fregno = FP_ARG_MIN_REG;
7662 cum->vregno = ALTIVEC_ARG_MIN_REG;
7663 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7664 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7665 ? CALL_LIBCALL : CALL_NORMAL);
7666 cum->sysv_gregno = GP_ARG_MIN_REG;
7667 cum->stdarg = stdarg_p (fntype);
7669 cum->nargs_prototype = 0;
7670 if (incoming || cum->prototype)
7671 cum->nargs_prototype = n_named_args;
7673 /* Check for a longcall attribute. */
7674 if ((!fntype && rs6000_default_long_calls)
7676 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7677 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7678 cum->call_cookie |= CALL_LONG;
7680 if (TARGET_DEBUG_ARG)
7682 fprintf (stderr, "\ninit_cumulative_args:");
7685 tree ret_type = TREE_TYPE (fntype);
7686 fprintf (stderr, " ret code = %s,",
7687 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7690 if (cum->call_cookie & CALL_LONG)
7691 fprintf (stderr, " longcall,");
7693 fprintf (stderr, " proto = %d, nargs = %d\n",
7694 cum->prototype, cum->nargs_prototype);
7699 && TARGET_ALTIVEC_ABI
7700 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7702 error ("cannot return value in vector register because"
7703 " altivec instructions are disabled, use -maltivec"
7708 /* Return true if TYPE must be passed on the stack and not in registers. */
7711 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7713 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7714 return must_pass_in_stack_var_size (mode, type);
7716 return must_pass_in_stack_var_size_or_pad (mode, type);
7719 /* If defined, a C expression which determines whether, and in which
7720 direction, to pad out an argument with extra space. The value
7721 should be of type `enum direction': either `upward' to pad above
7722 the argument, `downward' to pad below, or `none' to inhibit
7725 For the AIX ABI structs are always stored left shifted in their
7729 function_arg_padding (enum machine_mode mode, const_tree type)
7731 #ifndef AGGREGATE_PADDING_FIXED
7732 #define AGGREGATE_PADDING_FIXED 0
7734 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7735 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7738 if (!AGGREGATE_PADDING_FIXED)
7740 /* GCC used to pass structures of the same size as integer types as
7741 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7742 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7743 passed padded downward, except that -mstrict-align further
7744 muddied the water in that multi-component structures of 2 and 4
7745 bytes in size were passed padded upward.
7747 The following arranges for best compatibility with previous
7748 versions of gcc, but removes the -mstrict-align dependency. */
7749 if (BYTES_BIG_ENDIAN)
7751 HOST_WIDE_INT size = 0;
7753 if (mode == BLKmode)
7755 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7756 size = int_size_in_bytes (type);
7759 size = GET_MODE_SIZE (mode);
7761 if (size == 1 || size == 2 || size == 4)
7767 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7769 if (type != 0 && AGGREGATE_TYPE_P (type))
7773 /* Fall back to the default. */
7774 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7777 /* If defined, a C expression that gives the alignment boundary, in bits,
7778 of an argument with the specified mode and type. If it is not defined,
7779 PARM_BOUNDARY is used for all arguments.
7781 V.4 wants long longs and doubles to be double word aligned. Just
7782 testing the mode size is a boneheaded way to do this as it means
7783 that other types such as complex int are also double word aligned.
7784 However, we're stuck with this because changing the ABI might break
7785 existing library interfaces.
7787 Doubleword align SPE vectors.
7788 Quadword align Altivec vectors.
7789 Quadword align large synthetic vector types. */
7792 function_arg_boundary (enum machine_mode mode, const_tree type)
7794 if (DEFAULT_ABI == ABI_V4
7795 && (GET_MODE_SIZE (mode) == 8
7796 || (TARGET_HARD_FLOAT
7798 && (mode == TFmode || mode == TDmode))))
7800 else if (SPE_VECTOR_MODE (mode)
7801 || (type && TREE_CODE (type) == VECTOR_TYPE
7802 && int_size_in_bytes (type) >= 8
7803 && int_size_in_bytes (type) < 16))
7805 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7806 || (type && TREE_CODE (type) == VECTOR_TYPE
7807 && int_size_in_bytes (type) >= 16))
7809 else if (TARGET_MACHO
7810 && rs6000_darwin64_abi
7812 && type && TYPE_ALIGN (type) > 64)
7815 return PARM_BOUNDARY;
7818 /* For a function parm of MODE and TYPE, return the starting word in
7819 the parameter area. NWORDS of the parameter area are already used. */
7822 rs6000_parm_start (enum machine_mode mode, const_tree type,
7823 unsigned int nwords)
7826 unsigned int parm_offset;
7828 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7829 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7830 return nwords + (-(parm_offset + nwords) & align);
7833 /* Compute the size (in words) of a function argument. */
7835 static unsigned long
7836 rs6000_arg_size (enum machine_mode mode, const_tree type)
7840 if (mode != BLKmode)
7841 size = GET_MODE_SIZE (mode);
7843 size = int_size_in_bytes (type);
7846 return (size + 3) >> 2;
7848 return (size + 7) >> 3;
7851 /* Use this to flush pending int fields. */
7854 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7855 HOST_WIDE_INT bitpos, int final)
7857 unsigned int startbit, endbit;
7858 int intregs, intoffset;
7859 enum machine_mode mode;
7861 /* Handle the situations where a float is taking up the first half
7862 of the GPR, and the other half is empty (typically due to
7863 alignment restrictions). We can detect this by a 8-byte-aligned
7864 int field, or by seeing that this is the final flush for this
7865 argument. Count the word and continue on. */
7866 if (cum->floats_in_gpr == 1
7867 && (cum->intoffset % 64 == 0
7868 || (cum->intoffset == -1 && final)))
7871 cum->floats_in_gpr = 0;
7874 if (cum->intoffset == -1)
7877 intoffset = cum->intoffset;
7878 cum->intoffset = -1;
7879 cum->floats_in_gpr = 0;
7881 if (intoffset % BITS_PER_WORD != 0)
7883 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7885 if (mode == BLKmode)
7887 /* We couldn't find an appropriate mode, which happens,
7888 e.g., in packed structs when there are 3 bytes to load.
7889 Back intoffset back to the beginning of the word in this
7891 intoffset = intoffset & -BITS_PER_WORD;
7895 startbit = intoffset & -BITS_PER_WORD;
7896 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7897 intregs = (endbit - startbit) / BITS_PER_WORD;
7898 cum->words += intregs;
7899 /* words should be unsigned. */
7900 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7902 int pad = (endbit/BITS_PER_WORD) - cum->words;
7907 /* The darwin64 ABI calls for us to recurse down through structs,
7908 looking for elements passed in registers. Unfortunately, we have
7909 to track int register count here also because of misalignments
7910 in powerpc alignment mode. */
7913 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7915 HOST_WIDE_INT startbitpos)
7919 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7920 if (TREE_CODE (f) == FIELD_DECL)
7922 HOST_WIDE_INT bitpos = startbitpos;
7923 tree ftype = TREE_TYPE (f);
7924 enum machine_mode mode;
7925 if (ftype == error_mark_node)
7927 mode = TYPE_MODE (ftype);
7929 if (DECL_SIZE (f) != 0
7930 && host_integerp (bit_position (f), 1))
7931 bitpos += int_bit_position (f);
7933 /* ??? FIXME: else assume zero offset. */
7935 if (TREE_CODE (ftype) == RECORD_TYPE)
7936 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7937 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7939 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7940 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7941 /* Single-precision floats present a special problem for
7942 us, because they are smaller than an 8-byte GPR, and so
7943 the structure-packing rules combined with the standard
7944 varargs behavior mean that we want to pack float/float
7945 and float/int combinations into a single register's
7946 space. This is complicated by the arg advance flushing,
7947 which works on arbitrarily large groups of int-type
7951 if (cum->floats_in_gpr == 1)
7953 /* Two floats in a word; count the word and reset
7956 cum->floats_in_gpr = 0;
7958 else if (bitpos % 64 == 0)
7960 /* A float at the beginning of an 8-byte word;
7961 count it and put off adjusting cum->words until
7962 we see if a arg advance flush is going to do it
7964 cum->floats_in_gpr++;
7968 /* The float is at the end of a word, preceded
7969 by integer fields, so the arg advance flush
7970 just above has already set cum->words and
7971 everything is taken care of. */
7975 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7977 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7979 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7983 else if (cum->intoffset == -1)
7984 cum->intoffset = bitpos;
7988 /* Check for an item that needs to be considered specially under the darwin 64
7989 bit ABI. These are record types where the mode is BLK or the structure is
7992 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
7994 return rs6000_darwin64_abi
7995 && ((mode == BLKmode
7996 && TREE_CODE (type) == RECORD_TYPE
7997 && int_size_in_bytes (type) > 0)
7998 || (type && TREE_CODE (type) == RECORD_TYPE
7999 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8002 /* Update the data in CUM to advance over an argument
8003 of mode MODE and data type TYPE.
8004 (TYPE is null for libcalls where that information may not be available.)
8006 Note that for args passed by reference, function_arg will be called
8007 with MODE and TYPE set to that of the pointer to the arg, not the arg
8011 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8012 const_tree type, bool named, int depth)
8015 /* Only tick off an argument if we're not recursing. */
8017 cum->nargs_prototype--;
8019 if (TARGET_ALTIVEC_ABI
8020 && (ALTIVEC_VECTOR_MODE (mode)
8021 || VSX_VECTOR_MODE (mode)
8022 || (type && TREE_CODE (type) == VECTOR_TYPE
8023 && int_size_in_bytes (type) == 16)))
8027 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8030 if (!TARGET_ALTIVEC)
8031 error ("cannot pass argument in vector register because"
8032 " altivec instructions are disabled, use -maltivec"
8035 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8036 even if it is going to be passed in a vector register.
8037 Darwin does the same for variable-argument functions. */
8038 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8039 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8049 /* Vector parameters must be 16-byte aligned. This places
8050 them at 2 mod 4 in terms of words in 32-bit mode, since
8051 the parameter save area starts at offset 24 from the
8052 stack. In 64-bit mode, they just have to start on an
8053 even word, since the parameter save area is 16-byte
8054 aligned. Space for GPRs is reserved even if the argument
8055 will be passed in memory. */
8057 align = (2 - cum->words) & 3;
8059 align = cum->words & 1;
8060 cum->words += align + rs6000_arg_size (mode, type);
8062 if (TARGET_DEBUG_ARG)
8064 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8066 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8067 cum->nargs_prototype, cum->prototype,
8068 GET_MODE_NAME (mode));
8072 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8074 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8077 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8079 int size = int_size_in_bytes (type);
8080 /* Variable sized types have size == -1 and are
8081 treated as if consisting entirely of ints.
8082 Pad to 16 byte boundary if needed. */
8083 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8084 && (cum->words % 2) != 0)
8086 /* For varargs, we can just go up by the size of the struct. */
8088 cum->words += (size + 7) / 8;
8091 /* It is tempting to say int register count just goes up by
8092 sizeof(type)/8, but this is wrong in a case such as
8093 { int; double; int; } [powerpc alignment]. We have to
8094 grovel through the fields for these too. */
8096 cum->floats_in_gpr = 0;
8097 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8098 rs6000_darwin64_record_arg_advance_flush (cum,
8099 size * BITS_PER_UNIT, 1);
8101 if (TARGET_DEBUG_ARG)
8103 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8104 cum->words, TYPE_ALIGN (type), size);
8106 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8107 cum->nargs_prototype, cum->prototype,
8108 GET_MODE_NAME (mode));
8111 else if (DEFAULT_ABI == ABI_V4)
8113 if (TARGET_HARD_FLOAT && TARGET_FPRS
8114 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8115 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8116 || (mode == TFmode && !TARGET_IEEEQUAD)
8117 || mode == SDmode || mode == DDmode || mode == TDmode))
8119 /* _Decimal128 must use an even/odd register pair. This assumes
8120 that the register number is odd when fregno is odd. */
8121 if (mode == TDmode && (cum->fregno % 2) == 1)
8124 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8125 <= FP_ARG_V4_MAX_REG)
8126 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8129 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8130 if (mode == DFmode || mode == TFmode
8131 || mode == DDmode || mode == TDmode)
8132 cum->words += cum->words & 1;
8133 cum->words += rs6000_arg_size (mode, type);
8138 int n_words = rs6000_arg_size (mode, type);
8139 int gregno = cum->sysv_gregno;
8141 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8142 (r7,r8) or (r9,r10). As does any other 2 word item such
8143 as complex int due to a historical mistake. */
8145 gregno += (1 - gregno) & 1;
8147 /* Multi-reg args are not split between registers and stack. */
8148 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8150 /* Long long and SPE vectors are aligned on the stack.
8151 So are other 2 word items such as complex int due to
8152 a historical mistake. */
8154 cum->words += cum->words & 1;
8155 cum->words += n_words;
8158 /* Note: continuing to accumulate gregno past when we've started
8159 spilling to the stack indicates the fact that we've started
8160 spilling to the stack to expand_builtin_saveregs. */
8161 cum->sysv_gregno = gregno + n_words;
8164 if (TARGET_DEBUG_ARG)
8166 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8167 cum->words, cum->fregno);
8168 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8169 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8170 fprintf (stderr, "mode = %4s, named = %d\n",
8171 GET_MODE_NAME (mode), named);
8176 int n_words = rs6000_arg_size (mode, type);
8177 int start_words = cum->words;
8178 int align_words = rs6000_parm_start (mode, type, start_words);
8180 cum->words = align_words + n_words;
8182 if (SCALAR_FLOAT_MODE_P (mode)
8183 && TARGET_HARD_FLOAT && TARGET_FPRS)
8185 /* _Decimal128 must be passed in an even/odd float register pair.
8186 This assumes that the register number is odd when fregno is
8188 if (mode == TDmode && (cum->fregno % 2) == 1)
8190 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8193 if (TARGET_DEBUG_ARG)
8195 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8196 cum->words, cum->fregno);
8197 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8198 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8199 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8200 named, align_words - start_words, depth);
8206 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8207 const_tree type, bool named)
8209 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8213 spe_build_register_parallel (enum machine_mode mode, int gregno)
8220 r1 = gen_rtx_REG (DImode, gregno);
8221 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8222 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8226 r1 = gen_rtx_REG (DImode, gregno);
8227 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8228 r3 = gen_rtx_REG (DImode, gregno + 2);
8229 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8230 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8233 r1 = gen_rtx_REG (DImode, gregno);
8234 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8235 r3 = gen_rtx_REG (DImode, gregno + 2);
8236 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8237 r5 = gen_rtx_REG (DImode, gregno + 4);
8238 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8239 r7 = gen_rtx_REG (DImode, gregno + 6);
8240 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8241 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8248 /* Determine where to put a SIMD argument on the SPE. */
8250 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8253 int gregno = cum->sysv_gregno;
8255 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8256 are passed and returned in a pair of GPRs for ABI compatibility. */
8257 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8258 || mode == DCmode || mode == TCmode))
8260 int n_words = rs6000_arg_size (mode, type);
8262 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8264 gregno += (1 - gregno) & 1;
8266 /* Multi-reg args are not split between registers and stack. */
8267 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8270 return spe_build_register_parallel (mode, gregno);
8274 int n_words = rs6000_arg_size (mode, type);
8276 /* SPE vectors are put in odd registers. */
8277 if (n_words == 2 && (gregno & 1) == 0)
8280 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8283 enum machine_mode m = SImode;
8285 r1 = gen_rtx_REG (m, gregno);
8286 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8287 r2 = gen_rtx_REG (m, gregno + 1);
8288 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8289 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8296 if (gregno <= GP_ARG_MAX_REG)
8297 return gen_rtx_REG (mode, gregno);
8303 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8304 structure between cum->intoffset and bitpos to integer registers. */
8307 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8308 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8310 enum machine_mode mode;
8312 unsigned int startbit, endbit;
8313 int this_regno, intregs, intoffset;
8316 if (cum->intoffset == -1)
8319 intoffset = cum->intoffset;
8320 cum->intoffset = -1;
8322 /* If this is the trailing part of a word, try to only load that
8323 much into the register. Otherwise load the whole register. Note
8324 that in the latter case we may pick up unwanted bits. It's not a
8325 problem at the moment but may wish to revisit. */
8327 if (intoffset % BITS_PER_WORD != 0)
8329 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8331 if (mode == BLKmode)
8333 /* We couldn't find an appropriate mode, which happens,
8334 e.g., in packed structs when there are 3 bytes to load.
8335 Back intoffset back to the beginning of the word in this
8337 intoffset = intoffset & -BITS_PER_WORD;
8344 startbit = intoffset & -BITS_PER_WORD;
8345 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8346 intregs = (endbit - startbit) / BITS_PER_WORD;
8347 this_regno = cum->words + intoffset / BITS_PER_WORD;
8349 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8352 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8356 intoffset /= BITS_PER_UNIT;
8359 regno = GP_ARG_MIN_REG + this_regno;
8360 reg = gen_rtx_REG (mode, regno);
8362 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8365 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8369 while (intregs > 0);
8372 /* Recursive workhorse for the following. */
8375 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8376 HOST_WIDE_INT startbitpos, rtx rvec[],
8381 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8382 if (TREE_CODE (f) == FIELD_DECL)
8384 HOST_WIDE_INT bitpos = startbitpos;
8385 tree ftype = TREE_TYPE (f);
8386 enum machine_mode mode;
8387 if (ftype == error_mark_node)
8389 mode = TYPE_MODE (ftype);
8391 if (DECL_SIZE (f) != 0
8392 && host_integerp (bit_position (f), 1))
8393 bitpos += int_bit_position (f);
8395 /* ??? FIXME: else assume zero offset. */
8397 if (TREE_CODE (ftype) == RECORD_TYPE)
8398 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8399 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8404 case SCmode: mode = SFmode; break;
8405 case DCmode: mode = DFmode; break;
8406 case TCmode: mode = TFmode; break;
8410 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8412 = gen_rtx_EXPR_LIST (VOIDmode,
8413 gen_rtx_REG (mode, cum->fregno++),
8414 GEN_INT (bitpos / BITS_PER_UNIT));
8415 if (mode == TFmode || mode == TDmode)
8418 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8420 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8422 = gen_rtx_EXPR_LIST (VOIDmode,
8423 gen_rtx_REG (mode, cum->vregno++),
8424 GEN_INT (bitpos / BITS_PER_UNIT));
8426 else if (cum->intoffset == -1)
8427 cum->intoffset = bitpos;
8431 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8432 the register(s) to be used for each field and subfield of a struct
8433 being passed by value, along with the offset of where the
8434 register's value may be found in the block. FP fields go in FP
8435 register, vector fields go in vector registers, and everything
8436 else goes in int registers, packed as in memory.
8438 This code is also used for function return values. RETVAL indicates
8439 whether this is the case.
8441 Much of this is taken from the SPARC V9 port, which has a similar
8442 calling convention. */
8445 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8446 bool named, bool retval)
8448 rtx rvec[FIRST_PSEUDO_REGISTER];
8449 int k = 1, kbase = 1;
8450 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8451 /* This is a copy; modifications are not visible to our caller. */
8452 CUMULATIVE_ARGS copy_cum = *orig_cum;
8453 CUMULATIVE_ARGS *cum = ©_cum;
8455 /* Pad to 16 byte boundary if needed. */
8456 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8457 && (cum->words % 2) != 0)
8464 /* Put entries into rvec[] for individual FP and vector fields, and
8465 for the chunks of memory that go in int regs. Note we start at
8466 element 1; 0 is reserved for an indication of using memory, and
8467 may or may not be filled in below. */
8468 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8469 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8471 /* If any part of the struct went on the stack put all of it there.
8472 This hack is because the generic code for
8473 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8474 parts of the struct are not at the beginning. */
8478 return NULL_RTX; /* doesn't go in registers at all */
8480 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8482 if (k > 1 || cum->use_stack)
8483 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8488 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8491 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8496 rtx rvec[GP_ARG_NUM_REG + 1];
8498 if (align_words >= GP_ARG_NUM_REG)
8501 n_units = rs6000_arg_size (mode, type);
8503 /* Optimize the simple case where the arg fits in one gpr, except in
8504 the case of BLKmode due to assign_parms assuming that registers are
8505 BITS_PER_WORD wide. */
8507 || (n_units == 1 && mode != BLKmode))
8508 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8511 if (align_words + n_units > GP_ARG_NUM_REG)
8512 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8513 using a magic NULL_RTX component.
8514 This is not strictly correct. Only some of the arg belongs in
8515 memory, not all of it. However, the normal scheme using
8516 function_arg_partial_nregs can result in unusual subregs, eg.
8517 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8518 store the whole arg to memory is often more efficient than code
8519 to store pieces, and we know that space is available in the right
8520 place for the whole arg. */
8521 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8526 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8527 rtx off = GEN_INT (i++ * 4);
8528 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8530 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8532 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8535 /* Determine where to put an argument to a function.
8536 Value is zero to push the argument on the stack,
8537 or a hard register in which to store the argument.
8539 MODE is the argument's machine mode.
8540 TYPE is the data type of the argument (as a tree).
8541 This is null for libcalls where that information may
8543 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8544 the preceding args and about the function being called. It is
8545 not modified in this routine.
8546 NAMED is nonzero if this argument is a named parameter
8547 (otherwise it is an extra parameter matching an ellipsis).
8549 On RS/6000 the first eight words of non-FP are normally in registers
8550 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8551 Under V.4, the first 8 FP args are in registers.
8553 If this is floating-point and no prototype is specified, we use
8554 both an FP and integer register (or possibly FP reg and stack). Library
8555 functions (when CALL_LIBCALL is set) always have the proper types for args,
8556 so we can pass the FP value just in one register. emit_library_function
8557 doesn't support PARALLEL anyway.
8559 Note that for args passed by reference, function_arg will be called
8560 with MODE and TYPE set to that of the pointer to the arg, not the arg
8564 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8565 const_tree type, bool named)
8567 enum rs6000_abi abi = DEFAULT_ABI;
8569 /* Return a marker to indicate whether CR1 needs to set or clear the
8570 bit that V.4 uses to say fp args were passed in registers.
8571 Assume that we don't need the marker for software floating point,
8572 or compiler generated library calls. */
8573 if (mode == VOIDmode)
8576 && (cum->call_cookie & CALL_LIBCALL) == 0
8578 || (cum->nargs_prototype < 0
8579 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8581 /* For the SPE, we need to crxor CR6 always. */
8583 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8584 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8585 return GEN_INT (cum->call_cookie
8586 | ((cum->fregno == FP_ARG_MIN_REG)
8587 ? CALL_V4_SET_FP_ARGS
8588 : CALL_V4_CLEAR_FP_ARGS));
8591 return GEN_INT (cum->call_cookie);
8594 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8596 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8597 if (rslt != NULL_RTX)
8599 /* Else fall through to usual handling. */
8602 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8603 if (TARGET_64BIT && ! cum->prototype)
8605 /* Vector parameters get passed in vector register
8606 and also in GPRs or memory, in absence of prototype. */
8609 align_words = (cum->words + 1) & ~1;
8611 if (align_words >= GP_ARG_NUM_REG)
8617 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8619 return gen_rtx_PARALLEL (mode,
8621 gen_rtx_EXPR_LIST (VOIDmode,
8623 gen_rtx_EXPR_LIST (VOIDmode,
8624 gen_rtx_REG (mode, cum->vregno),
8628 return gen_rtx_REG (mode, cum->vregno);
8629 else if (TARGET_ALTIVEC_ABI
8630 && (ALTIVEC_VECTOR_MODE (mode)
8631 || VSX_VECTOR_MODE (mode)
8632 || (type && TREE_CODE (type) == VECTOR_TYPE
8633 && int_size_in_bytes (type) == 16)))
8635 if (named || abi == ABI_V4)
8639 /* Vector parameters to varargs functions under AIX or Darwin
8640 get passed in memory and possibly also in GPRs. */
8641 int align, align_words, n_words;
8642 enum machine_mode part_mode;
8644 /* Vector parameters must be 16-byte aligned. This places them at
8645 2 mod 4 in terms of words in 32-bit mode, since the parameter
8646 save area starts at offset 24 from the stack. In 64-bit mode,
8647 they just have to start on an even word, since the parameter
8648 save area is 16-byte aligned. */
8650 align = (2 - cum->words) & 3;
8652 align = cum->words & 1;
8653 align_words = cum->words + align;
8655 /* Out of registers? Memory, then. */
8656 if (align_words >= GP_ARG_NUM_REG)
8659 if (TARGET_32BIT && TARGET_POWERPC64)
8660 return rs6000_mixed_function_arg (mode, type, align_words);
8662 /* The vector value goes in GPRs. Only the part of the
8663 value in GPRs is reported here. */
8665 n_words = rs6000_arg_size (mode, type);
8666 if (align_words + n_words > GP_ARG_NUM_REG)
8667 /* Fortunately, there are only two possibilities, the value
8668 is either wholly in GPRs or half in GPRs and half not. */
8671 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8674 else if (TARGET_SPE_ABI && TARGET_SPE
8675 && (SPE_VECTOR_MODE (mode)
8676 || (TARGET_E500_DOUBLE && (mode == DFmode
8679 || mode == TCmode))))
8680 return rs6000_spe_function_arg (cum, mode, type);
8682 else if (abi == ABI_V4)
8684 if (TARGET_HARD_FLOAT && TARGET_FPRS
8685 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8686 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8687 || (mode == TFmode && !TARGET_IEEEQUAD)
8688 || mode == SDmode || mode == DDmode || mode == TDmode))
8690 /* _Decimal128 must use an even/odd register pair. This assumes
8691 that the register number is odd when fregno is odd. */
8692 if (mode == TDmode && (cum->fregno % 2) == 1)
8695 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8696 <= FP_ARG_V4_MAX_REG)
8697 return gen_rtx_REG (mode, cum->fregno);
8703 int n_words = rs6000_arg_size (mode, type);
8704 int gregno = cum->sysv_gregno;
8706 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8707 (r7,r8) or (r9,r10). As does any other 2 word item such
8708 as complex int due to a historical mistake. */
8710 gregno += (1 - gregno) & 1;
8712 /* Multi-reg args are not split between registers and stack. */
8713 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8716 if (TARGET_32BIT && TARGET_POWERPC64)
8717 return rs6000_mixed_function_arg (mode, type,
8718 gregno - GP_ARG_MIN_REG);
8719 return gen_rtx_REG (mode, gregno);
8724 int align_words = rs6000_parm_start (mode, type, cum->words);
8726 /* _Decimal128 must be passed in an even/odd float register pair.
8727 This assumes that the register number is odd when fregno is odd. */
8728 if (mode == TDmode && (cum->fregno % 2) == 1)
8731 if (USE_FP_FOR_ARG_P (cum, mode, type))
8733 rtx rvec[GP_ARG_NUM_REG + 1];
8737 enum machine_mode fmode = mode;
8738 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8740 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8742 /* Currently, we only ever need one reg here because complex
8743 doubles are split. */
8744 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8745 && (fmode == TFmode || fmode == TDmode));
8747 /* Long double or _Decimal128 split over regs and memory. */
8748 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8751 /* Do we also need to pass this arg in the parameter save
8754 && (cum->nargs_prototype <= 0
8755 || (DEFAULT_ABI == ABI_AIX
8757 && align_words >= GP_ARG_NUM_REG)));
8759 if (!needs_psave && mode == fmode)
8760 return gen_rtx_REG (fmode, cum->fregno);
8765 /* Describe the part that goes in gprs or the stack.
8766 This piece must come first, before the fprs. */
8767 if (align_words < GP_ARG_NUM_REG)
8769 unsigned long n_words = rs6000_arg_size (mode, type);
8771 if (align_words + n_words > GP_ARG_NUM_REG
8772 || (TARGET_32BIT && TARGET_POWERPC64))
8774 /* If this is partially on the stack, then we only
8775 include the portion actually in registers here. */
8776 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8779 if (align_words + n_words > GP_ARG_NUM_REG)
8780 /* Not all of the arg fits in gprs. Say that it
8781 goes in memory too, using a magic NULL_RTX
8782 component. Also see comment in
8783 rs6000_mixed_function_arg for why the normal
8784 function_arg_partial_nregs scheme doesn't work
8786 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8790 r = gen_rtx_REG (rmode,
8791 GP_ARG_MIN_REG + align_words);
8792 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8793 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8795 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8799 /* The whole arg fits in gprs. */
8800 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8801 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8805 /* It's entirely in memory. */
8806 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8809 /* Describe where this piece goes in the fprs. */
8810 r = gen_rtx_REG (fmode, cum->fregno);
8811 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8813 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8815 else if (align_words < GP_ARG_NUM_REG)
8817 if (TARGET_32BIT && TARGET_POWERPC64)
8818 return rs6000_mixed_function_arg (mode, type, align_words);
8820 if (mode == BLKmode)
8823 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8830 /* For an arg passed partly in registers and partly in memory, this is
8831 the number of bytes passed in registers. For args passed entirely in
8832 registers or entirely in memory, zero. When an arg is described by a
8833 PARALLEL, perhaps using more than one register type, this function
8834 returns the number of bytes used by the first element of the PARALLEL. */
8837 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8838 tree type, bool named)
8843 if (DEFAULT_ABI == ABI_V4)
8846 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8847 && cum->nargs_prototype >= 0)
8850 /* In this complicated case we just disable the partial_nregs code. */
8851 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8854 align_words = rs6000_parm_start (mode, type, cum->words);
8856 if (USE_FP_FOR_ARG_P (cum, mode, type))
8858 /* If we are passing this arg in the fixed parameter save area
8859 (gprs or memory) as well as fprs, then this function should
8860 return the number of partial bytes passed in the parameter
8861 save area rather than partial bytes passed in fprs. */
8863 && (cum->nargs_prototype <= 0
8864 || (DEFAULT_ABI == ABI_AIX
8866 && align_words >= GP_ARG_NUM_REG)))
8868 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8869 > FP_ARG_MAX_REG + 1)
8870 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8871 else if (cum->nargs_prototype >= 0)
8875 if (align_words < GP_ARG_NUM_REG
8876 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8877 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8879 if (ret != 0 && TARGET_DEBUG_ARG)
8880 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8885 /* A C expression that indicates when an argument must be passed by
8886 reference. If nonzero for an argument, a copy of that argument is
8887 made in memory and a pointer to the argument is passed instead of
8888 the argument itself. The pointer is passed in whatever way is
8889 appropriate for passing a pointer to that type.
8891 Under V.4, aggregates and long double are passed by reference.
8893 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8894 reference unless the AltiVec vector extension ABI is in force.
8896 As an extension to all ABIs, variable sized types are passed by
8900 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8901 enum machine_mode mode, const_tree type,
8902 bool named ATTRIBUTE_UNUSED)
8904 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8906 if (TARGET_DEBUG_ARG)
8907 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8914 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8916 if (TARGET_DEBUG_ARG)
8917 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8921 if (int_size_in_bytes (type) < 0)
8923 if (TARGET_DEBUG_ARG)
8924 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8928 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8929 modes only exist for GCC vector types if -maltivec. */
8930 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8932 if (TARGET_DEBUG_ARG)
8933 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8937 /* Pass synthetic vectors in memory. */
8938 if (TREE_CODE (type) == VECTOR_TYPE
8939 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8941 static bool warned_for_pass_big_vectors = false;
8942 if (TARGET_DEBUG_ARG)
8943 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8944 if (!warned_for_pass_big_vectors)
8946 warning (0, "GCC vector passed by reference: "
8947 "non-standard ABI extension with no compatibility guarantee");
8948 warned_for_pass_big_vectors = true;
8957 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8960 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8965 for (i = 0; i < nregs; i++)
8967 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8968 if (reload_completed)
8970 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8973 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8974 i * GET_MODE_SIZE (reg_mode));
8977 tem = replace_equiv_address (tem, XEXP (tem, 0));
8981 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8985 /* Perform any needed actions needed for a function that is receiving a
8986 variable number of arguments.
8990 MODE and TYPE are the mode and type of the current parameter.
8992 PRETEND_SIZE is a variable that should be set to the amount of stack
8993 that must be pushed by the prolog to pretend that our caller pushed
8996 Normally, this macro will push all remaining incoming registers on the
8997 stack and set PRETEND_SIZE to the length of the registers pushed. */
9000 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9001 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9004 CUMULATIVE_ARGS next_cum;
9005 int reg_size = TARGET_32BIT ? 4 : 8;
9006 rtx save_area = NULL_RTX, mem;
9007 int first_reg_offset;
9010 /* Skip the last named argument. */
9012 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9014 if (DEFAULT_ABI == ABI_V4)
9016 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9020 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9021 HOST_WIDE_INT offset = 0;
9023 /* Try to optimize the size of the varargs save area.
9024 The ABI requires that ap.reg_save_area is doubleword
9025 aligned, but we don't need to allocate space for all
9026 the bytes, only those to which we actually will save
9028 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9029 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9030 if (TARGET_HARD_FLOAT && TARGET_FPRS
9031 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9032 && cfun->va_list_fpr_size)
9035 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9036 * UNITS_PER_FP_WORD;
9037 if (cfun->va_list_fpr_size
9038 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9039 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9041 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9042 * UNITS_PER_FP_WORD;
9046 offset = -((first_reg_offset * reg_size) & ~7);
9047 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9049 gpr_reg_num = cfun->va_list_gpr_size;
9050 if (reg_size == 4 && (first_reg_offset & 1))
9053 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9056 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9058 - (int) (GP_ARG_NUM_REG * reg_size);
9060 if (gpr_size + fpr_size)
9063 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9064 gcc_assert (GET_CODE (reg_save_area) == MEM);
9065 reg_save_area = XEXP (reg_save_area, 0);
9066 if (GET_CODE (reg_save_area) == PLUS)
9068 gcc_assert (XEXP (reg_save_area, 0)
9069 == virtual_stack_vars_rtx);
9070 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9071 offset += INTVAL (XEXP (reg_save_area, 1));
9074 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9077 cfun->machine->varargs_save_offset = offset;
9078 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9083 first_reg_offset = next_cum.words;
9084 save_area = virtual_incoming_args_rtx;
9086 if (targetm.calls.must_pass_in_stack (mode, type))
9087 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9090 set = get_varargs_alias_set ();
9091 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9092 && cfun->va_list_gpr_size)
9094 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9096 if (va_list_gpr_counter_field)
9098 /* V4 va_list_gpr_size counts number of registers needed. */
9099 if (nregs > cfun->va_list_gpr_size)
9100 nregs = cfun->va_list_gpr_size;
9104 /* char * va_list instead counts number of bytes needed. */
9105 if (nregs > cfun->va_list_gpr_size / reg_size)
9106 nregs = cfun->va_list_gpr_size / reg_size;
9109 mem = gen_rtx_MEM (BLKmode,
9110 plus_constant (save_area,
9111 first_reg_offset * reg_size));
9112 MEM_NOTRAP_P (mem) = 1;
9113 set_mem_alias_set (mem, set);
9114 set_mem_align (mem, BITS_PER_WORD);
9116 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9120 /* Save FP registers if needed. */
9121 if (DEFAULT_ABI == ABI_V4
9122 && TARGET_HARD_FLOAT && TARGET_FPRS
9124 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9125 && cfun->va_list_fpr_size)
9127 int fregno = next_cum.fregno, nregs;
9128 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9129 rtx lab = gen_label_rtx ();
9130 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9131 * UNITS_PER_FP_WORD);
9134 (gen_rtx_SET (VOIDmode,
9136 gen_rtx_IF_THEN_ELSE (VOIDmode,
9137 gen_rtx_NE (VOIDmode, cr1,
9139 gen_rtx_LABEL_REF (VOIDmode, lab),
9143 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9144 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9146 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9148 plus_constant (save_area, off));
9149 MEM_NOTRAP_P (mem) = 1;
9150 set_mem_alias_set (mem, set);
9151 set_mem_align (mem, GET_MODE_ALIGNMENT (
9152 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9153 ? DFmode : SFmode));
9154 emit_move_insn (mem, gen_rtx_REG (
9155 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9156 ? DFmode : SFmode, fregno));
9163 /* Create the va_list data type. */
9166 rs6000_build_builtin_va_list (void)
9168 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9170 /* For AIX, prefer 'char *' because that's what the system
9171 header files like. */
9172 if (DEFAULT_ABI != ABI_V4)
9173 return build_pointer_type (char_type_node);
9175 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9176 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9177 get_identifier ("__va_list_tag"), record);
9179 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9180 unsigned_char_type_node);
9181 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9182 unsigned_char_type_node);
9183 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9185 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9186 get_identifier ("reserved"), short_unsigned_type_node);
9187 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9188 get_identifier ("overflow_arg_area"),
9190 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9191 get_identifier ("reg_save_area"),
9194 va_list_gpr_counter_field = f_gpr;
9195 va_list_fpr_counter_field = f_fpr;
9197 DECL_FIELD_CONTEXT (f_gpr) = record;
9198 DECL_FIELD_CONTEXT (f_fpr) = record;
9199 DECL_FIELD_CONTEXT (f_res) = record;
9200 DECL_FIELD_CONTEXT (f_ovf) = record;
9201 DECL_FIELD_CONTEXT (f_sav) = record;
9203 TREE_CHAIN (record) = type_decl;
9204 TYPE_NAME (record) = type_decl;
9205 TYPE_FIELDS (record) = f_gpr;
9206 DECL_CHAIN (f_gpr) = f_fpr;
9207 DECL_CHAIN (f_fpr) = f_res;
9208 DECL_CHAIN (f_res) = f_ovf;
9209 DECL_CHAIN (f_ovf) = f_sav;
9211 layout_type (record);
9213 /* The correct type is an array type of one element. */
9214 return build_array_type (record, build_index_type (size_zero_node));
9217 /* Implement va_start. */
9220 rs6000_va_start (tree valist, rtx nextarg)
9222 HOST_WIDE_INT words, n_gpr, n_fpr;
9223 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9224 tree gpr, fpr, ovf, sav, t;
9226 /* Only SVR4 needs something special. */
9227 if (DEFAULT_ABI != ABI_V4)
9229 std_expand_builtin_va_start (valist, nextarg);
9233 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9234 f_fpr = DECL_CHAIN (f_gpr);
9235 f_res = DECL_CHAIN (f_fpr);
9236 f_ovf = DECL_CHAIN (f_res);
9237 f_sav = DECL_CHAIN (f_ovf);
9239 valist = build_va_arg_indirect_ref (valist);
9240 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9241 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9243 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9245 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9248 /* Count number of gp and fp argument registers used. */
9249 words = crtl->args.info.words;
9250 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9252 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9255 if (TARGET_DEBUG_ARG)
9256 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9257 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9258 words, n_gpr, n_fpr);
9260 if (cfun->va_list_gpr_size)
9262 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9263 build_int_cst (NULL_TREE, n_gpr));
9264 TREE_SIDE_EFFECTS (t) = 1;
9265 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9268 if (cfun->va_list_fpr_size)
9270 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9271 build_int_cst (NULL_TREE, n_fpr));
9272 TREE_SIDE_EFFECTS (t) = 1;
9273 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9276 /* Find the overflow area. */
9277 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9279 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9280 size_int (words * UNITS_PER_WORD));
9281 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9282 TREE_SIDE_EFFECTS (t) = 1;
9283 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9285 /* If there were no va_arg invocations, don't set up the register
9287 if (!cfun->va_list_gpr_size
9288 && !cfun->va_list_fpr_size
9289 && n_gpr < GP_ARG_NUM_REG
9290 && n_fpr < FP_ARG_V4_MAX_REG)
9293 /* Find the register save area. */
9294 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9295 if (cfun->machine->varargs_save_offset)
9296 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9297 size_int (cfun->machine->varargs_save_offset));
9298 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9299 TREE_SIDE_EFFECTS (t) = 1;
9300 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9303 /* Implement va_arg. */
9306 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9309 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9310 tree gpr, fpr, ovf, sav, reg, t, u;
9311 int size, rsize, n_reg, sav_ofs, sav_scale;
9312 tree lab_false, lab_over, addr;
9314 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9318 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9320 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9321 return build_va_arg_indirect_ref (t);
9324 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9325 earlier version of gcc, with the property that it always applied alignment
9326 adjustments to the va-args (even for zero-sized types). The cheapest way
9327 to deal with this is to replicate the effect of the part of
9328 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9330 We don't need to check for pass-by-reference because of the test above.
9331 We can return a simplifed answer, since we know there's no offset to add. */
9334 && rs6000_darwin64_abi
9335 && integer_zerop (TYPE_SIZE (type)))
9337 unsigned HOST_WIDE_INT align, boundary;
9338 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9339 align = PARM_BOUNDARY / BITS_PER_UNIT;
9340 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9341 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9342 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9343 boundary /= BITS_PER_UNIT;
9344 if (boundary > align)
9347 /* This updates arg ptr by the amount that would be necessary
9348 to align the zero-sized (but not zero-alignment) item. */
9349 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9350 fold_build2 (POINTER_PLUS_EXPR,
9352 valist_tmp, size_int (boundary - 1)));
9353 gimplify_and_add (t, pre_p);
9355 t = fold_convert (sizetype, valist_tmp);
9356 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9357 fold_convert (TREE_TYPE (valist),
9358 fold_build2 (BIT_AND_EXPR, sizetype, t,
9359 size_int (-boundary))));
9360 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9361 gimplify_and_add (t, pre_p);
9363 /* Since it is zero-sized there's no increment for the item itself. */
9364 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9365 return build_va_arg_indirect_ref (valist_tmp);
9368 if (DEFAULT_ABI != ABI_V4)
9370 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9372 tree elem_type = TREE_TYPE (type);
9373 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9374 int elem_size = GET_MODE_SIZE (elem_mode);
9376 if (elem_size < UNITS_PER_WORD)
9378 tree real_part, imag_part;
9379 gimple_seq post = NULL;
9381 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9383 /* Copy the value into a temporary, lest the formal temporary
9384 be reused out from under us. */
9385 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9386 gimple_seq_add_seq (pre_p, post);
9388 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9391 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9395 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9398 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9399 f_fpr = DECL_CHAIN (f_gpr);
9400 f_res = DECL_CHAIN (f_fpr);
9401 f_ovf = DECL_CHAIN (f_res);
9402 f_sav = DECL_CHAIN (f_ovf);
9404 valist = build_va_arg_indirect_ref (valist);
9405 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9406 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9408 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9410 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9413 size = int_size_in_bytes (type);
9414 rsize = (size + 3) / 4;
9417 if (TARGET_HARD_FLOAT && TARGET_FPRS
9418 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9419 || (TARGET_DOUBLE_FLOAT
9420 && (TYPE_MODE (type) == DFmode
9421 || TYPE_MODE (type) == TFmode
9422 || TYPE_MODE (type) == SDmode
9423 || TYPE_MODE (type) == DDmode
9424 || TYPE_MODE (type) == TDmode))))
9426 /* FP args go in FP registers, if present. */
9428 n_reg = (size + 7) / 8;
9429 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9430 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9431 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9436 /* Otherwise into GP registers. */
9445 /* Pull the value out of the saved registers.... */
9448 addr = create_tmp_var (ptr_type_node, "addr");
9450 /* AltiVec vectors never go in registers when -mabi=altivec. */
9451 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9455 lab_false = create_artificial_label (input_location);
9456 lab_over = create_artificial_label (input_location);
9458 /* Long long and SPE vectors are aligned in the registers.
9459 As are any other 2 gpr item such as complex int due to a
9460 historical mistake. */
9462 if (n_reg == 2 && reg == gpr)
9465 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9466 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9467 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9468 unshare_expr (reg), u);
9470 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9471 reg number is 0 for f1, so we want to make it odd. */
9472 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9474 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9475 build_int_cst (TREE_TYPE (reg), 1));
9476 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9479 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9480 t = build2 (GE_EXPR, boolean_type_node, u, t);
9481 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9482 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9483 gimplify_and_add (t, pre_p);
9487 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9489 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9490 build_int_cst (TREE_TYPE (reg), n_reg));
9491 u = fold_convert (sizetype, u);
9492 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9493 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9495 /* _Decimal32 varargs are located in the second word of the 64-bit
9496 FP register for 32-bit binaries. */
9497 if (!TARGET_POWERPC64
9498 && TARGET_HARD_FLOAT && TARGET_FPRS
9499 && TYPE_MODE (type) == SDmode)
9500 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9502 gimplify_assign (addr, t, pre_p);
9504 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9506 stmt = gimple_build_label (lab_false);
9507 gimple_seq_add_stmt (pre_p, stmt);
9509 if ((n_reg == 2 && !regalign) || n_reg > 2)
9511 /* Ensure that we don't find any more args in regs.
9512 Alignment has taken care of for special cases. */
9513 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9517 /* ... otherwise out of the overflow area. */
9519 /* Care for on-stack alignment if needed. */
9523 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9524 t = fold_convert (sizetype, t);
9525 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9527 t = fold_convert (TREE_TYPE (ovf), t);
9529 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9531 gimplify_assign (unshare_expr (addr), t, pre_p);
9533 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9534 gimplify_assign (unshare_expr (ovf), t, pre_p);
9538 stmt = gimple_build_label (lab_over);
9539 gimple_seq_add_stmt (pre_p, stmt);
9542 if (STRICT_ALIGNMENT
9543 && (TYPE_ALIGN (type)
9544 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9546 /* The value (of type complex double, for example) may not be
9547 aligned in memory in the saved registers, so copy via a
9548 temporary. (This is the same code as used for SPARC.) */
9549 tree tmp = create_tmp_var (type, "va_arg_tmp");
9550 tree dest_addr = build_fold_addr_expr (tmp);
9552 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9553 3, dest_addr, addr, size_int (rsize * 4));
9555 gimplify_and_add (copy, pre_p);
9559 addr = fold_convert (ptrtype, addr);
9560 return build_va_arg_indirect_ref (addr);
9566 def_builtin (int mask, const char *name, tree type, int code)
9568 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9571 if (rs6000_builtin_decls[code])
9572 fatal_error ("internal error: builtin function to %s already processed.",
9575 rs6000_builtin_decls[code] = t =
9576 add_builtin_function (name, type, code, BUILT_IN_MD,
9579 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9580 switch (builtin_classify[code])
9585 /* assume builtin can do anything. */
9586 case RS6000_BTC_MISC:
9589 /* const function, function only depends on the inputs. */
9590 case RS6000_BTC_CONST:
9591 TREE_READONLY (t) = 1;
9592 TREE_NOTHROW (t) = 1;
9595 /* pure function, function can read global memory. */
9596 case RS6000_BTC_PURE:
9597 DECL_PURE_P (t) = 1;
9598 TREE_NOTHROW (t) = 1;
9601 /* Function is a math function. If rounding mode is on, then treat
9602 the function as not reading global memory, but it can have
9603 arbitrary side effects. If it is off, then assume the function is
9604 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9605 attribute in builtin-attribute.def that is used for the math
9607 case RS6000_BTC_FP_PURE:
9608 TREE_NOTHROW (t) = 1;
9609 if (flag_rounding_math)
9611 DECL_PURE_P (t) = 1;
9612 DECL_IS_NOVOPS (t) = 1;
9615 TREE_READONLY (t) = 1;
9621 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9623 static const struct builtin_description bdesc_3arg[] =
9625 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9626 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9627 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9628 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9629 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9630 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9631 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9632 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9633 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9634 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9635 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9636 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9637 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9638 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9639 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9640 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9641 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9642 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9643 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9644 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9645 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9646 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9647 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9648 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9649 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9650 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9651 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9652 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9653 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9654 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9655 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9656 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9657 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9658 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9659 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9663 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9664 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9665 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9666 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9667 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9668 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9669 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9670 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9671 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9672 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9673 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9674 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9675 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9677 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9678 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9679 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9680 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9682 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9683 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9684 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9685 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9690 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9691 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9692 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9693 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9694 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9695 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9696 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9697 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9698 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9699 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9701 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9702 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9703 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9704 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9705 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9706 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9707 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9708 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9709 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9710 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9712 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9713 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9714 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9715 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9716 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9717 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9718 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9719 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9720 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9722 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9723 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9724 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9725 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9726 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9727 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9728 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9730 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9731 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9732 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9733 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9734 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9735 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9736 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9737 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9738 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9741 /* DST operations: void foo (void *, const int, const char). */
9743 static const struct builtin_description bdesc_dst[] =
9745 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9746 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9747 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9748 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9752 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9753 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9756 /* Simple binary operations: VECc = foo (VECa, VECb). */
9758 static struct builtin_description bdesc_2arg[] =
9760 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9761 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9762 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9763 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9764 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9765 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9766 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9767 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9768 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9769 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9770 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9771 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9772 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9773 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9774 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9775 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9776 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9777 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9778 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9779 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9782 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9783 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9784 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9785 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9786 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9787 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9788 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9789 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9790 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9791 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9792 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9793 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9794 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9795 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9796 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9797 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9798 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9799 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9800 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9801 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9802 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9803 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9804 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9805 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9806 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9807 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9808 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9809 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9810 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9811 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9812 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9813 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9814 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9815 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9816 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9817 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9818 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9819 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9820 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9821 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9822 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9823 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9824 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9825 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9826 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9827 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9828 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9829 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9830 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9831 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9832 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9833 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9834 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9835 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9836 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9837 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9838 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9839 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9840 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9841 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9842 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9843 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9844 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9845 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9846 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9847 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9848 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9849 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9850 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9851 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9852 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9853 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9854 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9855 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9856 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9857 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9858 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9859 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9860 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9861 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9862 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9863 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9864 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9865 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9866 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9867 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9868 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9869 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9870 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9871 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9872 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9873 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9874 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9875 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9876 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9878 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9879 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9880 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9881 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9882 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9883 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9884 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9885 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9886 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9887 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9888 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9889 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9891 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9892 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9893 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9894 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9895 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9896 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9897 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9898 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9899 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9900 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9901 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9902 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9904 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9905 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9906 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9907 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9908 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9909 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9911 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9912 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9913 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9914 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9915 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9916 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9917 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9918 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9919 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9920 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9921 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9922 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9924 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9925 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9937 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9938 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9941 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9953 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9954 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9964 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9965 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9980 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9981 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9998 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9999 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10033 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10034 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10052 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10054 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10055 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10057 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10058 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10059 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10060 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10061 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10062 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10063 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10064 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10065 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10066 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10068 /* Place holder, leave as first spe builtin. */
10069 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10070 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10071 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10072 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10073 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10074 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10075 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10076 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10077 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10078 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10079 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10080 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10081 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10082 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10083 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10084 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10085 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10086 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10087 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10088 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10089 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10090 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10091 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10092 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10093 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10094 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10095 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10096 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10097 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10098 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10099 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10100 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10101 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10102 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10103 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10104 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10105 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10106 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10107 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10108 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10109 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10110 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10111 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10112 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10113 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10114 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10115 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10116 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10117 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10118 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10119 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10120 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10121 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10122 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10123 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10124 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10125 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10126 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10127 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10128 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10129 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10130 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10131 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10132 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10133 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10134 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10135 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10136 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10137 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10138 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10139 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10140 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10141 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10142 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10143 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10144 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10145 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10146 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10147 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10148 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10149 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10150 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10151 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10152 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10153 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10154 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10155 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10156 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10157 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10158 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10159 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10160 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10161 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10162 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10163 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10164 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10165 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10166 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10167 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10168 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10169 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10170 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10171 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10172 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10173 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10174 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10175 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10176 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10177 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10179 /* SPE binary operations expecting a 5-bit unsigned literal. */
10180 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10182 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10183 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10184 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10185 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10186 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10187 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10188 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10189 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10190 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10191 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10192 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10193 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10194 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10195 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10196 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10197 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10198 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10199 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10200 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10201 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10202 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10203 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10204 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10205 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10206 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10207 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10209 /* Place-holder. Leave as last binary SPE builtin. */
10210 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10213 /* AltiVec predicates. */
10215 struct builtin_description_predicates
10217 const unsigned int mask;
10218 const enum insn_code icode;
10219 const char *const name;
10220 const enum rs6000_builtins code;
10223 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10225 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10226 ALTIVEC_BUILTIN_VCMPBFP_P },
10227 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10228 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10229 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10230 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10231 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10232 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10233 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10234 ALTIVEC_BUILTIN_VCMPEQUW_P },
10235 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10236 ALTIVEC_BUILTIN_VCMPGTSW_P },
10237 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10238 ALTIVEC_BUILTIN_VCMPGTUW_P },
10239 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10240 ALTIVEC_BUILTIN_VCMPEQUH_P },
10241 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10242 ALTIVEC_BUILTIN_VCMPGTSH_P },
10243 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10244 ALTIVEC_BUILTIN_VCMPGTUH_P },
10245 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10246 ALTIVEC_BUILTIN_VCMPEQUB_P },
10247 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10248 ALTIVEC_BUILTIN_VCMPGTSB_P },
10249 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10250 ALTIVEC_BUILTIN_VCMPGTUB_P },
10252 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10253 VSX_BUILTIN_XVCMPEQSP_P },
10254 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10255 VSX_BUILTIN_XVCMPGESP_P },
10256 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10257 VSX_BUILTIN_XVCMPGTSP_P },
10258 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10259 VSX_BUILTIN_XVCMPEQDP_P },
10260 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10261 VSX_BUILTIN_XVCMPGEDP_P },
10262 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10263 VSX_BUILTIN_XVCMPGTDP_P },
10265 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10266 ALTIVEC_BUILTIN_VCMPEQ_P },
10267 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10268 ALTIVEC_BUILTIN_VCMPGT_P },
10269 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10270 ALTIVEC_BUILTIN_VCMPGE_P }
10273 /* SPE predicates. */
10274 static struct builtin_description bdesc_spe_predicates[] =
10276 /* Place-holder. Leave as first. */
10277 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10278 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10279 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10280 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10281 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10282 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10283 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10284 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10285 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10286 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10287 /* Place-holder. Leave as last. */
10288 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10291 /* SPE evsel predicates. */
10292 static struct builtin_description bdesc_spe_evsel[] =
10294 /* Place-holder. Leave as first. */
10295 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10296 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10297 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10298 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10299 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10300 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10301 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10302 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10303 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10304 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10305 /* Place-holder. Leave as last. */
10306 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10309 /* PAIRED predicates. */
10310 static const struct builtin_description bdesc_paired_preds[] =
10312 /* Place-holder. Leave as first. */
10313 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10314 /* Place-holder. Leave as last. */
10315 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10318 /* ABS* operations. */
10320 static const struct builtin_description bdesc_abs[] =
10322 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10323 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10324 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10325 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10326 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10327 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10328 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10329 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10330 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10331 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10332 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10335 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10338 static struct builtin_description bdesc_1arg[] =
10340 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10341 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10342 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10343 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10344 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10345 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10346 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10347 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10348 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10349 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10350 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10351 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10352 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10353 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10354 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10355 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10356 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10357 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10359 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10360 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10361 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10362 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10363 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10364 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10365 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10367 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10368 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10369 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10370 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10371 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10372 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10373 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10375 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10376 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10377 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10378 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10379 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10380 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10382 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10383 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10384 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10385 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10386 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10387 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10389 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10390 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10391 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10392 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10394 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10395 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10396 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10397 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10398 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10399 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10400 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10401 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10402 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10404 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10405 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10406 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10407 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10408 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10409 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10410 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10411 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10412 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10414 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10415 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10416 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10417 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10418 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10441 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10442 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10443 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10445 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10446 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10447 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10448 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10450 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10451 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10452 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10453 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10454 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10455 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10456 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10457 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10458 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10459 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10460 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10461 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10462 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10463 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10464 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10465 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10466 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10467 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10468 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10469 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10470 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10471 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10472 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10473 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10474 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10475 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10476 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10477 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10478 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10479 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10481 /* Place-holder. Leave as last unary SPE builtin. */
10482 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10484 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10485 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10486 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10487 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10488 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10492 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10495 tree arg0 = CALL_EXPR_ARG (exp, 0);
10496 rtx op0 = expand_normal (arg0);
10497 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10498 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10500 if (icode == CODE_FOR_nothing)
10501 /* Builtin not supported on this processor. */
10504 /* If we got invalid arguments bail out before generating bad rtl. */
10505 if (arg0 == error_mark_node)
10508 if (icode == CODE_FOR_altivec_vspltisb
10509 || icode == CODE_FOR_altivec_vspltish
10510 || icode == CODE_FOR_altivec_vspltisw
10511 || icode == CODE_FOR_spe_evsplatfi
10512 || icode == CODE_FOR_spe_evsplati)
10514 /* Only allow 5-bit *signed* literals. */
10515 if (GET_CODE (op0) != CONST_INT
10516 || INTVAL (op0) > 15
10517 || INTVAL (op0) < -16)
10519 error ("argument 1 must be a 5-bit signed literal");
10525 || GET_MODE (target) != tmode
10526 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10527 target = gen_reg_rtx (tmode);
10529 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10530 op0 = copy_to_mode_reg (mode0, op0);
10532 pat = GEN_FCN (icode) (target, op0);
10541 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10543 rtx pat, scratch1, scratch2;
10544 tree arg0 = CALL_EXPR_ARG (exp, 0);
10545 rtx op0 = expand_normal (arg0);
10546 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10547 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10549 /* If we have invalid arguments, bail out before generating bad rtl. */
10550 if (arg0 == error_mark_node)
10554 || GET_MODE (target) != tmode
10555 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10556 target = gen_reg_rtx (tmode);
10558 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10559 op0 = copy_to_mode_reg (mode0, op0);
10561 scratch1 = gen_reg_rtx (mode0);
10562 scratch2 = gen_reg_rtx (mode0);
10564 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10573 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10576 tree arg0 = CALL_EXPR_ARG (exp, 0);
10577 tree arg1 = CALL_EXPR_ARG (exp, 1);
10578 rtx op0 = expand_normal (arg0);
10579 rtx op1 = expand_normal (arg1);
10580 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10581 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10582 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10584 if (icode == CODE_FOR_nothing)
10585 /* Builtin not supported on this processor. */
10588 /* If we got invalid arguments bail out before generating bad rtl. */
10589 if (arg0 == error_mark_node || arg1 == error_mark_node)
10592 if (icode == CODE_FOR_altivec_vcfux
10593 || icode == CODE_FOR_altivec_vcfsx
10594 || icode == CODE_FOR_altivec_vctsxs
10595 || icode == CODE_FOR_altivec_vctuxs
10596 || icode == CODE_FOR_altivec_vspltb
10597 || icode == CODE_FOR_altivec_vsplth
10598 || icode == CODE_FOR_altivec_vspltw
10599 || icode == CODE_FOR_spe_evaddiw
10600 || icode == CODE_FOR_spe_evldd
10601 || icode == CODE_FOR_spe_evldh
10602 || icode == CODE_FOR_spe_evldw
10603 || icode == CODE_FOR_spe_evlhhesplat
10604 || icode == CODE_FOR_spe_evlhhossplat
10605 || icode == CODE_FOR_spe_evlhhousplat
10606 || icode == CODE_FOR_spe_evlwhe
10607 || icode == CODE_FOR_spe_evlwhos
10608 || icode == CODE_FOR_spe_evlwhou
10609 || icode == CODE_FOR_spe_evlwhsplat
10610 || icode == CODE_FOR_spe_evlwwsplat
10611 || icode == CODE_FOR_spe_evrlwi
10612 || icode == CODE_FOR_spe_evslwi
10613 || icode == CODE_FOR_spe_evsrwis
10614 || icode == CODE_FOR_spe_evsubifw
10615 || icode == CODE_FOR_spe_evsrwiu)
10617 /* Only allow 5-bit unsigned literals. */
10619 if (TREE_CODE (arg1) != INTEGER_CST
10620 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10622 error ("argument 2 must be a 5-bit unsigned literal");
10628 || GET_MODE (target) != tmode
10629 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10630 target = gen_reg_rtx (tmode);
10632 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10633 op0 = copy_to_mode_reg (mode0, op0);
10634 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10635 op1 = copy_to_mode_reg (mode1, op1);
10637 pat = GEN_FCN (icode) (target, op0, op1);
10646 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10649 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10650 tree arg0 = CALL_EXPR_ARG (exp, 1);
10651 tree arg1 = CALL_EXPR_ARG (exp, 2);
10652 rtx op0 = expand_normal (arg0);
10653 rtx op1 = expand_normal (arg1);
10654 enum machine_mode tmode = SImode;
10655 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10656 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10659 if (TREE_CODE (cr6_form) != INTEGER_CST)
10661 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10665 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10667 gcc_assert (mode0 == mode1);
10669 /* If we have invalid arguments, bail out before generating bad rtl. */
10670 if (arg0 == error_mark_node || arg1 == error_mark_node)
10674 || GET_MODE (target) != tmode
10675 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10676 target = gen_reg_rtx (tmode);
10678 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10679 op0 = copy_to_mode_reg (mode0, op0);
10680 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10681 op1 = copy_to_mode_reg (mode1, op1);
10683 scratch = gen_reg_rtx (mode0);
10685 pat = GEN_FCN (icode) (scratch, op0, op1);
10690 /* The vec_any* and vec_all* predicates use the same opcodes for two
10691 different operations, but the bits in CR6 will be different
10692 depending on what information we want. So we have to play tricks
10693 with CR6 to get the right bits out.
10695 If you think this is disgusting, look at the specs for the
10696 AltiVec predicates. */
10698 switch (cr6_form_int)
10701 emit_insn (gen_cr6_test_for_zero (target));
10704 emit_insn (gen_cr6_test_for_zero_reverse (target));
10707 emit_insn (gen_cr6_test_for_lt (target));
10710 emit_insn (gen_cr6_test_for_lt_reverse (target));
10713 error ("argument 1 of __builtin_altivec_predicate is out of range");
10721 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10724 tree arg0 = CALL_EXPR_ARG (exp, 0);
10725 tree arg1 = CALL_EXPR_ARG (exp, 1);
10726 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10727 enum machine_mode mode0 = Pmode;
10728 enum machine_mode mode1 = Pmode;
10729 rtx op0 = expand_normal (arg0);
10730 rtx op1 = expand_normal (arg1);
10732 if (icode == CODE_FOR_nothing)
10733 /* Builtin not supported on this processor. */
10736 /* If we got invalid arguments bail out before generating bad rtl. */
10737 if (arg0 == error_mark_node || arg1 == error_mark_node)
10741 || GET_MODE (target) != tmode
10742 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10743 target = gen_reg_rtx (tmode);
10745 op1 = copy_to_mode_reg (mode1, op1);
10747 if (op0 == const0_rtx)
10749 addr = gen_rtx_MEM (tmode, op1);
10753 op0 = copy_to_mode_reg (mode0, op0);
10754 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10757 pat = GEN_FCN (icode) (target, addr);
10767 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10770 tree arg0 = CALL_EXPR_ARG (exp, 0);
10771 tree arg1 = CALL_EXPR_ARG (exp, 1);
10772 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10773 enum machine_mode mode0 = Pmode;
10774 enum machine_mode mode1 = Pmode;
10775 rtx op0 = expand_normal (arg0);
10776 rtx op1 = expand_normal (arg1);
10778 if (icode == CODE_FOR_nothing)
10779 /* Builtin not supported on this processor. */
10782 /* If we got invalid arguments bail out before generating bad rtl. */
10783 if (arg0 == error_mark_node || arg1 == error_mark_node)
10787 || GET_MODE (target) != tmode
10788 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10789 target = gen_reg_rtx (tmode);
10791 op1 = copy_to_mode_reg (mode1, op1);
10793 if (op0 == const0_rtx)
10795 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10799 op0 = copy_to_mode_reg (mode0, op0);
10800 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10803 pat = GEN_FCN (icode) (target, addr);
10813 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10815 tree arg0 = CALL_EXPR_ARG (exp, 0);
10816 tree arg1 = CALL_EXPR_ARG (exp, 1);
10817 tree arg2 = CALL_EXPR_ARG (exp, 2);
10818 rtx op0 = expand_normal (arg0);
10819 rtx op1 = expand_normal (arg1);
10820 rtx op2 = expand_normal (arg2);
10822 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10823 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10824 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10826 /* Invalid arguments. Bail before doing anything stoopid! */
10827 if (arg0 == error_mark_node
10828 || arg1 == error_mark_node
10829 || arg2 == error_mark_node)
10832 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10833 op0 = copy_to_mode_reg (mode2, op0);
10834 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10835 op1 = copy_to_mode_reg (mode0, op1);
10836 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10837 op2 = copy_to_mode_reg (mode1, op2);
10839 pat = GEN_FCN (icode) (op1, op2, op0);
10846 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10848 tree arg0 = CALL_EXPR_ARG (exp, 0);
10849 tree arg1 = CALL_EXPR_ARG (exp, 1);
10850 tree arg2 = CALL_EXPR_ARG (exp, 2);
10851 rtx op0 = expand_normal (arg0);
10852 rtx op1 = expand_normal (arg1);
10853 rtx op2 = expand_normal (arg2);
10855 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10856 enum machine_mode mode1 = Pmode;
10857 enum machine_mode mode2 = Pmode;
10859 /* Invalid arguments. Bail before doing anything stoopid! */
10860 if (arg0 == error_mark_node
10861 || arg1 == error_mark_node
10862 || arg2 == error_mark_node)
10865 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10866 op0 = copy_to_mode_reg (tmode, op0);
10868 op2 = copy_to_mode_reg (mode2, op2);
10870 if (op1 == const0_rtx)
10872 addr = gen_rtx_MEM (tmode, op2);
10876 op1 = copy_to_mode_reg (mode1, op1);
10877 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10880 pat = GEN_FCN (icode) (addr, op0);
10887 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10889 tree arg0 = CALL_EXPR_ARG (exp, 0);
10890 tree arg1 = CALL_EXPR_ARG (exp, 1);
10891 tree arg2 = CALL_EXPR_ARG (exp, 2);
10892 rtx op0 = expand_normal (arg0);
10893 rtx op1 = expand_normal (arg1);
10894 rtx op2 = expand_normal (arg2);
10896 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10897 enum machine_mode mode1 = Pmode;
10898 enum machine_mode mode2 = Pmode;
10900 /* Invalid arguments. Bail before doing anything stoopid! */
10901 if (arg0 == error_mark_node
10902 || arg1 == error_mark_node
10903 || arg2 == error_mark_node)
10906 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10907 op0 = copy_to_mode_reg (tmode, op0);
10909 op2 = copy_to_mode_reg (mode2, op2);
10911 if (op1 == const0_rtx)
10913 addr = gen_rtx_MEM (tmode, op2);
10917 op1 = copy_to_mode_reg (mode1, op1);
10918 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10921 pat = GEN_FCN (icode) (addr, op0);
10928 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10931 tree arg0 = CALL_EXPR_ARG (exp, 0);
10932 tree arg1 = CALL_EXPR_ARG (exp, 1);
10933 tree arg2 = CALL_EXPR_ARG (exp, 2);
10934 rtx op0 = expand_normal (arg0);
10935 rtx op1 = expand_normal (arg1);
10936 rtx op2 = expand_normal (arg2);
10937 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10938 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10939 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10940 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10942 if (icode == CODE_FOR_nothing)
10943 /* Builtin not supported on this processor. */
10946 /* If we got invalid arguments bail out before generating bad rtl. */
10947 if (arg0 == error_mark_node
10948 || arg1 == error_mark_node
10949 || arg2 == error_mark_node)
10952 /* Check and prepare argument depending on the instruction code.
10954 Note that a switch statement instead of the sequence of tests
10955 would be incorrect as many of the CODE_FOR values could be
10956 CODE_FOR_nothing and that would yield multiple alternatives
10957 with identical values. We'd never reach here at runtime in
10959 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10960 || icode == CODE_FOR_altivec_vsldoi_v4si
10961 || icode == CODE_FOR_altivec_vsldoi_v8hi
10962 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10964 /* Only allow 4-bit unsigned literals. */
10966 if (TREE_CODE (arg2) != INTEGER_CST
10967 || TREE_INT_CST_LOW (arg2) & ~0xf)
10969 error ("argument 3 must be a 4-bit unsigned literal");
10973 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10974 || icode == CODE_FOR_vsx_xxpermdi_v2di
10975 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10976 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10977 || icode == CODE_FOR_vsx_xxsldwi_v4si
10978 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10979 || icode == CODE_FOR_vsx_xxsldwi_v2di
10980 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10982 /* Only allow 2-bit unsigned literals. */
10984 if (TREE_CODE (arg2) != INTEGER_CST
10985 || TREE_INT_CST_LOW (arg2) & ~0x3)
10987 error ("argument 3 must be a 2-bit unsigned literal");
10991 else if (icode == CODE_FOR_vsx_set_v2df
10992 || icode == CODE_FOR_vsx_set_v2di)
10994 /* Only allow 1-bit unsigned literals. */
10996 if (TREE_CODE (arg2) != INTEGER_CST
10997 || TREE_INT_CST_LOW (arg2) & ~0x1)
10999 error ("argument 3 must be a 1-bit unsigned literal");
11005 || GET_MODE (target) != tmode
11006 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11007 target = gen_reg_rtx (tmode);
11009 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11010 op0 = copy_to_mode_reg (mode0, op0);
11011 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11012 op1 = copy_to_mode_reg (mode1, op1);
11013 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11014 op2 = copy_to_mode_reg (mode2, op2);
11016 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11017 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11019 pat = GEN_FCN (icode) (target, op0, op1, op2);
11027 /* Expand the lvx builtins. */
11029 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11031 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11032 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11034 enum machine_mode tmode, mode0;
11036 enum insn_code icode;
11040 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11041 icode = CODE_FOR_vector_load_v16qi;
11043 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11044 icode = CODE_FOR_vector_load_v8hi;
11046 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11047 icode = CODE_FOR_vector_load_v4si;
11049 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11050 icode = CODE_FOR_vector_load_v4sf;
11053 *expandedp = false;
11059 arg0 = CALL_EXPR_ARG (exp, 0);
11060 op0 = expand_normal (arg0);
11061 tmode = insn_data[icode].operand[0].mode;
11062 mode0 = insn_data[icode].operand[1].mode;
11065 || GET_MODE (target) != tmode
11066 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11067 target = gen_reg_rtx (tmode);
11069 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11070 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11072 pat = GEN_FCN (icode) (target, op0);
11079 /* Expand the stvx builtins. */
11081 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11084 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11085 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11087 enum machine_mode mode0, mode1;
11089 enum insn_code icode;
11093 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11094 icode = CODE_FOR_vector_store_v16qi;
11096 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11097 icode = CODE_FOR_vector_store_v8hi;
11099 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11100 icode = CODE_FOR_vector_store_v4si;
11102 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11103 icode = CODE_FOR_vector_store_v4sf;
11106 *expandedp = false;
11110 arg0 = CALL_EXPR_ARG (exp, 0);
11111 arg1 = CALL_EXPR_ARG (exp, 1);
11112 op0 = expand_normal (arg0);
11113 op1 = expand_normal (arg1);
11114 mode0 = insn_data[icode].operand[0].mode;
11115 mode1 = insn_data[icode].operand[1].mode;
11117 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11118 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11119 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11120 op1 = copy_to_mode_reg (mode1, op1);
11122 pat = GEN_FCN (icode) (op0, op1);
11130 /* Expand the dst builtins. */
11132 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11135 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11136 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11137 tree arg0, arg1, arg2;
11138 enum machine_mode mode0, mode1;
11139 rtx pat, op0, op1, op2;
11140 const struct builtin_description *d;
11143 *expandedp = false;
11145 /* Handle DST variants. */
11147 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11148 if (d->code == fcode)
11150 arg0 = CALL_EXPR_ARG (exp, 0);
11151 arg1 = CALL_EXPR_ARG (exp, 1);
11152 arg2 = CALL_EXPR_ARG (exp, 2);
11153 op0 = expand_normal (arg0);
11154 op1 = expand_normal (arg1);
11155 op2 = expand_normal (arg2);
11156 mode0 = insn_data[d->icode].operand[0].mode;
11157 mode1 = insn_data[d->icode].operand[1].mode;
11159 /* Invalid arguments, bail out before generating bad rtl. */
11160 if (arg0 == error_mark_node
11161 || arg1 == error_mark_node
11162 || arg2 == error_mark_node)
11167 if (TREE_CODE (arg2) != INTEGER_CST
11168 || TREE_INT_CST_LOW (arg2) & ~0x3)
11170 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11174 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11175 op0 = copy_to_mode_reg (Pmode, op0);
11176 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11177 op1 = copy_to_mode_reg (mode1, op1);
11179 pat = GEN_FCN (d->icode) (op0, op1, op2);
11189 /* Expand vec_init builtin. */
11191 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11193 enum machine_mode tmode = TYPE_MODE (type);
11194 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11195 int i, n_elt = GET_MODE_NUNITS (tmode);
11196 rtvec v = rtvec_alloc (n_elt);
11198 gcc_assert (VECTOR_MODE_P (tmode));
11199 gcc_assert (n_elt == call_expr_nargs (exp));
11201 for (i = 0; i < n_elt; ++i)
11203 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11204 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11207 if (!target || !register_operand (target, tmode))
11208 target = gen_reg_rtx (tmode);
11210 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11214 /* Return the integer constant in ARG. Constrain it to be in the range
11215 of the subparts of VEC_TYPE; issue an error if not. */
11218 get_element_number (tree vec_type, tree arg)
11220 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11222 if (!host_integerp (arg, 1)
11223 || (elt = tree_low_cst (arg, 1), elt > max))
11225 error ("selector must be an integer constant in the range 0..%wi", max);
11232 /* Expand vec_set builtin. */
11234 altivec_expand_vec_set_builtin (tree exp)
11236 enum machine_mode tmode, mode1;
11237 tree arg0, arg1, arg2;
11241 arg0 = CALL_EXPR_ARG (exp, 0);
11242 arg1 = CALL_EXPR_ARG (exp, 1);
11243 arg2 = CALL_EXPR_ARG (exp, 2);
11245 tmode = TYPE_MODE (TREE_TYPE (arg0));
11246 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11247 gcc_assert (VECTOR_MODE_P (tmode));
11249 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11250 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11251 elt = get_element_number (TREE_TYPE (arg0), arg2);
11253 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11254 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11256 op0 = force_reg (tmode, op0);
11257 op1 = force_reg (mode1, op1);
11259 rs6000_expand_vector_set (op0, op1, elt);
11264 /* Expand vec_ext builtin. */
11266 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11268 enum machine_mode tmode, mode0;
11273 arg0 = CALL_EXPR_ARG (exp, 0);
11274 arg1 = CALL_EXPR_ARG (exp, 1);
11276 op0 = expand_normal (arg0);
11277 elt = get_element_number (TREE_TYPE (arg0), arg1);
11279 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11280 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11281 gcc_assert (VECTOR_MODE_P (mode0));
11283 op0 = force_reg (mode0, op0);
11285 if (optimize || !target || !register_operand (target, tmode))
11286 target = gen_reg_rtx (tmode);
11288 rs6000_expand_vector_extract (target, op0, elt);
11293 /* Expand the builtin in EXP and store the result in TARGET. Store
11294 true in *EXPANDEDP if we found a builtin to expand. */
11296 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11298 const struct builtin_description *d;
11299 const struct builtin_description_predicates *dp;
11301 enum insn_code icode;
11302 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11305 enum machine_mode tmode, mode0;
11306 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11308 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11309 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11310 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11311 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11314 error ("unresolved overload for Altivec builtin %qF", fndecl);
11318 target = altivec_expand_ld_builtin (exp, target, expandedp);
11322 target = altivec_expand_st_builtin (exp, target, expandedp);
11326 target = altivec_expand_dst_builtin (exp, target, expandedp);
11334 case ALTIVEC_BUILTIN_STVX:
11335 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11336 case ALTIVEC_BUILTIN_STVEBX:
11337 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11338 case ALTIVEC_BUILTIN_STVEHX:
11339 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11340 case ALTIVEC_BUILTIN_STVEWX:
11341 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11342 case ALTIVEC_BUILTIN_STVXL:
11343 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11345 case ALTIVEC_BUILTIN_STVLX:
11346 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11347 case ALTIVEC_BUILTIN_STVLXL:
11348 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11349 case ALTIVEC_BUILTIN_STVRX:
11350 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11351 case ALTIVEC_BUILTIN_STVRXL:
11352 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11354 case ALTIVEC_BUILTIN_MFVSCR:
11355 icode = CODE_FOR_altivec_mfvscr;
11356 tmode = insn_data[icode].operand[0].mode;
11359 || GET_MODE (target) != tmode
11360 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11361 target = gen_reg_rtx (tmode);
11363 pat = GEN_FCN (icode) (target);
11369 case ALTIVEC_BUILTIN_MTVSCR:
11370 icode = CODE_FOR_altivec_mtvscr;
11371 arg0 = CALL_EXPR_ARG (exp, 0);
11372 op0 = expand_normal (arg0);
11373 mode0 = insn_data[icode].operand[0].mode;
11375 /* If we got invalid arguments bail out before generating bad rtl. */
11376 if (arg0 == error_mark_node)
11379 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11380 op0 = copy_to_mode_reg (mode0, op0);
11382 pat = GEN_FCN (icode) (op0);
11387 case ALTIVEC_BUILTIN_DSSALL:
11388 emit_insn (gen_altivec_dssall ());
11391 case ALTIVEC_BUILTIN_DSS:
11392 icode = CODE_FOR_altivec_dss;
11393 arg0 = CALL_EXPR_ARG (exp, 0);
11395 op0 = expand_normal (arg0);
11396 mode0 = insn_data[icode].operand[0].mode;
11398 /* If we got invalid arguments bail out before generating bad rtl. */
11399 if (arg0 == error_mark_node)
11402 if (TREE_CODE (arg0) != INTEGER_CST
11403 || TREE_INT_CST_LOW (arg0) & ~0x3)
11405 error ("argument to dss must be a 2-bit unsigned literal");
11409 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11410 op0 = copy_to_mode_reg (mode0, op0);
11412 emit_insn (gen_altivec_dss (op0));
11415 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11416 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11417 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11418 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11419 case VSX_BUILTIN_VEC_INIT_V2DF:
11420 case VSX_BUILTIN_VEC_INIT_V2DI:
11421 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11423 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11424 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11425 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11426 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11427 case VSX_BUILTIN_VEC_SET_V2DF:
11428 case VSX_BUILTIN_VEC_SET_V2DI:
11429 return altivec_expand_vec_set_builtin (exp);
11431 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11432 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11433 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11434 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11435 case VSX_BUILTIN_VEC_EXT_V2DF:
11436 case VSX_BUILTIN_VEC_EXT_V2DI:
11437 return altivec_expand_vec_ext_builtin (exp, target);
11441 /* Fall through. */
11444 /* Expand abs* operations. */
11446 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11447 if (d->code == fcode)
11448 return altivec_expand_abs_builtin (d->icode, exp, target);
11450 /* Expand the AltiVec predicates. */
11451 dp = bdesc_altivec_preds;
11452 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11453 if (dp->code == fcode)
11454 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11456 /* LV* are funky. We initialized them differently. */
11459 case ALTIVEC_BUILTIN_LVSL:
11460 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11461 exp, target, false);
11462 case ALTIVEC_BUILTIN_LVSR:
11463 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11464 exp, target, false);
11465 case ALTIVEC_BUILTIN_LVEBX:
11466 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11467 exp, target, false);
11468 case ALTIVEC_BUILTIN_LVEHX:
11469 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11470 exp, target, false);
11471 case ALTIVEC_BUILTIN_LVEWX:
11472 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11473 exp, target, false);
11474 case ALTIVEC_BUILTIN_LVXL:
11475 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11476 exp, target, false);
11477 case ALTIVEC_BUILTIN_LVX:
11478 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11479 exp, target, false);
11480 case ALTIVEC_BUILTIN_LVLX:
11481 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11482 exp, target, true);
11483 case ALTIVEC_BUILTIN_LVLXL:
11484 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11485 exp, target, true);
11486 case ALTIVEC_BUILTIN_LVRX:
11487 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11488 exp, target, true);
11489 case ALTIVEC_BUILTIN_LVRXL:
11490 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11491 exp, target, true);
11494 /* Fall through. */
11497 *expandedp = false;
11501 /* Expand the builtin in EXP and store the result in TARGET. Store
11502 true in *EXPANDEDP if we found a builtin to expand. */
11504 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11506 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11507 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11508 const struct builtin_description *d;
11515 case PAIRED_BUILTIN_STX:
11516 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11517 case PAIRED_BUILTIN_LX:
11518 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11521 /* Fall through. */
11524 /* Expand the paired predicates. */
11525 d = bdesc_paired_preds;
11526 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11527 if (d->code == fcode)
11528 return paired_expand_predicate_builtin (d->icode, exp, target);
11530 *expandedp = false;
11534 /* Binops that need to be initialized manually, but can be expanded
11535 automagically by rs6000_expand_binop_builtin. */
11536 static struct builtin_description bdesc_2arg_spe[] =
11538 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11539 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11540 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11541 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11542 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11543 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11544 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11545 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11546 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11547 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11548 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11549 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11550 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11551 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11552 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11553 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11554 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11555 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11556 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11557 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11558 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11559 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11562 /* Expand the builtin in EXP and store the result in TARGET. Store
11563 true in *EXPANDEDP if we found a builtin to expand.
11565 This expands the SPE builtins that are not simple unary and binary
11568 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11570 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11572 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11573 enum insn_code icode;
11574 enum machine_mode tmode, mode0;
11576 struct builtin_description *d;
11581 /* Syntax check for a 5-bit unsigned immediate. */
11584 case SPE_BUILTIN_EVSTDD:
11585 case SPE_BUILTIN_EVSTDH:
11586 case SPE_BUILTIN_EVSTDW:
11587 case SPE_BUILTIN_EVSTWHE:
11588 case SPE_BUILTIN_EVSTWHO:
11589 case SPE_BUILTIN_EVSTWWE:
11590 case SPE_BUILTIN_EVSTWWO:
11591 arg1 = CALL_EXPR_ARG (exp, 2);
11592 if (TREE_CODE (arg1) != INTEGER_CST
11593 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11595 error ("argument 2 must be a 5-bit unsigned literal");
11603 /* The evsplat*i instructions are not quite generic. */
11606 case SPE_BUILTIN_EVSPLATFI:
11607 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11609 case SPE_BUILTIN_EVSPLATI:
11610 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11616 d = (struct builtin_description *) bdesc_2arg_spe;
11617 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11618 if (d->code == fcode)
11619 return rs6000_expand_binop_builtin (d->icode, exp, target);
11621 d = (struct builtin_description *) bdesc_spe_predicates;
11622 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11623 if (d->code == fcode)
11624 return spe_expand_predicate_builtin (d->icode, exp, target);
11626 d = (struct builtin_description *) bdesc_spe_evsel;
11627 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11628 if (d->code == fcode)
11629 return spe_expand_evsel_builtin (d->icode, exp, target);
11633 case SPE_BUILTIN_EVSTDDX:
11634 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11635 case SPE_BUILTIN_EVSTDHX:
11636 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11637 case SPE_BUILTIN_EVSTDWX:
11638 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11639 case SPE_BUILTIN_EVSTWHEX:
11640 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11641 case SPE_BUILTIN_EVSTWHOX:
11642 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11643 case SPE_BUILTIN_EVSTWWEX:
11644 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11645 case SPE_BUILTIN_EVSTWWOX:
11646 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11647 case SPE_BUILTIN_EVSTDD:
11648 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11649 case SPE_BUILTIN_EVSTDH:
11650 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11651 case SPE_BUILTIN_EVSTDW:
11652 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11653 case SPE_BUILTIN_EVSTWHE:
11654 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11655 case SPE_BUILTIN_EVSTWHO:
11656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11657 case SPE_BUILTIN_EVSTWWE:
11658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11659 case SPE_BUILTIN_EVSTWWO:
11660 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11661 case SPE_BUILTIN_MFSPEFSCR:
11662 icode = CODE_FOR_spe_mfspefscr;
11663 tmode = insn_data[icode].operand[0].mode;
11666 || GET_MODE (target) != tmode
11667 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11668 target = gen_reg_rtx (tmode);
11670 pat = GEN_FCN (icode) (target);
11675 case SPE_BUILTIN_MTSPEFSCR:
11676 icode = CODE_FOR_spe_mtspefscr;
11677 arg0 = CALL_EXPR_ARG (exp, 0);
11678 op0 = expand_normal (arg0);
11679 mode0 = insn_data[icode].operand[0].mode;
11681 if (arg0 == error_mark_node)
11684 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11685 op0 = copy_to_mode_reg (mode0, op0);
11687 pat = GEN_FCN (icode) (op0);
11695 *expandedp = false;
11700 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11702 rtx pat, scratch, tmp;
11703 tree form = CALL_EXPR_ARG (exp, 0);
11704 tree arg0 = CALL_EXPR_ARG (exp, 1);
11705 tree arg1 = CALL_EXPR_ARG (exp, 2);
11706 rtx op0 = expand_normal (arg0);
11707 rtx op1 = expand_normal (arg1);
11708 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11709 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11711 enum rtx_code code;
11713 if (TREE_CODE (form) != INTEGER_CST)
11715 error ("argument 1 of __builtin_paired_predicate must be a constant");
11719 form_int = TREE_INT_CST_LOW (form);
11721 gcc_assert (mode0 == mode1);
11723 if (arg0 == error_mark_node || arg1 == error_mark_node)
11727 || GET_MODE (target) != SImode
11728 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11729 target = gen_reg_rtx (SImode);
11730 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11731 op0 = copy_to_mode_reg (mode0, op0);
11732 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11733 op1 = copy_to_mode_reg (mode1, op1);
11735 scratch = gen_reg_rtx (CCFPmode);
11737 pat = GEN_FCN (icode) (scratch, op0, op1);
11759 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11762 error ("argument 1 of __builtin_paired_predicate is out of range");
11766 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11767 emit_move_insn (target, tmp);
11772 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11774 rtx pat, scratch, tmp;
11775 tree form = CALL_EXPR_ARG (exp, 0);
11776 tree arg0 = CALL_EXPR_ARG (exp, 1);
11777 tree arg1 = CALL_EXPR_ARG (exp, 2);
11778 rtx op0 = expand_normal (arg0);
11779 rtx op1 = expand_normal (arg1);
11780 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11781 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11783 enum rtx_code code;
11785 if (TREE_CODE (form) != INTEGER_CST)
11787 error ("argument 1 of __builtin_spe_predicate must be a constant");
11791 form_int = TREE_INT_CST_LOW (form);
11793 gcc_assert (mode0 == mode1);
11795 if (arg0 == error_mark_node || arg1 == error_mark_node)
11799 || GET_MODE (target) != SImode
11800 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11801 target = gen_reg_rtx (SImode);
11803 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11804 op0 = copy_to_mode_reg (mode0, op0);
11805 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11806 op1 = copy_to_mode_reg (mode1, op1);
11808 scratch = gen_reg_rtx (CCmode);
11810 pat = GEN_FCN (icode) (scratch, op0, op1);
11815 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11816 _lower_. We use one compare, but look in different bits of the
11817 CR for each variant.
11819 There are 2 elements in each SPE simd type (upper/lower). The CR
11820 bits are set as follows:
11822 BIT0 | BIT 1 | BIT 2 | BIT 3
11823 U | L | (U | L) | (U & L)
11825 So, for an "all" relationship, BIT 3 would be set.
11826 For an "any" relationship, BIT 2 would be set. Etc.
11828 Following traditional nomenclature, these bits map to:
11830 BIT0 | BIT 1 | BIT 2 | BIT 3
11833 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11838 /* All variant. OV bit. */
11840 /* We need to get to the OV bit, which is the ORDERED bit. We
11841 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11842 that's ugly and will make validate_condition_mode die.
11843 So let's just use another pattern. */
11844 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11846 /* Any variant. EQ bit. */
11850 /* Upper variant. LT bit. */
11854 /* Lower variant. GT bit. */
11859 error ("argument 1 of __builtin_spe_predicate is out of range");
11863 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11864 emit_move_insn (target, tmp);
11869 /* The evsel builtins look like this:
11871 e = __builtin_spe_evsel_OP (a, b, c, d);
11873 and work like this:
11875 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11876 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11880 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11883 tree arg0 = CALL_EXPR_ARG (exp, 0);
11884 tree arg1 = CALL_EXPR_ARG (exp, 1);
11885 tree arg2 = CALL_EXPR_ARG (exp, 2);
11886 tree arg3 = CALL_EXPR_ARG (exp, 3);
11887 rtx op0 = expand_normal (arg0);
11888 rtx op1 = expand_normal (arg1);
11889 rtx op2 = expand_normal (arg2);
11890 rtx op3 = expand_normal (arg3);
11891 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11892 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11894 gcc_assert (mode0 == mode1);
11896 if (arg0 == error_mark_node || arg1 == error_mark_node
11897 || arg2 == error_mark_node || arg3 == error_mark_node)
11901 || GET_MODE (target) != mode0
11902 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11903 target = gen_reg_rtx (mode0);
11905 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11906 op0 = copy_to_mode_reg (mode0, op0);
11907 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11908 op1 = copy_to_mode_reg (mode0, op1);
11909 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11910 op2 = copy_to_mode_reg (mode0, op2);
11911 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11912 op3 = copy_to_mode_reg (mode0, op3);
11914 /* Generate the compare. */
11915 scratch = gen_reg_rtx (CCmode);
11916 pat = GEN_FCN (icode) (scratch, op0, op1);
11921 if (mode0 == V2SImode)
11922 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11924 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11929 /* Expand an expression EXP that calls a built-in function,
11930 with result going to TARGET if that's convenient
11931 (and in mode MODE if that's convenient).
11932 SUBTARGET may be used as the target for computing one of EXP's operands.
11933 IGNORE is nonzero if the value is to be ignored. */
11936 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11937 enum machine_mode mode ATTRIBUTE_UNUSED,
11938 int ignore ATTRIBUTE_UNUSED)
11940 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11941 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11942 const struct builtin_description *d;
11949 case RS6000_BUILTIN_RECIP:
11950 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11952 case RS6000_BUILTIN_RECIPF:
11953 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11955 case RS6000_BUILTIN_RSQRTF:
11956 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11958 case RS6000_BUILTIN_RSQRT:
11959 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11961 case RS6000_BUILTIN_BSWAP_HI:
11962 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11964 case POWER7_BUILTIN_BPERMD:
11965 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11966 ? CODE_FOR_bpermd_di
11967 : CODE_FOR_bpermd_si), exp, target);
11969 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11970 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11972 int icode = (int) CODE_FOR_altivec_lvsr;
11973 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11974 enum machine_mode mode = insn_data[icode].operand[1].mode;
11978 gcc_assert (TARGET_ALTIVEC);
11980 arg = CALL_EXPR_ARG (exp, 0);
11981 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11982 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11983 addr = memory_address (mode, op);
11984 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11988 /* For the load case need to negate the address. */
11989 op = gen_reg_rtx (GET_MODE (addr));
11990 emit_insn (gen_rtx_SET (VOIDmode, op,
11991 gen_rtx_NEG (GET_MODE (addr), addr)));
11993 op = gen_rtx_MEM (mode, op);
11996 || GET_MODE (target) != tmode
11997 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11998 target = gen_reg_rtx (tmode);
12000 /*pat = gen_altivec_lvsr (target, op);*/
12001 pat = GEN_FCN (icode) (target, op);
12009 case ALTIVEC_BUILTIN_VCFUX:
12010 case ALTIVEC_BUILTIN_VCFSX:
12011 case ALTIVEC_BUILTIN_VCTUXS:
12012 case ALTIVEC_BUILTIN_VCTSXS:
12013 /* FIXME: There's got to be a nicer way to handle this case than
12014 constructing a new CALL_EXPR. */
12015 if (call_expr_nargs (exp) == 1)
12017 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12018 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12026 if (TARGET_ALTIVEC)
12028 ret = altivec_expand_builtin (exp, target, &success);
12035 ret = spe_expand_builtin (exp, target, &success);
12040 if (TARGET_PAIRED_FLOAT)
12042 ret = paired_expand_builtin (exp, target, &success);
12048 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12050 /* Handle simple unary operations. */
12051 d = (struct builtin_description *) bdesc_1arg;
12052 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12053 if (d->code == fcode)
12054 return rs6000_expand_unop_builtin (d->icode, exp, target);
12056 /* Handle simple binary operations. */
12057 d = (struct builtin_description *) bdesc_2arg;
12058 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12059 if (d->code == fcode)
12060 return rs6000_expand_binop_builtin (d->icode, exp, target);
12062 /* Handle simple ternary operations. */
12064 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12065 if (d->code == fcode)
12066 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12068 gcc_unreachable ();
12072 rs6000_init_builtins (void)
12077 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12078 V2SF_type_node = build_vector_type (float_type_node, 2);
12079 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12080 V2DF_type_node = build_vector_type (double_type_node, 2);
12081 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12082 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12083 V4SF_type_node = build_vector_type (float_type_node, 4);
12084 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12085 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12087 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12088 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12089 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12090 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12092 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12093 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12094 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12095 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12097 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12098 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12099 'vector unsigned short'. */
12101 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12102 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12103 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12104 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12105 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12107 long_integer_type_internal_node = long_integer_type_node;
12108 long_unsigned_type_internal_node = long_unsigned_type_node;
12109 intQI_type_internal_node = intQI_type_node;
12110 uintQI_type_internal_node = unsigned_intQI_type_node;
12111 intHI_type_internal_node = intHI_type_node;
12112 uintHI_type_internal_node = unsigned_intHI_type_node;
12113 intSI_type_internal_node = intSI_type_node;
12114 uintSI_type_internal_node = unsigned_intSI_type_node;
12115 intDI_type_internal_node = intDI_type_node;
12116 uintDI_type_internal_node = unsigned_intDI_type_node;
12117 float_type_internal_node = float_type_node;
12118 double_type_internal_node = float_type_node;
12119 void_type_internal_node = void_type_node;
12121 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12123 builtin_mode_to_type[QImode][0] = integer_type_node;
12124 builtin_mode_to_type[HImode][0] = integer_type_node;
12125 builtin_mode_to_type[SImode][0] = intSI_type_node;
12126 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12127 builtin_mode_to_type[DImode][0] = intDI_type_node;
12128 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12129 builtin_mode_to_type[SFmode][0] = float_type_node;
12130 builtin_mode_to_type[DFmode][0] = double_type_node;
12131 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12132 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12133 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12134 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12135 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12136 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12137 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12138 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12139 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12140 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12141 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12142 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12143 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12145 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12146 get_identifier ("__bool char"),
12147 bool_char_type_node);
12148 TYPE_NAME (bool_char_type_node) = tdecl;
12149 (*lang_hooks.decls.pushdecl) (tdecl);
12150 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12151 get_identifier ("__bool short"),
12152 bool_short_type_node);
12153 TYPE_NAME (bool_short_type_node) = tdecl;
12154 (*lang_hooks.decls.pushdecl) (tdecl);
12155 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12156 get_identifier ("__bool int"),
12157 bool_int_type_node);
12158 TYPE_NAME (bool_int_type_node) = tdecl;
12159 (*lang_hooks.decls.pushdecl) (tdecl);
12160 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12162 TYPE_NAME (pixel_type_node) = tdecl;
12163 (*lang_hooks.decls.pushdecl) (tdecl);
12165 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12166 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12167 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12168 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12169 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12171 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12172 get_identifier ("__vector unsigned char"),
12173 unsigned_V16QI_type_node);
12174 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12175 (*lang_hooks.decls.pushdecl) (tdecl);
12176 tdecl = build_decl (BUILTINS_LOCATION,
12177 TYPE_DECL, get_identifier ("__vector signed char"),
12179 TYPE_NAME (V16QI_type_node) = tdecl;
12180 (*lang_hooks.decls.pushdecl) (tdecl);
12181 tdecl = build_decl (BUILTINS_LOCATION,
12182 TYPE_DECL, get_identifier ("__vector __bool char"),
12183 bool_V16QI_type_node);
12184 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12185 (*lang_hooks.decls.pushdecl) (tdecl);
12187 tdecl = build_decl (BUILTINS_LOCATION,
12188 TYPE_DECL, get_identifier ("__vector unsigned short"),
12189 unsigned_V8HI_type_node);
12190 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12191 (*lang_hooks.decls.pushdecl) (tdecl);
12192 tdecl = build_decl (BUILTINS_LOCATION,
12193 TYPE_DECL, get_identifier ("__vector signed short"),
12195 TYPE_NAME (V8HI_type_node) = tdecl;
12196 (*lang_hooks.decls.pushdecl) (tdecl);
12197 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12198 get_identifier ("__vector __bool short"),
12199 bool_V8HI_type_node);
12200 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12201 (*lang_hooks.decls.pushdecl) (tdecl);
12203 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12204 get_identifier ("__vector unsigned int"),
12205 unsigned_V4SI_type_node);
12206 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12207 (*lang_hooks.decls.pushdecl) (tdecl);
12208 tdecl = build_decl (BUILTINS_LOCATION,
12209 TYPE_DECL, get_identifier ("__vector signed int"),
12211 TYPE_NAME (V4SI_type_node) = tdecl;
12212 (*lang_hooks.decls.pushdecl) (tdecl);
12213 tdecl = build_decl (BUILTINS_LOCATION,
12214 TYPE_DECL, get_identifier ("__vector __bool int"),
12215 bool_V4SI_type_node);
12216 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12217 (*lang_hooks.decls.pushdecl) (tdecl);
12219 tdecl = build_decl (BUILTINS_LOCATION,
12220 TYPE_DECL, get_identifier ("__vector float"),
12222 TYPE_NAME (V4SF_type_node) = tdecl;
12223 (*lang_hooks.decls.pushdecl) (tdecl);
12224 tdecl = build_decl (BUILTINS_LOCATION,
12225 TYPE_DECL, get_identifier ("__vector __pixel"),
12226 pixel_V8HI_type_node);
12227 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12228 (*lang_hooks.decls.pushdecl) (tdecl);
12232 tdecl = build_decl (BUILTINS_LOCATION,
12233 TYPE_DECL, get_identifier ("__vector double"),
12235 TYPE_NAME (V2DF_type_node) = tdecl;
12236 (*lang_hooks.decls.pushdecl) (tdecl);
12238 tdecl = build_decl (BUILTINS_LOCATION,
12239 TYPE_DECL, get_identifier ("__vector long"),
12241 TYPE_NAME (V2DI_type_node) = tdecl;
12242 (*lang_hooks.decls.pushdecl) (tdecl);
12244 tdecl = build_decl (BUILTINS_LOCATION,
12245 TYPE_DECL, get_identifier ("__vector unsigned long"),
12246 unsigned_V2DI_type_node);
12247 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12248 (*lang_hooks.decls.pushdecl) (tdecl);
12250 tdecl = build_decl (BUILTINS_LOCATION,
12251 TYPE_DECL, get_identifier ("__vector __bool long"),
12252 bool_V2DI_type_node);
12253 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12254 (*lang_hooks.decls.pushdecl) (tdecl);
12257 if (TARGET_PAIRED_FLOAT)
12258 paired_init_builtins ();
12260 spe_init_builtins ();
12261 if (TARGET_ALTIVEC)
12262 altivec_init_builtins ();
12263 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12264 rs6000_common_init_builtins ();
12267 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12268 RS6000_BUILTIN_RECIP,
12269 "__builtin_recipdiv");
12270 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12271 RS6000_BUILTIN_RECIP);
12275 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12276 RS6000_BUILTIN_RECIPF,
12277 "__builtin_recipdivf");
12278 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12279 RS6000_BUILTIN_RECIPF);
12281 if (TARGET_FRSQRTE)
12283 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12284 RS6000_BUILTIN_RSQRT,
12285 "__builtin_rsqrt");
12286 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12287 RS6000_BUILTIN_RSQRT);
12289 if (TARGET_FRSQRTES)
12291 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12292 RS6000_BUILTIN_RSQRTF,
12293 "__builtin_rsqrtf");
12294 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12295 RS6000_BUILTIN_RSQRTF);
12297 if (TARGET_POPCNTD)
12299 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12300 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12301 POWER7_BUILTIN_BPERMD,
12302 "__builtin_bpermd");
12303 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12304 POWER7_BUILTIN_BPERMD);
12306 if (TARGET_POWERPC)
12308 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12309 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12310 unsigned_intHI_type_node,
12312 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12313 RS6000_BUILTIN_BSWAP_HI);
12317 /* AIX libm provides clog as __clog. */
12318 if (built_in_decls [BUILT_IN_CLOG])
12319 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12322 #ifdef SUBTARGET_INIT_BUILTINS
12323 SUBTARGET_INIT_BUILTINS;
12327 /* Returns the rs6000 builtin decl for CODE. */
12330 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12332 if (code >= RS6000_BUILTIN_COUNT)
12333 return error_mark_node;
12335 return rs6000_builtin_decls[code];
12338 /* Search through a set of builtins and enable the mask bits.
12339 DESC is an array of builtins.
12340 SIZE is the total number of builtins.
12341 START is the builtin enum at which to start.
12342 END is the builtin enum at which to end. */
12344 enable_mask_for_builtins (struct builtin_description *desc, int size,
12345 enum rs6000_builtins start,
12346 enum rs6000_builtins end)
12350 for (i = 0; i < size; ++i)
12351 if (desc[i].code == start)
12357 for (; i < size; ++i)
12359 /* Flip all the bits on. */
12360 desc[i].mask = target_flags;
12361 if (desc[i].code == end)
12367 spe_init_builtins (void)
12369 tree endlink = void_list_node;
12370 tree puint_type_node = build_pointer_type (unsigned_type_node);
12371 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12372 struct builtin_description *d;
12375 tree v2si_ftype_4_v2si
12376 = build_function_type
12377 (opaque_V2SI_type_node,
12378 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12379 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12380 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12381 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12384 tree v2sf_ftype_4_v2sf
12385 = build_function_type
12386 (opaque_V2SF_type_node,
12387 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12388 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12389 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12390 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12393 tree int_ftype_int_v2si_v2si
12394 = build_function_type
12395 (integer_type_node,
12396 tree_cons (NULL_TREE, integer_type_node,
12397 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12398 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12401 tree int_ftype_int_v2sf_v2sf
12402 = build_function_type
12403 (integer_type_node,
12404 tree_cons (NULL_TREE, integer_type_node,
12405 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12406 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12409 tree void_ftype_v2si_puint_int
12410 = build_function_type (void_type_node,
12411 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12412 tree_cons (NULL_TREE, puint_type_node,
12413 tree_cons (NULL_TREE,
12417 tree void_ftype_v2si_puint_char
12418 = build_function_type (void_type_node,
12419 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12420 tree_cons (NULL_TREE, puint_type_node,
12421 tree_cons (NULL_TREE,
12425 tree void_ftype_v2si_pv2si_int
12426 = build_function_type (void_type_node,
12427 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12428 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12429 tree_cons (NULL_TREE,
12433 tree void_ftype_v2si_pv2si_char
12434 = build_function_type (void_type_node,
12435 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12436 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12437 tree_cons (NULL_TREE,
12441 tree void_ftype_int
12442 = build_function_type (void_type_node,
12443 tree_cons (NULL_TREE, integer_type_node, endlink));
12445 tree int_ftype_void
12446 = build_function_type (integer_type_node, endlink);
12448 tree v2si_ftype_pv2si_int
12449 = build_function_type (opaque_V2SI_type_node,
12450 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12451 tree_cons (NULL_TREE, integer_type_node,
12454 tree v2si_ftype_puint_int
12455 = build_function_type (opaque_V2SI_type_node,
12456 tree_cons (NULL_TREE, puint_type_node,
12457 tree_cons (NULL_TREE, integer_type_node,
12460 tree v2si_ftype_pushort_int
12461 = build_function_type (opaque_V2SI_type_node,
12462 tree_cons (NULL_TREE, pushort_type_node,
12463 tree_cons (NULL_TREE, integer_type_node,
12466 tree v2si_ftype_signed_char
12467 = build_function_type (opaque_V2SI_type_node,
12468 tree_cons (NULL_TREE, signed_char_type_node,
12471 /* The initialization of the simple binary and unary builtins is
12472 done in rs6000_common_init_builtins, but we have to enable the
12473 mask bits here manually because we have run out of `target_flags'
12474 bits. We really need to redesign this mask business. */
12476 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12477 ARRAY_SIZE (bdesc_2arg),
12478 SPE_BUILTIN_EVADDW,
12479 SPE_BUILTIN_EVXOR);
12480 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12481 ARRAY_SIZE (bdesc_1arg),
12483 SPE_BUILTIN_EVSUBFUSIAAW);
12484 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12485 ARRAY_SIZE (bdesc_spe_predicates),
12486 SPE_BUILTIN_EVCMPEQ,
12487 SPE_BUILTIN_EVFSTSTLT);
12488 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12489 ARRAY_SIZE (bdesc_spe_evsel),
12490 SPE_BUILTIN_EVSEL_CMPGTS,
12491 SPE_BUILTIN_EVSEL_FSTSTEQ);
12493 (*lang_hooks.decls.pushdecl)
12494 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12495 get_identifier ("__ev64_opaque__"),
12496 opaque_V2SI_type_node));
12498 /* Initialize irregular SPE builtins. */
12500 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12501 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12502 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12503 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12504 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12505 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12506 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12507 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12508 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12509 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12510 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12511 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12512 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12513 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12514 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12515 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12516 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12517 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12520 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12521 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12522 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12523 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12524 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12525 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12526 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12527 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12528 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12529 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12530 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12531 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12532 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12533 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12534 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12535 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12536 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12537 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12538 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12539 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12540 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12541 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12544 d = (struct builtin_description *) bdesc_spe_predicates;
12545 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12549 switch (insn_data[d->icode].operand[1].mode)
12552 type = int_ftype_int_v2si_v2si;
12555 type = int_ftype_int_v2sf_v2sf;
12558 gcc_unreachable ();
12561 def_builtin (d->mask, d->name, type, d->code);
12564 /* Evsel predicates. */
12565 d = (struct builtin_description *) bdesc_spe_evsel;
12566 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12570 switch (insn_data[d->icode].operand[1].mode)
12573 type = v2si_ftype_4_v2si;
12576 type = v2sf_ftype_4_v2sf;
12579 gcc_unreachable ();
12582 def_builtin (d->mask, d->name, type, d->code);
12587 paired_init_builtins (void)
12589 const struct builtin_description *d;
12591 tree endlink = void_list_node;
12593 tree int_ftype_int_v2sf_v2sf
12594 = build_function_type
12595 (integer_type_node,
12596 tree_cons (NULL_TREE, integer_type_node,
12597 tree_cons (NULL_TREE, V2SF_type_node,
12598 tree_cons (NULL_TREE, V2SF_type_node,
12600 tree pcfloat_type_node =
12601 build_pointer_type (build_qualified_type
12602 (float_type_node, TYPE_QUAL_CONST));
12604 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12605 long_integer_type_node,
12608 tree void_ftype_v2sf_long_pcfloat =
12609 build_function_type_list (void_type_node,
12611 long_integer_type_node,
12616 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12617 PAIRED_BUILTIN_LX);
12620 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12621 PAIRED_BUILTIN_STX);
12624 d = bdesc_paired_preds;
12625 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12629 switch (insn_data[d->icode].operand[1].mode)
12632 type = int_ftype_int_v2sf_v2sf;
12635 gcc_unreachable ();
12638 def_builtin (d->mask, d->name, type, d->code);
12643 altivec_init_builtins (void)
12645 const struct builtin_description *d;
12646 const struct builtin_description_predicates *dp;
12650 tree pfloat_type_node = build_pointer_type (float_type_node);
12651 tree pint_type_node = build_pointer_type (integer_type_node);
12652 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12653 tree pchar_type_node = build_pointer_type (char_type_node);
12655 tree pvoid_type_node = build_pointer_type (void_type_node);
12657 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12658 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12659 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12660 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12662 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12664 tree int_ftype_opaque
12665 = build_function_type_list (integer_type_node,
12666 opaque_V4SI_type_node, NULL_TREE);
12667 tree opaque_ftype_opaque
12668 = build_function_type (integer_type_node,
12670 tree opaque_ftype_opaque_int
12671 = build_function_type_list (opaque_V4SI_type_node,
12672 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12673 tree opaque_ftype_opaque_opaque_int
12674 = build_function_type_list (opaque_V4SI_type_node,
12675 opaque_V4SI_type_node, opaque_V4SI_type_node,
12676 integer_type_node, NULL_TREE);
12677 tree int_ftype_int_opaque_opaque
12678 = build_function_type_list (integer_type_node,
12679 integer_type_node, opaque_V4SI_type_node,
12680 opaque_V4SI_type_node, NULL_TREE);
12681 tree int_ftype_int_v4si_v4si
12682 = build_function_type_list (integer_type_node,
12683 integer_type_node, V4SI_type_node,
12684 V4SI_type_node, NULL_TREE);
12685 tree v4sf_ftype_pcfloat
12686 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12687 tree void_ftype_pfloat_v4sf
12688 = build_function_type_list (void_type_node,
12689 pfloat_type_node, V4SF_type_node, NULL_TREE);
12690 tree v4si_ftype_pcint
12691 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12692 tree void_ftype_pint_v4si
12693 = build_function_type_list (void_type_node,
12694 pint_type_node, V4SI_type_node, NULL_TREE);
12695 tree v8hi_ftype_pcshort
12696 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12697 tree void_ftype_pshort_v8hi
12698 = build_function_type_list (void_type_node,
12699 pshort_type_node, V8HI_type_node, NULL_TREE);
12700 tree v16qi_ftype_pcchar
12701 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12702 tree void_ftype_pchar_v16qi
12703 = build_function_type_list (void_type_node,
12704 pchar_type_node, V16QI_type_node, NULL_TREE);
12705 tree void_ftype_v4si
12706 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12707 tree v8hi_ftype_void
12708 = build_function_type (V8HI_type_node, void_list_node);
12709 tree void_ftype_void
12710 = build_function_type (void_type_node, void_list_node);
12711 tree void_ftype_int
12712 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12714 tree opaque_ftype_long_pcvoid
12715 = build_function_type_list (opaque_V4SI_type_node,
12716 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12717 tree v16qi_ftype_long_pcvoid
12718 = build_function_type_list (V16QI_type_node,
12719 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12720 tree v8hi_ftype_long_pcvoid
12721 = build_function_type_list (V8HI_type_node,
12722 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12723 tree v4si_ftype_long_pcvoid
12724 = build_function_type_list (V4SI_type_node,
12725 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12727 tree void_ftype_opaque_long_pvoid
12728 = build_function_type_list (void_type_node,
12729 opaque_V4SI_type_node, long_integer_type_node,
12730 pvoid_type_node, NULL_TREE);
12731 tree void_ftype_v4si_long_pvoid
12732 = build_function_type_list (void_type_node,
12733 V4SI_type_node, long_integer_type_node,
12734 pvoid_type_node, NULL_TREE);
12735 tree void_ftype_v16qi_long_pvoid
12736 = build_function_type_list (void_type_node,
12737 V16QI_type_node, long_integer_type_node,
12738 pvoid_type_node, NULL_TREE);
12739 tree void_ftype_v8hi_long_pvoid
12740 = build_function_type_list (void_type_node,
12741 V8HI_type_node, long_integer_type_node,
12742 pvoid_type_node, NULL_TREE);
12743 tree int_ftype_int_v8hi_v8hi
12744 = build_function_type_list (integer_type_node,
12745 integer_type_node, V8HI_type_node,
12746 V8HI_type_node, NULL_TREE);
12747 tree int_ftype_int_v16qi_v16qi
12748 = build_function_type_list (integer_type_node,
12749 integer_type_node, V16QI_type_node,
12750 V16QI_type_node, NULL_TREE);
12751 tree int_ftype_int_v4sf_v4sf
12752 = build_function_type_list (integer_type_node,
12753 integer_type_node, V4SF_type_node,
12754 V4SF_type_node, NULL_TREE);
12755 tree int_ftype_int_v2df_v2df
12756 = build_function_type_list (integer_type_node,
12757 integer_type_node, V2DF_type_node,
12758 V2DF_type_node, NULL_TREE);
12759 tree v4si_ftype_v4si
12760 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12761 tree v8hi_ftype_v8hi
12762 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12763 tree v16qi_ftype_v16qi
12764 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12765 tree v4sf_ftype_v4sf
12766 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12767 tree v2df_ftype_v2df
12768 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12769 tree void_ftype_pcvoid_int_int
12770 = build_function_type_list (void_type_node,
12771 pcvoid_type_node, integer_type_node,
12772 integer_type_node, NULL_TREE);
12774 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12775 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12776 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12777 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12778 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12779 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12781 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12783 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12785 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12787 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12789 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12791 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12793 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12795 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12801 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12802 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12803 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12804 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12805 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12806 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12807 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12808 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12809 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12810 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12811 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12812 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12813 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12814 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12815 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12816 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12817 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12818 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12819 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12821 if (rs6000_cpu == PROCESSOR_CELL)
12823 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12824 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12825 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12826 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12828 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12829 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12830 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12831 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12833 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12834 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12835 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12836 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12838 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12839 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12840 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12841 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12843 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12844 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12845 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12847 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12848 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12849 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12850 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12851 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12852 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12853 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12854 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12855 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12856 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12857 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12858 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12860 /* Add the DST variants. */
12862 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12863 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12865 /* Initialize the predicates. */
12866 dp = bdesc_altivec_preds;
12867 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12869 enum machine_mode mode1;
12871 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12872 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12873 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12874 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12879 mode1 = insn_data[dp->icode].operand[1].mode;
12884 type = int_ftype_int_opaque_opaque;
12887 type = int_ftype_int_v4si_v4si;
12890 type = int_ftype_int_v8hi_v8hi;
12893 type = int_ftype_int_v16qi_v16qi;
12896 type = int_ftype_int_v4sf_v4sf;
12899 type = int_ftype_int_v2df_v2df;
12902 gcc_unreachable ();
12905 def_builtin (dp->mask, dp->name, type, dp->code);
12908 /* Initialize the abs* operators. */
12910 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12912 enum machine_mode mode0;
12915 mode0 = insn_data[d->icode].operand[0].mode;
12920 type = v4si_ftype_v4si;
12923 type = v8hi_ftype_v8hi;
12926 type = v16qi_ftype_v16qi;
12929 type = v4sf_ftype_v4sf;
12932 type = v2df_ftype_v2df;
12935 gcc_unreachable ();
12938 def_builtin (d->mask, d->name, type, d->code);
12941 if (TARGET_ALTIVEC)
12945 /* Initialize target builtin that implements
12946 targetm.vectorize.builtin_mask_for_load. */
12948 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12949 v16qi_ftype_long_pcvoid,
12950 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12951 BUILT_IN_MD, NULL, NULL_TREE);
12952 TREE_READONLY (decl) = 1;
12953 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12954 altivec_builtin_mask_for_load = decl;
12957 /* Access to the vec_init patterns. */
12958 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12959 integer_type_node, integer_type_node,
12960 integer_type_node, NULL_TREE);
12961 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12962 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12964 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12965 short_integer_type_node,
12966 short_integer_type_node,
12967 short_integer_type_node,
12968 short_integer_type_node,
12969 short_integer_type_node,
12970 short_integer_type_node,
12971 short_integer_type_node, NULL_TREE);
12972 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12973 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12975 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12976 char_type_node, char_type_node,
12977 char_type_node, char_type_node,
12978 char_type_node, char_type_node,
12979 char_type_node, char_type_node,
12980 char_type_node, char_type_node,
12981 char_type_node, char_type_node,
12982 char_type_node, char_type_node,
12983 char_type_node, NULL_TREE);
12984 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12985 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12987 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12988 float_type_node, float_type_node,
12989 float_type_node, NULL_TREE);
12990 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12991 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12995 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12996 double_type_node, NULL_TREE);
12997 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12998 VSX_BUILTIN_VEC_INIT_V2DF);
13000 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13001 intDI_type_node, NULL_TREE);
13002 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13003 VSX_BUILTIN_VEC_INIT_V2DI);
13006 /* Access to the vec_set patterns. */
13007 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13009 integer_type_node, NULL_TREE);
13010 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13011 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13013 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13015 integer_type_node, NULL_TREE);
13016 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13017 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13019 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13021 integer_type_node, NULL_TREE);
13022 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13023 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13025 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13027 integer_type_node, NULL_TREE);
13028 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13029 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13033 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13035 integer_type_node, NULL_TREE);
13036 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13037 VSX_BUILTIN_VEC_SET_V2DF);
13039 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13041 integer_type_node, NULL_TREE);
13042 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13043 VSX_BUILTIN_VEC_SET_V2DI);
13046 /* Access to the vec_extract patterns. */
13047 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13048 integer_type_node, NULL_TREE);
13049 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13050 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13052 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13053 integer_type_node, NULL_TREE);
13054 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13055 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13057 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13058 integer_type_node, NULL_TREE);
13059 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13060 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13062 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13063 integer_type_node, NULL_TREE);
13064 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13065 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13069 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13070 integer_type_node, NULL_TREE);
13071 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13072 VSX_BUILTIN_VEC_EXT_V2DF);
13074 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13075 integer_type_node, NULL_TREE);
13076 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13077 VSX_BUILTIN_VEC_EXT_V2DI);
13081 /* Hash function for builtin functions with up to 3 arguments and a return
13084 builtin_hash_function (const void *hash_entry)
13088 const struct builtin_hash_struct *bh =
13089 (const struct builtin_hash_struct *) hash_entry;
13091 for (i = 0; i < 4; i++)
13093 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13094 ret = (ret * 2) + bh->uns_p[i];
13100 /* Compare builtin hash entries H1 and H2 for equivalence. */
13102 builtin_hash_eq (const void *h1, const void *h2)
13104 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13105 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13107 return ((p1->mode[0] == p2->mode[0])
13108 && (p1->mode[1] == p2->mode[1])
13109 && (p1->mode[2] == p2->mode[2])
13110 && (p1->mode[3] == p2->mode[3])
13111 && (p1->uns_p[0] == p2->uns_p[0])
13112 && (p1->uns_p[1] == p2->uns_p[1])
13113 && (p1->uns_p[2] == p2->uns_p[2])
13114 && (p1->uns_p[3] == p2->uns_p[3]));
13117 /* Map types for builtin functions with an explicit return type and up to 3
13118 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13119 of the argument. */
13121 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13122 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13123 enum rs6000_builtins builtin, const char *name)
13125 struct builtin_hash_struct h;
13126 struct builtin_hash_struct *h2;
13130 tree ret_type = NULL_TREE;
13131 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13134 /* Create builtin_hash_table. */
13135 if (builtin_hash_table == NULL)
13136 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13137 builtin_hash_eq, NULL);
13139 h.type = NULL_TREE;
13140 h.mode[0] = mode_ret;
13141 h.mode[1] = mode_arg0;
13142 h.mode[2] = mode_arg1;
13143 h.mode[3] = mode_arg2;
13149 /* If the builtin is a type that produces unsigned results or takes unsigned
13150 arguments, and it is returned as a decl for the vectorizer (such as
13151 widening multiplies, permute), make sure the arguments and return value
13152 are type correct. */
13155 /* unsigned 2 argument functions. */
13156 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13157 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13158 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13159 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13165 /* unsigned 3 argument functions. */
13166 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13167 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13168 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13169 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13170 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13171 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13172 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13173 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13174 case VSX_BUILTIN_VPERM_16QI_UNS:
13175 case VSX_BUILTIN_VPERM_8HI_UNS:
13176 case VSX_BUILTIN_VPERM_4SI_UNS:
13177 case VSX_BUILTIN_VPERM_2DI_UNS:
13178 case VSX_BUILTIN_XXSEL_16QI_UNS:
13179 case VSX_BUILTIN_XXSEL_8HI_UNS:
13180 case VSX_BUILTIN_XXSEL_4SI_UNS:
13181 case VSX_BUILTIN_XXSEL_2DI_UNS:
13188 /* signed permute functions with unsigned char mask. */
13189 case ALTIVEC_BUILTIN_VPERM_16QI:
13190 case ALTIVEC_BUILTIN_VPERM_8HI:
13191 case ALTIVEC_BUILTIN_VPERM_4SI:
13192 case ALTIVEC_BUILTIN_VPERM_4SF:
13193 case ALTIVEC_BUILTIN_VPERM_2DI:
13194 case ALTIVEC_BUILTIN_VPERM_2DF:
13195 case VSX_BUILTIN_VPERM_16QI:
13196 case VSX_BUILTIN_VPERM_8HI:
13197 case VSX_BUILTIN_VPERM_4SI:
13198 case VSX_BUILTIN_VPERM_4SF:
13199 case VSX_BUILTIN_VPERM_2DI:
13200 case VSX_BUILTIN_VPERM_2DF:
13204 /* unsigned args, signed return. */
13205 case VSX_BUILTIN_XVCVUXDDP_UNS:
13206 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13210 /* signed args, unsigned return. */
13211 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13212 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13220 /* Figure out how many args are present. */
13221 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13225 fatal_error ("internal error: builtin function %s had no type", name);
13227 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13228 if (!ret_type && h.uns_p[0])
13229 ret_type = builtin_mode_to_type[h.mode[0]][0];
13232 fatal_error ("internal error: builtin function %s had an unexpected "
13233 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13235 for (i = 0; i < num_args; i++)
13237 int m = (int) h.mode[i+1];
13238 int uns_p = h.uns_p[i+1];
13240 arg_type[i] = builtin_mode_to_type[m][uns_p];
13241 if (!arg_type[i] && uns_p)
13242 arg_type[i] = builtin_mode_to_type[m][0];
13245 fatal_error ("internal error: builtin function %s, argument %d "
13246 "had unexpected argument type %s", name, i,
13247 GET_MODE_NAME (m));
13250 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13251 if (*found == NULL)
13253 h2 = ggc_alloc_builtin_hash_struct ();
13255 *found = (void *)h2;
13256 args = void_list_node;
13258 for (i = num_args - 1; i >= 0; i--)
13259 args = tree_cons (NULL_TREE, arg_type[i], args);
13261 h2->type = build_function_type (ret_type, args);
13264 return ((struct builtin_hash_struct *)(*found))->type;
13268 rs6000_common_init_builtins (void)
13270 const struct builtin_description *d;
13273 tree opaque_ftype_opaque = NULL_TREE;
13274 tree opaque_ftype_opaque_opaque = NULL_TREE;
13275 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13276 tree v2si_ftype_qi = NULL_TREE;
13277 tree v2si_ftype_v2si_qi = NULL_TREE;
13278 tree v2si_ftype_int_qi = NULL_TREE;
13280 if (!TARGET_PAIRED_FLOAT)
13282 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13283 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13286 /* Add the ternary operators. */
13288 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13291 int mask = d->mask;
13293 if ((mask != 0 && (mask & target_flags) == 0)
13294 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13297 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13298 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13299 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13300 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13302 if (! (type = opaque_ftype_opaque_opaque_opaque))
13303 type = opaque_ftype_opaque_opaque_opaque
13304 = build_function_type_list (opaque_V4SI_type_node,
13305 opaque_V4SI_type_node,
13306 opaque_V4SI_type_node,
13307 opaque_V4SI_type_node,
13312 enum insn_code icode = d->icode;
13313 if (d->name == 0 || icode == CODE_FOR_nothing)
13316 type = builtin_function_type (insn_data[icode].operand[0].mode,
13317 insn_data[icode].operand[1].mode,
13318 insn_data[icode].operand[2].mode,
13319 insn_data[icode].operand[3].mode,
13323 def_builtin (d->mask, d->name, type, d->code);
13326 /* Add the binary operators. */
13328 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13330 enum machine_mode mode0, mode1, mode2;
13332 int mask = d->mask;
13334 if ((mask != 0 && (mask & target_flags) == 0)
13335 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13338 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13339 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13340 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13341 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13343 if (! (type = opaque_ftype_opaque_opaque))
13344 type = opaque_ftype_opaque_opaque
13345 = build_function_type_list (opaque_V4SI_type_node,
13346 opaque_V4SI_type_node,
13347 opaque_V4SI_type_node,
13352 enum insn_code icode = d->icode;
13353 if (d->name == 0 || icode == CODE_FOR_nothing)
13356 mode0 = insn_data[icode].operand[0].mode;
13357 mode1 = insn_data[icode].operand[1].mode;
13358 mode2 = insn_data[icode].operand[2].mode;
13360 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13362 if (! (type = v2si_ftype_v2si_qi))
13363 type = v2si_ftype_v2si_qi
13364 = build_function_type_list (opaque_V2SI_type_node,
13365 opaque_V2SI_type_node,
13370 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13371 && mode2 == QImode)
13373 if (! (type = v2si_ftype_int_qi))
13374 type = v2si_ftype_int_qi
13375 = build_function_type_list (opaque_V2SI_type_node,
13382 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13386 def_builtin (d->mask, d->name, type, d->code);
13389 /* Add the simple unary operators. */
13390 d = (struct builtin_description *) bdesc_1arg;
13391 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13393 enum machine_mode mode0, mode1;
13395 int mask = d->mask;
13397 if ((mask != 0 && (mask & target_flags) == 0)
13398 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13401 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13402 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13403 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13404 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13406 if (! (type = opaque_ftype_opaque))
13407 type = opaque_ftype_opaque
13408 = build_function_type_list (opaque_V4SI_type_node,
13409 opaque_V4SI_type_node,
13414 enum insn_code icode = d->icode;
13415 if (d->name == 0 || icode == CODE_FOR_nothing)
13418 mode0 = insn_data[icode].operand[0].mode;
13419 mode1 = insn_data[icode].operand[1].mode;
13421 if (mode0 == V2SImode && mode1 == QImode)
13423 if (! (type = v2si_ftype_qi))
13424 type = v2si_ftype_qi
13425 = build_function_type_list (opaque_V2SI_type_node,
13431 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13435 def_builtin (d->mask, d->name, type, d->code);
13440 rs6000_init_libfuncs (void)
13442 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13443 && !TARGET_POWER2 && !TARGET_POWERPC)
13445 /* AIX library routines for float->int conversion. */
13446 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13447 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13448 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13449 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13452 if (!TARGET_IEEEQUAD)
13453 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13454 if (!TARGET_XL_COMPAT)
13456 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13457 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13458 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13459 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13461 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13463 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13464 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13465 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13466 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13467 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13468 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13469 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13471 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13472 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13473 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13474 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13475 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13476 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13477 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13478 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13481 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13482 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13486 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13487 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13488 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13489 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13493 /* 32-bit SVR4 quad floating point routines. */
13495 set_optab_libfunc (add_optab, TFmode, "_q_add");
13496 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13497 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13498 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13499 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13500 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13501 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13503 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13504 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13505 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13506 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13507 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13508 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13510 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13511 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13512 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13513 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13514 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13515 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13516 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13517 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13522 /* Expand a block clear operation, and return 1 if successful. Return 0
13523 if we should let the compiler generate normal code.
13525 operands[0] is the destination
13526 operands[1] is the length
13527 operands[3] is the alignment */
13530 expand_block_clear (rtx operands[])
13532 rtx orig_dest = operands[0];
13533 rtx bytes_rtx = operands[1];
13534 rtx align_rtx = operands[3];
13535 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13536 HOST_WIDE_INT align;
13537 HOST_WIDE_INT bytes;
13542 /* If this is not a fixed size move, just call memcpy */
13546 /* This must be a fixed size alignment */
13547 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13548 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13550 /* Anything to clear? */
13551 bytes = INTVAL (bytes_rtx);
13555 /* Use the builtin memset after a point, to avoid huge code bloat.
13556 When optimize_size, avoid any significant code bloat; calling
13557 memset is about 4 instructions, so allow for one instruction to
13558 load zero and three to do clearing. */
13559 if (TARGET_ALTIVEC && align >= 128)
13561 else if (TARGET_POWERPC64 && align >= 32)
13563 else if (TARGET_SPE && align >= 64)
13568 if (optimize_size && bytes > 3 * clear_step)
13570 if (! optimize_size && bytes > 8 * clear_step)
13573 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13575 enum machine_mode mode = BLKmode;
13578 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13583 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13588 else if (bytes >= 8 && TARGET_POWERPC64
13589 /* 64-bit loads and stores require word-aligned
13591 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13596 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13597 { /* move 4 bytes */
13601 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13602 { /* move 2 bytes */
13606 else /* move 1 byte at a time */
13612 dest = adjust_address (orig_dest, mode, offset);
13614 emit_move_insn (dest, CONST0_RTX (mode));
13621 /* Expand a block move operation, and return 1 if successful. Return 0
13622 if we should let the compiler generate normal code.
13624 operands[0] is the destination
13625 operands[1] is the source
13626 operands[2] is the length
13627 operands[3] is the alignment */
13629 #define MAX_MOVE_REG 4
13632 expand_block_move (rtx operands[])
13634 rtx orig_dest = operands[0];
13635 rtx orig_src = operands[1];
13636 rtx bytes_rtx = operands[2];
13637 rtx align_rtx = operands[3];
13638 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13643 rtx stores[MAX_MOVE_REG];
13646 /* If this is not a fixed size move, just call memcpy */
13650 /* This must be a fixed size alignment */
13651 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13652 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13654 /* Anything to move? */
13655 bytes = INTVAL (bytes_rtx);
13659 if (bytes > rs6000_block_move_inline_limit)
13662 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13665 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13666 rtx (*mov) (rtx, rtx);
13668 enum machine_mode mode = BLKmode;
13671 /* Altivec first, since it will be faster than a string move
13672 when it applies, and usually not significantly larger. */
13673 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13677 gen_func.mov = gen_movv4si;
13679 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13683 gen_func.mov = gen_movv2si;
13685 else if (TARGET_STRING
13686 && bytes > 24 /* move up to 32 bytes at a time */
13692 && ! fixed_regs[10]
13693 && ! fixed_regs[11]
13694 && ! fixed_regs[12])
13696 move_bytes = (bytes > 32) ? 32 : bytes;
13697 gen_func.movmemsi = gen_movmemsi_8reg;
13699 else if (TARGET_STRING
13700 && bytes > 16 /* move up to 24 bytes at a time */
13706 && ! fixed_regs[10])
13708 move_bytes = (bytes > 24) ? 24 : bytes;
13709 gen_func.movmemsi = gen_movmemsi_6reg;
13711 else if (TARGET_STRING
13712 && bytes > 8 /* move up to 16 bytes at a time */
13716 && ! fixed_regs[8])
13718 move_bytes = (bytes > 16) ? 16 : bytes;
13719 gen_func.movmemsi = gen_movmemsi_4reg;
13721 else if (bytes >= 8 && TARGET_POWERPC64
13722 /* 64-bit loads and stores require word-aligned
13724 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13728 gen_func.mov = gen_movdi;
13730 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13731 { /* move up to 8 bytes at a time */
13732 move_bytes = (bytes > 8) ? 8 : bytes;
13733 gen_func.movmemsi = gen_movmemsi_2reg;
13735 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13736 { /* move 4 bytes */
13739 gen_func.mov = gen_movsi;
13741 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13742 { /* move 2 bytes */
13745 gen_func.mov = gen_movhi;
13747 else if (TARGET_STRING && bytes > 1)
13748 { /* move up to 4 bytes at a time */
13749 move_bytes = (bytes > 4) ? 4 : bytes;
13750 gen_func.movmemsi = gen_movmemsi_1reg;
13752 else /* move 1 byte at a time */
13756 gen_func.mov = gen_movqi;
13759 src = adjust_address (orig_src, mode, offset);
13760 dest = adjust_address (orig_dest, mode, offset);
13762 if (mode != BLKmode)
13764 rtx tmp_reg = gen_reg_rtx (mode);
13766 emit_insn ((*gen_func.mov) (tmp_reg, src));
13767 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13770 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13773 for (i = 0; i < num_reg; i++)
13774 emit_insn (stores[i]);
13778 if (mode == BLKmode)
13780 /* Move the address into scratch registers. The movmemsi
13781 patterns require zero offset. */
13782 if (!REG_P (XEXP (src, 0)))
13784 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13785 src = replace_equiv_address (src, src_reg);
13787 set_mem_size (src, GEN_INT (move_bytes));
13789 if (!REG_P (XEXP (dest, 0)))
13791 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13792 dest = replace_equiv_address (dest, dest_reg);
13794 set_mem_size (dest, GEN_INT (move_bytes));
13796 emit_insn ((*gen_func.movmemsi) (dest, src,
13797 GEN_INT (move_bytes & 31),
13806 /* Return a string to perform a load_multiple operation.
13807 operands[0] is the vector.
13808 operands[1] is the source address.
13809 operands[2] is the first destination register. */
13812 rs6000_output_load_multiple (rtx operands[3])
13814 /* We have to handle the case where the pseudo used to contain the address
13815 is assigned to one of the output registers. */
13817 int words = XVECLEN (operands[0], 0);
13820 if (XVECLEN (operands[0], 0) == 1)
13821 return "{l|lwz} %2,0(%1)";
13823 for (i = 0; i < words; i++)
13824 if (refers_to_regno_p (REGNO (operands[2]) + i,
13825 REGNO (operands[2]) + i + 1, operands[1], 0))
13829 xop[0] = GEN_INT (4 * (words-1));
13830 xop[1] = operands[1];
13831 xop[2] = operands[2];
13832 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13837 xop[0] = GEN_INT (4 * (words-1));
13838 xop[1] = operands[1];
13839 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13840 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);
13845 for (j = 0; j < words; j++)
13848 xop[0] = GEN_INT (j * 4);
13849 xop[1] = operands[1];
13850 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13851 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13853 xop[0] = GEN_INT (i * 4);
13854 xop[1] = operands[1];
13855 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13860 return "{lsi|lswi} %2,%1,%N0";
13864 /* A validation routine: say whether CODE, a condition code, and MODE
13865 match. The other alternatives either don't make sense or should
13866 never be generated. */
13869 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13871 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13872 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13873 && GET_MODE_CLASS (mode) == MODE_CC);
13875 /* These don't make sense. */
13876 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13877 || mode != CCUNSmode);
13879 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13880 || mode == CCUNSmode);
13882 gcc_assert (mode == CCFPmode
13883 || (code != ORDERED && code != UNORDERED
13884 && code != UNEQ && code != LTGT
13885 && code != UNGT && code != UNLT
13886 && code != UNGE && code != UNLE));
13888 /* These should never be generated except for
13889 flag_finite_math_only. */
13890 gcc_assert (mode != CCFPmode
13891 || flag_finite_math_only
13892 || (code != LE && code != GE
13893 && code != UNEQ && code != LTGT
13894 && code != UNGT && code != UNLT));
13896 /* These are invalid; the information is not there. */
13897 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13901 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13902 mask required to convert the result of a rotate insn into a shift
13903 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13906 includes_lshift_p (rtx shiftop, rtx andop)
13908 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13910 shift_mask <<= INTVAL (shiftop);
13912 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13915 /* Similar, but for right shift. */
13918 includes_rshift_p (rtx shiftop, rtx andop)
13920 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13922 shift_mask >>= INTVAL (shiftop);
13924 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13927 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13928 to perform a left shift. It must have exactly SHIFTOP least
13929 significant 0's, then one or more 1's, then zero or more 0's. */
13932 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13934 if (GET_CODE (andop) == CONST_INT)
13936 HOST_WIDE_INT c, lsb, shift_mask;
13938 c = INTVAL (andop);
13939 if (c == 0 || c == ~0)
13943 shift_mask <<= INTVAL (shiftop);
13945 /* Find the least significant one bit. */
13948 /* It must coincide with the LSB of the shift mask. */
13949 if (-lsb != shift_mask)
13952 /* Invert to look for the next transition (if any). */
13955 /* Remove the low group of ones (originally low group of zeros). */
13958 /* Again find the lsb, and check we have all 1's above. */
13962 else if (GET_CODE (andop) == CONST_DOUBLE
13963 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13965 HOST_WIDE_INT low, high, lsb;
13966 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13968 low = CONST_DOUBLE_LOW (andop);
13969 if (HOST_BITS_PER_WIDE_INT < 64)
13970 high = CONST_DOUBLE_HIGH (andop);
13972 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13973 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13976 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13978 shift_mask_high = ~0;
13979 if (INTVAL (shiftop) > 32)
13980 shift_mask_high <<= INTVAL (shiftop) - 32;
13982 lsb = high & -high;
13984 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13990 lsb = high & -high;
13991 return high == -lsb;
13994 shift_mask_low = ~0;
13995 shift_mask_low <<= INTVAL (shiftop);
13999 if (-lsb != shift_mask_low)
14002 if (HOST_BITS_PER_WIDE_INT < 64)
14007 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14009 lsb = high & -high;
14010 return high == -lsb;
14014 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14020 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14021 to perform a left shift. It must have SHIFTOP or more least
14022 significant 0's, with the remainder of the word 1's. */
14025 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14027 if (GET_CODE (andop) == CONST_INT)
14029 HOST_WIDE_INT c, lsb, shift_mask;
14032 shift_mask <<= INTVAL (shiftop);
14033 c = INTVAL (andop);
14035 /* Find the least significant one bit. */
14038 /* It must be covered by the shift mask.
14039 This test also rejects c == 0. */
14040 if ((lsb & shift_mask) == 0)
14043 /* Check we have all 1's above the transition, and reject all 1's. */
14044 return c == -lsb && lsb != 1;
14046 else if (GET_CODE (andop) == CONST_DOUBLE
14047 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14049 HOST_WIDE_INT low, lsb, shift_mask_low;
14051 low = CONST_DOUBLE_LOW (andop);
14053 if (HOST_BITS_PER_WIDE_INT < 64)
14055 HOST_WIDE_INT high, shift_mask_high;
14057 high = CONST_DOUBLE_HIGH (andop);
14061 shift_mask_high = ~0;
14062 if (INTVAL (shiftop) > 32)
14063 shift_mask_high <<= INTVAL (shiftop) - 32;
14065 lsb = high & -high;
14067 if ((lsb & shift_mask_high) == 0)
14070 return high == -lsb;
14076 shift_mask_low = ~0;
14077 shift_mask_low <<= INTVAL (shiftop);
14081 if ((lsb & shift_mask_low) == 0)
14084 return low == -lsb && lsb != 1;
14090 /* Return 1 if operands will generate a valid arguments to rlwimi
14091 instruction for insert with right shift in 64-bit mode. The mask may
14092 not start on the first bit or stop on the last bit because wrap-around
14093 effects of instruction do not correspond to semantics of RTL insn. */
14096 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14098 if (INTVAL (startop) > 32
14099 && INTVAL (startop) < 64
14100 && INTVAL (sizeop) > 1
14101 && INTVAL (sizeop) + INTVAL (startop) < 64
14102 && INTVAL (shiftop) > 0
14103 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14104 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14110 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14111 for lfq and stfq insns iff the registers are hard registers. */
14114 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14116 /* We might have been passed a SUBREG. */
14117 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14120 /* We might have been passed non floating point registers. */
14121 if (!FP_REGNO_P (REGNO (reg1))
14122 || !FP_REGNO_P (REGNO (reg2)))
14125 return (REGNO (reg1) == REGNO (reg2) - 1);
14128 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14129 addr1 and addr2 must be in consecutive memory locations
14130 (addr2 == addr1 + 8). */
14133 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14136 unsigned int reg1, reg2;
14137 int offset1, offset2;
14139 /* The mems cannot be volatile. */
14140 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14143 addr1 = XEXP (mem1, 0);
14144 addr2 = XEXP (mem2, 0);
14146 /* Extract an offset (if used) from the first addr. */
14147 if (GET_CODE (addr1) == PLUS)
14149 /* If not a REG, return zero. */
14150 if (GET_CODE (XEXP (addr1, 0)) != REG)
14154 reg1 = REGNO (XEXP (addr1, 0));
14155 /* The offset must be constant! */
14156 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14158 offset1 = INTVAL (XEXP (addr1, 1));
14161 else if (GET_CODE (addr1) != REG)
14165 reg1 = REGNO (addr1);
14166 /* This was a simple (mem (reg)) expression. Offset is 0. */
14170 /* And now for the second addr. */
14171 if (GET_CODE (addr2) == PLUS)
14173 /* If not a REG, return zero. */
14174 if (GET_CODE (XEXP (addr2, 0)) != REG)
14178 reg2 = REGNO (XEXP (addr2, 0));
14179 /* The offset must be constant. */
14180 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14182 offset2 = INTVAL (XEXP (addr2, 1));
14185 else if (GET_CODE (addr2) != REG)
14189 reg2 = REGNO (addr2);
14190 /* This was a simple (mem (reg)) expression. Offset is 0. */
14194 /* Both of these must have the same base register. */
14198 /* The offset for the second addr must be 8 more than the first addr. */
14199 if (offset2 != offset1 + 8)
14202 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14209 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14211 static bool eliminated = false;
14214 if (mode != SDmode)
14215 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14218 rtx mem = cfun->machine->sdmode_stack_slot;
14219 gcc_assert (mem != NULL_RTX);
14223 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14224 cfun->machine->sdmode_stack_slot = mem;
14230 if (TARGET_DEBUG_ADDR)
14232 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14233 GET_MODE_NAME (mode));
14235 fprintf (stderr, "\tNULL_RTX\n");
14244 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14246 /* Don't walk into types. */
14247 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14249 *walk_subtrees = 0;
14253 switch (TREE_CODE (*tp))
14262 case VIEW_CONVERT_EXPR:
14263 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14273 enum reload_reg_type {
14275 VECTOR_REGISTER_TYPE,
14276 OTHER_REGISTER_TYPE
14279 static enum reload_reg_type
14280 rs6000_reload_register_type (enum reg_class rclass)
14286 return GPR_REGISTER_TYPE;
14291 return VECTOR_REGISTER_TYPE;
14294 return OTHER_REGISTER_TYPE;
14298 /* Inform reload about cases where moving X with a mode MODE to a register in
14299 RCLASS requires an extra scratch or immediate register. Return the class
14300 needed for the immediate register.
14302 For VSX and Altivec, we may need a register to convert sp+offset into
14306 rs6000_secondary_reload (bool in_p,
14308 reg_class_t rclass_i,
14309 enum machine_mode mode,
14310 secondary_reload_info *sri)
14312 enum reg_class rclass = (enum reg_class) rclass_i;
14313 reg_class_t ret = ALL_REGS;
14314 enum insn_code icode;
14315 bool default_p = false;
14317 sri->icode = CODE_FOR_nothing;
14319 /* Convert vector loads and stores into gprs to use an additional base
14321 icode = rs6000_vector_reload[mode][in_p != false];
14322 if (icode != CODE_FOR_nothing)
14325 sri->icode = CODE_FOR_nothing;
14326 sri->extra_cost = 0;
14328 if (GET_CODE (x) == MEM)
14330 rtx addr = XEXP (x, 0);
14332 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14333 an extra register in that case, but it would need an extra
14334 register if the addressing is reg+reg or (reg+reg)&(-16). */
14335 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14337 if (!legitimate_indirect_address_p (addr, false)
14338 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14340 sri->icode = icode;
14341 /* account for splitting the loads, and converting the
14342 address from reg+reg to reg. */
14343 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14344 + ((GET_CODE (addr) == AND) ? 1 : 0));
14347 /* Loads to and stores from vector registers can only do reg+reg
14348 addressing. Altivec registers can also do (reg+reg)&(-16). */
14349 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14350 || rclass == FLOAT_REGS || rclass == NO_REGS)
14352 if (!VECTOR_MEM_ALTIVEC_P (mode)
14353 && GET_CODE (addr) == AND
14354 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14355 && INTVAL (XEXP (addr, 1)) == -16
14356 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14357 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14359 sri->icode = icode;
14360 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14363 else if (!legitimate_indirect_address_p (addr, false)
14364 && (rclass == NO_REGS
14365 || !legitimate_indexed_address_p (addr, false)))
14367 sri->icode = icode;
14368 sri->extra_cost = 1;
14371 icode = CODE_FOR_nothing;
14373 /* Any other loads, including to pseudo registers which haven't been
14374 assigned to a register yet, default to require a scratch
14378 sri->icode = icode;
14379 sri->extra_cost = 2;
14382 else if (REG_P (x))
14384 int regno = true_regnum (x);
14386 icode = CODE_FOR_nothing;
14387 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14391 enum reg_class xclass = REGNO_REG_CLASS (regno);
14392 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14393 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14395 /* If memory is needed, use default_secondary_reload to create the
14397 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14410 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14412 gcc_assert (ret != ALL_REGS);
14414 if (TARGET_DEBUG_ADDR)
14417 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14419 reg_class_names[ret],
14420 in_p ? "true" : "false",
14421 reg_class_names[rclass],
14422 GET_MODE_NAME (mode));
14425 fprintf (stderr, ", default secondary reload");
14427 if (sri->icode != CODE_FOR_nothing)
14428 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14429 insn_data[sri->icode].name, sri->extra_cost);
14431 fprintf (stderr, "\n");
14439 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14440 to SP+reg addressing. */
14443 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14445 int regno = true_regnum (reg);
14446 enum machine_mode mode = GET_MODE (reg);
14447 enum reg_class rclass;
14449 rtx and_op2 = NULL_RTX;
14452 rtx scratch_or_premodify = scratch;
14456 if (TARGET_DEBUG_ADDR)
14458 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14459 store_p ? "store" : "load");
14460 fprintf (stderr, "reg:\n");
14462 fprintf (stderr, "mem:\n");
14464 fprintf (stderr, "scratch:\n");
14465 debug_rtx (scratch);
14468 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14469 gcc_assert (GET_CODE (mem) == MEM);
14470 rclass = REGNO_REG_CLASS (regno);
14471 addr = XEXP (mem, 0);
14475 /* GPRs can handle reg + small constant, all other addresses need to use
14476 the scratch register. */
14479 if (GET_CODE (addr) == AND)
14481 and_op2 = XEXP (addr, 1);
14482 addr = XEXP (addr, 0);
14485 if (GET_CODE (addr) == PRE_MODIFY)
14487 scratch_or_premodify = XEXP (addr, 0);
14488 gcc_assert (REG_P (scratch_or_premodify));
14489 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14490 addr = XEXP (addr, 1);
14493 if (GET_CODE (addr) == PLUS
14494 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14495 || and_op2 != NULL_RTX))
14497 addr_op1 = XEXP (addr, 0);
14498 addr_op2 = XEXP (addr, 1);
14499 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14501 if (!REG_P (addr_op2)
14502 && (GET_CODE (addr_op2) != CONST_INT
14503 || !satisfies_constraint_I (addr_op2)))
14505 if (TARGET_DEBUG_ADDR)
14508 "\nMove plus addr to register %s, mode = %s: ",
14509 rs6000_reg_names[REGNO (scratch)],
14510 GET_MODE_NAME (mode));
14511 debug_rtx (addr_op2);
14513 rs6000_emit_move (scratch, addr_op2, Pmode);
14514 addr_op2 = scratch;
14517 emit_insn (gen_rtx_SET (VOIDmode,
14518 scratch_or_premodify,
14519 gen_rtx_PLUS (Pmode,
14523 addr = scratch_or_premodify;
14524 scratch_or_premodify = scratch;
14526 else if (!legitimate_indirect_address_p (addr, false)
14527 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14529 if (TARGET_DEBUG_ADDR)
14531 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14532 rs6000_reg_names[REGNO (scratch_or_premodify)],
14533 GET_MODE_NAME (mode));
14536 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14537 addr = scratch_or_premodify;
14538 scratch_or_premodify = scratch;
14542 /* Float/Altivec registers can only handle reg+reg addressing. Move
14543 other addresses into a scratch register. */
14548 /* With float regs, we need to handle the AND ourselves, since we can't
14549 use the Altivec instruction with an implicit AND -16. Allow scalar
14550 loads to float registers to use reg+offset even if VSX. */
14551 if (GET_CODE (addr) == AND
14552 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14553 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14554 || INTVAL (XEXP (addr, 1)) != -16
14555 || !VECTOR_MEM_ALTIVEC_P (mode)))
14557 and_op2 = XEXP (addr, 1);
14558 addr = XEXP (addr, 0);
14561 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14562 as the address later. */
14563 if (GET_CODE (addr) == PRE_MODIFY
14564 && (!VECTOR_MEM_VSX_P (mode)
14565 || and_op2 != NULL_RTX
14566 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14568 scratch_or_premodify = XEXP (addr, 0);
14569 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14571 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14572 addr = XEXP (addr, 1);
14575 if (legitimate_indirect_address_p (addr, false) /* reg */
14576 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14577 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14578 || (GET_CODE (addr) == AND /* Altivec memory */
14579 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14580 && INTVAL (XEXP (addr, 1)) == -16
14581 && VECTOR_MEM_ALTIVEC_P (mode))
14582 || (rclass == FLOAT_REGS /* legacy float mem */
14583 && GET_MODE_SIZE (mode) == 8
14584 && and_op2 == NULL_RTX
14585 && scratch_or_premodify == scratch
14586 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14589 else if (GET_CODE (addr) == PLUS)
14591 addr_op1 = XEXP (addr, 0);
14592 addr_op2 = XEXP (addr, 1);
14593 gcc_assert (REG_P (addr_op1));
14595 if (TARGET_DEBUG_ADDR)
14597 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14598 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14599 debug_rtx (addr_op2);
14601 rs6000_emit_move (scratch, addr_op2, Pmode);
14602 emit_insn (gen_rtx_SET (VOIDmode,
14603 scratch_or_premodify,
14604 gen_rtx_PLUS (Pmode,
14607 addr = scratch_or_premodify;
14608 scratch_or_premodify = scratch;
14611 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14612 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14614 if (TARGET_DEBUG_ADDR)
14616 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14617 rs6000_reg_names[REGNO (scratch_or_premodify)],
14618 GET_MODE_NAME (mode));
14622 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14623 addr = scratch_or_premodify;
14624 scratch_or_premodify = scratch;
14628 gcc_unreachable ();
14633 gcc_unreachable ();
14636 /* If the original address involved a pre-modify that we couldn't use the VSX
14637 memory instruction with update, and we haven't taken care of already,
14638 store the address in the pre-modify register and use that as the
14640 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14642 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14643 addr = scratch_or_premodify;
14646 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14647 memory instruction, recreate the AND now, including the clobber which is
14648 generated by the general ANDSI3/ANDDI3 patterns for the
14649 andi. instruction. */
14650 if (and_op2 != NULL_RTX)
14652 if (! legitimate_indirect_address_p (addr, false))
14654 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14658 if (TARGET_DEBUG_ADDR)
14660 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14661 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14662 debug_rtx (and_op2);
14665 and_rtx = gen_rtx_SET (VOIDmode,
14667 gen_rtx_AND (Pmode,
14671 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14672 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14673 gen_rtvec (2, and_rtx, cc_clobber)));
14677 /* Adjust the address if it changed. */
14678 if (addr != XEXP (mem, 0))
14680 mem = change_address (mem, mode, addr);
14681 if (TARGET_DEBUG_ADDR)
14682 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14685 /* Now create the move. */
14687 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14689 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14694 /* Target hook to return the cover classes for Integrated Register Allocator.
14695 Cover classes is a set of non-intersected register classes covering all hard
14696 registers used for register allocation purpose. Any move between two
14697 registers of a cover class should be cheaper than load or store of the
14698 registers. The value is array of register classes with LIM_REG_CLASSES used
14701 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14702 account for the Altivec and Floating registers being subsets of the VSX
14703 register set under VSX, but distinct register sets on pre-VSX machines. */
14705 static const reg_class_t *
14706 rs6000_ira_cover_classes (void)
14708 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14709 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14711 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14714 /* Allocate a 64-bit stack slot to be used for copying SDmode
14715 values through if this function has any SDmode references. */
14718 rs6000_alloc_sdmode_stack_slot (void)
14722 gimple_stmt_iterator gsi;
14724 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14727 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14729 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14732 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14733 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14739 /* Check for any SDmode parameters of the function. */
14740 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14742 if (TREE_TYPE (t) == error_mark_node)
14745 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14746 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14748 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14749 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14757 rs6000_instantiate_decls (void)
14759 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14760 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14763 /* Given an rtx X being reloaded into a reg required to be
14764 in class CLASS, return the class of reg to actually use.
14765 In general this is just CLASS; but on some machines
14766 in some cases it is preferable to use a more restrictive class.
14768 On the RS/6000, we have to return NO_REGS when we want to reload a
14769 floating-point CONST_DOUBLE to force it to be copied to memory.
14771 We also don't want to reload integer values into floating-point
14772 registers if we can at all help it. In fact, this can
14773 cause reload to die, if it tries to generate a reload of CTR
14774 into a FP register and discovers it doesn't have the memory location
14777 ??? Would it be a good idea to have reload do the converse, that is
14778 try to reload floating modes into FP registers if possible?
14781 static enum reg_class
14782 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14784 enum machine_mode mode = GET_MODE (x);
14786 if (VECTOR_UNIT_VSX_P (mode)
14787 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14790 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14791 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14792 && easy_vector_constant (x, mode))
14793 return ALTIVEC_REGS;
14795 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14798 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14799 return GENERAL_REGS;
14801 /* For VSX, prefer the traditional registers for 64-bit values because we can
14802 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14803 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14804 prefer Altivec loads.. */
14805 if (rclass == VSX_REGS)
14807 if (GET_MODE_SIZE (mode) <= 8)
14810 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14811 return ALTIVEC_REGS;
14819 /* Debug version of rs6000_preferred_reload_class. */
14820 static enum reg_class
14821 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14823 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14826 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14828 reg_class_names[ret], reg_class_names[rclass],
14829 GET_MODE_NAME (GET_MODE (x)));
14835 /* If we are copying between FP or AltiVec registers and anything else, we need
14836 a memory location. The exception is when we are targeting ppc64 and the
14837 move to/from fpr to gpr instructions are available. Also, under VSX, you
14838 can copy vector registers from the FP register set to the Altivec register
14839 set and vice versa. */
14842 rs6000_secondary_memory_needed (enum reg_class class1,
14843 enum reg_class class2,
14844 enum machine_mode mode)
14846 if (class1 == class2)
14849 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14850 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14851 between these classes. But we need memory for other things that can go in
14852 FLOAT_REGS like SFmode. */
14854 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14855 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14856 || class1 == FLOAT_REGS))
14857 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14858 && class2 != FLOAT_REGS);
14860 if (class1 == VSX_REGS || class2 == VSX_REGS)
14863 if (class1 == FLOAT_REGS
14864 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14865 || ((mode != DFmode)
14866 && (mode != DDmode)
14867 && (mode != DImode))))
14870 if (class2 == FLOAT_REGS
14871 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14872 || ((mode != DFmode)
14873 && (mode != DDmode)
14874 && (mode != DImode))))
14877 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14883 /* Debug version of rs6000_secondary_memory_needed. */
14885 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14886 enum reg_class class2,
14887 enum machine_mode mode)
14889 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14892 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14893 "class2 = %s, mode = %s\n",
14894 ret ? "true" : "false", reg_class_names[class1],
14895 reg_class_names[class2], GET_MODE_NAME (mode));
14900 /* Return the register class of a scratch register needed to copy IN into
14901 or out of a register in RCLASS in MODE. If it can be done directly,
14902 NO_REGS is returned. */
14904 static enum reg_class
14905 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14910 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14912 && MACHOPIC_INDIRECT
14916 /* We cannot copy a symbolic operand directly into anything
14917 other than BASE_REGS for TARGET_ELF. So indicate that a
14918 register from BASE_REGS is needed as an intermediate
14921 On Darwin, pic addresses require a load from memory, which
14922 needs a base register. */
14923 if (rclass != BASE_REGS
14924 && (GET_CODE (in) == SYMBOL_REF
14925 || GET_CODE (in) == HIGH
14926 || GET_CODE (in) == LABEL_REF
14927 || GET_CODE (in) == CONST))
14931 if (GET_CODE (in) == REG)
14933 regno = REGNO (in);
14934 if (regno >= FIRST_PSEUDO_REGISTER)
14936 regno = true_regnum (in);
14937 if (regno >= FIRST_PSEUDO_REGISTER)
14941 else if (GET_CODE (in) == SUBREG)
14943 regno = true_regnum (in);
14944 if (regno >= FIRST_PSEUDO_REGISTER)
14950 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14952 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14953 || (regno >= 0 && INT_REGNO_P (regno)))
14956 /* Constants, memory, and FP registers can go into FP registers. */
14957 if ((regno == -1 || FP_REGNO_P (regno))
14958 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14959 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14961 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14964 && (regno == -1 || VSX_REGNO_P (regno))
14965 && VSX_REG_CLASS_P (rclass))
14968 /* Memory, and AltiVec registers can go into AltiVec registers. */
14969 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14970 && rclass == ALTIVEC_REGS)
14973 /* We can copy among the CR registers. */
14974 if ((rclass == CR_REGS || rclass == CR0_REGS)
14975 && regno >= 0 && CR_REGNO_P (regno))
14978 /* Otherwise, we need GENERAL_REGS. */
14979 return GENERAL_REGS;
14982 /* Debug version of rs6000_secondary_reload_class. */
14983 static enum reg_class
14984 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14985 enum machine_mode mode, rtx in)
14987 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14989 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14990 "mode = %s, input rtx:\n",
14991 reg_class_names[ret], reg_class_names[rclass],
14992 GET_MODE_NAME (mode));
14998 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15001 rs6000_cannot_change_mode_class (enum machine_mode from,
15002 enum machine_mode to,
15003 enum reg_class rclass)
15005 unsigned from_size = GET_MODE_SIZE (from);
15006 unsigned to_size = GET_MODE_SIZE (to);
15008 if (from_size != to_size)
15010 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15011 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15012 && reg_classes_intersect_p (xclass, rclass));
15015 if (TARGET_E500_DOUBLE
15016 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15017 || (((to) == TFmode) + ((from) == TFmode)) == 1
15018 || (((to) == DDmode) + ((from) == DDmode)) == 1
15019 || (((to) == TDmode) + ((from) == TDmode)) == 1
15020 || (((to) == DImode) + ((from) == DImode)) == 1))
15023 /* Since the VSX register set includes traditional floating point registers
15024 and altivec registers, just check for the size being different instead of
15025 trying to check whether the modes are vector modes. Otherwise it won't
15026 allow say DF and DI to change classes. */
15027 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15028 return (from_size != 8 && from_size != 16);
15030 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15031 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15034 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15035 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15041 /* Debug version of rs6000_cannot_change_mode_class. */
15043 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15044 enum machine_mode to,
15045 enum reg_class rclass)
15047 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15050 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15051 "to = %s, rclass = %s\n",
15052 ret ? "true" : "false",
15053 GET_MODE_NAME (from), GET_MODE_NAME (to),
15054 reg_class_names[rclass]);
15059 /* Given a comparison operation, return the bit number in CCR to test. We
15060 know this is a valid comparison.
15062 SCC_P is 1 if this is for an scc. That means that %D will have been
15063 used instead of %C, so the bits will be in different places.
15065 Return -1 if OP isn't a valid comparison for some reason. */
15068 ccr_bit (rtx op, int scc_p)
15070 enum rtx_code code = GET_CODE (op);
15071 enum machine_mode cc_mode;
15076 if (!COMPARISON_P (op))
15079 reg = XEXP (op, 0);
15081 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15083 cc_mode = GET_MODE (reg);
15084 cc_regnum = REGNO (reg);
15085 base_bit = 4 * (cc_regnum - CR0_REGNO);
15087 validate_condition_mode (code, cc_mode);
15089 /* When generating a sCOND operation, only positive conditions are
15092 || code == EQ || code == GT || code == LT || code == UNORDERED
15093 || code == GTU || code == LTU);
15098 return scc_p ? base_bit + 3 : base_bit + 2;
15100 return base_bit + 2;
15101 case GT: case GTU: case UNLE:
15102 return base_bit + 1;
15103 case LT: case LTU: case UNGE:
15105 case ORDERED: case UNORDERED:
15106 return base_bit + 3;
15109 /* If scc, we will have done a cror to put the bit in the
15110 unordered position. So test that bit. For integer, this is ! LT
15111 unless this is an scc insn. */
15112 return scc_p ? base_bit + 3 : base_bit;
15115 return scc_p ? base_bit + 3 : base_bit + 1;
15118 gcc_unreachable ();
15122 /* Return the GOT register. */
15125 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15127 /* The second flow pass currently (June 1999) can't update
15128 regs_ever_live without disturbing other parts of the compiler, so
15129 update it here to make the prolog/epilogue code happy. */
15130 if (!can_create_pseudo_p ()
15131 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15132 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15134 crtl->uses_pic_offset_table = 1;
15136 return pic_offset_table_rtx;
15139 /* Function to init struct machine_function.
15140 This will be called, via a pointer variable,
15141 from push_function_context. */
15143 static struct machine_function *
15144 rs6000_init_machine_status (void)
15146 return ggc_alloc_cleared_machine_function ();
15149 /* These macros test for integers and extract the low-order bits. */
15151 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15152 && GET_MODE (X) == VOIDmode)
15154 #define INT_LOWPART(X) \
15155 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15158 extract_MB (rtx op)
15161 unsigned long val = INT_LOWPART (op);
15163 /* If the high bit is zero, the value is the first 1 bit we find
15165 if ((val & 0x80000000) == 0)
15167 gcc_assert (val & 0xffffffff);
15170 while (((val <<= 1) & 0x80000000) == 0)
15175 /* If the high bit is set and the low bit is not, or the mask is all
15176 1's, the value is zero. */
15177 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15180 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15183 while (((val >>= 1) & 1) != 0)
15190 extract_ME (rtx op)
15193 unsigned long val = INT_LOWPART (op);
15195 /* If the low bit is zero, the value is the first 1 bit we find from
15197 if ((val & 1) == 0)
15199 gcc_assert (val & 0xffffffff);
15202 while (((val >>= 1) & 1) == 0)
15208 /* If the low bit is set and the high bit is not, or the mask is all
15209 1's, the value is 31. */
15210 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15213 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15216 while (((val <<= 1) & 0x80000000) != 0)
15222 /* Locate some local-dynamic symbol still in use by this function
15223 so that we can print its name in some tls_ld pattern. */
15225 static const char *
15226 rs6000_get_some_local_dynamic_name (void)
15230 if (cfun->machine->some_ld_name)
15231 return cfun->machine->some_ld_name;
15233 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15235 && for_each_rtx (&PATTERN (insn),
15236 rs6000_get_some_local_dynamic_name_1, 0))
15237 return cfun->machine->some_ld_name;
15239 gcc_unreachable ();
15242 /* Helper function for rs6000_get_some_local_dynamic_name. */
15245 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15249 if (GET_CODE (x) == SYMBOL_REF)
15251 const char *str = XSTR (x, 0);
15252 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15254 cfun->machine->some_ld_name = str;
15262 /* Write out a function code label. */
15265 rs6000_output_function_entry (FILE *file, const char *fname)
15267 if (fname[0] != '.')
15269 switch (DEFAULT_ABI)
15272 gcc_unreachable ();
15278 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15287 RS6000_OUTPUT_BASENAME (file, fname);
15290 /* Print an operand. Recognize special options, documented below. */
15293 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15294 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15296 #define SMALL_DATA_RELOC "sda21"
15297 #define SMALL_DATA_REG 0
15301 print_operand (FILE *file, rtx x, int code)
15305 unsigned HOST_WIDE_INT uval;
15310 /* Write out an instruction after the call which may be replaced
15311 with glue code by the loader. This depends on the AIX version. */
15312 asm_fprintf (file, RS6000_CALL_GLUE);
15315 /* %a is output_address. */
15318 /* If X is a constant integer whose low-order 5 bits are zero,
15319 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15320 in the AIX assembler where "sri" with a zero shift count
15321 writes a trash instruction. */
15322 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15329 /* If constant, low-order 16 bits of constant, unsigned.
15330 Otherwise, write normally. */
15332 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15334 print_operand (file, x, 0);
15338 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15339 for 64-bit mask direction. */
15340 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15343 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15347 /* X is a CR register. Print the number of the GT bit of the CR. */
15348 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15349 output_operand_lossage ("invalid %%c value");
15351 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15355 /* Like 'J' but get to the GT bit only. */
15356 gcc_assert (GET_CODE (x) == REG);
15358 /* Bit 1 is GT bit. */
15359 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15361 /* Add one for shift count in rlinm for scc. */
15362 fprintf (file, "%d", i + 1);
15366 /* X is a CR register. Print the number of the EQ bit of the CR */
15367 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15368 output_operand_lossage ("invalid %%E value");
15370 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15374 /* X is a CR register. Print the shift count needed to move it
15375 to the high-order four bits. */
15376 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15377 output_operand_lossage ("invalid %%f value");
15379 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15383 /* Similar, but print the count for the rotate in the opposite
15385 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15386 output_operand_lossage ("invalid %%F value");
15388 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15392 /* X is a constant integer. If it is negative, print "m",
15393 otherwise print "z". This is to make an aze or ame insn. */
15394 if (GET_CODE (x) != CONST_INT)
15395 output_operand_lossage ("invalid %%G value");
15396 else if (INTVAL (x) >= 0)
15403 /* If constant, output low-order five bits. Otherwise, write
15406 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15408 print_operand (file, x, 0);
15412 /* If constant, output low-order six bits. Otherwise, write
15415 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15417 print_operand (file, x, 0);
15421 /* Print `i' if this is a constant, else nothing. */
15427 /* Write the bit number in CCR for jump. */
15428 i = ccr_bit (x, 0);
15430 output_operand_lossage ("invalid %%j code");
15432 fprintf (file, "%d", i);
15436 /* Similar, but add one for shift count in rlinm for scc and pass
15437 scc flag to `ccr_bit'. */
15438 i = ccr_bit (x, 1);
15440 output_operand_lossage ("invalid %%J code");
15442 /* If we want bit 31, write a shift count of zero, not 32. */
15443 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15447 /* X must be a constant. Write the 1's complement of the
15450 output_operand_lossage ("invalid %%k value");
15452 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15456 /* X must be a symbolic constant on ELF. Write an
15457 expression suitable for an 'addi' that adds in the low 16
15458 bits of the MEM. */
15459 if (GET_CODE (x) == CONST)
15461 if (GET_CODE (XEXP (x, 0)) != PLUS
15462 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15463 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15464 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15465 output_operand_lossage ("invalid %%K value");
15467 print_operand_address (file, x);
15468 fputs ("@l", file);
15471 /* %l is output_asm_label. */
15474 /* Write second word of DImode or DFmode reference. Works on register
15475 or non-indexed memory only. */
15476 if (GET_CODE (x) == REG)
15477 fputs (reg_names[REGNO (x) + 1], file);
15478 else if (GET_CODE (x) == MEM)
15480 /* Handle possible auto-increment. Since it is pre-increment and
15481 we have already done it, we can just use an offset of word. */
15482 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15483 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15484 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15486 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15487 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15490 output_address (XEXP (adjust_address_nv (x, SImode,
15494 if (small_data_operand (x, GET_MODE (x)))
15495 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15496 reg_names[SMALL_DATA_REG]);
15501 /* MB value for a mask operand. */
15502 if (! mask_operand (x, SImode))
15503 output_operand_lossage ("invalid %%m value");
15505 fprintf (file, "%d", extract_MB (x));
15509 /* ME value for a mask operand. */
15510 if (! mask_operand (x, SImode))
15511 output_operand_lossage ("invalid %%M value");
15513 fprintf (file, "%d", extract_ME (x));
15516 /* %n outputs the negative of its operand. */
15519 /* Write the number of elements in the vector times 4. */
15520 if (GET_CODE (x) != PARALLEL)
15521 output_operand_lossage ("invalid %%N value");
15523 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15527 /* Similar, but subtract 1 first. */
15528 if (GET_CODE (x) != PARALLEL)
15529 output_operand_lossage ("invalid %%O value");
15531 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15535 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15537 || INT_LOWPART (x) < 0
15538 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15539 output_operand_lossage ("invalid %%p value");
15541 fprintf (file, "%d", i);
15545 /* The operand must be an indirect memory reference. The result
15546 is the register name. */
15547 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15548 || REGNO (XEXP (x, 0)) >= 32)
15549 output_operand_lossage ("invalid %%P value");
15551 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15555 /* This outputs the logical code corresponding to a boolean
15556 expression. The expression may have one or both operands
15557 negated (if one, only the first one). For condition register
15558 logical operations, it will also treat the negated
15559 CR codes as NOTs, but not handle NOTs of them. */
15561 const char *const *t = 0;
15563 enum rtx_code code = GET_CODE (x);
15564 static const char * const tbl[3][3] = {
15565 { "and", "andc", "nor" },
15566 { "or", "orc", "nand" },
15567 { "xor", "eqv", "xor" } };
15571 else if (code == IOR)
15573 else if (code == XOR)
15576 output_operand_lossage ("invalid %%q value");
15578 if (GET_CODE (XEXP (x, 0)) != NOT)
15582 if (GET_CODE (XEXP (x, 1)) == NOT)
15600 /* X is a CR register. Print the mask for `mtcrf'. */
15601 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15602 output_operand_lossage ("invalid %%R value");
15604 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15608 /* Low 5 bits of 32 - value */
15610 output_operand_lossage ("invalid %%s value");
15612 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15616 /* PowerPC64 mask position. All 0's is excluded.
15617 CONST_INT 32-bit mask is considered sign-extended so any
15618 transition must occur within the CONST_INT, not on the boundary. */
15619 if (! mask64_operand (x, DImode))
15620 output_operand_lossage ("invalid %%S value");
15622 uval = INT_LOWPART (x);
15624 if (uval & 1) /* Clear Left */
15626 #if HOST_BITS_PER_WIDE_INT > 64
15627 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15631 else /* Clear Right */
15634 #if HOST_BITS_PER_WIDE_INT > 64
15635 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15641 gcc_assert (i >= 0);
15642 fprintf (file, "%d", i);
15646 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15647 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15649 /* Bit 3 is OV bit. */
15650 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15652 /* If we want bit 31, write a shift count of zero, not 32. */
15653 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15657 /* Print the symbolic name of a branch target register. */
15658 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15659 && REGNO (x) != CTR_REGNO))
15660 output_operand_lossage ("invalid %%T value");
15661 else if (REGNO (x) == LR_REGNO)
15662 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15664 fputs ("ctr", file);
15668 /* High-order 16 bits of constant for use in unsigned operand. */
15670 output_operand_lossage ("invalid %%u value");
15672 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15673 (INT_LOWPART (x) >> 16) & 0xffff);
15677 /* High-order 16 bits of constant for use in signed operand. */
15679 output_operand_lossage ("invalid %%v value");
15681 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15682 (INT_LOWPART (x) >> 16) & 0xffff);
15686 /* Print `u' if this has an auto-increment or auto-decrement. */
15687 if (GET_CODE (x) == MEM
15688 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15689 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15690 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15695 /* Print the trap code for this operand. */
15696 switch (GET_CODE (x))
15699 fputs ("eq", file); /* 4 */
15702 fputs ("ne", file); /* 24 */
15705 fputs ("lt", file); /* 16 */
15708 fputs ("le", file); /* 20 */
15711 fputs ("gt", file); /* 8 */
15714 fputs ("ge", file); /* 12 */
15717 fputs ("llt", file); /* 2 */
15720 fputs ("lle", file); /* 6 */
15723 fputs ("lgt", file); /* 1 */
15726 fputs ("lge", file); /* 5 */
15729 gcc_unreachable ();
15734 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15737 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15738 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15740 print_operand (file, x, 0);
15744 /* MB value for a PowerPC64 rldic operand. */
15745 val = (GET_CODE (x) == CONST_INT
15746 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15751 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15752 if ((val <<= 1) < 0)
15755 #if HOST_BITS_PER_WIDE_INT == 32
15756 if (GET_CODE (x) == CONST_INT && i >= 0)
15757 i += 32; /* zero-extend high-part was all 0's */
15758 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15760 val = CONST_DOUBLE_LOW (x);
15766 for ( ; i < 64; i++)
15767 if ((val <<= 1) < 0)
15772 fprintf (file, "%d", i + 1);
15776 /* X is a FPR or Altivec register used in a VSX context. */
15777 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15778 output_operand_lossage ("invalid %%x value");
15781 int reg = REGNO (x);
15782 int vsx_reg = (FP_REGNO_P (reg)
15784 : reg - FIRST_ALTIVEC_REGNO + 32);
15786 #ifdef TARGET_REGNAMES
15787 if (TARGET_REGNAMES)
15788 fprintf (file, "%%vs%d", vsx_reg);
15791 fprintf (file, "%d", vsx_reg);
15796 if (GET_CODE (x) == MEM
15797 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15798 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15799 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15804 /* Like 'L', for third word of TImode */
15805 if (GET_CODE (x) == REG)
15806 fputs (reg_names[REGNO (x) + 2], file);
15807 else if (GET_CODE (x) == MEM)
15809 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15810 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15811 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15812 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15813 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15815 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15816 if (small_data_operand (x, GET_MODE (x)))
15817 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15818 reg_names[SMALL_DATA_REG]);
15823 /* X is a SYMBOL_REF. Write out the name preceded by a
15824 period and without any trailing data in brackets. Used for function
15825 names. If we are configured for System V (or the embedded ABI) on
15826 the PowerPC, do not emit the period, since those systems do not use
15827 TOCs and the like. */
15828 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15830 /* Mark the decl as referenced so that cgraph will output the
15832 if (SYMBOL_REF_DECL (x))
15833 mark_decl_referenced (SYMBOL_REF_DECL (x));
15835 /* For macho, check to see if we need a stub. */
15838 const char *name = XSTR (x, 0);
15840 if (darwin_emit_branch_islands
15841 && MACHOPIC_INDIRECT
15842 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15843 name = machopic_indirection_name (x, /*stub_p=*/true);
15845 assemble_name (file, name);
15847 else if (!DOT_SYMBOLS)
15848 assemble_name (file, XSTR (x, 0));
15850 rs6000_output_function_entry (file, XSTR (x, 0));
15854 /* Like 'L', for last word of TImode. */
15855 if (GET_CODE (x) == REG)
15856 fputs (reg_names[REGNO (x) + 3], file);
15857 else if (GET_CODE (x) == MEM)
15859 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15860 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15861 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15862 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15863 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15865 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15866 if (small_data_operand (x, GET_MODE (x)))
15867 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15868 reg_names[SMALL_DATA_REG]);
15872 /* Print AltiVec or SPE memory operand. */
15877 gcc_assert (GET_CODE (x) == MEM);
15881 /* Ugly hack because %y is overloaded. */
15882 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15883 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15884 || GET_MODE (x) == TFmode
15885 || GET_MODE (x) == TImode))
15887 /* Handle [reg]. */
15888 if (GET_CODE (tmp) == REG)
15890 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15893 /* Handle [reg+UIMM]. */
15894 else if (GET_CODE (tmp) == PLUS &&
15895 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15899 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15901 x = INTVAL (XEXP (tmp, 1));
15902 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15906 /* Fall through. Must be [reg+reg]. */
15908 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15909 && GET_CODE (tmp) == AND
15910 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15911 && INTVAL (XEXP (tmp, 1)) == -16)
15912 tmp = XEXP (tmp, 0);
15913 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15914 && GET_CODE (tmp) == PRE_MODIFY)
15915 tmp = XEXP (tmp, 1);
15916 if (GET_CODE (tmp) == REG)
15917 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15920 if (!GET_CODE (tmp) == PLUS
15921 || !REG_P (XEXP (tmp, 0))
15922 || !REG_P (XEXP (tmp, 1)))
15924 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15928 if (REGNO (XEXP (tmp, 0)) == 0)
15929 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15930 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15932 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15933 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15939 if (GET_CODE (x) == REG)
15940 fprintf (file, "%s", reg_names[REGNO (x)]);
15941 else if (GET_CODE (x) == MEM)
15943 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15944 know the width from the mode. */
15945 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15946 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15947 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15948 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15949 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15950 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15951 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15952 output_address (XEXP (XEXP (x, 0), 1));
15954 output_address (XEXP (x, 0));
15957 output_addr_const (file, x);
15961 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15965 output_operand_lossage ("invalid %%xn code");
15969 /* Print the address of an operand. */
15972 print_operand_address (FILE *file, rtx x)
15974 if (GET_CODE (x) == REG)
15975 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15976 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15977 || GET_CODE (x) == LABEL_REF)
15979 output_addr_const (file, x);
15980 if (small_data_operand (x, GET_MODE (x)))
15981 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15982 reg_names[SMALL_DATA_REG]);
15984 gcc_assert (!TARGET_TOC);
15986 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15988 gcc_assert (REG_P (XEXP (x, 0)));
15989 if (REGNO (XEXP (x, 0)) == 0)
15990 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15991 reg_names[ REGNO (XEXP (x, 0)) ]);
15993 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15994 reg_names[ REGNO (XEXP (x, 1)) ]);
15996 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15997 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15998 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16000 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16001 && CONSTANT_P (XEXP (x, 1)))
16003 fprintf (file, "lo16(");
16004 output_addr_const (file, XEXP (x, 1));
16005 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16008 else if (legitimate_constant_pool_address_p (x, true))
16010 /* This hack along with a corresponding hack in
16011 rs6000_output_addr_const_extra arranges to output addends
16012 where the assembler expects to find them. eg.
16014 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16015 without this hack would be output as "x@toc+8@l(9)". We
16016 want "x+8@toc@l(9)". */
16017 output_addr_const (file, tocrel_base);
16018 if (GET_CODE (x) == LO_SUM)
16019 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16021 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16024 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16025 && CONSTANT_P (XEXP (x, 1)))
16027 output_addr_const (file, XEXP (x, 1));
16028 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16032 gcc_unreachable ();
16035 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16038 rs6000_output_addr_const_extra (FILE *file, rtx x)
16040 if (GET_CODE (x) == UNSPEC)
16041 switch (XINT (x, 1))
16043 case UNSPEC_TOCREL:
16044 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16045 output_addr_const (file, XVECEXP (x, 0, 0));
16046 if (x == tocrel_base && tocrel_offset != const0_rtx)
16048 if (INTVAL (tocrel_offset) >= 0)
16049 fprintf (file, "+");
16050 output_addr_const (file, tocrel_offset);
16052 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16055 assemble_name (file, toc_label_name);
16057 else if (TARGET_ELF)
16058 fputs ("@toc", file);
16062 case UNSPEC_MACHOPIC_OFFSET:
16063 output_addr_const (file, XVECEXP (x, 0, 0));
16065 machopic_output_function_base_name (file);
16072 /* Target hook for assembling integer objects. The PowerPC version has
16073 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16074 is defined. It also needs to handle DI-mode objects on 64-bit
16078 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16080 #ifdef RELOCATABLE_NEEDS_FIXUP
16081 /* Special handling for SI values. */
16082 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16084 static int recurse = 0;
16086 /* For -mrelocatable, we mark all addresses that need to be fixed up
16087 in the .fixup section. */
16088 if (TARGET_RELOCATABLE
16089 && in_section != toc_section
16090 && in_section != text_section
16091 && !unlikely_text_section_p (in_section)
16093 && GET_CODE (x) != CONST_INT
16094 && GET_CODE (x) != CONST_DOUBLE
16100 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16102 ASM_OUTPUT_LABEL (asm_out_file, buf);
16103 fprintf (asm_out_file, "\t.long\t(");
16104 output_addr_const (asm_out_file, x);
16105 fprintf (asm_out_file, ")@fixup\n");
16106 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16107 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16108 fprintf (asm_out_file, "\t.long\t");
16109 assemble_name (asm_out_file, buf);
16110 fprintf (asm_out_file, "\n\t.previous\n");
16114 /* Remove initial .'s to turn a -mcall-aixdesc function
16115 address into the address of the descriptor, not the function
16117 else if (GET_CODE (x) == SYMBOL_REF
16118 && XSTR (x, 0)[0] == '.'
16119 && DEFAULT_ABI == ABI_AIX)
16121 const char *name = XSTR (x, 0);
16122 while (*name == '.')
16125 fprintf (asm_out_file, "\t.long\t%s\n", name);
16129 #endif /* RELOCATABLE_NEEDS_FIXUP */
16130 return default_assemble_integer (x, size, aligned_p);
16133 #ifdef HAVE_GAS_HIDDEN
16134 /* Emit an assembler directive to set symbol visibility for DECL to
16135 VISIBILITY_TYPE. */
16138 rs6000_assemble_visibility (tree decl, int vis)
16140 /* Functions need to have their entry point symbol visibility set as
16141 well as their descriptor symbol visibility. */
16142 if (DEFAULT_ABI == ABI_AIX
16144 && TREE_CODE (decl) == FUNCTION_DECL)
16146 static const char * const visibility_types[] = {
16147 NULL, "internal", "hidden", "protected"
16150 const char *name, *type;
16152 name = ((* targetm.strip_name_encoding)
16153 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16154 type = visibility_types[vis];
16156 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16157 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16160 default_assemble_visibility (decl, vis);
16165 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16167 /* Reversal of FP compares takes care -- an ordered compare
16168 becomes an unordered compare and vice versa. */
16169 if (mode == CCFPmode
16170 && (!flag_finite_math_only
16171 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16172 || code == UNEQ || code == LTGT))
16173 return reverse_condition_maybe_unordered (code);
16175 return reverse_condition (code);
16178 /* Generate a compare for CODE. Return a brand-new rtx that
16179 represents the result of the compare. */
16182 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16184 enum machine_mode comp_mode;
16185 rtx compare_result;
16186 enum rtx_code code = GET_CODE (cmp);
16187 rtx op0 = XEXP (cmp, 0);
16188 rtx op1 = XEXP (cmp, 1);
16190 if (FLOAT_MODE_P (mode))
16191 comp_mode = CCFPmode;
16192 else if (code == GTU || code == LTU
16193 || code == GEU || code == LEU)
16194 comp_mode = CCUNSmode;
16195 else if ((code == EQ || code == NE)
16196 && GET_CODE (op0) == SUBREG
16197 && GET_CODE (op1) == SUBREG
16198 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16199 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16200 /* These are unsigned values, perhaps there will be a later
16201 ordering compare that can be shared with this one.
16202 Unfortunately we cannot detect the signedness of the operands
16203 for non-subregs. */
16204 comp_mode = CCUNSmode;
16206 comp_mode = CCmode;
16208 /* First, the compare. */
16209 compare_result = gen_reg_rtx (comp_mode);
16211 /* E500 FP compare instructions on the GPRs. Yuck! */
16212 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16213 && FLOAT_MODE_P (mode))
16215 rtx cmp, or_result, compare_result2;
16216 enum machine_mode op_mode = GET_MODE (op0);
16218 if (op_mode == VOIDmode)
16219 op_mode = GET_MODE (op1);
16221 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16222 This explains the following mess. */
16226 case EQ: case UNEQ: case NE: case LTGT:
16230 cmp = (flag_finite_math_only && !flag_trapping_math)
16231 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16232 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16236 cmp = (flag_finite_math_only && !flag_trapping_math)
16237 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16238 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16242 cmp = (flag_finite_math_only && !flag_trapping_math)
16243 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16244 : gen_cmptfeq_gpr (compare_result, op0, op1);
16248 gcc_unreachable ();
16252 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16256 cmp = (flag_finite_math_only && !flag_trapping_math)
16257 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16258 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16262 cmp = (flag_finite_math_only && !flag_trapping_math)
16263 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16264 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16268 cmp = (flag_finite_math_only && !flag_trapping_math)
16269 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16270 : gen_cmptfgt_gpr (compare_result, op0, op1);
16274 gcc_unreachable ();
16278 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16282 cmp = (flag_finite_math_only && !flag_trapping_math)
16283 ? gen_tstsflt_gpr (compare_result, op0, op1)
16284 : gen_cmpsflt_gpr (compare_result, op0, op1);
16288 cmp = (flag_finite_math_only && !flag_trapping_math)
16289 ? gen_tstdflt_gpr (compare_result, op0, op1)
16290 : gen_cmpdflt_gpr (compare_result, op0, op1);
16294 cmp = (flag_finite_math_only && !flag_trapping_math)
16295 ? gen_tsttflt_gpr (compare_result, op0, op1)
16296 : gen_cmptflt_gpr (compare_result, op0, op1);
16300 gcc_unreachable ();
16304 gcc_unreachable ();
16307 /* Synthesize LE and GE from LT/GT || EQ. */
16308 if (code == LE || code == GE || code == LEU || code == GEU)
16314 case LE: code = LT; break;
16315 case GE: code = GT; break;
16316 case LEU: code = LT; break;
16317 case GEU: code = GT; break;
16318 default: gcc_unreachable ();
16321 compare_result2 = gen_reg_rtx (CCFPmode);
16327 cmp = (flag_finite_math_only && !flag_trapping_math)
16328 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16329 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16333 cmp = (flag_finite_math_only && !flag_trapping_math)
16334 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16335 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16339 cmp = (flag_finite_math_only && !flag_trapping_math)
16340 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16341 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16345 gcc_unreachable ();
16349 /* OR them together. */
16350 or_result = gen_reg_rtx (CCFPmode);
16351 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16353 compare_result = or_result;
16358 if (code == NE || code == LTGT)
16368 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16369 CLOBBERs to match cmptf_internal2 pattern. */
16370 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16371 && GET_MODE (op0) == TFmode
16372 && !TARGET_IEEEQUAD
16373 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16374 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16376 gen_rtx_SET (VOIDmode,
16378 gen_rtx_COMPARE (comp_mode, op0, op1)),
16379 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16380 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16381 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16382 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16383 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16384 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16385 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16386 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16387 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16388 else if (GET_CODE (op1) == UNSPEC
16389 && XINT (op1, 1) == UNSPEC_SP_TEST)
16391 rtx op1b = XVECEXP (op1, 0, 0);
16392 comp_mode = CCEQmode;
16393 compare_result = gen_reg_rtx (CCEQmode);
16395 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16397 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16400 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16401 gen_rtx_COMPARE (comp_mode, op0, op1)));
16404 /* Some kinds of FP comparisons need an OR operation;
16405 under flag_finite_math_only we don't bother. */
16406 if (FLOAT_MODE_P (mode)
16407 && !flag_finite_math_only
16408 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16409 && (code == LE || code == GE
16410 || code == UNEQ || code == LTGT
16411 || code == UNGT || code == UNLT))
16413 enum rtx_code or1, or2;
16414 rtx or1_rtx, or2_rtx, compare2_rtx;
16415 rtx or_result = gen_reg_rtx (CCEQmode);
16419 case LE: or1 = LT; or2 = EQ; break;
16420 case GE: or1 = GT; or2 = EQ; break;
16421 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16422 case LTGT: or1 = LT; or2 = GT; break;
16423 case UNGT: or1 = UNORDERED; or2 = GT; break;
16424 case UNLT: or1 = UNORDERED; or2 = LT; break;
16425 default: gcc_unreachable ();
16427 validate_condition_mode (or1, comp_mode);
16428 validate_condition_mode (or2, comp_mode);
16429 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16430 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16431 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16432 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16434 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16436 compare_result = or_result;
16440 validate_condition_mode (code, GET_MODE (compare_result));
16442 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16446 /* Emit the RTL for an sISEL pattern. */
16449 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16451 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16455 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16458 enum machine_mode op_mode;
16459 enum rtx_code cond_code;
16460 rtx result = operands[0];
16462 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16464 rs6000_emit_sISEL (mode, operands);
16468 condition_rtx = rs6000_generate_compare (operands[1], mode);
16469 cond_code = GET_CODE (condition_rtx);
16471 if (FLOAT_MODE_P (mode)
16472 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16476 PUT_MODE (condition_rtx, SImode);
16477 t = XEXP (condition_rtx, 0);
16479 gcc_assert (cond_code == NE || cond_code == EQ);
16481 if (cond_code == NE)
16482 emit_insn (gen_e500_flip_gt_bit (t, t));
16484 emit_insn (gen_move_from_CR_gt_bit (result, t));
16488 if (cond_code == NE
16489 || cond_code == GE || cond_code == LE
16490 || cond_code == GEU || cond_code == LEU
16491 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16493 rtx not_result = gen_reg_rtx (CCEQmode);
16494 rtx not_op, rev_cond_rtx;
16495 enum machine_mode cc_mode;
16497 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16499 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16500 SImode, XEXP (condition_rtx, 0), const0_rtx);
16501 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16502 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16503 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16506 op_mode = GET_MODE (XEXP (operands[1], 0));
16507 if (op_mode == VOIDmode)
16508 op_mode = GET_MODE (XEXP (operands[1], 1));
16510 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16512 PUT_MODE (condition_rtx, DImode);
16513 convert_move (result, condition_rtx, 0);
16517 PUT_MODE (condition_rtx, SImode);
16518 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16522 /* Emit a branch of kind CODE to location LOC. */
16525 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16527 rtx condition_rtx, loc_ref;
16529 condition_rtx = rs6000_generate_compare (operands[0], mode);
16530 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16531 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16532 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16533 loc_ref, pc_rtx)));
16536 /* Return the string to output a conditional branch to LABEL, which is
16537 the operand number of the label, or -1 if the branch is really a
16538 conditional return.
16540 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16541 condition code register and its mode specifies what kind of
16542 comparison we made.
16544 REVERSED is nonzero if we should reverse the sense of the comparison.
16546 INSN is the insn. */
16549 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16551 static char string[64];
16552 enum rtx_code code = GET_CODE (op);
16553 rtx cc_reg = XEXP (op, 0);
16554 enum machine_mode mode = GET_MODE (cc_reg);
16555 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16556 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16557 int really_reversed = reversed ^ need_longbranch;
16563 validate_condition_mode (code, mode);
16565 /* Work out which way this really branches. We could use
16566 reverse_condition_maybe_unordered here always but this
16567 makes the resulting assembler clearer. */
16568 if (really_reversed)
16570 /* Reversal of FP compares takes care -- an ordered compare
16571 becomes an unordered compare and vice versa. */
16572 if (mode == CCFPmode)
16573 code = reverse_condition_maybe_unordered (code);
16575 code = reverse_condition (code);
16578 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16580 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16585 /* Opposite of GT. */
16594 gcc_unreachable ();
16600 /* Not all of these are actually distinct opcodes, but
16601 we distinguish them for clarity of the resulting assembler. */
16602 case NE: case LTGT:
16603 ccode = "ne"; break;
16604 case EQ: case UNEQ:
16605 ccode = "eq"; break;
16607 ccode = "ge"; break;
16608 case GT: case GTU: case UNGT:
16609 ccode = "gt"; break;
16611 ccode = "le"; break;
16612 case LT: case LTU: case UNLT:
16613 ccode = "lt"; break;
16614 case UNORDERED: ccode = "un"; break;
16615 case ORDERED: ccode = "nu"; break;
16616 case UNGE: ccode = "nl"; break;
16617 case UNLE: ccode = "ng"; break;
16619 gcc_unreachable ();
16622 /* Maybe we have a guess as to how likely the branch is.
16623 The old mnemonics don't have a way to specify this information. */
16625 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16626 if (note != NULL_RTX)
16628 /* PROB is the difference from 50%. */
16629 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16631 /* Only hint for highly probable/improbable branches on newer
16632 cpus as static prediction overrides processor dynamic
16633 prediction. For older cpus we may as well always hint, but
16634 assume not taken for branches that are very close to 50% as a
16635 mispredicted taken branch is more expensive than a
16636 mispredicted not-taken branch. */
16637 if (rs6000_always_hint
16638 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16639 && br_prob_note_reliable_p (note)))
16641 if (abs (prob) > REG_BR_PROB_BASE / 20
16642 && ((prob > 0) ^ need_longbranch))
16650 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16652 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16654 /* We need to escape any '%' characters in the reg_names string.
16655 Assume they'd only be the first character.... */
16656 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16658 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16662 /* If the branch distance was too far, we may have to use an
16663 unconditional branch to go the distance. */
16664 if (need_longbranch)
16665 s += sprintf (s, ",$+8\n\tb %s", label);
16667 s += sprintf (s, ",%s", label);
16673 /* Return the string to flip the GT bit on a CR. */
16675 output_e500_flip_gt_bit (rtx dst, rtx src)
16677 static char string[64];
16680 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16681 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16684 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16685 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16687 sprintf (string, "crnot %d,%d", a, b);
16691 /* Return insn for VSX or Altivec comparisons. */
16694 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16697 enum machine_mode mode = GET_MODE (op0);
16705 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16711 mask = gen_reg_rtx (mode);
16712 emit_insn (gen_rtx_SET (VOIDmode,
16714 gen_rtx_fmt_ee (code, mode, op0, op1)));
16721 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16722 DMODE is expected destination mode. This is a recursive function. */
16725 rs6000_emit_vector_compare (enum rtx_code rcode,
16727 enum machine_mode dmode)
16730 bool swap_operands = false;
16731 bool try_again = false;
16733 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16734 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16736 /* See if the comparison works as is. */
16737 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16745 swap_operands = true;
16750 swap_operands = true;
16758 /* Invert condition and try again.
16759 e.g., A != B becomes ~(A==B). */
16761 enum rtx_code rev_code;
16762 enum insn_code nor_code;
16765 rev_code = reverse_condition_maybe_unordered (rcode);
16766 if (rev_code == UNKNOWN)
16769 nor_code = optab_handler (one_cmpl_optab, dmode);
16770 if (nor_code == CODE_FOR_nothing)
16773 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16777 mask = gen_reg_rtx (dmode);
16778 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16786 /* Try GT/GTU/LT/LTU OR EQ */
16789 enum insn_code ior_code;
16790 enum rtx_code new_code;
16811 gcc_unreachable ();
16814 ior_code = optab_handler (ior_optab, dmode);
16815 if (ior_code == CODE_FOR_nothing)
16818 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16822 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16826 mask = gen_reg_rtx (dmode);
16827 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16845 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16850 /* You only get two chances. */
16854 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16855 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16856 operands for the relation operation COND. */
16859 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16860 rtx cond, rtx cc_op0, rtx cc_op1)
16862 enum machine_mode dest_mode = GET_MODE (dest);
16863 enum rtx_code rcode = GET_CODE (cond);
16864 enum machine_mode cc_mode = CCmode;
16868 bool invert_move = false;
16870 if (VECTOR_UNIT_NONE_P (dest_mode))
16875 /* Swap operands if we can, and fall back to doing the operation as
16876 specified, and doing a NOR to invert the test. */
16882 /* Invert condition and try again.
16883 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16884 invert_move = true;
16885 rcode = reverse_condition_maybe_unordered (rcode);
16886 if (rcode == UNKNOWN)
16890 /* Mark unsigned tests with CCUNSmode. */
16895 cc_mode = CCUNSmode;
16902 /* Get the vector mask for the given relational operations. */
16903 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16911 op_true = op_false;
16915 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16916 emit_insn (gen_rtx_SET (VOIDmode,
16918 gen_rtx_IF_THEN_ELSE (dest_mode,
16925 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16926 operands of the last comparison is nonzero/true, FALSE_COND if it
16927 is zero/false. Return 0 if the hardware has no such operation. */
16930 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16932 enum rtx_code code = GET_CODE (op);
16933 rtx op0 = XEXP (op, 0);
16934 rtx op1 = XEXP (op, 1);
16935 REAL_VALUE_TYPE c1;
16936 enum machine_mode compare_mode = GET_MODE (op0);
16937 enum machine_mode result_mode = GET_MODE (dest);
16939 bool is_against_zero;
16941 /* These modes should always match. */
16942 if (GET_MODE (op1) != compare_mode
16943 /* In the isel case however, we can use a compare immediate, so
16944 op1 may be a small constant. */
16945 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16947 if (GET_MODE (true_cond) != result_mode)
16949 if (GET_MODE (false_cond) != result_mode)
16952 /* First, work out if the hardware can do this at all, or
16953 if it's too slow.... */
16954 if (!FLOAT_MODE_P (compare_mode))
16957 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16960 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16961 && SCALAR_FLOAT_MODE_P (compare_mode))
16964 is_against_zero = op1 == CONST0_RTX (compare_mode);
16966 /* A floating-point subtract might overflow, underflow, or produce
16967 an inexact result, thus changing the floating-point flags, so it
16968 can't be generated if we care about that. It's safe if one side
16969 of the construct is zero, since then no subtract will be
16971 if (SCALAR_FLOAT_MODE_P (compare_mode)
16972 && flag_trapping_math && ! is_against_zero)
16975 /* Eliminate half of the comparisons by switching operands, this
16976 makes the remaining code simpler. */
16977 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16978 || code == LTGT || code == LT || code == UNLE)
16980 code = reverse_condition_maybe_unordered (code);
16982 true_cond = false_cond;
16986 /* UNEQ and LTGT take four instructions for a comparison with zero,
16987 it'll probably be faster to use a branch here too. */
16988 if (code == UNEQ && HONOR_NANS (compare_mode))
16991 if (GET_CODE (op1) == CONST_DOUBLE)
16992 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16994 /* We're going to try to implement comparisons by performing
16995 a subtract, then comparing against zero. Unfortunately,
16996 Inf - Inf is NaN which is not zero, and so if we don't
16997 know that the operand is finite and the comparison
16998 would treat EQ different to UNORDERED, we can't do it. */
16999 if (HONOR_INFINITIES (compare_mode)
17000 && code != GT && code != UNGE
17001 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17002 /* Constructs of the form (a OP b ? a : b) are safe. */
17003 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17004 || (! rtx_equal_p (op0, true_cond)
17005 && ! rtx_equal_p (op1, true_cond))))
17008 /* At this point we know we can use fsel. */
17010 /* Reduce the comparison to a comparison against zero. */
17011 if (! is_against_zero)
17013 temp = gen_reg_rtx (compare_mode);
17014 emit_insn (gen_rtx_SET (VOIDmode, temp,
17015 gen_rtx_MINUS (compare_mode, op0, op1)));
17017 op1 = CONST0_RTX (compare_mode);
17020 /* If we don't care about NaNs we can reduce some of the comparisons
17021 down to faster ones. */
17022 if (! HONOR_NANS (compare_mode))
17028 true_cond = false_cond;
17041 /* Now, reduce everything down to a GE. */
17048 temp = gen_reg_rtx (compare_mode);
17049 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17054 temp = gen_reg_rtx (compare_mode);
17055 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17060 temp = gen_reg_rtx (compare_mode);
17061 emit_insn (gen_rtx_SET (VOIDmode, temp,
17062 gen_rtx_NEG (compare_mode,
17063 gen_rtx_ABS (compare_mode, op0))));
17068 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17069 temp = gen_reg_rtx (result_mode);
17070 emit_insn (gen_rtx_SET (VOIDmode, temp,
17071 gen_rtx_IF_THEN_ELSE (result_mode,
17072 gen_rtx_GE (VOIDmode,
17074 true_cond, false_cond)));
17075 false_cond = true_cond;
17078 temp = gen_reg_rtx (compare_mode);
17079 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17084 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17085 temp = gen_reg_rtx (result_mode);
17086 emit_insn (gen_rtx_SET (VOIDmode, temp,
17087 gen_rtx_IF_THEN_ELSE (result_mode,
17088 gen_rtx_GE (VOIDmode,
17090 true_cond, false_cond)));
17091 true_cond = false_cond;
17094 temp = gen_reg_rtx (compare_mode);
17095 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17100 gcc_unreachable ();
17103 emit_insn (gen_rtx_SET (VOIDmode, dest,
17104 gen_rtx_IF_THEN_ELSE (result_mode,
17105 gen_rtx_GE (VOIDmode,
17107 true_cond, false_cond)));
17111 /* Same as above, but for ints (isel). */
17114 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17116 rtx condition_rtx, cr;
17117 enum machine_mode mode = GET_MODE (dest);
17118 enum rtx_code cond_code;
17119 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17122 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17125 /* We still have to do the compare, because isel doesn't do a
17126 compare, it just looks at the CRx bits set by a previous compare
17128 condition_rtx = rs6000_generate_compare (op, mode);
17129 cond_code = GET_CODE (condition_rtx);
17130 cr = XEXP (condition_rtx, 0);
17131 signedp = GET_MODE (cr) == CCmode;
17133 isel_func = (mode == SImode
17134 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17135 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17139 case LT: case GT: case LTU: case GTU: case EQ:
17140 /* isel handles these directly. */
17144 /* We need to swap the sense of the comparison. */
17147 true_cond = false_cond;
17149 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17154 false_cond = force_reg (mode, false_cond);
17155 if (true_cond != const0_rtx)
17156 true_cond = force_reg (mode, true_cond);
17158 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17164 output_isel (rtx *operands)
17166 enum rtx_code code;
17168 code = GET_CODE (operands[1]);
17170 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17172 gcc_assert (GET_CODE (operands[2]) == REG
17173 && GET_CODE (operands[3]) == REG);
17174 PUT_CODE (operands[1], reverse_condition (code));
17175 return "isel %0,%3,%2,%j1";
17178 return "isel %0,%2,%3,%j1";
17182 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17184 enum machine_mode mode = GET_MODE (op0);
17188 /* VSX/altivec have direct min/max insns. */
17189 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
17191 emit_insn (gen_rtx_SET (VOIDmode,
17193 gen_rtx_fmt_ee (code, mode, op0, op1)));
17197 if (code == SMAX || code == SMIN)
17202 if (code == SMAX || code == UMAX)
17203 target = emit_conditional_move (dest, c, op0, op1, mode,
17204 op0, op1, mode, 0);
17206 target = emit_conditional_move (dest, c, op0, op1, mode,
17207 op1, op0, mode, 0);
17208 gcc_assert (target);
17209 if (target != dest)
17210 emit_move_insn (dest, target);
17213 /* Emit instructions to perform a load-reserved/store-conditional operation.
17214 The operation performed is an atomic
17215 (set M (CODE:MODE M OP))
17216 If not NULL, BEFORE is atomically set to M before the operation, and
17217 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17218 If SYNC_P then a memory barrier is emitted before the operation.
17219 Either OP or M may be wrapped in a NOT operation. */
17222 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17223 rtx m, rtx op, rtx before_param, rtx after_param,
17226 enum machine_mode used_mode;
17227 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17230 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17231 rtx shift = NULL_RTX;
17234 emit_insn (gen_lwsync ());
17238 /* If this is smaller than SImode, we'll have to use SImode with
17240 if (mode == QImode || mode == HImode)
17244 if (MEM_ALIGN (used_m) >= 32)
17247 if (BYTES_BIG_ENDIAN)
17248 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17250 shift = GEN_INT (ishift);
17251 used_m = change_address (used_m, SImode, 0);
17255 rtx addrSI, aligned_addr;
17256 int shift_mask = mode == QImode ? 0x18 : 0x10;
17258 addrSI = gen_lowpart_common (SImode,
17259 force_reg (Pmode, XEXP (used_m, 0)));
17260 addrSI = force_reg (SImode, addrSI);
17261 shift = gen_reg_rtx (SImode);
17263 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17264 GEN_INT (shift_mask)));
17265 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17267 aligned_addr = expand_binop (Pmode, and_optab,
17269 GEN_INT (-4), NULL_RTX,
17270 1, OPTAB_LIB_WIDEN);
17271 used_m = change_address (used_m, SImode, aligned_addr);
17272 set_mem_align (used_m, 32);
17274 /* It's safe to keep the old alias set of USED_M, because
17275 the operation is atomic and only affects the original
17279 if (GET_CODE (op) == NOT)
17281 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17282 oldop = gen_rtx_NOT (SImode, oldop);
17285 oldop = lowpart_subreg (SImode, op, mode);
17291 newop = expand_binop (SImode, and_optab,
17292 oldop, GEN_INT (imask), NULL_RTX,
17293 1, OPTAB_LIB_WIDEN);
17294 emit_insn (gen_ashlsi3 (newop, newop, shift));
17297 case NOT: /* NAND */
17298 newop = expand_binop (SImode, ior_optab,
17299 oldop, GEN_INT (~imask), NULL_RTX,
17300 1, OPTAB_LIB_WIDEN);
17301 emit_insn (gen_rotlsi3 (newop, newop, shift));
17305 newop = expand_binop (SImode, ior_optab,
17306 oldop, GEN_INT (~imask), NULL_RTX,
17307 1, OPTAB_LIB_WIDEN);
17308 emit_insn (gen_rotlsi3 (newop, newop, shift));
17316 newop = expand_binop (SImode, and_optab,
17317 oldop, GEN_INT (imask), NULL_RTX,
17318 1, OPTAB_LIB_WIDEN);
17319 emit_insn (gen_ashlsi3 (newop, newop, shift));
17321 mask = gen_reg_rtx (SImode);
17322 emit_move_insn (mask, GEN_INT (imask));
17323 emit_insn (gen_ashlsi3 (mask, mask, shift));
17326 newop = gen_rtx_PLUS (SImode, m, newop);
17328 newop = gen_rtx_MINUS (SImode, m, newop);
17329 newop = gen_rtx_AND (SImode, newop, mask);
17330 newop = gen_rtx_IOR (SImode, newop,
17331 gen_rtx_AND (SImode,
17332 gen_rtx_NOT (SImode, mask),
17338 gcc_unreachable ();
17342 used_mode = SImode;
17343 before = gen_reg_rtx (used_mode);
17344 after = gen_reg_rtx (used_mode);
17349 before = before_param;
17350 after = after_param;
17352 if (before == NULL_RTX)
17353 before = gen_reg_rtx (used_mode);
17354 if (after == NULL_RTX)
17355 after = gen_reg_rtx (used_mode);
17358 if ((code == PLUS || code == MINUS)
17359 && used_mode != mode)
17360 the_op = op; /* Computed above. */
17361 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17362 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17363 else if (code == NOT)
17364 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17365 gen_rtx_NOT (used_mode, m),
17366 gen_rtx_NOT (used_mode, op));
17368 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17370 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17371 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17372 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17373 gen_rtx_UNSPEC (used_mode,
17374 gen_rtvec (1, the_op),
17376 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17378 if ((code == PLUS || code == MINUS) && used_mode != mode)
17379 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17380 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17382 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17383 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17385 /* Shift and mask the return values properly. */
17386 if (used_mode != mode && before_param)
17388 emit_insn (gen_lshrsi3 (before, before, shift));
17389 convert_move (before_param, before, 1);
17392 if (used_mode != mode && after_param)
17394 emit_insn (gen_lshrsi3 (after, after, shift));
17395 convert_move (after_param, after, 1);
17398 /* The previous sequence will end with a branch that's dependent on
17399 the conditional store, so placing an isync will ensure that no
17400 other instructions (especially, no load or store instructions)
17401 can start before the atomic operation completes. */
17403 emit_insn (gen_isync ());
17406 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17407 COND is true. Mark the jump as unlikely to be taken. */
17410 emit_unlikely_jump (rtx cond, rtx label)
17412 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17415 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17416 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17417 add_reg_note (x, REG_BR_PROB, very_unlikely);
17420 /* A subroutine of the atomic operation splitters. Emit a load-locked
17421 instruction in MODE. */
17424 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17426 rtx (*fn) (rtx, rtx) = NULL;
17427 if (mode == SImode)
17428 fn = gen_load_locked_si;
17429 else if (mode == DImode)
17430 fn = gen_load_locked_di;
17431 emit_insn (fn (reg, mem));
17434 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17435 instruction in MODE. */
17438 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17440 rtx (*fn) (rtx, rtx, rtx) = NULL;
17441 if (mode == SImode)
17442 fn = gen_store_conditional_si;
17443 else if (mode == DImode)
17444 fn = gen_store_conditional_di;
17446 /* Emit sync before stwcx. to address PPC405 Erratum. */
17447 if (PPC405_ERRATUM77)
17448 emit_insn (gen_memory_barrier ());
17450 emit_insn (fn (res, mem, val));
17453 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17454 to perform. MEM is the memory on which to operate. VAL is the second
17455 operand of the binary operator. BEFORE and AFTER are optional locations to
17456 return the value of MEM either before of after the operation. SCRATCH is
17457 a scratch register. */
17460 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17461 rtx before, rtx after, rtx scratch)
17463 enum machine_mode mode = GET_MODE (mem);
17464 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17466 emit_insn (gen_lwsync ());
17468 label = gen_label_rtx ();
17469 emit_label (label);
17470 label = gen_rtx_LABEL_REF (VOIDmode, label);
17472 if (before == NULL_RTX)
17474 emit_load_locked (mode, before, mem);
17477 x = gen_rtx_IOR (mode,
17478 gen_rtx_NOT (mode, before),
17479 gen_rtx_NOT (mode, val));
17480 else if (code == AND)
17481 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17483 x = gen_rtx_fmt_ee (code, mode, before, val);
17485 if (after != NULL_RTX)
17486 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17487 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17489 emit_store_conditional (mode, cond, mem, scratch);
17491 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17492 emit_unlikely_jump (x, label);
17494 emit_insn (gen_isync ());
17497 /* Expand an atomic compare and swap operation. MEM is the memory on which
17498 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17499 value to be stored. SCRATCH is a scratch GPR. */
17502 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17505 enum machine_mode mode = GET_MODE (mem);
17506 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17508 emit_insn (gen_lwsync ());
17510 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17511 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17512 emit_label (XEXP (label1, 0));
17514 emit_load_locked (mode, retval, mem);
17516 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17517 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17519 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17520 emit_unlikely_jump (x, label2);
17522 emit_move_insn (scratch, newval);
17523 emit_store_conditional (mode, cond, mem, scratch);
17525 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17526 emit_unlikely_jump (x, label1);
17528 emit_insn (gen_isync ());
17529 emit_label (XEXP (label2, 0));
17532 /* Expand an atomic test and set operation. MEM is the memory on which
17533 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17536 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17538 enum machine_mode mode = GET_MODE (mem);
17539 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17541 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17542 emit_label (XEXP (label, 0));
17544 emit_load_locked (mode, retval, mem);
17545 emit_move_insn (scratch, val);
17546 emit_store_conditional (mode, cond, mem, scratch);
17548 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17549 emit_unlikely_jump (x, label);
17551 emit_insn (gen_isync ());
17555 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17557 enum machine_mode mode = GET_MODE (mem);
17558 rtx addrSI, align, wdst, shift, mask;
17559 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17560 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17562 /* Shift amount for subword relative to aligned word. */
17563 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17564 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17565 shift = gen_reg_rtx (SImode);
17566 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17567 GEN_INT (shift_mask)));
17568 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17570 /* Shift and mask old value into position within word. */
17571 oldval = convert_modes (SImode, mode, oldval, 1);
17572 oldval = expand_binop (SImode, and_optab,
17573 oldval, GEN_INT (imask), NULL_RTX,
17574 1, OPTAB_LIB_WIDEN);
17575 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17577 /* Shift and mask new value into position within word. */
17578 newval = convert_modes (SImode, mode, newval, 1);
17579 newval = expand_binop (SImode, and_optab,
17580 newval, GEN_INT (imask), NULL_RTX,
17581 1, OPTAB_LIB_WIDEN);
17582 emit_insn (gen_ashlsi3 (newval, newval, shift));
17584 /* Mask for insertion. */
17585 mask = gen_reg_rtx (SImode);
17586 emit_move_insn (mask, GEN_INT (imask));
17587 emit_insn (gen_ashlsi3 (mask, mask, shift));
17589 /* Address of aligned word containing subword. */
17590 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17591 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17592 mem = change_address (mem, SImode, align);
17593 set_mem_align (mem, 32);
17594 MEM_VOLATILE_P (mem) = 1;
17596 wdst = gen_reg_rtx (SImode);
17597 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17598 oldval, newval, mem));
17600 /* Shift the result back. */
17601 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17603 emit_move_insn (dst, gen_lowpart (mode, wdst));
17607 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17608 rtx oldval, rtx newval, rtx mem,
17611 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17613 emit_insn (gen_lwsync ());
17614 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17615 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17616 emit_label (XEXP (label1, 0));
17618 emit_load_locked (SImode, scratch, mem);
17620 /* Mask subword within loaded value for comparison with oldval.
17621 Use UNSPEC_AND to avoid clobber.*/
17622 emit_insn (gen_rtx_SET (SImode, dest,
17623 gen_rtx_UNSPEC (SImode,
17624 gen_rtvec (2, scratch, mask),
17627 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17628 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17630 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17631 emit_unlikely_jump (x, label2);
17633 /* Clear subword within loaded value for insertion of new value. */
17634 emit_insn (gen_rtx_SET (SImode, scratch,
17635 gen_rtx_AND (SImode,
17636 gen_rtx_NOT (SImode, mask), scratch)));
17637 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17638 emit_store_conditional (SImode, cond, mem, scratch);
17640 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17641 emit_unlikely_jump (x, label1);
17643 emit_insn (gen_isync ());
17644 emit_label (XEXP (label2, 0));
17648 /* Emit instructions to move SRC to DST. Called by splitters for
17649 multi-register moves. It will emit at most one instruction for
17650 each register that is accessed; that is, it won't emit li/lis pairs
17651 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17655 rs6000_split_multireg_move (rtx dst, rtx src)
17657 /* The register number of the first register being moved. */
17659 /* The mode that is to be moved. */
17660 enum machine_mode mode;
17661 /* The mode that the move is being done in, and its size. */
17662 enum machine_mode reg_mode;
17664 /* The number of registers that will be moved. */
17667 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17668 mode = GET_MODE (dst);
17669 nregs = hard_regno_nregs[reg][mode];
17670 if (FP_REGNO_P (reg))
17671 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17672 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17673 else if (ALTIVEC_REGNO_P (reg))
17674 reg_mode = V16QImode;
17675 else if (TARGET_E500_DOUBLE && mode == TFmode)
17678 reg_mode = word_mode;
17679 reg_mode_size = GET_MODE_SIZE (reg_mode);
17681 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17683 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17685 /* Move register range backwards, if we might have destructive
17688 for (i = nregs - 1; i >= 0; i--)
17689 emit_insn (gen_rtx_SET (VOIDmode,
17690 simplify_gen_subreg (reg_mode, dst, mode,
17691 i * reg_mode_size),
17692 simplify_gen_subreg (reg_mode, src, mode,
17693 i * reg_mode_size)));
17699 bool used_update = false;
17700 rtx restore_basereg = NULL_RTX;
17702 if (MEM_P (src) && INT_REGNO_P (reg))
17706 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17707 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17710 breg = XEXP (XEXP (src, 0), 0);
17711 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17712 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17713 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17714 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17715 src = replace_equiv_address (src, breg);
17717 else if (! rs6000_offsettable_memref_p (src))
17719 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17721 rtx basereg = XEXP (XEXP (src, 0), 0);
17724 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17725 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17726 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17727 used_update = true;
17730 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17731 XEXP (XEXP (src, 0), 1)));
17732 src = replace_equiv_address (src, basereg);
17736 rtx basereg = gen_rtx_REG (Pmode, reg);
17737 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17738 src = replace_equiv_address (src, basereg);
17742 breg = XEXP (src, 0);
17743 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17744 breg = XEXP (breg, 0);
17746 /* If the base register we are using to address memory is
17747 also a destination reg, then change that register last. */
17749 && REGNO (breg) >= REGNO (dst)
17750 && REGNO (breg) < REGNO (dst) + nregs)
17751 j = REGNO (breg) - REGNO (dst);
17753 else if (MEM_P (dst) && INT_REGNO_P (reg))
17757 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17758 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17761 breg = XEXP (XEXP (dst, 0), 0);
17762 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17763 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17764 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17766 /* We have to update the breg before doing the store.
17767 Use store with update, if available. */
17771 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17772 emit_insn (TARGET_32BIT
17773 ? (TARGET_POWERPC64
17774 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17775 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17776 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17777 used_update = true;
17780 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17781 dst = replace_equiv_address (dst, breg);
17783 else if (!rs6000_offsettable_memref_p (dst)
17784 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17786 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17788 rtx basereg = XEXP (XEXP (dst, 0), 0);
17791 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17792 emit_insn (gen_rtx_SET (VOIDmode,
17793 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17794 used_update = true;
17797 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17798 XEXP (XEXP (dst, 0), 1)));
17799 dst = replace_equiv_address (dst, basereg);
17803 rtx basereg = XEXP (XEXP (dst, 0), 0);
17804 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17805 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17807 && REG_P (offsetreg)
17808 && REGNO (basereg) != REGNO (offsetreg));
17809 if (REGNO (basereg) == 0)
17811 rtx tmp = offsetreg;
17812 offsetreg = basereg;
17815 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17816 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17817 dst = replace_equiv_address (dst, basereg);
17820 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17821 gcc_assert (rs6000_offsettable_memref_p (dst));
17824 for (i = 0; i < nregs; i++)
17826 /* Calculate index to next subword. */
17831 /* If compiler already emitted move of first word by
17832 store with update, no need to do anything. */
17833 if (j == 0 && used_update)
17836 emit_insn (gen_rtx_SET (VOIDmode,
17837 simplify_gen_subreg (reg_mode, dst, mode,
17838 j * reg_mode_size),
17839 simplify_gen_subreg (reg_mode, src, mode,
17840 j * reg_mode_size)));
17842 if (restore_basereg != NULL_RTX)
17843 emit_insn (restore_basereg);
17848 /* This page contains routines that are used to determine what the
17849 function prologue and epilogue code will do and write them out. */
17851 /* Return the first fixed-point register that is required to be
17852 saved. 32 if none. */
17855 first_reg_to_save (void)
17859 /* Find lowest numbered live register. */
17860 for (first_reg = 13; first_reg <= 31; first_reg++)
17861 if (df_regs_ever_live_p (first_reg)
17862 && (! call_used_regs[first_reg]
17863 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17864 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17865 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17866 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17871 && crtl->uses_pic_offset_table
17872 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17873 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17879 /* Similar, for FP regs. */
17882 first_fp_reg_to_save (void)
17886 /* Find lowest numbered live register. */
17887 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17888 if (df_regs_ever_live_p (first_reg))
17894 /* Similar, for AltiVec regs. */
17897 first_altivec_reg_to_save (void)
17901 /* Stack frame remains as is unless we are in AltiVec ABI. */
17902 if (! TARGET_ALTIVEC_ABI)
17903 return LAST_ALTIVEC_REGNO + 1;
17905 /* On Darwin, the unwind routines are compiled without
17906 TARGET_ALTIVEC, and use save_world to save/restore the
17907 altivec registers when necessary. */
17908 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17909 && ! TARGET_ALTIVEC)
17910 return FIRST_ALTIVEC_REGNO + 20;
17912 /* Find lowest numbered live register. */
17913 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17914 if (df_regs_ever_live_p (i))
17920 /* Return a 32-bit mask of the AltiVec registers we need to set in
17921 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17922 the 32-bit word is 0. */
17924 static unsigned int
17925 compute_vrsave_mask (void)
17927 unsigned int i, mask = 0;
17929 /* On Darwin, the unwind routines are compiled without
17930 TARGET_ALTIVEC, and use save_world to save/restore the
17931 call-saved altivec registers when necessary. */
17932 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17933 && ! TARGET_ALTIVEC)
17936 /* First, find out if we use _any_ altivec registers. */
17937 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17938 if (df_regs_ever_live_p (i))
17939 mask |= ALTIVEC_REG_BIT (i);
17944 /* Next, remove the argument registers from the set. These must
17945 be in the VRSAVE mask set by the caller, so we don't need to add
17946 them in again. More importantly, the mask we compute here is
17947 used to generate CLOBBERs in the set_vrsave insn, and we do not
17948 wish the argument registers to die. */
17949 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17950 mask &= ~ALTIVEC_REG_BIT (i);
17952 /* Similarly, remove the return value from the set. */
17955 diddle_return_value (is_altivec_return_reg, &yes);
17957 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17963 /* For a very restricted set of circumstances, we can cut down the
17964 size of prologues/epilogues by calling our own save/restore-the-world
17968 compute_save_world_info (rs6000_stack_t *info_ptr)
17970 info_ptr->world_save_p = 1;
17971 info_ptr->world_save_p
17972 = (WORLD_SAVE_P (info_ptr)
17973 && DEFAULT_ABI == ABI_DARWIN
17974 && ! (cfun->calls_setjmp && flag_exceptions)
17975 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17976 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17977 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17978 && info_ptr->cr_save_p);
17980 /* This will not work in conjunction with sibcalls. Make sure there
17981 are none. (This check is expensive, but seldom executed.) */
17982 if (WORLD_SAVE_P (info_ptr))
17985 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17986 if ( GET_CODE (insn) == CALL_INSN
17987 && SIBLING_CALL_P (insn))
17989 info_ptr->world_save_p = 0;
17994 if (WORLD_SAVE_P (info_ptr))
17996 /* Even if we're not touching VRsave, make sure there's room on the
17997 stack for it, if it looks like we're calling SAVE_WORLD, which
17998 will attempt to save it. */
17999 info_ptr->vrsave_size = 4;
18001 /* If we are going to save the world, we need to save the link register too. */
18002 info_ptr->lr_save_p = 1;
18004 /* "Save" the VRsave register too if we're saving the world. */
18005 if (info_ptr->vrsave_mask == 0)
18006 info_ptr->vrsave_mask = compute_vrsave_mask ();
18008 /* Because the Darwin register save/restore routines only handle
18009 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18011 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18012 && (info_ptr->first_altivec_reg_save
18013 >= FIRST_SAVED_ALTIVEC_REGNO));
18020 is_altivec_return_reg (rtx reg, void *xyes)
18022 bool *yes = (bool *) xyes;
18023 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18028 /* Calculate the stack information for the current function. This is
18029 complicated by having two separate calling sequences, the AIX calling
18030 sequence and the V.4 calling sequence.
18032 AIX (and Darwin/Mac OS X) stack frames look like:
18034 SP----> +---------------------------------------+
18035 | back chain to caller | 0 0
18036 +---------------------------------------+
18037 | saved CR | 4 8 (8-11)
18038 +---------------------------------------+
18040 +---------------------------------------+
18041 | reserved for compilers | 12 24
18042 +---------------------------------------+
18043 | reserved for binders | 16 32
18044 +---------------------------------------+
18045 | saved TOC pointer | 20 40
18046 +---------------------------------------+
18047 | Parameter save area (P) | 24 48
18048 +---------------------------------------+
18049 | Alloca space (A) | 24+P etc.
18050 +---------------------------------------+
18051 | Local variable space (L) | 24+P+A
18052 +---------------------------------------+
18053 | Float/int conversion temporary (X) | 24+P+A+L
18054 +---------------------------------------+
18055 | Save area for AltiVec registers (W) | 24+P+A+L+X
18056 +---------------------------------------+
18057 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18058 +---------------------------------------+
18059 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18060 +---------------------------------------+
18061 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18062 +---------------------------------------+
18063 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18064 +---------------------------------------+
18065 old SP->| back chain to caller's caller |
18066 +---------------------------------------+
18068 The required alignment for AIX configurations is two words (i.e., 8
18072 V.4 stack frames look like:
18074 SP----> +---------------------------------------+
18075 | back chain to caller | 0
18076 +---------------------------------------+
18077 | caller's saved LR | 4
18078 +---------------------------------------+
18079 | Parameter save area (P) | 8
18080 +---------------------------------------+
18081 | Alloca space (A) | 8+P
18082 +---------------------------------------+
18083 | Varargs save area (V) | 8+P+A
18084 +---------------------------------------+
18085 | Local variable space (L) | 8+P+A+V
18086 +---------------------------------------+
18087 | Float/int conversion temporary (X) | 8+P+A+V+L
18088 +---------------------------------------+
18089 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18090 +---------------------------------------+
18091 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18092 +---------------------------------------+
18093 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18094 +---------------------------------------+
18095 | SPE: area for 64-bit GP registers |
18096 +---------------------------------------+
18097 | SPE alignment padding |
18098 +---------------------------------------+
18099 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18100 +---------------------------------------+
18101 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18102 +---------------------------------------+
18103 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18104 +---------------------------------------+
18105 old SP->| back chain to caller's caller |
18106 +---------------------------------------+
18108 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18109 given. (But note below and in sysv4.h that we require only 8 and
18110 may round up the size of our stack frame anyways. The historical
18111 reason is early versions of powerpc-linux which didn't properly
18112 align the stack at program startup. A happy side-effect is that
18113 -mno-eabi libraries can be used with -meabi programs.)
18115 The EABI configuration defaults to the V.4 layout. However,
18116 the stack alignment requirements may differ. If -mno-eabi is not
18117 given, the required stack alignment is 8 bytes; if -mno-eabi is
18118 given, the required alignment is 16 bytes. (But see V.4 comment
18121 #ifndef ABI_STACK_BOUNDARY
18122 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18125 static rs6000_stack_t *
18126 rs6000_stack_info (void)
18128 static rs6000_stack_t info;
18129 rs6000_stack_t *info_ptr = &info;
18130 int reg_size = TARGET_32BIT ? 4 : 8;
18134 HOST_WIDE_INT non_fixed_size;
18136 memset (&info, 0, sizeof (info));
18140 /* Cache value so we don't rescan instruction chain over and over. */
18141 if (cfun->machine->insn_chain_scanned_p == 0)
18142 cfun->machine->insn_chain_scanned_p
18143 = spe_func_has_64bit_regs_p () + 1;
18144 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18147 /* Select which calling sequence. */
18148 info_ptr->abi = DEFAULT_ABI;
18150 /* Calculate which registers need to be saved & save area size. */
18151 info_ptr->first_gp_reg_save = first_reg_to_save ();
18152 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18153 even if it currently looks like we won't. Reload may need it to
18154 get at a constant; if so, it will have already created a constant
18155 pool entry for it. */
18156 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18157 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18158 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18159 && crtl->uses_const_pool
18160 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18161 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18163 first_gp = info_ptr->first_gp_reg_save;
18165 info_ptr->gp_size = reg_size * (32 - first_gp);
18167 /* For the SPE, we have an additional upper 32-bits on each GPR.
18168 Ideally we should save the entire 64-bits only when the upper
18169 half is used in SIMD instructions. Since we only record
18170 registers live (not the size they are used in), this proves
18171 difficult because we'd have to traverse the instruction chain at
18172 the right time, taking reload into account. This is a real pain,
18173 so we opt to save the GPRs in 64-bits always if but one register
18174 gets used in 64-bits. Otherwise, all the registers in the frame
18175 get saved in 32-bits.
18177 So... since when we save all GPRs (except the SP) in 64-bits, the
18178 traditional GP save area will be empty. */
18179 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18180 info_ptr->gp_size = 0;
18182 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18183 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18185 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18186 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18187 - info_ptr->first_altivec_reg_save);
18189 /* Does this function call anything? */
18190 info_ptr->calls_p = (! current_function_is_leaf
18191 || cfun->machine->ra_needs_full_frame);
18193 /* Determine if we need to save the link register. */
18194 if ((DEFAULT_ABI == ABI_AIX
18196 && !TARGET_PROFILE_KERNEL)
18197 #ifdef TARGET_RELOCATABLE
18198 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18200 || (info_ptr->first_fp_reg_save != 64
18201 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
18202 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18203 || info_ptr->calls_p
18204 || rs6000_ra_ever_killed ())
18206 info_ptr->lr_save_p = 1;
18207 df_set_regs_ever_live (LR_REGNO, true);
18210 /* Determine if we need to save the condition code registers. */
18211 if (df_regs_ever_live_p (CR2_REGNO)
18212 || df_regs_ever_live_p (CR3_REGNO)
18213 || df_regs_ever_live_p (CR4_REGNO))
18215 info_ptr->cr_save_p = 1;
18216 if (DEFAULT_ABI == ABI_V4)
18217 info_ptr->cr_size = reg_size;
18220 /* If the current function calls __builtin_eh_return, then we need
18221 to allocate stack space for registers that will hold data for
18222 the exception handler. */
18223 if (crtl->calls_eh_return)
18226 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18229 /* SPE saves EH registers in 64-bits. */
18230 ehrd_size = i * (TARGET_SPE_ABI
18231 && info_ptr->spe_64bit_regs_used != 0
18232 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18237 /* Determine various sizes. */
18238 info_ptr->reg_size = reg_size;
18239 info_ptr->fixed_size = RS6000_SAVE_AREA;
18240 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18241 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18242 TARGET_ALTIVEC ? 16 : 8);
18243 if (FRAME_GROWS_DOWNWARD)
18244 info_ptr->vars_size
18245 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18246 + info_ptr->parm_size,
18247 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18248 - (info_ptr->fixed_size + info_ptr->vars_size
18249 + info_ptr->parm_size);
18251 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18252 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18254 info_ptr->spe_gp_size = 0;
18256 if (TARGET_ALTIVEC_ABI)
18257 info_ptr->vrsave_mask = compute_vrsave_mask ();
18259 info_ptr->vrsave_mask = 0;
18261 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18262 info_ptr->vrsave_size = 4;
18264 info_ptr->vrsave_size = 0;
18266 compute_save_world_info (info_ptr);
18268 /* Calculate the offsets. */
18269 switch (DEFAULT_ABI)
18273 gcc_unreachable ();
18277 info_ptr->fp_save_offset = - info_ptr->fp_size;
18278 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18280 if (TARGET_ALTIVEC_ABI)
18282 info_ptr->vrsave_save_offset
18283 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18285 /* Align stack so vector save area is on a quadword boundary.
18286 The padding goes above the vectors. */
18287 if (info_ptr->altivec_size != 0)
18288 info_ptr->altivec_padding_size
18289 = info_ptr->vrsave_save_offset & 0xF;
18291 info_ptr->altivec_padding_size = 0;
18293 info_ptr->altivec_save_offset
18294 = info_ptr->vrsave_save_offset
18295 - info_ptr->altivec_padding_size
18296 - info_ptr->altivec_size;
18297 gcc_assert (info_ptr->altivec_size == 0
18298 || info_ptr->altivec_save_offset % 16 == 0);
18300 /* Adjust for AltiVec case. */
18301 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18304 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18305 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18306 info_ptr->lr_save_offset = 2*reg_size;
18310 info_ptr->fp_save_offset = - info_ptr->fp_size;
18311 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18312 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18314 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18316 /* Align stack so SPE GPR save area is aligned on a
18317 double-word boundary. */
18318 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18319 info_ptr->spe_padding_size
18320 = 8 - (-info_ptr->cr_save_offset % 8);
18322 info_ptr->spe_padding_size = 0;
18324 info_ptr->spe_gp_save_offset
18325 = info_ptr->cr_save_offset
18326 - info_ptr->spe_padding_size
18327 - info_ptr->spe_gp_size;
18329 /* Adjust for SPE case. */
18330 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18332 else if (TARGET_ALTIVEC_ABI)
18334 info_ptr->vrsave_save_offset
18335 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18337 /* Align stack so vector save area is on a quadword boundary. */
18338 if (info_ptr->altivec_size != 0)
18339 info_ptr->altivec_padding_size
18340 = 16 - (-info_ptr->vrsave_save_offset % 16);
18342 info_ptr->altivec_padding_size = 0;
18344 info_ptr->altivec_save_offset
18345 = info_ptr->vrsave_save_offset
18346 - info_ptr->altivec_padding_size
18347 - info_ptr->altivec_size;
18349 /* Adjust for AltiVec case. */
18350 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18353 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18354 info_ptr->ehrd_offset -= ehrd_size;
18355 info_ptr->lr_save_offset = reg_size;
18359 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18360 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18361 + info_ptr->gp_size
18362 + info_ptr->altivec_size
18363 + info_ptr->altivec_padding_size
18364 + info_ptr->spe_gp_size
18365 + info_ptr->spe_padding_size
18367 + info_ptr->cr_size
18368 + info_ptr->vrsave_size,
18371 non_fixed_size = (info_ptr->vars_size
18372 + info_ptr->parm_size
18373 + info_ptr->save_size);
18375 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18376 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18378 /* Determine if we need to allocate any stack frame:
18380 For AIX we need to push the stack if a frame pointer is needed
18381 (because the stack might be dynamically adjusted), if we are
18382 debugging, if we make calls, or if the sum of fp_save, gp_save,
18383 and local variables are more than the space needed to save all
18384 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18385 + 18*8 = 288 (GPR13 reserved).
18387 For V.4 we don't have the stack cushion that AIX uses, but assume
18388 that the debugger can handle stackless frames. */
18390 if (info_ptr->calls_p)
18391 info_ptr->push_p = 1;
18393 else if (DEFAULT_ABI == ABI_V4)
18394 info_ptr->push_p = non_fixed_size != 0;
18396 else if (frame_pointer_needed)
18397 info_ptr->push_p = 1;
18399 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18400 info_ptr->push_p = 1;
18403 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18405 /* Zero offsets if we're not saving those registers. */
18406 if (info_ptr->fp_size == 0)
18407 info_ptr->fp_save_offset = 0;
18409 if (info_ptr->gp_size == 0)
18410 info_ptr->gp_save_offset = 0;
18412 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18413 info_ptr->altivec_save_offset = 0;
18415 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18416 info_ptr->vrsave_save_offset = 0;
18418 if (! TARGET_SPE_ABI
18419 || info_ptr->spe_64bit_regs_used == 0
18420 || info_ptr->spe_gp_size == 0)
18421 info_ptr->spe_gp_save_offset = 0;
18423 if (! info_ptr->lr_save_p)
18424 info_ptr->lr_save_offset = 0;
18426 if (! info_ptr->cr_save_p)
18427 info_ptr->cr_save_offset = 0;
18432 /* Return true if the current function uses any GPRs in 64-bit SIMD
18436 spe_func_has_64bit_regs_p (void)
18440 /* Functions that save and restore all the call-saved registers will
18441 need to save/restore the registers in 64-bits. */
18442 if (crtl->calls_eh_return
18443 || cfun->calls_setjmp
18444 || crtl->has_nonlocal_goto)
18447 insns = get_insns ();
18449 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18455 /* FIXME: This should be implemented with attributes...
18457 (set_attr "spe64" "true")....then,
18458 if (get_spe64(insn)) return true;
18460 It's the only reliable way to do the stuff below. */
18462 i = PATTERN (insn);
18463 if (GET_CODE (i) == SET)
18465 enum machine_mode mode = GET_MODE (SET_SRC (i));
18467 if (SPE_VECTOR_MODE (mode))
18469 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18479 debug_stack_info (rs6000_stack_t *info)
18481 const char *abi_string;
18484 info = rs6000_stack_info ();
18486 fprintf (stderr, "\nStack information for function %s:\n",
18487 ((current_function_decl && DECL_NAME (current_function_decl))
18488 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18493 default: abi_string = "Unknown"; break;
18494 case ABI_NONE: abi_string = "NONE"; break;
18495 case ABI_AIX: abi_string = "AIX"; break;
18496 case ABI_DARWIN: abi_string = "Darwin"; break;
18497 case ABI_V4: abi_string = "V.4"; break;
18500 fprintf (stderr, "\tABI = %5s\n", abi_string);
18502 if (TARGET_ALTIVEC_ABI)
18503 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18505 if (TARGET_SPE_ABI)
18506 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18508 if (info->first_gp_reg_save != 32)
18509 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18511 if (info->first_fp_reg_save != 64)
18512 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18514 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18515 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18516 info->first_altivec_reg_save);
18518 if (info->lr_save_p)
18519 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18521 if (info->cr_save_p)
18522 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18524 if (info->vrsave_mask)
18525 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18528 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18531 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18533 if (info->gp_save_offset)
18534 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18536 if (info->fp_save_offset)
18537 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18539 if (info->altivec_save_offset)
18540 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18541 info->altivec_save_offset);
18543 if (info->spe_gp_save_offset)
18544 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18545 info->spe_gp_save_offset);
18547 if (info->vrsave_save_offset)
18548 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18549 info->vrsave_save_offset);
18551 if (info->lr_save_offset)
18552 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18554 if (info->cr_save_offset)
18555 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18557 if (info->varargs_save_offset)
18558 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18560 if (info->total_size)
18561 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18564 if (info->vars_size)
18565 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18568 if (info->parm_size)
18569 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18571 if (info->fixed_size)
18572 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18575 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18577 if (info->spe_gp_size)
18578 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18581 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18583 if (info->altivec_size)
18584 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18586 if (info->vrsave_size)
18587 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18589 if (info->altivec_padding_size)
18590 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18591 info->altivec_padding_size);
18593 if (info->spe_padding_size)
18594 fprintf (stderr, "\tspe_padding_size = %5d\n",
18595 info->spe_padding_size);
18598 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18600 if (info->save_size)
18601 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18603 if (info->reg_size != 4)
18604 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18606 fprintf (stderr, "\n");
18610 rs6000_return_addr (int count, rtx frame)
18612 /* Currently we don't optimize very well between prolog and body
18613 code and for PIC code the code can be actually quite bad, so
18614 don't try to be too clever here. */
18615 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18617 cfun->machine->ra_needs_full_frame = 1;
18624 plus_constant (copy_to_reg
18625 (gen_rtx_MEM (Pmode,
18626 memory_address (Pmode, frame))),
18627 RETURN_ADDRESS_OFFSET)));
18630 cfun->machine->ra_need_lr = 1;
18631 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18634 /* Say whether a function is a candidate for sibcall handling or not.
18635 We do not allow indirect calls to be optimized into sibling calls.
18636 Also, we can't do it if there are any vector parameters; there's
18637 nowhere to put the VRsave code so it works; note that functions with
18638 vector parameters are required to have a prototype, so the argument
18639 type info must be available here. (The tail recursion case can work
18640 with vector parameters, but there's no way to distinguish here.) */
18642 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18647 if (TARGET_ALTIVEC_VRSAVE)
18649 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18650 type; type = TREE_CHAIN (type))
18652 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18656 if (DEFAULT_ABI == ABI_DARWIN
18657 || ((*targetm.binds_local_p) (decl)
18658 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18660 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18662 if (!lookup_attribute ("longcall", attr_list)
18663 || lookup_attribute ("shortcall", attr_list))
18670 /* NULL if INSN insn is valid within a low-overhead loop.
18671 Otherwise return why doloop cannot be applied.
18672 PowerPC uses the COUNT register for branch on table instructions. */
18674 static const char *
18675 rs6000_invalid_within_doloop (const_rtx insn)
18678 return "Function call in the loop.";
18681 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18682 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18683 return "Computed branch in the loop.";
18689 rs6000_ra_ever_killed (void)
18695 if (cfun->is_thunk)
18698 if (cfun->machine->lr_save_state)
18699 return cfun->machine->lr_save_state - 1;
18701 /* regs_ever_live has LR marked as used if any sibcalls are present,
18702 but this should not force saving and restoring in the
18703 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18704 clobbers LR, so that is inappropriate. */
18706 /* Also, the prologue can generate a store into LR that
18707 doesn't really count, like this:
18710 bcl to set PIC register
18714 When we're called from the epilogue, we need to avoid counting
18715 this as a store. */
18717 push_topmost_sequence ();
18718 top = get_insns ();
18719 pop_topmost_sequence ();
18720 reg = gen_rtx_REG (Pmode, LR_REGNO);
18722 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18728 if (!SIBLING_CALL_P (insn))
18731 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18733 else if (set_of (reg, insn) != NULL_RTX
18734 && !prologue_epilogue_contains (insn))
18741 /* Emit instructions needed to load the TOC register.
18742 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18743 a constant pool; or for SVR4 -fpic. */
18746 rs6000_emit_load_toc_table (int fromprolog)
18749 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18751 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18754 rtx lab, tmp1, tmp2, got;
18756 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18757 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18759 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18761 got = rs6000_got_sym ();
18762 tmp1 = tmp2 = dest;
18765 tmp1 = gen_reg_rtx (Pmode);
18766 tmp2 = gen_reg_rtx (Pmode);
18768 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18769 emit_move_insn (tmp1,
18770 gen_rtx_REG (Pmode, LR_REGNO));
18771 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18772 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18774 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18776 emit_insn (gen_load_toc_v4_pic_si ());
18777 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18779 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18782 rtx temp0 = (fromprolog
18783 ? gen_rtx_REG (Pmode, 0)
18784 : gen_reg_rtx (Pmode));
18790 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18791 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18793 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18794 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18796 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18797 emit_move_insn (dest,
18798 gen_rtx_REG (Pmode, LR_REGNO));
18799 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18805 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18806 lab = gen_label_rtx ();
18807 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18808 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18809 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18811 emit_insn (gen_addsi3 (dest, temp0, dest));
18813 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18815 /* This is for AIX code running in non-PIC ELF32. */
18818 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18819 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18821 emit_insn (gen_elf_high (dest, realsym));
18822 emit_insn (gen_elf_low (dest, dest, realsym));
18826 gcc_assert (DEFAULT_ABI == ABI_AIX);
18829 emit_insn (gen_load_toc_aix_si (dest));
18831 emit_insn (gen_load_toc_aix_di (dest));
18835 /* Emit instructions to restore the link register after determining where
18836 its value has been stored. */
18839 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18841 rs6000_stack_t *info = rs6000_stack_info ();
18844 operands[0] = source;
18845 operands[1] = scratch;
18847 if (info->lr_save_p)
18849 rtx frame_rtx = stack_pointer_rtx;
18850 HOST_WIDE_INT sp_offset = 0;
18853 if (frame_pointer_needed
18854 || cfun->calls_alloca
18855 || info->total_size > 32767)
18857 tmp = gen_frame_mem (Pmode, frame_rtx);
18858 emit_move_insn (operands[1], tmp);
18859 frame_rtx = operands[1];
18861 else if (info->push_p)
18862 sp_offset = info->total_size;
18864 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18865 tmp = gen_frame_mem (Pmode, tmp);
18866 emit_move_insn (tmp, operands[0]);
18869 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18871 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18872 state of lr_save_p so any change from here on would be a bug. In
18873 particular, stop rs6000_ra_ever_killed from considering the SET
18874 of lr we may have added just above. */
18875 cfun->machine->lr_save_state = info->lr_save_p + 1;
18878 static GTY(()) alias_set_type set = -1;
18881 get_TOC_alias_set (void)
18884 set = new_alias_set ();
18888 /* This returns nonzero if the current function uses the TOC. This is
18889 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18890 is generated by the ABI_V4 load_toc_* patterns. */
18897 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18900 rtx pat = PATTERN (insn);
18903 if (GET_CODE (pat) == PARALLEL)
18904 for (i = 0; i < XVECLEN (pat, 0); i++)
18906 rtx sub = XVECEXP (pat, 0, i);
18907 if (GET_CODE (sub) == USE)
18909 sub = XEXP (sub, 0);
18910 if (GET_CODE (sub) == UNSPEC
18911 && XINT (sub, 1) == UNSPEC_TOC)
18921 create_TOC_reference (rtx symbol, rtx largetoc_reg)
18923 rtx tocrel, tocreg;
18925 if (TARGET_DEBUG_ADDR)
18927 if (GET_CODE (symbol) == SYMBOL_REF)
18928 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18932 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18933 GET_RTX_NAME (GET_CODE (symbol)));
18934 debug_rtx (symbol);
18938 if (!can_create_pseudo_p ())
18939 df_set_regs_ever_live (TOC_REGISTER, true);
18941 tocrel = gen_rtx_CONST (Pmode,
18942 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
18944 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
18945 if (TARGET_CMODEL != CMODEL_SMALL)
18947 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
18948 if (largetoc_reg != NULL)
18950 emit_move_insn (largetoc_reg, hi);
18953 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
18956 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
18959 /* Issue assembly directives that create a reference to the given DWARF
18960 FRAME_TABLE_LABEL from the current function section. */
18962 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18964 fprintf (asm_out_file, "\t.ref %s\n",
18965 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18968 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18969 and the change to the stack pointer. */
18972 rs6000_emit_stack_tie (void)
18974 rtx mem = gen_frame_mem (BLKmode,
18975 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18977 emit_insn (gen_stack_tie (mem));
18980 /* Emit the correct code for allocating stack space, as insns.
18981 If COPY_REG, make sure a copy of the old frame is left there.
18982 The generated code may use hard register 0 as a temporary. */
18985 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18988 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18989 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18990 rtx todec = gen_int_mode (-size, Pmode);
18993 if (INTVAL (todec) != -size)
18995 warning (0, "stack frame too large");
18996 emit_insn (gen_trap ());
19000 if (crtl->limit_stack)
19002 if (REG_P (stack_limit_rtx)
19003 && REGNO (stack_limit_rtx) > 1
19004 && REGNO (stack_limit_rtx) <= 31)
19006 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19007 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19010 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19012 && DEFAULT_ABI == ABI_V4)
19014 rtx toload = gen_rtx_CONST (VOIDmode,
19015 gen_rtx_PLUS (Pmode,
19019 emit_insn (gen_elf_high (tmp_reg, toload));
19020 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19021 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19025 warning (0, "stack limit expression is not supported");
19029 emit_move_insn (copy_reg, stack_reg);
19033 /* Need a note here so that try_split doesn't get confused. */
19034 if (get_last_insn () == NULL_RTX)
19035 emit_note (NOTE_INSN_DELETED);
19036 insn = emit_move_insn (tmp_reg, todec);
19037 try_split (PATTERN (insn), insn, 0);
19041 insn = emit_insn (TARGET_32BIT
19042 ? gen_movsi_update_stack (stack_reg, stack_reg,
19044 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19045 todec, stack_reg));
19046 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19047 it now and set the alias set/attributes. The above gen_*_update
19048 calls will generate a PARALLEL with the MEM set being the first
19050 par = PATTERN (insn);
19051 gcc_assert (GET_CODE (par) == PARALLEL);
19052 set = XVECEXP (par, 0, 0);
19053 gcc_assert (GET_CODE (set) == SET);
19054 mem = SET_DEST (set);
19055 gcc_assert (MEM_P (mem));
19056 MEM_NOTRAP_P (mem) = 1;
19057 set_mem_alias_set (mem, get_frame_alias_set ());
19059 RTX_FRAME_RELATED_P (insn) = 1;
19060 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19061 gen_rtx_SET (VOIDmode, stack_reg,
19062 gen_rtx_PLUS (Pmode, stack_reg,
19063 GEN_INT (-size))));
19066 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19068 #if PROBE_INTERVAL > 32768
19069 #error Cannot use indexed addressing mode for stack probing
19072 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19073 inclusive. These are offsets from the current stack pointer. */
19076 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19078 /* See if we have a constant small number of probes to generate. If so,
19079 that's the easy case. */
19080 if (first + size <= 32768)
19084 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19085 it exceeds SIZE. If only one probe is needed, this will not
19086 generate any code. Then probe at FIRST + SIZE. */
19087 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19088 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19090 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19093 /* Otherwise, do the same as above, but in a loop. Note that we must be
19094 extra careful with variables wrapping around because we might be at
19095 the very top (or the very bottom) of the address space and we have
19096 to be able to handle this case properly; in particular, we use an
19097 equality test for the loop condition. */
19100 HOST_WIDE_INT rounded_size;
19101 rtx r12 = gen_rtx_REG (Pmode, 12);
19102 rtx r0 = gen_rtx_REG (Pmode, 0);
19104 /* Sanity check for the addressing mode we're going to use. */
19105 gcc_assert (first <= 32768);
19107 /* Step 1: round SIZE to the previous multiple of the interval. */
19109 rounded_size = size & -PROBE_INTERVAL;
19112 /* Step 2: compute initial and final value of the loop counter. */
19114 /* TEST_ADDR = SP + FIRST. */
19115 emit_insn (gen_rtx_SET (VOIDmode, r12,
19116 plus_constant (stack_pointer_rtx, -first)));
19118 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19119 if (rounded_size > 32768)
19121 emit_move_insn (r0, GEN_INT (-rounded_size));
19122 emit_insn (gen_rtx_SET (VOIDmode, r0,
19123 gen_rtx_PLUS (Pmode, r12, r0)));
19126 emit_insn (gen_rtx_SET (VOIDmode, r0,
19127 plus_constant (r12, -rounded_size)));
19130 /* Step 3: the loop
19132 while (TEST_ADDR != LAST_ADDR)
19134 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19138 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19139 until it is equal to ROUNDED_SIZE. */
19142 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19144 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19147 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19148 that SIZE is equal to ROUNDED_SIZE. */
19150 if (size != rounded_size)
19151 emit_stack_probe (plus_constant (r12, rounded_size - size));
19155 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19156 absolute addresses. */
19159 output_probe_stack_range (rtx reg1, rtx reg2)
19161 static int labelno = 0;
19162 char loop_lab[32], end_lab[32];
19165 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19166 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19168 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19170 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19174 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19176 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19178 fputs ("\tbeq 0,", asm_out_file);
19179 assemble_name_raw (asm_out_file, end_lab);
19180 fputc ('\n', asm_out_file);
19182 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19183 xops[1] = GEN_INT (-PROBE_INTERVAL);
19184 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19186 /* Probe at TEST_ADDR and branch. */
19187 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19188 fprintf (asm_out_file, "\tb ");
19189 assemble_name_raw (asm_out_file, loop_lab);
19190 fputc ('\n', asm_out_file);
19192 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19197 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19198 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19199 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19200 deduce these equivalences by itself so it wasn't necessary to hold
19201 its hand so much. */
19204 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19205 rtx reg2, rtx rreg)
19209 /* copy_rtx will not make unique copies of registers, so we need to
19210 ensure we don't have unwanted sharing here. */
19212 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19215 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19217 real = copy_rtx (PATTERN (insn));
19219 if (reg2 != NULL_RTX)
19220 real = replace_rtx (real, reg2, rreg);
19222 real = replace_rtx (real, reg,
19223 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19224 STACK_POINTER_REGNUM),
19227 /* We expect that 'real' is either a SET or a PARALLEL containing
19228 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19229 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19231 if (GET_CODE (real) == SET)
19235 temp = simplify_rtx (SET_SRC (set));
19237 SET_SRC (set) = temp;
19238 temp = simplify_rtx (SET_DEST (set));
19240 SET_DEST (set) = temp;
19241 if (GET_CODE (SET_DEST (set)) == MEM)
19243 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19245 XEXP (SET_DEST (set), 0) = temp;
19252 gcc_assert (GET_CODE (real) == PARALLEL);
19253 for (i = 0; i < XVECLEN (real, 0); i++)
19254 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19256 rtx set = XVECEXP (real, 0, i);
19258 temp = simplify_rtx (SET_SRC (set));
19260 SET_SRC (set) = temp;
19261 temp = simplify_rtx (SET_DEST (set));
19263 SET_DEST (set) = temp;
19264 if (GET_CODE (SET_DEST (set)) == MEM)
19266 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19268 XEXP (SET_DEST (set), 0) = temp;
19270 RTX_FRAME_RELATED_P (set) = 1;
19274 RTX_FRAME_RELATED_P (insn) = 1;
19275 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19278 /* Returns an insn that has a vrsave set operation with the
19279 appropriate CLOBBERs. */
19282 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19285 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19286 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19289 = gen_rtx_SET (VOIDmode,
19291 gen_rtx_UNSPEC_VOLATILE (SImode,
19292 gen_rtvec (2, reg, vrsave),
19293 UNSPECV_SET_VRSAVE));
19297 /* We need to clobber the registers in the mask so the scheduler
19298 does not move sets to VRSAVE before sets of AltiVec registers.
19300 However, if the function receives nonlocal gotos, reload will set
19301 all call saved registers live. We will end up with:
19303 (set (reg 999) (mem))
19304 (parallel [ (set (reg vrsave) (unspec blah))
19305 (clobber (reg 999))])
19307 The clobber will cause the store into reg 999 to be dead, and
19308 flow will attempt to delete an epilogue insn. In this case, we
19309 need an unspec use/set of the register. */
19311 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19312 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19314 if (!epiloguep || call_used_regs [i])
19315 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19316 gen_rtx_REG (V4SImode, i));
19319 rtx reg = gen_rtx_REG (V4SImode, i);
19322 = gen_rtx_SET (VOIDmode,
19324 gen_rtx_UNSPEC (V4SImode,
19325 gen_rtvec (1, reg), 27));
19329 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19331 for (i = 0; i < nclobs; ++i)
19332 XVECEXP (insn, 0, i) = clobs[i];
19337 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19338 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19341 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19342 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19344 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19345 rtx replacea, replaceb;
19347 int_rtx = GEN_INT (offset);
19349 /* Some cases that need register indexed addressing. */
19350 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19351 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19352 || (TARGET_E500_DOUBLE && mode == DFmode)
19354 && SPE_VECTOR_MODE (mode)
19355 && !SPE_CONST_OFFSET_OK (offset)))
19357 /* Whomever calls us must make sure r11 is available in the
19358 flow path of instructions in the prologue. */
19359 offset_rtx = gen_rtx_REG (Pmode, 11);
19360 emit_move_insn (offset_rtx, int_rtx);
19362 replacea = offset_rtx;
19363 replaceb = int_rtx;
19367 offset_rtx = int_rtx;
19368 replacea = NULL_RTX;
19369 replaceb = NULL_RTX;
19372 reg = gen_rtx_REG (mode, regno);
19373 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19374 mem = gen_frame_mem (mode, addr);
19376 insn = emit_move_insn (mem, reg);
19378 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19381 /* Emit an offset memory reference suitable for a frame store, while
19382 converting to a valid addressing mode. */
19385 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19387 rtx int_rtx, offset_rtx;
19389 int_rtx = GEN_INT (offset);
19391 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19392 || (TARGET_E500_DOUBLE && mode == DFmode))
19394 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19395 emit_move_insn (offset_rtx, int_rtx);
19398 offset_rtx = int_rtx;
19400 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19403 /* Look for user-defined global regs. We should not save and restore these,
19404 and cannot use stmw/lmw if there are any in its range. */
19407 no_global_regs_above (int first, bool gpr)
19410 int last = gpr ? 32 : 64;
19411 for (i = first; i < last; i++)
19412 if (global_regs[i])
19417 #ifndef TARGET_FIX_AND_CONTINUE
19418 #define TARGET_FIX_AND_CONTINUE 0
19421 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19422 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19423 #define LAST_SAVRES_REGISTER 31
19424 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19426 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19428 /* Temporary holding space for an out-of-line register save/restore
19430 static char savres_routine_name[30];
19432 /* Return the name for an out-of-line register save/restore routine.
19433 We are saving/restoring GPRs if GPR is true. */
19436 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19437 bool savep, bool gpr, bool lr)
19439 const char *prefix = "";
19440 const char *suffix = "";
19442 /* Different targets are supposed to define
19443 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19444 routine name could be defined with:
19446 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19448 This is a nice idea in practice, but in reality, things are
19449 complicated in several ways:
19451 - ELF targets have save/restore routines for GPRs.
19453 - SPE targets use different prefixes for 32/64-bit registers, and
19454 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19456 - PPC64 ELF targets have routines for save/restore of GPRs that
19457 differ in what they do with the link register, so having a set
19458 prefix doesn't work. (We only use one of the save routines at
19459 the moment, though.)
19461 - PPC32 elf targets have "exit" versions of the restore routines
19462 that restore the link register and can save some extra space.
19463 These require an extra suffix. (There are also "tail" versions
19464 of the restore routines and "GOT" versions of the save routines,
19465 but we don't generate those at present. Same problems apply,
19468 We deal with all this by synthesizing our own prefix/suffix and
19469 using that for the simple sprintf call shown above. */
19472 /* No floating point saves on the SPE. */
19476 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19478 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19483 else if (DEFAULT_ABI == ABI_V4)
19489 prefix = savep ? "_savegpr_" : "_restgpr_";
19491 prefix = savep ? "_savefpr_" : "_restfpr_";
19496 else if (DEFAULT_ABI == ABI_AIX)
19498 #ifndef POWERPC_LINUX
19499 /* No out-of-line save/restore routines for GPRs on AIX. */
19500 gcc_assert (!TARGET_AIX || !gpr);
19506 ? (lr ? "_savegpr0_" : "_savegpr1_")
19507 : (lr ? "_restgpr0_" : "_restgpr1_"));
19508 #ifdef POWERPC_LINUX
19510 prefix = (savep ? "_savefpr_" : "_restfpr_");
19514 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19515 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19518 else if (DEFAULT_ABI == ABI_DARWIN)
19519 sorry ("Out-of-line save/restore routines not supported on Darwin");
19521 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19523 return savres_routine_name;
19526 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19527 We are saving/restoring GPRs if GPR is true. */
19530 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19533 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19535 int select = ((savep ? 1 : 0) << 2
19537 /* On the SPE, we never have any FPRs, but we do have
19538 32/64-bit versions of the routines. */
19539 ? (info->spe_64bit_regs_used ? 1 : 0)
19540 : (gpr ? 1 : 0)) << 1)
19543 /* Don't generate bogus routine names. */
19544 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19545 && regno <= LAST_SAVRES_REGISTER);
19547 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19553 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19555 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19556 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19557 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19563 /* Emit a sequence of insns, including a stack tie if needed, for
19564 resetting the stack pointer. If SAVRES is true, then don't reset the
19565 stack pointer, but move the base of the frame into r11 for use by
19566 out-of-line register restore routines. */
19569 rs6000_emit_stack_reset (rs6000_stack_t *info,
19570 rtx sp_reg_rtx, rtx frame_reg_rtx,
19571 int sp_offset, bool savres)
19573 /* This blockage is needed so that sched doesn't decide to move
19574 the sp change before the register restores. */
19575 if (frame_reg_rtx != sp_reg_rtx
19577 && info->spe_64bit_regs_used != 0
19578 && info->first_gp_reg_save != 32))
19579 rs6000_emit_stack_tie ();
19581 if (frame_reg_rtx != sp_reg_rtx)
19583 if (sp_offset != 0)
19585 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19586 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19587 GEN_INT (sp_offset)));
19590 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19592 else if (sp_offset != 0)
19594 /* If we are restoring registers out-of-line, we will be using the
19595 "exit" variants of the restore routines, which will reset the
19596 stack for us. But we do need to point r11 into the right place
19597 for those routines. */
19598 rtx dest_reg = (savres
19599 ? gen_rtx_REG (Pmode, 11)
19602 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19603 GEN_INT (sp_offset)));
19610 /* Construct a parallel rtx describing the effect of a call to an
19611 out-of-line register save/restore routine. */
19614 rs6000_make_savres_rtx (rs6000_stack_t *info,
19615 rtx frame_reg_rtx, int save_area_offset,
19616 enum machine_mode reg_mode,
19617 bool savep, bool gpr, bool lr)
19620 int offset, start_reg, end_reg, n_regs;
19621 int reg_size = GET_MODE_SIZE (reg_mode);
19627 ? info->first_gp_reg_save
19628 : info->first_fp_reg_save);
19629 end_reg = gpr ? 32 : 64;
19630 n_regs = end_reg - start_reg;
19631 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19634 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19636 RTVEC_ELT (p, offset++)
19637 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19639 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19640 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19641 RTVEC_ELT (p, offset++)
19642 = gen_rtx_USE (VOIDmode,
19643 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19647 for (i = 0; i < end_reg - start_reg; i++)
19649 rtx addr, reg, mem;
19650 reg = gen_rtx_REG (reg_mode, start_reg + i);
19651 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19652 GEN_INT (save_area_offset + reg_size*i));
19653 mem = gen_frame_mem (reg_mode, addr);
19655 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19657 savep ? reg : mem);
19662 rtx addr, reg, mem;
19663 reg = gen_rtx_REG (Pmode, 0);
19664 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19665 GEN_INT (info->lr_save_offset));
19666 mem = gen_frame_mem (Pmode, addr);
19667 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19670 return gen_rtx_PARALLEL (VOIDmode, p);
19673 /* Determine whether the gp REG is really used. */
19676 rs6000_reg_live_or_pic_offset_p (int reg)
19678 return ((df_regs_ever_live_p (reg)
19679 && (!call_used_regs[reg]
19680 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19681 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19682 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19683 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19684 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19688 SAVRES_MULTIPLE = 0x1,
19689 SAVRES_INLINE_FPRS = 0x2,
19690 SAVRES_INLINE_GPRS = 0x4,
19691 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
19692 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
19693 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
19696 /* Determine the strategy for savings/restoring registers. */
19699 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
19700 int using_static_chain_p, int sibcall)
19702 bool using_multiple_p;
19704 bool savres_fprs_inline;
19705 bool savres_gprs_inline;
19706 bool noclobber_global_gprs
19707 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
19710 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
19711 && (!TARGET_SPE_ABI
19712 || info->spe_64bit_regs_used == 0)
19713 && info->first_gp_reg_save < 31
19714 && noclobber_global_gprs);
19715 /* Don't bother to try to save things out-of-line if r11 is occupied
19716 by the static chain. It would require too much fiddling and the
19717 static chain is rarely used anyway. */
19718 common = (using_static_chain_p
19720 || crtl->calls_eh_return
19721 || !info->lr_save_p
19722 || cfun->machine->ra_need_lr
19723 || info->total_size > 32767);
19724 savres_fprs_inline = (common
19725 || info->first_fp_reg_save == 64
19726 || !no_global_regs_above (info->first_fp_reg_save,
19728 /* The out-of-line FP routines use
19729 double-precision stores; we can't use those
19730 routines if we don't have such stores. */
19731 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
19732 || FP_SAVE_INLINE (info->first_fp_reg_save));
19733 savres_gprs_inline = (common
19734 /* Saving CR interferes with the exit routines
19735 used on the SPE, so just punt here. */
19738 && info->spe_64bit_regs_used != 0
19739 && info->cr_save_p != 0)
19740 || info->first_gp_reg_save == 32
19741 || !noclobber_global_gprs
19742 || GP_SAVE_INLINE (info->first_gp_reg_save));
19745 /* If we are going to use store multiple, then don't even bother
19746 with the out-of-line routines, since the store-multiple instruction
19747 will always be smaller. */
19748 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19751 /* The situation is more complicated with load multiple. We'd
19752 prefer to use the out-of-line routines for restores, since the
19753 "exit" out-of-line routines can handle the restore of LR and
19754 the frame teardown. But we can only use the out-of-line
19755 routines if we know that we've used store multiple or
19756 out-of-line routines in the prologue, i.e. if we've saved all
19757 the registers from first_gp_reg_save. Otherwise, we risk
19758 loading garbage from the stack. Furthermore, we can only use
19759 the "exit" out-of-line gpr restore if we haven't saved any
19761 bool saved_all = !savres_gprs_inline || using_multiple_p;
19763 if (saved_all && info->first_fp_reg_save != 64)
19764 /* We can't use the exit routine; use load multiple if it's
19766 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19769 strategy = (using_multiple_p
19770 | (savres_fprs_inline << 1)
19771 | (savres_gprs_inline << 2));
19772 #ifdef POWERPC_LINUX
19775 if (!savres_fprs_inline)
19776 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19777 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19778 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19781 if (TARGET_AIX && !savres_fprs_inline)
19782 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19787 /* Emit function prologue as insns. */
19790 rs6000_emit_prologue (void)
19792 rs6000_stack_t *info = rs6000_stack_info ();
19793 enum machine_mode reg_mode = Pmode;
19794 int reg_size = TARGET_32BIT ? 4 : 8;
19795 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19796 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19797 rtx frame_reg_rtx = sp_reg_rtx;
19798 rtx cr_save_rtx = NULL_RTX;
19801 int saving_FPRs_inline;
19802 int saving_GPRs_inline;
19803 int using_store_multiple;
19804 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19805 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19806 && call_used_regs[STATIC_CHAIN_REGNUM]);
19807 HOST_WIDE_INT sp_offset = 0;
19809 if (flag_stack_usage)
19810 current_function_static_stack_size = info->total_size;
19812 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19813 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19815 if (TARGET_FIX_AND_CONTINUE)
19817 /* gdb on darwin arranges to forward a function from the old
19818 address by modifying the first 5 instructions of the function
19819 to branch to the overriding function. This is necessary to
19820 permit function pointers that point to the old function to
19821 actually forward to the new function. */
19822 emit_insn (gen_nop ());
19823 emit_insn (gen_nop ());
19824 emit_insn (gen_nop ());
19825 emit_insn (gen_nop ());
19826 emit_insn (gen_nop ());
19829 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19831 reg_mode = V2SImode;
19835 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19836 /*static_chain_p=*/using_static_chain_p,
19838 using_store_multiple = strategy & SAVRES_MULTIPLE;
19839 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19840 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19842 /* For V.4, update stack before we do any saving and set back pointer. */
19843 if (! WORLD_SAVE_P (info)
19845 && (DEFAULT_ABI == ABI_V4
19846 || crtl->calls_eh_return))
19848 bool need_r11 = (TARGET_SPE
19849 ? (!saving_GPRs_inline
19850 && info->spe_64bit_regs_used == 0)
19851 : (!saving_FPRs_inline || !saving_GPRs_inline));
19852 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19854 if (info->total_size < 32767)
19855 sp_offset = info->total_size;
19857 frame_reg_rtx = copy_reg;
19858 else if (info->cr_save_p
19860 || info->first_fp_reg_save < 64
19861 || info->first_gp_reg_save < 32
19862 || info->altivec_size != 0
19863 || info->vrsave_mask != 0
19864 || crtl->calls_eh_return)
19866 copy_reg = frame_ptr_rtx;
19867 frame_reg_rtx = copy_reg;
19871 /* The prologue won't be saving any regs so there is no need
19872 to set up a frame register to access any frame save area.
19873 We also won't be using sp_offset anywhere below, but set
19874 the correct value anyway to protect against future
19875 changes to this function. */
19876 sp_offset = info->total_size;
19878 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19879 if (frame_reg_rtx != sp_reg_rtx)
19880 rs6000_emit_stack_tie ();
19883 /* Handle world saves specially here. */
19884 if (WORLD_SAVE_P (info))
19891 /* save_world expects lr in r0. */
19892 reg0 = gen_rtx_REG (Pmode, 0);
19893 if (info->lr_save_p)
19895 insn = emit_move_insn (reg0,
19896 gen_rtx_REG (Pmode, LR_REGNO));
19897 RTX_FRAME_RELATED_P (insn) = 1;
19900 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19901 assumptions about the offsets of various bits of the stack
19903 gcc_assert (info->gp_save_offset == -220
19904 && info->fp_save_offset == -144
19905 && info->lr_save_offset == 8
19906 && info->cr_save_offset == 4
19909 && (!crtl->calls_eh_return
19910 || info->ehrd_offset == -432)
19911 && info->vrsave_save_offset == -224
19912 && info->altivec_save_offset == -416);
19914 treg = gen_rtx_REG (SImode, 11);
19915 emit_move_insn (treg, GEN_INT (-info->total_size));
19917 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19918 in R11. It also clobbers R12, so beware! */
19920 /* Preserve CR2 for save_world prologues */
19922 sz += 32 - info->first_gp_reg_save;
19923 sz += 64 - info->first_fp_reg_save;
19924 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19925 p = rtvec_alloc (sz);
19927 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19928 gen_rtx_REG (SImode,
19930 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19931 gen_rtx_SYMBOL_REF (Pmode,
19933 /* We do floats first so that the instruction pattern matches
19935 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19937 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19938 ? DFmode : SFmode),
19939 info->first_fp_reg_save + i);
19940 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19941 GEN_INT (info->fp_save_offset
19942 + sp_offset + 8 * i));
19943 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19944 ? DFmode : SFmode), addr);
19946 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19948 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19950 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19951 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19952 GEN_INT (info->altivec_save_offset
19953 + sp_offset + 16 * i));
19954 rtx mem = gen_frame_mem (V4SImode, addr);
19956 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19958 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19960 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19961 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19962 GEN_INT (info->gp_save_offset
19963 + sp_offset + reg_size * i));
19964 rtx mem = gen_frame_mem (reg_mode, addr);
19966 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19970 /* CR register traditionally saved as CR2. */
19971 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19972 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19973 GEN_INT (info->cr_save_offset
19975 rtx mem = gen_frame_mem (reg_mode, addr);
19977 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19979 /* Explain about use of R0. */
19980 if (info->lr_save_p)
19982 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19983 GEN_INT (info->lr_save_offset
19985 rtx mem = gen_frame_mem (reg_mode, addr);
19987 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19989 /* Explain what happens to the stack pointer. */
19991 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19992 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19995 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19996 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19997 treg, GEN_INT (-info->total_size));
19998 sp_offset = info->total_size;
20001 /* If we use the link register, get it into r0. */
20002 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20004 rtx addr, reg, mem;
20006 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20007 gen_rtx_REG (Pmode, LR_REGNO));
20008 RTX_FRAME_RELATED_P (insn) = 1;
20010 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
20011 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
20013 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20014 GEN_INT (info->lr_save_offset + sp_offset));
20015 reg = gen_rtx_REG (Pmode, 0);
20016 mem = gen_rtx_MEM (Pmode, addr);
20017 /* This should not be of rs6000_sr_alias_set, because of
20018 __builtin_return_address. */
20020 insn = emit_move_insn (mem, reg);
20021 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20022 NULL_RTX, NULL_RTX);
20026 /* If we need to save CR, put it into r12 or r11. */
20027 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20032 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20034 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20035 RTX_FRAME_RELATED_P (insn) = 1;
20036 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20037 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20038 But that's OK. All we have to do is specify that _one_ condition
20039 code register is saved in this stack slot. The thrower's epilogue
20040 will then restore all the call-saved registers.
20041 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20042 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20043 gen_rtx_REG (SImode, CR2_REGNO));
20044 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20047 /* Do any required saving of fpr's. If only one or two to save, do
20048 it ourselves. Otherwise, call function. */
20049 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20052 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20053 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20054 && ! call_used_regs[info->first_fp_reg_save+i]))
20055 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20056 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20058 info->first_fp_reg_save + i,
20059 info->fp_save_offset + sp_offset + 8 * i,
20062 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20066 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20067 info->fp_save_offset + sp_offset,
20069 /*savep=*/true, /*gpr=*/false,
20071 & SAVRES_NOINLINE_FPRS_SAVES_LR)
20073 insn = emit_insn (par);
20074 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20075 NULL_RTX, NULL_RTX);
20078 /* Save GPRs. This is done as a PARALLEL if we are using
20079 the store-multiple instructions. */
20080 if (!WORLD_SAVE_P (info)
20082 && info->spe_64bit_regs_used != 0
20083 && info->first_gp_reg_save != 32)
20086 rtx spe_save_area_ptr;
20088 /* Determine whether we can address all of the registers that need
20089 to be saved with an offset from the stack pointer that fits in
20090 the small const field for SPE memory instructions. */
20091 int spe_regs_addressable_via_sp
20092 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20093 + (32 - info->first_gp_reg_save - 1) * reg_size)
20094 && saving_GPRs_inline);
20097 if (spe_regs_addressable_via_sp)
20099 spe_save_area_ptr = frame_reg_rtx;
20100 spe_offset = info->spe_gp_save_offset + sp_offset;
20104 /* Make r11 point to the start of the SPE save area. We need
20105 to be careful here if r11 is holding the static chain. If
20106 it is, then temporarily save it in r0. We would use r0 as
20107 our base register here, but using r0 as a base register in
20108 loads and stores means something different from what we
20110 int ool_adjust = (saving_GPRs_inline
20112 : (info->first_gp_reg_save
20113 - (FIRST_SAVRES_REGISTER+1))*8);
20114 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20115 + sp_offset - ool_adjust);
20117 if (using_static_chain_p)
20119 rtx r0 = gen_rtx_REG (Pmode, 0);
20120 gcc_assert (info->first_gp_reg_save > 11);
20122 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20125 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20126 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20128 GEN_INT (offset)));
20129 /* We need to make sure the move to r11 gets noted for
20130 properly outputting unwind information. */
20131 if (!saving_GPRs_inline)
20132 rs6000_frame_related (insn, frame_reg_rtx, offset,
20133 NULL_RTX, NULL_RTX);
20137 if (saving_GPRs_inline)
20139 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20140 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20142 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20143 rtx offset, addr, mem;
20145 /* We're doing all this to ensure that the offset fits into
20146 the immediate offset of 'evstdd'. */
20147 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20149 offset = GEN_INT (reg_size * i + spe_offset);
20150 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20151 mem = gen_rtx_MEM (V2SImode, addr);
20153 insn = emit_move_insn (mem, reg);
20155 rs6000_frame_related (insn, spe_save_area_ptr,
20156 info->spe_gp_save_offset
20157 + sp_offset + reg_size * i,
20158 offset, const0_rtx);
20165 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20167 /*savep=*/true, /*gpr=*/true,
20169 insn = emit_insn (par);
20170 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20171 NULL_RTX, NULL_RTX);
20175 /* Move the static chain pointer back. */
20176 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20177 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20179 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20183 /* Need to adjust r11 (r12) if we saved any FPRs. */
20184 if (info->first_fp_reg_save != 64)
20186 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20188 rtx offset = GEN_INT (sp_offset
20189 + (-8 * (64-info->first_fp_reg_save)));
20190 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20193 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20194 info->gp_save_offset + sp_offset,
20196 /*savep=*/true, /*gpr=*/true,
20198 & SAVRES_NOINLINE_GPRS_SAVES_LR)
20200 insn = emit_insn (par);
20201 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20202 NULL_RTX, NULL_RTX);
20204 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20208 p = rtvec_alloc (32 - info->first_gp_reg_save);
20209 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20211 rtx addr, reg, mem;
20212 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20213 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20214 GEN_INT (info->gp_save_offset
20217 mem = gen_frame_mem (reg_mode, addr);
20219 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20221 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20222 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20223 NULL_RTX, NULL_RTX);
20225 else if (!WORLD_SAVE_P (info))
20228 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20229 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20231 rtx addr, reg, mem;
20232 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20234 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20235 GEN_INT (info->gp_save_offset
20238 mem = gen_frame_mem (reg_mode, addr);
20240 insn = emit_move_insn (mem, reg);
20241 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20242 NULL_RTX, NULL_RTX);
20246 /* ??? There's no need to emit actual instructions here, but it's the
20247 easiest way to get the frame unwind information emitted. */
20248 if (crtl->calls_eh_return)
20250 unsigned int i, regno;
20254 regno = EH_RETURN_DATA_REGNO (i);
20255 if (regno == INVALID_REGNUM)
20258 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20259 info->ehrd_offset + sp_offset
20260 + reg_size * (int) i,
20265 /* In AIX ABI we need to make sure r2 is really saved. */
20266 if (TARGET_AIX && crtl->calls_eh_return)
20268 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20269 long toc_restore_insn;
20271 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20272 || frame_reg_rtx == sp_reg_rtx);
20273 tmp_reg = gen_rtx_REG (Pmode, 11);
20274 tmp_reg_si = gen_rtx_REG (SImode, 11);
20275 if (using_static_chain_p)
20276 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20277 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20278 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20279 /* Peek at instruction to which this function returns. If it's
20280 restoring r2, then we know we've already saved r2. We can't
20281 unconditionally save r2 because the value we have will already
20282 be updated if we arrived at this function via a plt call or
20283 toc adjusting stub. */
20284 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20285 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20286 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20287 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20288 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20289 validate_condition_mode (EQ, CCUNSmode);
20290 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20291 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20292 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20293 toc_save_done = gen_label_rtx ();
20294 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20295 gen_rtx_EQ (VOIDmode, compare_result,
20297 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20299 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20300 JUMP_LABEL (jump) = toc_save_done;
20301 LABEL_NUSES (toc_save_done) += 1;
20303 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20304 sp_offset + 5 * reg_size, info->total_size);
20305 emit_label (toc_save_done);
20306 if (using_static_chain_p)
20307 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20310 /* Save CR if we use any that must be preserved. */
20311 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20313 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20314 GEN_INT (info->cr_save_offset + sp_offset));
20315 rtx mem = gen_frame_mem (SImode, addr);
20316 /* See the large comment above about why CR2_REGNO is used. */
20317 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20319 /* If r12 was used to hold the original sp, copy cr into r0 now
20321 if (REGNO (frame_reg_rtx) == 12)
20325 cr_save_rtx = gen_rtx_REG (SImode, 0);
20326 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20327 RTX_FRAME_RELATED_P (insn) = 1;
20328 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20329 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20331 insn = emit_move_insn (mem, cr_save_rtx);
20333 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20334 NULL_RTX, NULL_RTX);
20337 /* Update stack and set back pointer unless this is V.4,
20338 for which it was done previously. */
20339 if (!WORLD_SAVE_P (info) && info->push_p
20340 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20342 rtx copy_reg = NULL;
20344 if (info->total_size < 32767)
20345 sp_offset = info->total_size;
20346 else if (info->altivec_size != 0
20347 || info->vrsave_mask != 0)
20349 copy_reg = frame_ptr_rtx;
20350 frame_reg_rtx = copy_reg;
20353 sp_offset = info->total_size;
20354 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20355 if (frame_reg_rtx != sp_reg_rtx)
20356 rs6000_emit_stack_tie ();
20359 /* Set frame pointer, if needed. */
20360 if (frame_pointer_needed)
20362 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20364 RTX_FRAME_RELATED_P (insn) = 1;
20367 /* Save AltiVec registers if needed. Save here because the red zone does
20368 not include AltiVec registers. */
20369 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20373 /* There should be a non inline version of this, for when we
20374 are saving lots of vector registers. */
20375 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20376 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20378 rtx areg, savereg, mem;
20381 offset = info->altivec_save_offset + sp_offset
20382 + 16 * (i - info->first_altivec_reg_save);
20384 savereg = gen_rtx_REG (V4SImode, i);
20386 areg = gen_rtx_REG (Pmode, 0);
20387 emit_move_insn (areg, GEN_INT (offset));
20389 /* AltiVec addressing mode is [reg+reg]. */
20390 mem = gen_frame_mem (V4SImode,
20391 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20393 insn = emit_move_insn (mem, savereg);
20395 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20396 areg, GEN_INT (offset));
20400 /* VRSAVE is a bit vector representing which AltiVec registers
20401 are used. The OS uses this to determine which vector
20402 registers to save on a context switch. We need to save
20403 VRSAVE on the stack frame, add whatever AltiVec registers we
20404 used in this function, and do the corresponding magic in the
20407 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20408 && info->vrsave_mask != 0)
20410 rtx reg, mem, vrsave;
20413 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20414 as frame_reg_rtx and r11 as the static chain pointer for
20415 nested functions. */
20416 reg = gen_rtx_REG (SImode, 0);
20417 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20419 emit_insn (gen_get_vrsave_internal (reg));
20421 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20423 if (!WORLD_SAVE_P (info))
20426 offset = info->vrsave_save_offset + sp_offset;
20427 mem = gen_frame_mem (SImode,
20428 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20429 GEN_INT (offset)));
20430 insn = emit_move_insn (mem, reg);
20433 /* Include the registers in the mask. */
20434 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20436 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20439 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20440 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20441 || (DEFAULT_ABI == ABI_V4
20442 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20443 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20445 /* If emit_load_toc_table will use the link register, we need to save
20446 it. We use R12 for this purpose because emit_load_toc_table
20447 can use register 0. This allows us to use a plain 'blr' to return
20448 from the procedure more often. */
20449 int save_LR_around_toc_setup = (TARGET_ELF
20450 && DEFAULT_ABI != ABI_AIX
20452 && ! info->lr_save_p
20453 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20454 if (save_LR_around_toc_setup)
20456 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20458 insn = emit_move_insn (frame_ptr_rtx, lr);
20459 RTX_FRAME_RELATED_P (insn) = 1;
20461 rs6000_emit_load_toc_table (TRUE);
20463 insn = emit_move_insn (lr, frame_ptr_rtx);
20464 RTX_FRAME_RELATED_P (insn) = 1;
20467 rs6000_emit_load_toc_table (TRUE);
20471 if (DEFAULT_ABI == ABI_DARWIN
20472 && flag_pic && crtl->uses_pic_offset_table)
20474 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20475 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20477 /* Save and restore LR locally around this call (in R0). */
20478 if (!info->lr_save_p)
20479 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20481 emit_insn (gen_load_macho_picbase (src));
20483 emit_move_insn (gen_rtx_REG (Pmode,
20484 RS6000_PIC_OFFSET_TABLE_REGNUM),
20487 if (!info->lr_save_p)
20488 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20493 /* Write function prologue. */
20496 rs6000_output_function_prologue (FILE *file,
20497 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20499 rs6000_stack_t *info = rs6000_stack_info ();
20501 if (TARGET_DEBUG_STACK)
20502 debug_stack_info (info);
20504 /* Write .extern for any function we will call to save and restore
20506 if (info->first_fp_reg_save < 64
20507 && !FP_SAVE_INLINE (info->first_fp_reg_save))
20510 int regno = info->first_fp_reg_save - 32;
20512 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20513 /*gpr=*/false, /*lr=*/false);
20514 fprintf (file, "\t.extern %s\n", name);
20516 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20517 /*gpr=*/false, /*lr=*/true);
20518 fprintf (file, "\t.extern %s\n", name);
20521 /* Write .extern for AIX common mode routines, if needed. */
20522 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20524 fputs ("\t.extern __mulh\n", file);
20525 fputs ("\t.extern __mull\n", file);
20526 fputs ("\t.extern __divss\n", file);
20527 fputs ("\t.extern __divus\n", file);
20528 fputs ("\t.extern __quoss\n", file);
20529 fputs ("\t.extern __quous\n", file);
20530 common_mode_defined = 1;
20533 if (! HAVE_prologue)
20539 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20540 the "toplevel" insn chain. */
20541 emit_note (NOTE_INSN_DELETED);
20542 rs6000_emit_prologue ();
20543 emit_note (NOTE_INSN_DELETED);
20545 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20549 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20551 INSN_ADDRESSES_NEW (insn, addr);
20556 prologue = get_insns ();
20559 if (TARGET_DEBUG_STACK)
20560 debug_rtx_list (prologue, 100);
20562 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20566 rs6000_pic_labelno++;
20569 /* Non-zero if vmx regs are restored before the frame pop, zero if
20570 we restore after the pop when possible. */
20571 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20573 /* Reload CR from REG. */
20576 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20581 if (using_mfcr_multiple)
20583 for (i = 0; i < 8; i++)
20584 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20586 gcc_assert (count);
20589 if (using_mfcr_multiple && count > 1)
20594 p = rtvec_alloc (count);
20597 for (i = 0; i < 8; i++)
20598 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20600 rtvec r = rtvec_alloc (2);
20601 RTVEC_ELT (r, 0) = reg;
20602 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20603 RTVEC_ELT (p, ndx) =
20604 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20605 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20608 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20609 gcc_assert (ndx == count);
20612 for (i = 0; i < 8; i++)
20613 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20615 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20621 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20622 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20623 below stack pointer not cloberred by signals. */
20626 offset_below_red_zone_p (HOST_WIDE_INT offset)
20628 return offset < (DEFAULT_ABI == ABI_V4
20630 : TARGET_32BIT ? -220 : -288);
20633 /* Emit function epilogue as insns. */
20636 rs6000_emit_epilogue (int sibcall)
20638 rs6000_stack_t *info;
20639 int restoring_GPRs_inline;
20640 int restoring_FPRs_inline;
20641 int using_load_multiple;
20642 int using_mtcr_multiple;
20643 int use_backchain_to_restore_sp;
20647 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20648 rtx frame_reg_rtx = sp_reg_rtx;
20649 rtx cfa_restores = NULL_RTX;
20651 rtx cr_save_reg = NULL_RTX;
20652 enum machine_mode reg_mode = Pmode;
20653 int reg_size = TARGET_32BIT ? 4 : 8;
20656 info = rs6000_stack_info ();
20658 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20660 reg_mode = V2SImode;
20664 strategy = rs6000_savres_strategy (info, /*savep=*/false,
20665 /*static_chain_p=*/0, sibcall);
20666 using_load_multiple = strategy & SAVRES_MULTIPLE;
20667 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
20668 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
20669 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20670 || rs6000_cpu == PROCESSOR_PPC603
20671 || rs6000_cpu == PROCESSOR_PPC750
20673 /* Restore via the backchain when we have a large frame, since this
20674 is more efficient than an addis, addi pair. The second condition
20675 here will not trigger at the moment; We don't actually need a
20676 frame pointer for alloca, but the generic parts of the compiler
20677 give us one anyway. */
20678 use_backchain_to_restore_sp = (info->total_size > 32767
20679 || info->total_size
20680 + (info->lr_save_p ? info->lr_save_offset : 0)
20682 || (cfun->calls_alloca
20683 && !frame_pointer_needed));
20684 restore_lr = (info->lr_save_p
20685 && (restoring_FPRs_inline
20686 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20687 && (restoring_GPRs_inline
20688 || info->first_fp_reg_save < 64));
20690 if (WORLD_SAVE_P (info))
20694 const char *alloc_rname;
20697 /* eh_rest_world_r10 will return to the location saved in the LR
20698 stack slot (which is not likely to be our caller.)
20699 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20700 rest_world is similar, except any R10 parameter is ignored.
20701 The exception-handling stuff that was here in 2.95 is no
20702 longer necessary. */
20706 + 32 - info->first_gp_reg_save
20707 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20708 + 63 + 1 - info->first_fp_reg_save);
20710 strcpy (rname, ((crtl->calls_eh_return) ?
20711 "*eh_rest_world_r10" : "*rest_world"));
20712 alloc_rname = ggc_strdup (rname);
20715 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20716 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20717 gen_rtx_REG (Pmode,
20720 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20721 /* The instruction pattern requires a clobber here;
20722 it is shared with the restVEC helper. */
20724 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20727 /* CR register traditionally saved as CR2. */
20728 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20729 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20730 GEN_INT (info->cr_save_offset));
20731 rtx mem = gen_frame_mem (reg_mode, addr);
20733 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20736 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20738 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20739 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20740 GEN_INT (info->gp_save_offset
20742 rtx mem = gen_frame_mem (reg_mode, addr);
20744 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20746 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20748 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20749 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20750 GEN_INT (info->altivec_save_offset
20752 rtx mem = gen_frame_mem (V4SImode, addr);
20754 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20756 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20758 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20759 ? DFmode : SFmode),
20760 info->first_fp_reg_save + i);
20761 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20762 GEN_INT (info->fp_save_offset
20764 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20765 ? DFmode : SFmode), addr);
20767 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20770 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20772 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20774 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20776 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20778 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20779 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20784 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20786 sp_offset = info->total_size;
20788 /* Restore AltiVec registers if we must do so before adjusting the
20790 if (TARGET_ALTIVEC_ABI
20791 && info->altivec_size != 0
20792 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20793 || (DEFAULT_ABI != ABI_V4
20794 && offset_below_red_zone_p (info->altivec_save_offset))))
20798 if (use_backchain_to_restore_sp)
20800 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20801 emit_move_insn (frame_reg_rtx,
20802 gen_rtx_MEM (Pmode, sp_reg_rtx));
20805 else if (frame_pointer_needed)
20806 frame_reg_rtx = hard_frame_pointer_rtx;
20808 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20809 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20811 rtx addr, areg, mem, reg;
20813 areg = gen_rtx_REG (Pmode, 0);
20815 (areg, GEN_INT (info->altivec_save_offset
20817 + 16 * (i - info->first_altivec_reg_save)));
20819 /* AltiVec addressing mode is [reg+reg]. */
20820 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20821 mem = gen_frame_mem (V4SImode, addr);
20823 reg = gen_rtx_REG (V4SImode, i);
20824 emit_move_insn (reg, mem);
20825 if (offset_below_red_zone_p (info->altivec_save_offset
20826 + (i - info->first_altivec_reg_save)
20828 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20833 /* Restore VRSAVE if we must do so before adjusting the stack. */
20835 && TARGET_ALTIVEC_VRSAVE
20836 && info->vrsave_mask != 0
20837 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20838 || (DEFAULT_ABI != ABI_V4
20839 && offset_below_red_zone_p (info->vrsave_save_offset))))
20841 rtx addr, mem, reg;
20843 if (frame_reg_rtx == sp_reg_rtx)
20845 if (use_backchain_to_restore_sp)
20847 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20848 emit_move_insn (frame_reg_rtx,
20849 gen_rtx_MEM (Pmode, sp_reg_rtx));
20852 else if (frame_pointer_needed)
20853 frame_reg_rtx = hard_frame_pointer_rtx;
20856 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20857 GEN_INT (info->vrsave_save_offset + sp_offset));
20858 mem = gen_frame_mem (SImode, addr);
20859 reg = gen_rtx_REG (SImode, 12);
20860 emit_move_insn (reg, mem);
20862 emit_insn (generate_set_vrsave (reg, info, 1));
20866 /* If we have a large stack frame, restore the old stack pointer
20867 using the backchain. */
20868 if (use_backchain_to_restore_sp)
20870 if (frame_reg_rtx == sp_reg_rtx)
20872 /* Under V.4, don't reset the stack pointer until after we're done
20873 loading the saved registers. */
20874 if (DEFAULT_ABI == ABI_V4)
20875 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20877 insn = emit_move_insn (frame_reg_rtx,
20878 gen_rtx_MEM (Pmode, sp_reg_rtx));
20881 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20882 && DEFAULT_ABI == ABI_V4)
20883 /* frame_reg_rtx has been set up by the altivec restore. */
20887 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20888 frame_reg_rtx = sp_reg_rtx;
20891 /* If we have a frame pointer, we can restore the old stack pointer
20893 else if (frame_pointer_needed)
20895 frame_reg_rtx = sp_reg_rtx;
20896 if (DEFAULT_ABI == ABI_V4)
20897 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20898 /* Prevent reordering memory accesses against stack pointer restore. */
20899 else if (cfun->calls_alloca
20900 || offset_below_red_zone_p (-info->total_size))
20902 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20903 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20904 MEM_NOTRAP_P (mem1) = 1;
20905 MEM_NOTRAP_P (mem2) = 1;
20906 emit_insn (gen_frame_tie (mem1, mem2));
20909 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20910 GEN_INT (info->total_size)));
20913 else if (info->push_p
20914 && DEFAULT_ABI != ABI_V4
20915 && !crtl->calls_eh_return)
20917 /* Prevent reordering memory accesses against stack pointer restore. */
20918 if (cfun->calls_alloca
20919 || offset_below_red_zone_p (-info->total_size))
20921 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20922 MEM_NOTRAP_P (mem) = 1;
20923 emit_insn (gen_stack_tie (mem));
20925 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20926 GEN_INT (info->total_size)));
20929 if (insn && frame_reg_rtx == sp_reg_rtx)
20933 REG_NOTES (insn) = cfa_restores;
20934 cfa_restores = NULL_RTX;
20936 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20937 RTX_FRAME_RELATED_P (insn) = 1;
20940 /* Restore AltiVec registers if we have not done so already. */
20941 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20942 && TARGET_ALTIVEC_ABI
20943 && info->altivec_size != 0
20944 && (DEFAULT_ABI == ABI_V4
20945 || !offset_below_red_zone_p (info->altivec_save_offset)))
20949 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20950 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20952 rtx addr, areg, mem, reg;
20954 areg = gen_rtx_REG (Pmode, 0);
20956 (areg, GEN_INT (info->altivec_save_offset
20958 + 16 * (i - info->first_altivec_reg_save)));
20960 /* AltiVec addressing mode is [reg+reg]. */
20961 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20962 mem = gen_frame_mem (V4SImode, addr);
20964 reg = gen_rtx_REG (V4SImode, i);
20965 emit_move_insn (reg, mem);
20966 if (DEFAULT_ABI == ABI_V4)
20967 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20972 /* Restore VRSAVE if we have not done so already. */
20973 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20975 && TARGET_ALTIVEC_VRSAVE
20976 && info->vrsave_mask != 0
20977 && (DEFAULT_ABI == ABI_V4
20978 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20980 rtx addr, mem, reg;
20982 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20983 GEN_INT (info->vrsave_save_offset + sp_offset));
20984 mem = gen_frame_mem (SImode, addr);
20985 reg = gen_rtx_REG (SImode, 12);
20986 emit_move_insn (reg, mem);
20988 emit_insn (generate_set_vrsave (reg, info, 1));
20991 /* Get the old lr if we saved it. If we are restoring registers
20992 out-of-line, then the out-of-line routines can do this for us. */
20993 if (restore_lr && restoring_GPRs_inline)
20995 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20996 info->lr_save_offset + sp_offset);
20998 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21001 /* Get the old cr if we saved it. */
21002 if (info->cr_save_p)
21004 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21005 GEN_INT (info->cr_save_offset + sp_offset));
21006 rtx mem = gen_frame_mem (SImode, addr);
21008 cr_save_reg = gen_rtx_REG (SImode,
21009 DEFAULT_ABI == ABI_AIX
21010 && !restoring_GPRs_inline
21011 && info->first_fp_reg_save < 64
21013 emit_move_insn (cr_save_reg, mem);
21016 /* Set LR here to try to overlap restores below. LR is always saved
21017 above incoming stack, so it never needs REG_CFA_RESTORE. */
21018 if (restore_lr && restoring_GPRs_inline)
21019 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21020 gen_rtx_REG (Pmode, 0));
21022 /* Load exception handler data registers, if needed. */
21023 if (crtl->calls_eh_return)
21025 unsigned int i, regno;
21029 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21030 GEN_INT (sp_offset + 5 * reg_size));
21031 rtx mem = gen_frame_mem (reg_mode, addr);
21033 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21040 regno = EH_RETURN_DATA_REGNO (i);
21041 if (regno == INVALID_REGNUM)
21044 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21045 info->ehrd_offset + sp_offset
21046 + reg_size * (int) i);
21048 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21052 /* Restore GPRs. This is done as a PARALLEL if we are using
21053 the load-multiple instructions. */
21055 && info->spe_64bit_regs_used != 0
21056 && info->first_gp_reg_save != 32)
21058 /* Determine whether we can address all of the registers that need
21059 to be saved with an offset from the stack pointer that fits in
21060 the small const field for SPE memory instructions. */
21061 int spe_regs_addressable_via_sp
21062 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21063 + (32 - info->first_gp_reg_save - 1) * reg_size)
21064 && restoring_GPRs_inline);
21067 if (spe_regs_addressable_via_sp)
21068 spe_offset = info->spe_gp_save_offset + sp_offset;
21071 rtx old_frame_reg_rtx = frame_reg_rtx;
21072 /* Make r11 point to the start of the SPE save area. We worried about
21073 not clobbering it when we were saving registers in the prologue.
21074 There's no need to worry here because the static chain is passed
21075 anew to every function. */
21076 int ool_adjust = (restoring_GPRs_inline
21078 : (info->first_gp_reg_save
21079 - (FIRST_SAVRES_REGISTER+1))*8);
21081 if (frame_reg_rtx == sp_reg_rtx)
21082 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21083 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21084 GEN_INT (info->spe_gp_save_offset
21087 /* Keep the invariant that frame_reg_rtx + sp_offset points
21088 at the top of the stack frame. */
21089 sp_offset = -info->spe_gp_save_offset;
21094 if (restoring_GPRs_inline)
21096 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21097 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21099 rtx offset, addr, mem, reg;
21101 /* We're doing all this to ensure that the immediate offset
21102 fits into the immediate field of 'evldd'. */
21103 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21105 offset = GEN_INT (spe_offset + reg_size * i);
21106 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21107 mem = gen_rtx_MEM (V2SImode, addr);
21108 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21110 insn = emit_move_insn (reg, mem);
21111 if (DEFAULT_ABI == ABI_V4)
21113 if (frame_pointer_needed
21114 && info->first_gp_reg_save + i
21115 == HARD_FRAME_POINTER_REGNUM)
21117 add_reg_note (insn, REG_CFA_DEF_CFA,
21118 plus_constant (frame_reg_rtx,
21120 RTX_FRAME_RELATED_P (insn) = 1;
21123 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21132 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21134 /*savep=*/false, /*gpr=*/true,
21136 emit_jump_insn (par);
21137 /* We don't want anybody else emitting things after we jumped
21142 else if (!restoring_GPRs_inline)
21144 /* We are jumping to an out-of-line function. */
21145 bool can_use_exit = info->first_fp_reg_save == 64;
21148 /* Emit stack reset code if we need it. */
21150 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21151 sp_offset, can_use_exit);
21154 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21157 GEN_INT (sp_offset - info->fp_size)));
21158 if (REGNO (frame_reg_rtx) == 11)
21159 sp_offset += info->fp_size;
21162 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21163 info->gp_save_offset, reg_mode,
21164 /*savep=*/false, /*gpr=*/true,
21165 /*lr=*/can_use_exit);
21169 if (info->cr_save_p)
21171 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21172 if (DEFAULT_ABI == ABI_V4)
21174 = alloc_reg_note (REG_CFA_RESTORE,
21175 gen_rtx_REG (SImode, CR2_REGNO),
21179 emit_jump_insn (par);
21181 /* We don't want anybody else emitting things after we jumped
21186 insn = emit_insn (par);
21187 if (DEFAULT_ABI == ABI_V4)
21189 if (frame_pointer_needed)
21191 add_reg_note (insn, REG_CFA_DEF_CFA,
21192 plus_constant (frame_reg_rtx, sp_offset));
21193 RTX_FRAME_RELATED_P (insn) = 1;
21196 for (i = info->first_gp_reg_save; i < 32; i++)
21198 = alloc_reg_note (REG_CFA_RESTORE,
21199 gen_rtx_REG (reg_mode, i), cfa_restores);
21202 else if (using_load_multiple)
21205 p = rtvec_alloc (32 - info->first_gp_reg_save);
21206 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21208 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21209 GEN_INT (info->gp_save_offset
21212 rtx mem = gen_frame_mem (reg_mode, addr);
21213 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21215 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21216 if (DEFAULT_ABI == ABI_V4)
21217 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21220 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21221 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21223 add_reg_note (insn, REG_CFA_DEF_CFA,
21224 plus_constant (frame_reg_rtx, sp_offset));
21225 RTX_FRAME_RELATED_P (insn) = 1;
21230 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21231 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21233 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21234 GEN_INT (info->gp_save_offset
21237 rtx mem = gen_frame_mem (reg_mode, addr);
21238 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21240 insn = emit_move_insn (reg, mem);
21241 if (DEFAULT_ABI == ABI_V4)
21243 if (frame_pointer_needed
21244 && info->first_gp_reg_save + i
21245 == HARD_FRAME_POINTER_REGNUM)
21247 add_reg_note (insn, REG_CFA_DEF_CFA,
21248 plus_constant (frame_reg_rtx, sp_offset));
21249 RTX_FRAME_RELATED_P (insn) = 1;
21252 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21258 if (restore_lr && !restoring_GPRs_inline)
21260 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21261 info->lr_save_offset + sp_offset);
21263 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21264 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21265 gen_rtx_REG (Pmode, 0));
21268 /* Restore fpr's if we need to do it without calling a function. */
21269 if (restoring_FPRs_inline)
21270 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21271 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21272 && ! call_used_regs[info->first_fp_reg_save+i]))
21274 rtx addr, mem, reg;
21275 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21276 GEN_INT (info->fp_save_offset
21279 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21280 ? DFmode : SFmode), addr);
21281 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21282 ? DFmode : SFmode),
21283 info->first_fp_reg_save + i);
21285 emit_move_insn (reg, mem);
21286 if (DEFAULT_ABI == ABI_V4)
21287 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21291 /* If we saved cr, restore it here. Just those that were used. */
21292 if (info->cr_save_p)
21294 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21295 if (DEFAULT_ABI == ABI_V4)
21297 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21301 /* If this is V.4, unwind the stack pointer after all of the loads
21303 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21304 sp_offset, !restoring_FPRs_inline);
21309 REG_NOTES (insn) = cfa_restores;
21310 cfa_restores = NULL_RTX;
21312 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21313 RTX_FRAME_RELATED_P (insn) = 1;
21316 if (crtl->calls_eh_return)
21318 rtx sa = EH_RETURN_STACKADJ_RTX;
21319 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21325 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21326 if (! restoring_FPRs_inline)
21327 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21329 p = rtvec_alloc (2);
21331 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21332 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21333 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21334 : gen_rtx_CLOBBER (VOIDmode,
21335 gen_rtx_REG (Pmode, 65)));
21337 /* If we have to restore more than two FP registers, branch to the
21338 restore function. It will return to our caller. */
21339 if (! restoring_FPRs_inline)
21344 sym = rs6000_savres_routine_sym (info,
21348 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21349 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21350 gen_rtx_REG (Pmode,
21351 DEFAULT_ABI == ABI_AIX
21353 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21356 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21357 GEN_INT (info->fp_save_offset + 8*i));
21358 mem = gen_frame_mem (DFmode, addr);
21360 RTVEC_ELT (p, i+4) =
21361 gen_rtx_SET (VOIDmode,
21362 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21367 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21371 /* Write function epilogue. */
21374 rs6000_output_function_epilogue (FILE *file,
21375 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21377 if (! HAVE_epilogue)
21379 rtx insn = get_last_insn ();
21380 /* If the last insn was a BARRIER, we don't have to write anything except
21381 the trace table. */
21382 if (GET_CODE (insn) == NOTE)
21383 insn = prev_nonnote_insn (insn);
21384 if (insn == 0 || GET_CODE (insn) != BARRIER)
21386 /* This is slightly ugly, but at least we don't have two
21387 copies of the epilogue-emitting code. */
21390 /* A NOTE_INSN_DELETED is supposed to be at the start
21391 and end of the "toplevel" insn chain. */
21392 emit_note (NOTE_INSN_DELETED);
21393 rs6000_emit_epilogue (FALSE);
21394 emit_note (NOTE_INSN_DELETED);
21396 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21400 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21402 INSN_ADDRESSES_NEW (insn, addr);
21407 if (TARGET_DEBUG_STACK)
21408 debug_rtx_list (get_insns (), 100);
21409 final (get_insns (), file, FALSE);
21415 macho_branch_islands ();
21416 /* Mach-O doesn't support labels at the end of objects, so if
21417 it looks like we might want one, insert a NOP. */
21419 rtx insn = get_last_insn ();
21422 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21423 insn = PREV_INSN (insn);
21427 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21428 fputs ("\tnop\n", file);
21432 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21435 We don't output a traceback table if -finhibit-size-directive was
21436 used. The documentation for -finhibit-size-directive reads
21437 ``don't output a @code{.size} assembler directive, or anything
21438 else that would cause trouble if the function is split in the
21439 middle, and the two halves are placed at locations far apart in
21440 memory.'' The traceback table has this property, since it
21441 includes the offset from the start of the function to the
21442 traceback table itself.
21444 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21445 different traceback table. */
21446 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21447 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21449 const char *fname = NULL;
21450 const char *language_string = lang_hooks.name;
21451 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21453 int optional_tbtab;
21454 rs6000_stack_t *info = rs6000_stack_info ();
21456 if (rs6000_traceback == traceback_full)
21457 optional_tbtab = 1;
21458 else if (rs6000_traceback == traceback_part)
21459 optional_tbtab = 0;
21461 optional_tbtab = !optimize_size && !TARGET_ELF;
21463 if (optional_tbtab)
21465 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21466 while (*fname == '.') /* V.4 encodes . in the name */
21469 /* Need label immediately before tbtab, so we can compute
21470 its offset from the function start. */
21471 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21472 ASM_OUTPUT_LABEL (file, fname);
21475 /* The .tbtab pseudo-op can only be used for the first eight
21476 expressions, since it can't handle the possibly variable
21477 length fields that follow. However, if you omit the optional
21478 fields, the assembler outputs zeros for all optional fields
21479 anyways, giving each variable length field is minimum length
21480 (as defined in sys/debug.h). Thus we can not use the .tbtab
21481 pseudo-op at all. */
21483 /* An all-zero word flags the start of the tbtab, for debuggers
21484 that have to find it by searching forward from the entry
21485 point or from the current pc. */
21486 fputs ("\t.long 0\n", file);
21488 /* Tbtab format type. Use format type 0. */
21489 fputs ("\t.byte 0,", file);
21491 /* Language type. Unfortunately, there does not seem to be any
21492 official way to discover the language being compiled, so we
21493 use language_string.
21494 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21495 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21496 a number, so for now use 9. LTO isn't assigned a number either,
21497 so for now use 0. */
21498 if (! strcmp (language_string, "GNU C")
21499 || ! strcmp (language_string, "GNU GIMPLE"))
21501 else if (! strcmp (language_string, "GNU F77")
21502 || ! strcmp (language_string, "GNU Fortran"))
21504 else if (! strcmp (language_string, "GNU Pascal"))
21506 else if (! strcmp (language_string, "GNU Ada"))
21508 else if (! strcmp (language_string, "GNU C++")
21509 || ! strcmp (language_string, "GNU Objective-C++"))
21511 else if (! strcmp (language_string, "GNU Java"))
21513 else if (! strcmp (language_string, "GNU Objective-C"))
21516 gcc_unreachable ();
21517 fprintf (file, "%d,", i);
21519 /* 8 single bit fields: global linkage (not set for C extern linkage,
21520 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21521 from start of procedure stored in tbtab, internal function, function
21522 has controlled storage, function has no toc, function uses fp,
21523 function logs/aborts fp operations. */
21524 /* Assume that fp operations are used if any fp reg must be saved. */
21525 fprintf (file, "%d,",
21526 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21528 /* 6 bitfields: function is interrupt handler, name present in
21529 proc table, function calls alloca, on condition directives
21530 (controls stack walks, 3 bits), saves condition reg, saves
21532 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21533 set up as a frame pointer, even when there is no alloca call. */
21534 fprintf (file, "%d,",
21535 ((optional_tbtab << 6)
21536 | ((optional_tbtab & frame_pointer_needed) << 5)
21537 | (info->cr_save_p << 1)
21538 | (info->lr_save_p)));
21540 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21542 fprintf (file, "%d,",
21543 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21545 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21546 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21548 if (optional_tbtab)
21550 /* Compute the parameter info from the function decl argument
21553 int next_parm_info_bit = 31;
21555 for (decl = DECL_ARGUMENTS (current_function_decl);
21556 decl; decl = DECL_CHAIN (decl))
21558 rtx parameter = DECL_INCOMING_RTL (decl);
21559 enum machine_mode mode = GET_MODE (parameter);
21561 if (GET_CODE (parameter) == REG)
21563 if (SCALAR_FLOAT_MODE_P (mode))
21584 gcc_unreachable ();
21587 /* If only one bit will fit, don't or in this entry. */
21588 if (next_parm_info_bit > 0)
21589 parm_info |= (bits << (next_parm_info_bit - 1));
21590 next_parm_info_bit -= 2;
21594 fixed_parms += ((GET_MODE_SIZE (mode)
21595 + (UNITS_PER_WORD - 1))
21597 next_parm_info_bit -= 1;
21603 /* Number of fixed point parameters. */
21604 /* This is actually the number of words of fixed point parameters; thus
21605 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21606 fprintf (file, "%d,", fixed_parms);
21608 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21610 /* This is actually the number of fp registers that hold parameters;
21611 and thus the maximum value is 13. */
21612 /* Set parameters on stack bit if parameters are not in their original
21613 registers, regardless of whether they are on the stack? Xlc
21614 seems to set the bit when not optimizing. */
21615 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21617 if (! optional_tbtab)
21620 /* Optional fields follow. Some are variable length. */
21622 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21623 11 double float. */
21624 /* There is an entry for each parameter in a register, in the order that
21625 they occur in the parameter list. Any intervening arguments on the
21626 stack are ignored. If the list overflows a long (max possible length
21627 34 bits) then completely leave off all elements that don't fit. */
21628 /* Only emit this long if there was at least one parameter. */
21629 if (fixed_parms || float_parms)
21630 fprintf (file, "\t.long %d\n", parm_info);
21632 /* Offset from start of code to tb table. */
21633 fputs ("\t.long ", file);
21634 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21635 RS6000_OUTPUT_BASENAME (file, fname);
21637 rs6000_output_function_entry (file, fname);
21640 /* Interrupt handler mask. */
21641 /* Omit this long, since we never set the interrupt handler bit
21644 /* Number of CTL (controlled storage) anchors. */
21645 /* Omit this long, since the has_ctl bit is never set above. */
21647 /* Displacement into stack of each CTL anchor. */
21648 /* Omit this list of longs, because there are no CTL anchors. */
21650 /* Length of function name. */
21653 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21655 /* Function name. */
21656 assemble_string (fname, strlen (fname));
21658 /* Register for alloca automatic storage; this is always reg 31.
21659 Only emit this if the alloca bit was set above. */
21660 if (frame_pointer_needed)
21661 fputs ("\t.byte 31\n", file);
21663 fputs ("\t.align 2\n", file);
21667 /* A C compound statement that outputs the assembler code for a thunk
21668 function, used to implement C++ virtual function calls with
21669 multiple inheritance. The thunk acts as a wrapper around a virtual
21670 function, adjusting the implicit object parameter before handing
21671 control off to the real function.
21673 First, emit code to add the integer DELTA to the location that
21674 contains the incoming first argument. Assume that this argument
21675 contains a pointer, and is the one used to pass the `this' pointer
21676 in C++. This is the incoming argument *before* the function
21677 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21678 values of all other incoming arguments.
21680 After the addition, emit code to jump to FUNCTION, which is a
21681 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21682 not touch the return address. Hence returning from FUNCTION will
21683 return to whoever called the current `thunk'.
21685 The effect must be as if FUNCTION had been called directly with the
21686 adjusted first argument. This macro is responsible for emitting
21687 all of the code for a thunk function; output_function_prologue()
21688 and output_function_epilogue() are not invoked.
21690 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21691 been extracted from it.) It might possibly be useful on some
21692 targets, but probably not.
21694 If you do not define this macro, the target-independent code in the
21695 C++ frontend will generate a less efficient heavyweight thunk that
21696 calls FUNCTION instead of jumping to it. The generic approach does
21697 not support varargs. */
21700 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21701 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21704 rtx this_rtx, insn, funexp;
21706 reload_completed = 1;
21707 epilogue_completed = 1;
21709 /* Mark the end of the (empty) prologue. */
21710 emit_note (NOTE_INSN_PROLOGUE_END);
21712 /* Find the "this" pointer. If the function returns a structure,
21713 the structure return pointer is in r3. */
21714 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21715 this_rtx = gen_rtx_REG (Pmode, 4);
21717 this_rtx = gen_rtx_REG (Pmode, 3);
21719 /* Apply the constant offset, if required. */
21721 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21723 /* Apply the offset from the vtable, if required. */
21726 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21727 rtx tmp = gen_rtx_REG (Pmode, 12);
21729 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21730 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21732 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21733 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21737 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21739 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21741 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21744 /* Generate a tail call to the target function. */
21745 if (!TREE_USED (function))
21747 assemble_external (function);
21748 TREE_USED (function) = 1;
21750 funexp = XEXP (DECL_RTL (function), 0);
21751 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21754 if (MACHOPIC_INDIRECT)
21755 funexp = machopic_indirect_call_target (funexp);
21758 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21759 generate sibcall RTL explicitly. */
21760 insn = emit_call_insn (
21761 gen_rtx_PARALLEL (VOIDmode,
21763 gen_rtx_CALL (VOIDmode,
21764 funexp, const0_rtx),
21765 gen_rtx_USE (VOIDmode, const0_rtx),
21766 gen_rtx_USE (VOIDmode,
21767 gen_rtx_REG (SImode,
21769 gen_rtx_RETURN (VOIDmode))));
21770 SIBLING_CALL_P (insn) = 1;
21773 /* Run just enough of rest_of_compilation to get the insns emitted.
21774 There's not really enough bulk here to make other passes such as
21775 instruction scheduling worth while. Note that use_thunk calls
21776 assemble_start_function and assemble_end_function. */
21777 insn = get_insns ();
21778 insn_locators_alloc ();
21779 shorten_branches (insn);
21780 final_start_function (insn, file, 1);
21781 final (insn, file, 1);
21782 final_end_function ();
21784 reload_completed = 0;
21785 epilogue_completed = 0;
21788 /* A quick summary of the various types of 'constant-pool tables'
21791 Target Flags Name One table per
21792 AIX (none) AIX TOC object file
21793 AIX -mfull-toc AIX TOC object file
21794 AIX -mminimal-toc AIX minimal TOC translation unit
21795 SVR4/EABI (none) SVR4 SDATA object file
21796 SVR4/EABI -fpic SVR4 pic object file
21797 SVR4/EABI -fPIC SVR4 PIC translation unit
21798 SVR4/EABI -mrelocatable EABI TOC function
21799 SVR4/EABI -maix AIX TOC object file
21800 SVR4/EABI -maix -mminimal-toc
21801 AIX minimal TOC translation unit
21803 Name Reg. Set by entries contains:
21804 made by addrs? fp? sum?
21806 AIX TOC 2 crt0 as Y option option
21807 AIX minimal TOC 30 prolog gcc Y Y option
21808 SVR4 SDATA 13 crt0 gcc N Y N
21809 SVR4 pic 30 prolog ld Y not yet N
21810 SVR4 PIC 30 prolog gcc Y option option
21811 EABI TOC 30 prolog gcc Y option option
21815 /* Hash functions for the hash table. */
21818 rs6000_hash_constant (rtx k)
21820 enum rtx_code code = GET_CODE (k);
21821 enum machine_mode mode = GET_MODE (k);
21822 unsigned result = (code << 3) ^ mode;
21823 const char *format;
21826 format = GET_RTX_FORMAT (code);
21827 flen = strlen (format);
21833 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21836 if (mode != VOIDmode)
21837 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21849 for (; fidx < flen; fidx++)
21850 switch (format[fidx])
21855 const char *str = XSTR (k, fidx);
21856 len = strlen (str);
21857 result = result * 613 + len;
21858 for (i = 0; i < len; i++)
21859 result = result * 613 + (unsigned) str[i];
21864 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21868 result = result * 613 + (unsigned) XINT (k, fidx);
21871 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21872 result = result * 613 + (unsigned) XWINT (k, fidx);
21876 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21877 result = result * 613 + (unsigned) (XWINT (k, fidx)
21884 gcc_unreachable ();
21891 toc_hash_function (const void *hash_entry)
21893 const struct toc_hash_struct *thc =
21894 (const struct toc_hash_struct *) hash_entry;
21895 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21898 /* Compare H1 and H2 for equivalence. */
21901 toc_hash_eq (const void *h1, const void *h2)
21903 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21904 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21906 if (((const struct toc_hash_struct *) h1)->key_mode
21907 != ((const struct toc_hash_struct *) h2)->key_mode)
21910 return rtx_equal_p (r1, r2);
21913 /* These are the names given by the C++ front-end to vtables, and
21914 vtable-like objects. Ideally, this logic should not be here;
21915 instead, there should be some programmatic way of inquiring as
21916 to whether or not an object is a vtable. */
21918 #define VTABLE_NAME_P(NAME) \
21919 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21920 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21921 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21922 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21923 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21925 #ifdef NO_DOLLAR_IN_LABEL
21926 /* Return a GGC-allocated character string translating dollar signs in
21927 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21930 rs6000_xcoff_strip_dollar (const char *name)
21935 p = strchr (name, '$');
21937 if (p == 0 || p == name)
21940 len = strlen (name);
21941 strip = (char *) alloca (len + 1);
21942 strcpy (strip, name);
21943 p = strchr (strip, '$');
21947 p = strchr (p + 1, '$');
21950 return ggc_alloc_string (strip, len);
21955 rs6000_output_symbol_ref (FILE *file, rtx x)
21957 /* Currently C++ toc references to vtables can be emitted before it
21958 is decided whether the vtable is public or private. If this is
21959 the case, then the linker will eventually complain that there is
21960 a reference to an unknown section. Thus, for vtables only,
21961 we emit the TOC reference to reference the symbol and not the
21963 const char *name = XSTR (x, 0);
21965 if (VTABLE_NAME_P (name))
21967 RS6000_OUTPUT_BASENAME (file, name);
21970 assemble_name (file, name);
21973 /* Output a TOC entry. We derive the entry name from what is being
21977 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21980 const char *name = buf;
21982 HOST_WIDE_INT offset = 0;
21984 gcc_assert (!TARGET_NO_TOC);
21986 /* When the linker won't eliminate them, don't output duplicate
21987 TOC entries (this happens on AIX if there is any kind of TOC,
21988 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21990 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21992 struct toc_hash_struct *h;
21995 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
21996 time because GGC is not initialized at that point. */
21997 if (toc_hash_table == NULL)
21998 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21999 toc_hash_eq, NULL);
22001 h = ggc_alloc_toc_hash_struct ();
22003 h->key_mode = mode;
22004 h->labelno = labelno;
22006 found = htab_find_slot (toc_hash_table, h, INSERT);
22007 if (*found == NULL)
22009 else /* This is indeed a duplicate.
22010 Set this label equal to that label. */
22012 fputs ("\t.set ", file);
22013 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22014 fprintf (file, "%d,", labelno);
22015 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22016 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22022 /* If we're going to put a double constant in the TOC, make sure it's
22023 aligned properly when strict alignment is on. */
22024 if (GET_CODE (x) == CONST_DOUBLE
22025 && STRICT_ALIGNMENT
22026 && GET_MODE_BITSIZE (mode) >= 64
22027 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22028 ASM_OUTPUT_ALIGN (file, 3);
22031 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22033 /* Handle FP constants specially. Note that if we have a minimal
22034 TOC, things we put here aren't actually in the TOC, so we can allow
22036 if (GET_CODE (x) == CONST_DOUBLE &&
22037 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22039 REAL_VALUE_TYPE rv;
22042 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22043 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22044 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22046 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22050 if (TARGET_MINIMAL_TOC)
22051 fputs (DOUBLE_INT_ASM_OP, file);
22053 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22054 k[0] & 0xffffffff, k[1] & 0xffffffff,
22055 k[2] & 0xffffffff, k[3] & 0xffffffff);
22056 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22057 k[0] & 0xffffffff, k[1] & 0xffffffff,
22058 k[2] & 0xffffffff, k[3] & 0xffffffff);
22063 if (TARGET_MINIMAL_TOC)
22064 fputs ("\t.long ", file);
22066 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22067 k[0] & 0xffffffff, k[1] & 0xffffffff,
22068 k[2] & 0xffffffff, k[3] & 0xffffffff);
22069 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22070 k[0] & 0xffffffff, k[1] & 0xffffffff,
22071 k[2] & 0xffffffff, k[3] & 0xffffffff);
22075 else if (GET_CODE (x) == CONST_DOUBLE &&
22076 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22078 REAL_VALUE_TYPE rv;
22081 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22083 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22084 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22086 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22090 if (TARGET_MINIMAL_TOC)
22091 fputs (DOUBLE_INT_ASM_OP, file);
22093 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22094 k[0] & 0xffffffff, k[1] & 0xffffffff);
22095 fprintf (file, "0x%lx%08lx\n",
22096 k[0] & 0xffffffff, k[1] & 0xffffffff);
22101 if (TARGET_MINIMAL_TOC)
22102 fputs ("\t.long ", file);
22104 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22105 k[0] & 0xffffffff, k[1] & 0xffffffff);
22106 fprintf (file, "0x%lx,0x%lx\n",
22107 k[0] & 0xffffffff, k[1] & 0xffffffff);
22111 else if (GET_CODE (x) == CONST_DOUBLE &&
22112 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22114 REAL_VALUE_TYPE rv;
22117 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22118 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22119 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22121 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22125 if (TARGET_MINIMAL_TOC)
22126 fputs (DOUBLE_INT_ASM_OP, file);
22128 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22129 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22134 if (TARGET_MINIMAL_TOC)
22135 fputs ("\t.long ", file);
22137 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22138 fprintf (file, "0x%lx\n", l & 0xffffffff);
22142 else if (GET_MODE (x) == VOIDmode
22143 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22145 unsigned HOST_WIDE_INT low;
22146 HOST_WIDE_INT high;
22148 if (GET_CODE (x) == CONST_DOUBLE)
22150 low = CONST_DOUBLE_LOW (x);
22151 high = CONST_DOUBLE_HIGH (x);
22154 #if HOST_BITS_PER_WIDE_INT == 32
22157 high = (low & 0x80000000) ? ~0 : 0;
22161 low = INTVAL (x) & 0xffffffff;
22162 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22166 /* TOC entries are always Pmode-sized, but since this
22167 is a bigendian machine then if we're putting smaller
22168 integer constants in the TOC we have to pad them.
22169 (This is still a win over putting the constants in
22170 a separate constant pool, because then we'd have
22171 to have both a TOC entry _and_ the actual constant.)
22173 For a 32-bit target, CONST_INT values are loaded and shifted
22174 entirely within `low' and can be stored in one TOC entry. */
22176 /* It would be easy to make this work, but it doesn't now. */
22177 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22179 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22181 #if HOST_BITS_PER_WIDE_INT == 32
22182 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22183 POINTER_SIZE, &low, &high, 0);
22186 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22187 high = (HOST_WIDE_INT) low >> 32;
22194 if (TARGET_MINIMAL_TOC)
22195 fputs (DOUBLE_INT_ASM_OP, file);
22197 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22198 (long) high & 0xffffffff, (long) low & 0xffffffff);
22199 fprintf (file, "0x%lx%08lx\n",
22200 (long) high & 0xffffffff, (long) low & 0xffffffff);
22205 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22207 if (TARGET_MINIMAL_TOC)
22208 fputs ("\t.long ", file);
22210 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22211 (long) high & 0xffffffff, (long) low & 0xffffffff);
22212 fprintf (file, "0x%lx,0x%lx\n",
22213 (long) high & 0xffffffff, (long) low & 0xffffffff);
22217 if (TARGET_MINIMAL_TOC)
22218 fputs ("\t.long ", file);
22220 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22221 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22227 if (GET_CODE (x) == CONST)
22229 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22230 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22232 base = XEXP (XEXP (x, 0), 0);
22233 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22236 switch (GET_CODE (base))
22239 name = XSTR (base, 0);
22243 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22244 CODE_LABEL_NUMBER (XEXP (base, 0)));
22248 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22252 gcc_unreachable ();
22255 if (TARGET_MINIMAL_TOC)
22256 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22259 fputs ("\t.tc ", file);
22260 RS6000_OUTPUT_BASENAME (file, name);
22263 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22265 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22267 fputs ("[TC],", file);
22270 /* Currently C++ toc references to vtables can be emitted before it
22271 is decided whether the vtable is public or private. If this is
22272 the case, then the linker will eventually complain that there is
22273 a TOC reference to an unknown section. Thus, for vtables only,
22274 we emit the TOC reference to reference the symbol and not the
22276 if (VTABLE_NAME_P (name))
22278 RS6000_OUTPUT_BASENAME (file, name);
22280 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22281 else if (offset > 0)
22282 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22285 output_addr_const (file, x);
22289 /* Output an assembler pseudo-op to write an ASCII string of N characters
22290 starting at P to FILE.
22292 On the RS/6000, we have to do this using the .byte operation and
22293 write out special characters outside the quoted string.
22294 Also, the assembler is broken; very long strings are truncated,
22295 so we must artificially break them up early. */
22298 output_ascii (FILE *file, const char *p, int n)
22301 int i, count_string;
22302 const char *for_string = "\t.byte \"";
22303 const char *for_decimal = "\t.byte ";
22304 const char *to_close = NULL;
22307 for (i = 0; i < n; i++)
22310 if (c >= ' ' && c < 0177)
22313 fputs (for_string, file);
22316 /* Write two quotes to get one. */
22324 for_decimal = "\"\n\t.byte ";
22328 if (count_string >= 512)
22330 fputs (to_close, file);
22332 for_string = "\t.byte \"";
22333 for_decimal = "\t.byte ";
22341 fputs (for_decimal, file);
22342 fprintf (file, "%d", c);
22344 for_string = "\n\t.byte \"";
22345 for_decimal = ", ";
22351 /* Now close the string if we have written one. Then end the line. */
22353 fputs (to_close, file);
22356 /* Generate a unique section name for FILENAME for a section type
22357 represented by SECTION_DESC. Output goes into BUF.
22359 SECTION_DESC can be any string, as long as it is different for each
22360 possible section type.
22362 We name the section in the same manner as xlc. The name begins with an
22363 underscore followed by the filename (after stripping any leading directory
22364 names) with the last period replaced by the string SECTION_DESC. If
22365 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22369 rs6000_gen_section_name (char **buf, const char *filename,
22370 const char *section_desc)
22372 const char *q, *after_last_slash, *last_period = 0;
22376 after_last_slash = filename;
22377 for (q = filename; *q; q++)
22380 after_last_slash = q + 1;
22381 else if (*q == '.')
22385 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22386 *buf = (char *) xmalloc (len);
22391 for (q = after_last_slash; *q; q++)
22393 if (q == last_period)
22395 strcpy (p, section_desc);
22396 p += strlen (section_desc);
22400 else if (ISALNUM (*q))
22404 if (last_period == 0)
22405 strcpy (p, section_desc);
22410 /* Emit profile function. */
22413 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22415 /* Non-standard profiling for kernels, which just saves LR then calls
22416 _mcount without worrying about arg saves. The idea is to change
22417 the function prologue as little as possible as it isn't easy to
22418 account for arg save/restore code added just for _mcount. */
22419 if (TARGET_PROFILE_KERNEL)
22422 if (DEFAULT_ABI == ABI_AIX)
22424 #ifndef NO_PROFILE_COUNTERS
22425 # define NO_PROFILE_COUNTERS 0
22427 if (NO_PROFILE_COUNTERS)
22428 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22429 LCT_NORMAL, VOIDmode, 0);
22433 const char *label_name;
22436 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22437 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22438 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22440 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22441 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22444 else if (DEFAULT_ABI == ABI_DARWIN)
22446 const char *mcount_name = RS6000_MCOUNT;
22447 int caller_addr_regno = LR_REGNO;
22449 /* Be conservative and always set this, at least for now. */
22450 crtl->uses_pic_offset_table = 1;
22453 /* For PIC code, set up a stub and collect the caller's address
22454 from r0, which is where the prologue puts it. */
22455 if (MACHOPIC_INDIRECT
22456 && crtl->uses_pic_offset_table)
22457 caller_addr_regno = 0;
22459 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22460 LCT_NORMAL, VOIDmode, 1,
22461 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22465 /* Write function profiler code. */
22468 output_function_profiler (FILE *file, int labelno)
22472 switch (DEFAULT_ABI)
22475 gcc_unreachable ();
22480 warning (0, "no profiling of 64-bit code for this ABI");
22483 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22484 fprintf (file, "\tmflr %s\n", reg_names[0]);
22485 if (NO_PROFILE_COUNTERS)
22487 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22488 reg_names[0], reg_names[1]);
22490 else if (TARGET_SECURE_PLT && flag_pic)
22492 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22493 reg_names[0], reg_names[1]);
22494 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22495 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22496 reg_names[12], reg_names[12]);
22497 assemble_name (file, buf);
22498 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22499 assemble_name (file, buf);
22500 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22502 else if (flag_pic == 1)
22504 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22505 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22506 reg_names[0], reg_names[1]);
22507 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22508 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22509 assemble_name (file, buf);
22510 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22512 else if (flag_pic > 1)
22514 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22515 reg_names[0], reg_names[1]);
22516 /* Now, we need to get the address of the label. */
22517 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22518 assemble_name (file, buf);
22519 fputs ("-.\n1:", file);
22520 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22521 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22522 reg_names[0], reg_names[11]);
22523 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22524 reg_names[0], reg_names[0], reg_names[11]);
22528 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22529 assemble_name (file, buf);
22530 fputs ("@ha\n", file);
22531 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22532 reg_names[0], reg_names[1]);
22533 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22534 assemble_name (file, buf);
22535 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22538 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22539 fprintf (file, "\tbl %s%s\n",
22540 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22545 if (!TARGET_PROFILE_KERNEL)
22547 /* Don't do anything, done in output_profile_hook (). */
22551 gcc_assert (!TARGET_32BIT);
22553 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22554 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22556 if (cfun->static_chain_decl != NULL)
22558 asm_fprintf (file, "\tstd %s,24(%s)\n",
22559 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22560 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22561 asm_fprintf (file, "\tld %s,24(%s)\n",
22562 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22565 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22573 /* The following variable value is the last issued insn. */
22575 static rtx last_scheduled_insn;
22577 /* The following variable helps to balance issuing of load and
22578 store instructions */
22580 static int load_store_pendulum;
22582 /* Power4 load update and store update instructions are cracked into a
22583 load or store and an integer insn which are executed in the same cycle.
22584 Branches have their own dispatch slot which does not count against the
22585 GCC issue rate, but it changes the program flow so there are no other
22586 instructions to issue in this cycle. */
22589 rs6000_variable_issue_1 (rtx insn, int more)
22591 last_scheduled_insn = insn;
22592 if (GET_CODE (PATTERN (insn)) == USE
22593 || GET_CODE (PATTERN (insn)) == CLOBBER)
22595 cached_can_issue_more = more;
22596 return cached_can_issue_more;
22599 if (insn_terminates_group_p (insn, current_group))
22601 cached_can_issue_more = 0;
22602 return cached_can_issue_more;
22605 /* If no reservation, but reach here */
22606 if (recog_memoized (insn) < 0)
22609 if (rs6000_sched_groups)
22611 if (is_microcoded_insn (insn))
22612 cached_can_issue_more = 0;
22613 else if (is_cracked_insn (insn))
22614 cached_can_issue_more = more > 2 ? more - 2 : 0;
22616 cached_can_issue_more = more - 1;
22618 return cached_can_issue_more;
22621 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22624 cached_can_issue_more = more - 1;
22625 return cached_can_issue_more;
22629 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22631 int r = rs6000_variable_issue_1 (insn, more);
22633 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22637 /* Adjust the cost of a scheduling dependency. Return the new cost of
22638 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22641 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22643 enum attr_type attr_type;
22645 if (! recog_memoized (insn))
22648 switch (REG_NOTE_KIND (link))
22652 /* Data dependency; DEP_INSN writes a register that INSN reads
22653 some cycles later. */
22655 /* Separate a load from a narrower, dependent store. */
22656 if (rs6000_sched_groups
22657 && GET_CODE (PATTERN (insn)) == SET
22658 && GET_CODE (PATTERN (dep_insn)) == SET
22659 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22660 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22661 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22662 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22665 attr_type = get_attr_type (insn);
22670 /* Tell the first scheduling pass about the latency between
22671 a mtctr and bctr (and mtlr and br/blr). The first
22672 scheduling pass will not know about this latency since
22673 the mtctr instruction, which has the latency associated
22674 to it, will be generated by reload. */
22675 return TARGET_POWER ? 5 : 4;
22677 /* Leave some extra cycles between a compare and its
22678 dependent branch, to inhibit expensive mispredicts. */
22679 if ((rs6000_cpu_attr == CPU_PPC603
22680 || rs6000_cpu_attr == CPU_PPC604
22681 || rs6000_cpu_attr == CPU_PPC604E
22682 || rs6000_cpu_attr == CPU_PPC620
22683 || rs6000_cpu_attr == CPU_PPC630
22684 || rs6000_cpu_attr == CPU_PPC750
22685 || rs6000_cpu_attr == CPU_PPC7400
22686 || rs6000_cpu_attr == CPU_PPC7450
22687 || rs6000_cpu_attr == CPU_POWER4
22688 || rs6000_cpu_attr == CPU_POWER5
22689 || rs6000_cpu_attr == CPU_POWER7
22690 || rs6000_cpu_attr == CPU_CELL)
22691 && recog_memoized (dep_insn)
22692 && (INSN_CODE (dep_insn) >= 0))
22694 switch (get_attr_type (dep_insn))
22698 case TYPE_DELAYED_COMPARE:
22699 case TYPE_IMUL_COMPARE:
22700 case TYPE_LMUL_COMPARE:
22701 case TYPE_FPCOMPARE:
22702 case TYPE_CR_LOGICAL:
22703 case TYPE_DELAYED_CR:
22712 case TYPE_STORE_UX:
22714 case TYPE_FPSTORE_U:
22715 case TYPE_FPSTORE_UX:
22716 if ((rs6000_cpu == PROCESSOR_POWER6)
22717 && recog_memoized (dep_insn)
22718 && (INSN_CODE (dep_insn) >= 0))
22721 if (GET_CODE (PATTERN (insn)) != SET)
22722 /* If this happens, we have to extend this to schedule
22723 optimally. Return default for now. */
22726 /* Adjust the cost for the case where the value written
22727 by a fixed point operation is used as the address
22728 gen value on a store. */
22729 switch (get_attr_type (dep_insn))
22736 if (! store_data_bypass_p (dep_insn, insn))
22740 case TYPE_LOAD_EXT:
22741 case TYPE_LOAD_EXT_U:
22742 case TYPE_LOAD_EXT_UX:
22743 case TYPE_VAR_SHIFT_ROTATE:
22744 case TYPE_VAR_DELAYED_COMPARE:
22746 if (! store_data_bypass_p (dep_insn, insn))
22752 case TYPE_FAST_COMPARE:
22755 case TYPE_INSERT_WORD:
22756 case TYPE_INSERT_DWORD:
22757 case TYPE_FPLOAD_U:
22758 case TYPE_FPLOAD_UX:
22760 case TYPE_STORE_UX:
22761 case TYPE_FPSTORE_U:
22762 case TYPE_FPSTORE_UX:
22764 if (! store_data_bypass_p (dep_insn, insn))
22772 case TYPE_IMUL_COMPARE:
22773 case TYPE_LMUL_COMPARE:
22775 if (! store_data_bypass_p (dep_insn, insn))
22781 if (! store_data_bypass_p (dep_insn, insn))
22787 if (! store_data_bypass_p (dep_insn, insn))
22800 case TYPE_LOAD_EXT:
22801 case TYPE_LOAD_EXT_U:
22802 case TYPE_LOAD_EXT_UX:
22803 if ((rs6000_cpu == PROCESSOR_POWER6)
22804 && recog_memoized (dep_insn)
22805 && (INSN_CODE (dep_insn) >= 0))
22808 /* Adjust the cost for the case where the value written
22809 by a fixed point instruction is used within the address
22810 gen portion of a subsequent load(u)(x) */
22811 switch (get_attr_type (dep_insn))
22818 if (set_to_load_agen (dep_insn, insn))
22822 case TYPE_LOAD_EXT:
22823 case TYPE_LOAD_EXT_U:
22824 case TYPE_LOAD_EXT_UX:
22825 case TYPE_VAR_SHIFT_ROTATE:
22826 case TYPE_VAR_DELAYED_COMPARE:
22828 if (set_to_load_agen (dep_insn, insn))
22834 case TYPE_FAST_COMPARE:
22837 case TYPE_INSERT_WORD:
22838 case TYPE_INSERT_DWORD:
22839 case TYPE_FPLOAD_U:
22840 case TYPE_FPLOAD_UX:
22842 case TYPE_STORE_UX:
22843 case TYPE_FPSTORE_U:
22844 case TYPE_FPSTORE_UX:
22846 if (set_to_load_agen (dep_insn, insn))
22854 case TYPE_IMUL_COMPARE:
22855 case TYPE_LMUL_COMPARE:
22857 if (set_to_load_agen (dep_insn, insn))
22863 if (set_to_load_agen (dep_insn, insn))
22869 if (set_to_load_agen (dep_insn, insn))
22880 if ((rs6000_cpu == PROCESSOR_POWER6)
22881 && recog_memoized (dep_insn)
22882 && (INSN_CODE (dep_insn) >= 0)
22883 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22890 /* Fall out to return default cost. */
22894 case REG_DEP_OUTPUT:
22895 /* Output dependency; DEP_INSN writes a register that INSN writes some
22897 if ((rs6000_cpu == PROCESSOR_POWER6)
22898 && recog_memoized (dep_insn)
22899 && (INSN_CODE (dep_insn) >= 0))
22901 attr_type = get_attr_type (insn);
22906 if (get_attr_type (dep_insn) == TYPE_FP)
22910 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22918 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22923 gcc_unreachable ();
22929 /* Debug version of rs6000_adjust_cost. */
22932 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22934 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22940 switch (REG_NOTE_KIND (link))
22942 default: dep = "unknown depencency"; break;
22943 case REG_DEP_TRUE: dep = "data dependency"; break;
22944 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22945 case REG_DEP_ANTI: dep = "anti depencency"; break;
22949 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22950 "%s, insn:\n", ret, cost, dep);
22958 /* The function returns a true if INSN is microcoded.
22959 Return false otherwise. */
22962 is_microcoded_insn (rtx insn)
22964 if (!insn || !NONDEBUG_INSN_P (insn)
22965 || GET_CODE (PATTERN (insn)) == USE
22966 || GET_CODE (PATTERN (insn)) == CLOBBER)
22969 if (rs6000_cpu_attr == CPU_CELL)
22970 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22972 if (rs6000_sched_groups)
22974 enum attr_type type = get_attr_type (insn);
22975 if (type == TYPE_LOAD_EXT_U
22976 || type == TYPE_LOAD_EXT_UX
22977 || type == TYPE_LOAD_UX
22978 || type == TYPE_STORE_UX
22979 || type == TYPE_MFCR)
22986 /* The function returns true if INSN is cracked into 2 instructions
22987 by the processor (and therefore occupies 2 issue slots). */
22990 is_cracked_insn (rtx insn)
22992 if (!insn || !NONDEBUG_INSN_P (insn)
22993 || GET_CODE (PATTERN (insn)) == USE
22994 || GET_CODE (PATTERN (insn)) == CLOBBER)
22997 if (rs6000_sched_groups)
22999 enum attr_type type = get_attr_type (insn);
23000 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23001 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23002 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23003 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23004 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23005 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23006 || type == TYPE_IDIV || type == TYPE_LDIV
23007 || type == TYPE_INSERT_WORD)
23014 /* The function returns true if INSN can be issued only from
23015 the branch slot. */
23018 is_branch_slot_insn (rtx insn)
23020 if (!insn || !NONDEBUG_INSN_P (insn)
23021 || GET_CODE (PATTERN (insn)) == USE
23022 || GET_CODE (PATTERN (insn)) == CLOBBER)
23025 if (rs6000_sched_groups)
23027 enum attr_type type = get_attr_type (insn);
23028 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23036 /* The function returns true if out_inst sets a value that is
23037 used in the address generation computation of in_insn */
23039 set_to_load_agen (rtx out_insn, rtx in_insn)
23041 rtx out_set, in_set;
23043 /* For performance reasons, only handle the simple case where
23044 both loads are a single_set. */
23045 out_set = single_set (out_insn);
23048 in_set = single_set (in_insn);
23050 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23056 /* The function returns true if the target storage location of
23057 out_insn is adjacent to the target storage location of in_insn */
23058 /* Return 1 if memory locations are adjacent. */
23061 adjacent_mem_locations (rtx insn1, rtx insn2)
23064 rtx a = get_store_dest (PATTERN (insn1));
23065 rtx b = get_store_dest (PATTERN (insn2));
23067 if ((GET_CODE (XEXP (a, 0)) == REG
23068 || (GET_CODE (XEXP (a, 0)) == PLUS
23069 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23070 && (GET_CODE (XEXP (b, 0)) == REG
23071 || (GET_CODE (XEXP (b, 0)) == PLUS
23072 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23074 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23077 if (GET_CODE (XEXP (a, 0)) == PLUS)
23079 reg0 = XEXP (XEXP (a, 0), 0);
23080 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23083 reg0 = XEXP (a, 0);
23085 if (GET_CODE (XEXP (b, 0)) == PLUS)
23087 reg1 = XEXP (XEXP (b, 0), 0);
23088 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23091 reg1 = XEXP (b, 0);
23093 val_diff = val1 - val0;
23095 return ((REGNO (reg0) == REGNO (reg1))
23096 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23097 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23103 /* A C statement (sans semicolon) to update the integer scheduling
23104 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23105 INSN earlier, reduce the priority to execute INSN later. Do not
23106 define this macro if you do not need to adjust the scheduling
23107 priorities of insns. */
23110 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23112 /* On machines (like the 750) which have asymmetric integer units,
23113 where one integer unit can do multiply and divides and the other
23114 can't, reduce the priority of multiply/divide so it is scheduled
23115 before other integer operations. */
23118 if (! INSN_P (insn))
23121 if (GET_CODE (PATTERN (insn)) == USE)
23124 switch (rs6000_cpu_attr) {
23126 switch (get_attr_type (insn))
23133 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23134 priority, priority);
23135 if (priority >= 0 && priority < 0x01000000)
23142 if (insn_must_be_first_in_group (insn)
23143 && reload_completed
23144 && current_sched_info->sched_max_insns_priority
23145 && rs6000_sched_restricted_insns_priority)
23148 /* Prioritize insns that can be dispatched only in the first
23150 if (rs6000_sched_restricted_insns_priority == 1)
23151 /* Attach highest priority to insn. This means that in
23152 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23153 precede 'priority' (critical path) considerations. */
23154 return current_sched_info->sched_max_insns_priority;
23155 else if (rs6000_sched_restricted_insns_priority == 2)
23156 /* Increase priority of insn by a minimal amount. This means that in
23157 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23158 considerations precede dispatch-slot restriction considerations. */
23159 return (priority + 1);
23162 if (rs6000_cpu == PROCESSOR_POWER6
23163 && ((load_store_pendulum == -2 && is_load_insn (insn))
23164 || (load_store_pendulum == 2 && is_store_insn (insn))))
23165 /* Attach highest priority to insn if the scheduler has just issued two
23166 stores and this instruction is a load, or two loads and this instruction
23167 is a store. Power6 wants loads and stores scheduled alternately
23169 return current_sched_info->sched_max_insns_priority;
23174 /* Return true if the instruction is nonpipelined on the Cell. */
23176 is_nonpipeline_insn (rtx insn)
23178 enum attr_type type;
23179 if (!insn || !NONDEBUG_INSN_P (insn)
23180 || GET_CODE (PATTERN (insn)) == USE
23181 || GET_CODE (PATTERN (insn)) == CLOBBER)
23184 type = get_attr_type (insn);
23185 if (type == TYPE_IMUL
23186 || type == TYPE_IMUL2
23187 || type == TYPE_IMUL3
23188 || type == TYPE_LMUL
23189 || type == TYPE_IDIV
23190 || type == TYPE_LDIV
23191 || type == TYPE_SDIV
23192 || type == TYPE_DDIV
23193 || type == TYPE_SSQRT
23194 || type == TYPE_DSQRT
23195 || type == TYPE_MFCR
23196 || type == TYPE_MFCRF
23197 || type == TYPE_MFJMPR)
23205 /* Return how many instructions the machine can issue per cycle. */
23208 rs6000_issue_rate (void)
23210 /* Unless scheduling for register pressure, use issue rate of 1 for
23211 first scheduling pass to decrease degradation. */
23212 if (!reload_completed && !flag_sched_pressure)
23215 switch (rs6000_cpu_attr) {
23216 case CPU_RIOS1: /* ? */
23218 case CPU_PPC601: /* ? */
23227 case CPU_PPCE300C2:
23228 case CPU_PPCE300C3:
23229 case CPU_PPCE500MC:
23230 case CPU_PPCE500MC64:
23250 /* Return how many instructions to look ahead for better insn
23254 rs6000_use_sched_lookahead (void)
23256 if (rs6000_cpu_attr == CPU_PPC8540)
23258 if (rs6000_cpu_attr == CPU_CELL)
23259 return (reload_completed ? 8 : 0);
23263 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23265 rs6000_use_sched_lookahead_guard (rtx insn)
23267 if (rs6000_cpu_attr != CPU_CELL)
23270 if (insn == NULL_RTX || !INSN_P (insn))
23273 if (!reload_completed
23274 || is_nonpipeline_insn (insn)
23275 || is_microcoded_insn (insn))
23281 /* Determine is PAT refers to memory. */
23284 is_mem_ref (rtx pat)
23290 /* stack_tie does not produce any real memory traffic. */
23291 if (GET_CODE (pat) == UNSPEC
23292 && XINT (pat, 1) == UNSPEC_TIE)
23295 if (GET_CODE (pat) == MEM)
23298 /* Recursively process the pattern. */
23299 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23301 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23304 ret |= is_mem_ref (XEXP (pat, i));
23305 else if (fmt[i] == 'E')
23306 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23307 ret |= is_mem_ref (XVECEXP (pat, i, j));
23313 /* Determine if PAT is a PATTERN of a load insn. */
23316 is_load_insn1 (rtx pat)
23318 if (!pat || pat == NULL_RTX)
23321 if (GET_CODE (pat) == SET)
23322 return is_mem_ref (SET_SRC (pat));
23324 if (GET_CODE (pat) == PARALLEL)
23328 for (i = 0; i < XVECLEN (pat, 0); i++)
23329 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23336 /* Determine if INSN loads from memory. */
23339 is_load_insn (rtx insn)
23341 if (!insn || !INSN_P (insn))
23344 if (GET_CODE (insn) == CALL_INSN)
23347 return is_load_insn1 (PATTERN (insn));
23350 /* Determine if PAT is a PATTERN of a store insn. */
23353 is_store_insn1 (rtx pat)
23355 if (!pat || pat == NULL_RTX)
23358 if (GET_CODE (pat) == SET)
23359 return is_mem_ref (SET_DEST (pat));
23361 if (GET_CODE (pat) == PARALLEL)
23365 for (i = 0; i < XVECLEN (pat, 0); i++)
23366 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23373 /* Determine if INSN stores to memory. */
23376 is_store_insn (rtx insn)
23378 if (!insn || !INSN_P (insn))
23381 return is_store_insn1 (PATTERN (insn));
23384 /* Return the dest of a store insn. */
23387 get_store_dest (rtx pat)
23389 gcc_assert (is_store_insn1 (pat));
23391 if (GET_CODE (pat) == SET)
23392 return SET_DEST (pat);
23393 else if (GET_CODE (pat) == PARALLEL)
23397 for (i = 0; i < XVECLEN (pat, 0); i++)
23399 rtx inner_pat = XVECEXP (pat, 0, i);
23400 if (GET_CODE (inner_pat) == SET
23401 && is_mem_ref (SET_DEST (inner_pat)))
23405 /* We shouldn't get here, because we should have either a simple
23406 store insn or a store with update which are covered above. */
23410 /* Returns whether the dependence between INSN and NEXT is considered
23411 costly by the given target. */
23414 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23419 /* If the flag is not enabled - no dependence is considered costly;
23420 allow all dependent insns in the same group.
23421 This is the most aggressive option. */
23422 if (rs6000_sched_costly_dep == no_dep_costly)
23425 /* If the flag is set to 1 - a dependence is always considered costly;
23426 do not allow dependent instructions in the same group.
23427 This is the most conservative option. */
23428 if (rs6000_sched_costly_dep == all_deps_costly)
23431 insn = DEP_PRO (dep);
23432 next = DEP_CON (dep);
23434 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23435 && is_load_insn (next)
23436 && is_store_insn (insn))
23437 /* Prevent load after store in the same group. */
23440 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23441 && is_load_insn (next)
23442 && is_store_insn (insn)
23443 && DEP_TYPE (dep) == REG_DEP_TRUE)
23444 /* Prevent load after store in the same group if it is a true
23448 /* The flag is set to X; dependences with latency >= X are considered costly,
23449 and will not be scheduled in the same group. */
23450 if (rs6000_sched_costly_dep <= max_dep_latency
23451 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23457 /* Return the next insn after INSN that is found before TAIL is reached,
23458 skipping any "non-active" insns - insns that will not actually occupy
23459 an issue slot. Return NULL_RTX if such an insn is not found. */
23462 get_next_active_insn (rtx insn, rtx tail)
23464 if (insn == NULL_RTX || insn == tail)
23469 insn = NEXT_INSN (insn);
23470 if (insn == NULL_RTX || insn == tail)
23475 || (NONJUMP_INSN_P (insn)
23476 && GET_CODE (PATTERN (insn)) != USE
23477 && GET_CODE (PATTERN (insn)) != CLOBBER
23478 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23484 /* We are about to begin issuing insns for this clock cycle. */
23487 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23488 rtx *ready ATTRIBUTE_UNUSED,
23489 int *pn_ready ATTRIBUTE_UNUSED,
23490 int clock_var ATTRIBUTE_UNUSED)
23492 int n_ready = *pn_ready;
23495 fprintf (dump, "// rs6000_sched_reorder :\n");
23497 /* Reorder the ready list, if the second to last ready insn
23498 is a nonepipeline insn. */
23499 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23501 if (is_nonpipeline_insn (ready[n_ready - 1])
23502 && (recog_memoized (ready[n_ready - 2]) > 0))
23503 /* Simply swap first two insns. */
23505 rtx tmp = ready[n_ready - 1];
23506 ready[n_ready - 1] = ready[n_ready - 2];
23507 ready[n_ready - 2] = tmp;
23511 if (rs6000_cpu == PROCESSOR_POWER6)
23512 load_store_pendulum = 0;
23514 return rs6000_issue_rate ();
23517 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23520 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23521 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23524 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23526 /* For Power6, we need to handle some special cases to try and keep the
23527 store queue from overflowing and triggering expensive flushes.
23529 This code monitors how load and store instructions are being issued
23530 and skews the ready list one way or the other to increase the likelihood
23531 that a desired instruction is issued at the proper time.
23533 A couple of things are done. First, we maintain a "load_store_pendulum"
23534 to track the current state of load/store issue.
23536 - If the pendulum is at zero, then no loads or stores have been
23537 issued in the current cycle so we do nothing.
23539 - If the pendulum is 1, then a single load has been issued in this
23540 cycle and we attempt to locate another load in the ready list to
23543 - If the pendulum is -2, then two stores have already been
23544 issued in this cycle, so we increase the priority of the first load
23545 in the ready list to increase it's likelihood of being chosen first
23548 - If the pendulum is -1, then a single store has been issued in this
23549 cycle and we attempt to locate another store in the ready list to
23550 issue with it, preferring a store to an adjacent memory location to
23551 facilitate store pairing in the store queue.
23553 - If the pendulum is 2, then two loads have already been
23554 issued in this cycle, so we increase the priority of the first store
23555 in the ready list to increase it's likelihood of being chosen first
23558 - If the pendulum < -2 or > 2, then do nothing.
23560 Note: This code covers the most common scenarios. There exist non
23561 load/store instructions which make use of the LSU and which
23562 would need to be accounted for to strictly model the behavior
23563 of the machine. Those instructions are currently unaccounted
23564 for to help minimize compile time overhead of this code.
23566 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23572 if (is_store_insn (last_scheduled_insn))
23573 /* Issuing a store, swing the load_store_pendulum to the left */
23574 load_store_pendulum--;
23575 else if (is_load_insn (last_scheduled_insn))
23576 /* Issuing a load, swing the load_store_pendulum to the right */
23577 load_store_pendulum++;
23579 return cached_can_issue_more;
23581 /* If the pendulum is balanced, or there is only one instruction on
23582 the ready list, then all is well, so return. */
23583 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23584 return cached_can_issue_more;
23586 if (load_store_pendulum == 1)
23588 /* A load has been issued in this cycle. Scan the ready list
23589 for another load to issue with it */
23594 if (is_load_insn (ready[pos]))
23596 /* Found a load. Move it to the head of the ready list,
23597 and adjust it's priority so that it is more likely to
23600 for (i=pos; i<*pn_ready-1; i++)
23601 ready[i] = ready[i + 1];
23602 ready[*pn_ready-1] = tmp;
23604 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23605 INSN_PRIORITY (tmp)++;
23611 else if (load_store_pendulum == -2)
23613 /* Two stores have been issued in this cycle. Increase the
23614 priority of the first load in the ready list to favor it for
23615 issuing in the next cycle. */
23620 if (is_load_insn (ready[pos])
23622 && INSN_PRIORITY_KNOWN (ready[pos]))
23624 INSN_PRIORITY (ready[pos])++;
23626 /* Adjust the pendulum to account for the fact that a load
23627 was found and increased in priority. This is to prevent
23628 increasing the priority of multiple loads */
23629 load_store_pendulum--;
23636 else if (load_store_pendulum == -1)
23638 /* A store has been issued in this cycle. Scan the ready list for
23639 another store to issue with it, preferring a store to an adjacent
23641 int first_store_pos = -1;
23647 if (is_store_insn (ready[pos]))
23649 /* Maintain the index of the first store found on the
23651 if (first_store_pos == -1)
23652 first_store_pos = pos;
23654 if (is_store_insn (last_scheduled_insn)
23655 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23657 /* Found an adjacent store. Move it to the head of the
23658 ready list, and adjust it's priority so that it is
23659 more likely to stay there */
23661 for (i=pos; i<*pn_ready-1; i++)
23662 ready[i] = ready[i + 1];
23663 ready[*pn_ready-1] = tmp;
23665 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23666 INSN_PRIORITY (tmp)++;
23668 first_store_pos = -1;
23676 if (first_store_pos >= 0)
23678 /* An adjacent store wasn't found, but a non-adjacent store was,
23679 so move the non-adjacent store to the front of the ready
23680 list, and adjust its priority so that it is more likely to
23682 tmp = ready[first_store_pos];
23683 for (i=first_store_pos; i<*pn_ready-1; i++)
23684 ready[i] = ready[i + 1];
23685 ready[*pn_ready-1] = tmp;
23686 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23687 INSN_PRIORITY (tmp)++;
23690 else if (load_store_pendulum == 2)
23692 /* Two loads have been issued in this cycle. Increase the priority
23693 of the first store in the ready list to favor it for issuing in
23699 if (is_store_insn (ready[pos])
23701 && INSN_PRIORITY_KNOWN (ready[pos]))
23703 INSN_PRIORITY (ready[pos])++;
23705 /* Adjust the pendulum to account for the fact that a store
23706 was found and increased in priority. This is to prevent
23707 increasing the priority of multiple stores */
23708 load_store_pendulum++;
23717 return cached_can_issue_more;
23720 /* Return whether the presence of INSN causes a dispatch group termination
23721 of group WHICH_GROUP.
23723 If WHICH_GROUP == current_group, this function will return true if INSN
23724 causes the termination of the current group (i.e, the dispatch group to
23725 which INSN belongs). This means that INSN will be the last insn in the
23726 group it belongs to.
23728 If WHICH_GROUP == previous_group, this function will return true if INSN
23729 causes the termination of the previous group (i.e, the dispatch group that
23730 precedes the group to which INSN belongs). This means that INSN will be
23731 the first insn in the group it belongs to). */
23734 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23741 first = insn_must_be_first_in_group (insn);
23742 last = insn_must_be_last_in_group (insn);
23747 if (which_group == current_group)
23749 else if (which_group == previous_group)
23757 insn_must_be_first_in_group (rtx insn)
23759 enum attr_type type;
23762 || GET_CODE (insn) == NOTE
23763 || DEBUG_INSN_P (insn)
23764 || GET_CODE (PATTERN (insn)) == USE
23765 || GET_CODE (PATTERN (insn)) == CLOBBER)
23768 switch (rs6000_cpu)
23770 case PROCESSOR_POWER5:
23771 if (is_cracked_insn (insn))
23773 case PROCESSOR_POWER4:
23774 if (is_microcoded_insn (insn))
23777 if (!rs6000_sched_groups)
23780 type = get_attr_type (insn);
23787 case TYPE_DELAYED_CR:
23788 case TYPE_CR_LOGICAL:
23802 case PROCESSOR_POWER6:
23803 type = get_attr_type (insn);
23807 case TYPE_INSERT_DWORD:
23811 case TYPE_VAR_SHIFT_ROTATE:
23818 case TYPE_INSERT_WORD:
23819 case TYPE_DELAYED_COMPARE:
23820 case TYPE_IMUL_COMPARE:
23821 case TYPE_LMUL_COMPARE:
23822 case TYPE_FPCOMPARE:
23833 case TYPE_LOAD_EXT_UX:
23835 case TYPE_STORE_UX:
23836 case TYPE_FPLOAD_U:
23837 case TYPE_FPLOAD_UX:
23838 case TYPE_FPSTORE_U:
23839 case TYPE_FPSTORE_UX:
23845 case PROCESSOR_POWER7:
23846 type = get_attr_type (insn);
23850 case TYPE_CR_LOGICAL:
23857 case TYPE_DELAYED_COMPARE:
23858 case TYPE_VAR_DELAYED_COMPARE:
23864 case TYPE_LOAD_EXT:
23865 case TYPE_LOAD_EXT_U:
23866 case TYPE_LOAD_EXT_UX:
23868 case TYPE_STORE_UX:
23869 case TYPE_FPLOAD_U:
23870 case TYPE_FPLOAD_UX:
23871 case TYPE_FPSTORE_U:
23872 case TYPE_FPSTORE_UX:
23888 insn_must_be_last_in_group (rtx insn)
23890 enum attr_type type;
23893 || GET_CODE (insn) == NOTE
23894 || DEBUG_INSN_P (insn)
23895 || GET_CODE (PATTERN (insn)) == USE
23896 || GET_CODE (PATTERN (insn)) == CLOBBER)
23899 switch (rs6000_cpu) {
23900 case PROCESSOR_POWER4:
23901 case PROCESSOR_POWER5:
23902 if (is_microcoded_insn (insn))
23905 if (is_branch_slot_insn (insn))
23909 case PROCESSOR_POWER6:
23910 type = get_attr_type (insn);
23917 case TYPE_VAR_SHIFT_ROTATE:
23924 case TYPE_DELAYED_COMPARE:
23925 case TYPE_IMUL_COMPARE:
23926 case TYPE_LMUL_COMPARE:
23927 case TYPE_FPCOMPARE:
23941 case PROCESSOR_POWER7:
23942 type = get_attr_type (insn);
23950 case TYPE_LOAD_EXT_U:
23951 case TYPE_LOAD_EXT_UX:
23952 case TYPE_STORE_UX:
23965 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23966 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23969 is_costly_group (rtx *group_insns, rtx next_insn)
23972 int issue_rate = rs6000_issue_rate ();
23974 for (i = 0; i < issue_rate; i++)
23976 sd_iterator_def sd_it;
23978 rtx insn = group_insns[i];
23983 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23985 rtx next = DEP_CON (dep);
23987 if (next == next_insn
23988 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23996 /* Utility of the function redefine_groups.
23997 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23998 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23999 to keep it "far" (in a separate group) from GROUP_INSNS, following
24000 one of the following schemes, depending on the value of the flag
24001 -minsert_sched_nops = X:
24002 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24003 in order to force NEXT_INSN into a separate group.
24004 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24005 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24006 insertion (has a group just ended, how many vacant issue slots remain in the
24007 last group, and how many dispatch groups were encountered so far). */
24010 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24011 rtx next_insn, bool *group_end, int can_issue_more,
24016 int issue_rate = rs6000_issue_rate ();
24017 bool end = *group_end;
24020 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24021 return can_issue_more;
24023 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24024 return can_issue_more;
24026 force = is_costly_group (group_insns, next_insn);
24028 return can_issue_more;
24030 if (sched_verbose > 6)
24031 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24032 *group_count ,can_issue_more);
24034 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24037 can_issue_more = 0;
24039 /* Since only a branch can be issued in the last issue_slot, it is
24040 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24041 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24042 in this case the last nop will start a new group and the branch
24043 will be forced to the new group. */
24044 if (can_issue_more && !is_branch_slot_insn (next_insn))
24047 while (can_issue_more > 0)
24050 emit_insn_before (nop, next_insn);
24058 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24060 int n_nops = rs6000_sched_insert_nops;
24062 /* Nops can't be issued from the branch slot, so the effective
24063 issue_rate for nops is 'issue_rate - 1'. */
24064 if (can_issue_more == 0)
24065 can_issue_more = issue_rate;
24067 if (can_issue_more == 0)
24069 can_issue_more = issue_rate - 1;
24072 for (i = 0; i < issue_rate; i++)
24074 group_insns[i] = 0;
24081 emit_insn_before (nop, next_insn);
24082 if (can_issue_more == issue_rate - 1) /* new group begins */
24085 if (can_issue_more == 0)
24087 can_issue_more = issue_rate - 1;
24090 for (i = 0; i < issue_rate; i++)
24092 group_insns[i] = 0;
24098 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24101 /* Is next_insn going to start a new group? */
24104 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24105 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24106 || (can_issue_more < issue_rate &&
24107 insn_terminates_group_p (next_insn, previous_group)));
24108 if (*group_end && end)
24111 if (sched_verbose > 6)
24112 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24113 *group_count, can_issue_more);
24114 return can_issue_more;
24117 return can_issue_more;
24120 /* This function tries to synch the dispatch groups that the compiler "sees"
24121 with the dispatch groups that the processor dispatcher is expected to
24122 form in practice. It tries to achieve this synchronization by forcing the
24123 estimated processor grouping on the compiler (as opposed to the function
24124 'pad_goups' which tries to force the scheduler's grouping on the processor).
24126 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24127 examines the (estimated) dispatch groups that will be formed by the processor
24128 dispatcher. It marks these group boundaries to reflect the estimated
24129 processor grouping, overriding the grouping that the scheduler had marked.
24130 Depending on the value of the flag '-minsert-sched-nops' this function can
24131 force certain insns into separate groups or force a certain distance between
24132 them by inserting nops, for example, if there exists a "costly dependence"
24135 The function estimates the group boundaries that the processor will form as
24136 follows: It keeps track of how many vacant issue slots are available after
24137 each insn. A subsequent insn will start a new group if one of the following
24139 - no more vacant issue slots remain in the current dispatch group.
24140 - only the last issue slot, which is the branch slot, is vacant, but the next
24141 insn is not a branch.
24142 - only the last 2 or less issue slots, including the branch slot, are vacant,
24143 which means that a cracked insn (which occupies two issue slots) can't be
24144 issued in this group.
24145 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24146 start a new group. */
24149 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24151 rtx insn, next_insn;
24153 int can_issue_more;
24156 int group_count = 0;
24160 issue_rate = rs6000_issue_rate ();
24161 group_insns = XALLOCAVEC (rtx, issue_rate);
24162 for (i = 0; i < issue_rate; i++)
24164 group_insns[i] = 0;
24166 can_issue_more = issue_rate;
24168 insn = get_next_active_insn (prev_head_insn, tail);
24171 while (insn != NULL_RTX)
24173 slot = (issue_rate - can_issue_more);
24174 group_insns[slot] = insn;
24176 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24177 if (insn_terminates_group_p (insn, current_group))
24178 can_issue_more = 0;
24180 next_insn = get_next_active_insn (insn, tail);
24181 if (next_insn == NULL_RTX)
24182 return group_count + 1;
24184 /* Is next_insn going to start a new group? */
24186 = (can_issue_more == 0
24187 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24188 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24189 || (can_issue_more < issue_rate &&
24190 insn_terminates_group_p (next_insn, previous_group)));
24192 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24193 next_insn, &group_end, can_issue_more,
24199 can_issue_more = 0;
24200 for (i = 0; i < issue_rate; i++)
24202 group_insns[i] = 0;
24206 if (GET_MODE (next_insn) == TImode && can_issue_more)
24207 PUT_MODE (next_insn, VOIDmode);
24208 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24209 PUT_MODE (next_insn, TImode);
24212 if (can_issue_more == 0)
24213 can_issue_more = issue_rate;
24216 return group_count;
24219 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24220 dispatch group boundaries that the scheduler had marked. Pad with nops
24221 any dispatch groups which have vacant issue slots, in order to force the
24222 scheduler's grouping on the processor dispatcher. The function
24223 returns the number of dispatch groups found. */
24226 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24228 rtx insn, next_insn;
24231 int can_issue_more;
24233 int group_count = 0;
24235 /* Initialize issue_rate. */
24236 issue_rate = rs6000_issue_rate ();
24237 can_issue_more = issue_rate;
24239 insn = get_next_active_insn (prev_head_insn, tail);
24240 next_insn = get_next_active_insn (insn, tail);
24242 while (insn != NULL_RTX)
24245 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24247 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24249 if (next_insn == NULL_RTX)
24254 /* If the scheduler had marked group termination at this location
24255 (between insn and next_insn), and neither insn nor next_insn will
24256 force group termination, pad the group with nops to force group
24259 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24260 && !insn_terminates_group_p (insn, current_group)
24261 && !insn_terminates_group_p (next_insn, previous_group))
24263 if (!is_branch_slot_insn (next_insn))
24266 while (can_issue_more)
24269 emit_insn_before (nop, next_insn);
24274 can_issue_more = issue_rate;
24279 next_insn = get_next_active_insn (insn, tail);
24282 return group_count;
24285 /* We're beginning a new block. Initialize data structures as necessary. */
24288 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24289 int sched_verbose ATTRIBUTE_UNUSED,
24290 int max_ready ATTRIBUTE_UNUSED)
24292 last_scheduled_insn = NULL_RTX;
24293 load_store_pendulum = 0;
24296 /* The following function is called at the end of scheduling BB.
24297 After reload, it inserts nops at insn group bundling. */
24300 rs6000_sched_finish (FILE *dump, int sched_verbose)
24305 fprintf (dump, "=== Finishing schedule.\n");
24307 if (reload_completed && rs6000_sched_groups)
24309 /* Do not run sched_finish hook when selective scheduling enabled. */
24310 if (sel_sched_p ())
24313 if (rs6000_sched_insert_nops == sched_finish_none)
24316 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24317 n_groups = pad_groups (dump, sched_verbose,
24318 current_sched_info->prev_head,
24319 current_sched_info->next_tail);
24321 n_groups = redefine_groups (dump, sched_verbose,
24322 current_sched_info->prev_head,
24323 current_sched_info->next_tail);
24325 if (sched_verbose >= 6)
24327 fprintf (dump, "ngroups = %d\n", n_groups);
24328 print_rtl (dump, current_sched_info->prev_head);
24329 fprintf (dump, "Done finish_sched\n");
24334 struct _rs6000_sched_context
24336 short cached_can_issue_more;
24337 rtx last_scheduled_insn;
24338 int load_store_pendulum;
24341 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24342 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24344 /* Allocate store for new scheduling context. */
24346 rs6000_alloc_sched_context (void)
24348 return xmalloc (sizeof (rs6000_sched_context_def));
24351 /* If CLEAN_P is true then initializes _SC with clean data,
24352 and from the global context otherwise. */
24354 rs6000_init_sched_context (void *_sc, bool clean_p)
24356 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24360 sc->cached_can_issue_more = 0;
24361 sc->last_scheduled_insn = NULL_RTX;
24362 sc->load_store_pendulum = 0;
24366 sc->cached_can_issue_more = cached_can_issue_more;
24367 sc->last_scheduled_insn = last_scheduled_insn;
24368 sc->load_store_pendulum = load_store_pendulum;
24372 /* Sets the global scheduling context to the one pointed to by _SC. */
24374 rs6000_set_sched_context (void *_sc)
24376 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24378 gcc_assert (sc != NULL);
24380 cached_can_issue_more = sc->cached_can_issue_more;
24381 last_scheduled_insn = sc->last_scheduled_insn;
24382 load_store_pendulum = sc->load_store_pendulum;
24387 rs6000_free_sched_context (void *_sc)
24389 gcc_assert (_sc != NULL);
24395 /* Length in units of the trampoline for entering a nested function. */
24398 rs6000_trampoline_size (void)
24402 switch (DEFAULT_ABI)
24405 gcc_unreachable ();
24408 ret = (TARGET_32BIT) ? 12 : 24;
24413 ret = (TARGET_32BIT) ? 40 : 48;
24420 /* Emit RTL insns to initialize the variable parts of a trampoline.
24421 FNADDR is an RTX for the address of the function's pure code.
24422 CXT is an RTX for the static chain value for the function. */
24425 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24427 int regsize = (TARGET_32BIT) ? 4 : 8;
24428 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24429 rtx ctx_reg = force_reg (Pmode, cxt);
24430 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24432 switch (DEFAULT_ABI)
24435 gcc_unreachable ();
24437 /* Under AIX, just build the 3 word function descriptor */
24440 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24441 rtx fn_reg = gen_reg_rtx (Pmode);
24442 rtx toc_reg = gen_reg_rtx (Pmode);
24444 /* Macro to shorten the code expansions below. */
24445 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24447 m_tramp = replace_equiv_address (m_tramp, addr);
24449 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24450 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24451 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24452 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24453 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24459 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24462 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24463 LCT_NORMAL, VOIDmode, 4,
24465 GEN_INT (rs6000_trampoline_size ()), SImode,
24473 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24474 identifier as an argument, so the front end shouldn't look it up. */
24477 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24479 return is_attribute_p ("altivec", attr_id);
24482 /* Handle the "altivec" attribute. The attribute may have
24483 arguments as follows:
24485 __attribute__((altivec(vector__)))
24486 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24487 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24489 and may appear more than once (e.g., 'vector bool char') in a
24490 given declaration. */
24493 rs6000_handle_altivec_attribute (tree *node,
24494 tree name ATTRIBUTE_UNUSED,
24496 int flags ATTRIBUTE_UNUSED,
24497 bool *no_add_attrs)
24499 tree type = *node, result = NULL_TREE;
24500 enum machine_mode mode;
24503 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24504 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24505 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24508 while (POINTER_TYPE_P (type)
24509 || TREE_CODE (type) == FUNCTION_TYPE
24510 || TREE_CODE (type) == METHOD_TYPE
24511 || TREE_CODE (type) == ARRAY_TYPE)
24512 type = TREE_TYPE (type);
24514 mode = TYPE_MODE (type);
24516 /* Check for invalid AltiVec type qualifiers. */
24517 if (type == long_double_type_node)
24518 error ("use of %<long double%> in AltiVec types is invalid");
24519 else if (type == boolean_type_node)
24520 error ("use of boolean types in AltiVec types is invalid");
24521 else if (TREE_CODE (type) == COMPLEX_TYPE)
24522 error ("use of %<complex%> in AltiVec types is invalid");
24523 else if (DECIMAL_FLOAT_MODE_P (mode))
24524 error ("use of decimal floating point types in AltiVec types is invalid");
24525 else if (!TARGET_VSX)
24527 if (type == long_unsigned_type_node || type == long_integer_type_node)
24530 error ("use of %<long%> in AltiVec types is invalid for "
24531 "64-bit code without -mvsx");
24532 else if (rs6000_warn_altivec_long)
24533 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24536 else if (type == long_long_unsigned_type_node
24537 || type == long_long_integer_type_node)
24538 error ("use of %<long long%> in AltiVec types is invalid without "
24540 else if (type == double_type_node)
24541 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24544 switch (altivec_type)
24547 unsigned_p = TYPE_UNSIGNED (type);
24551 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24554 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24557 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24560 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24562 case SFmode: result = V4SF_type_node; break;
24563 case DFmode: result = V2DF_type_node; break;
24564 /* If the user says 'vector int bool', we may be handed the 'bool'
24565 attribute _before_ the 'vector' attribute, and so select the
24566 proper type in the 'b' case below. */
24567 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24568 case V2DImode: case V2DFmode:
24576 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24577 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24578 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24579 case QImode: case V16QImode: result = bool_V16QI_type_node;
24586 case V8HImode: result = pixel_V8HI_type_node;
24592 /* Propagate qualifiers attached to the element type
24593 onto the vector type. */
24594 if (result && result != type && TYPE_QUALS (type))
24595 result = build_qualified_type (result, TYPE_QUALS (type));
24597 *no_add_attrs = true; /* No need to hang on to the attribute. */
24600 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24605 /* AltiVec defines four built-in scalar types that serve as vector
24606 elements; we must teach the compiler how to mangle them. */
24608 static const char *
24609 rs6000_mangle_type (const_tree type)
24611 type = TYPE_MAIN_VARIANT (type);
24613 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24614 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24617 if (type == bool_char_type_node) return "U6__boolc";
24618 if (type == bool_short_type_node) return "U6__bools";
24619 if (type == pixel_type_node) return "u7__pixel";
24620 if (type == bool_int_type_node) return "U6__booli";
24621 if (type == bool_long_type_node) return "U6__booll";
24623 /* Mangle IBM extended float long double as `g' (__float128) on
24624 powerpc*-linux where long-double-64 previously was the default. */
24625 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24627 && TARGET_LONG_DOUBLE_128
24628 && !TARGET_IEEEQUAD)
24631 /* For all other types, use normal C++ mangling. */
24635 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24636 struct attribute_spec.handler. */
24639 rs6000_handle_longcall_attribute (tree *node, tree name,
24640 tree args ATTRIBUTE_UNUSED,
24641 int flags ATTRIBUTE_UNUSED,
24642 bool *no_add_attrs)
24644 if (TREE_CODE (*node) != FUNCTION_TYPE
24645 && TREE_CODE (*node) != FIELD_DECL
24646 && TREE_CODE (*node) != TYPE_DECL)
24648 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24650 *no_add_attrs = true;
24656 /* Set longcall attributes on all functions declared when
24657 rs6000_default_long_calls is true. */
24659 rs6000_set_default_type_attributes (tree type)
24661 if (rs6000_default_long_calls
24662 && (TREE_CODE (type) == FUNCTION_TYPE
24663 || TREE_CODE (type) == METHOD_TYPE))
24664 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24666 TYPE_ATTRIBUTES (type));
24669 darwin_set_default_type_attributes (type);
24673 /* Return a reference suitable for calling a function with the
24674 longcall attribute. */
24677 rs6000_longcall_ref (rtx call_ref)
24679 const char *call_name;
24682 if (GET_CODE (call_ref) != SYMBOL_REF)
24685 /* System V adds '.' to the internal name, so skip them. */
24686 call_name = XSTR (call_ref, 0);
24687 if (*call_name == '.')
24689 while (*call_name == '.')
24692 node = get_identifier (call_name);
24693 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24696 return force_reg (Pmode, call_ref);
24699 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24700 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24703 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24704 struct attribute_spec.handler. */
24706 rs6000_handle_struct_attribute (tree *node, tree name,
24707 tree args ATTRIBUTE_UNUSED,
24708 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24711 if (DECL_P (*node))
24713 if (TREE_CODE (*node) == TYPE_DECL)
24714 type = &TREE_TYPE (*node);
24719 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24720 || TREE_CODE (*type) == UNION_TYPE)))
24722 warning (OPT_Wattributes, "%qE attribute ignored", name);
24723 *no_add_attrs = true;
24726 else if ((is_attribute_p ("ms_struct", name)
24727 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24728 || ((is_attribute_p ("gcc_struct", name)
24729 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24731 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24733 *no_add_attrs = true;
24740 rs6000_ms_bitfield_layout_p (const_tree record_type)
24742 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24743 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24744 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24747 #ifdef USING_ELFOS_H
24749 /* A get_unnamed_section callback, used for switching to toc_section. */
24752 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24754 if (DEFAULT_ABI == ABI_AIX
24755 && TARGET_MINIMAL_TOC
24756 && !TARGET_RELOCATABLE)
24758 if (!toc_initialized)
24760 toc_initialized = 1;
24761 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24762 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24763 fprintf (asm_out_file, "\t.tc ");
24764 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24765 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24766 fprintf (asm_out_file, "\n");
24768 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24769 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24770 fprintf (asm_out_file, " = .+32768\n");
24773 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24775 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24776 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24779 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24780 if (!toc_initialized)
24782 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24783 fprintf (asm_out_file, " = .+32768\n");
24784 toc_initialized = 1;
24789 /* Implement TARGET_ASM_INIT_SECTIONS. */
24792 rs6000_elf_asm_init_sections (void)
24795 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24798 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24799 SDATA2_SECTION_ASM_OP);
24802 /* Implement TARGET_SELECT_RTX_SECTION. */
24805 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24806 unsigned HOST_WIDE_INT align)
24808 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24809 return toc_section;
24811 return default_elf_select_rtx_section (mode, x, align);
24814 /* For a SYMBOL_REF, set generic flags and then perform some
24815 target-specific processing.
24817 When the AIX ABI is requested on a non-AIX system, replace the
24818 function name with the real name (with a leading .) rather than the
24819 function descriptor name. This saves a lot of overriding code to
24820 read the prefixes. */
24823 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24825 default_encode_section_info (decl, rtl, first);
24828 && TREE_CODE (decl) == FUNCTION_DECL
24830 && DEFAULT_ABI == ABI_AIX)
24832 rtx sym_ref = XEXP (rtl, 0);
24833 size_t len = strlen (XSTR (sym_ref, 0));
24834 char *str = XALLOCAVEC (char, len + 2);
24836 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24837 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24842 compare_section_name (const char *section, const char *templ)
24846 len = strlen (templ);
24847 return (strncmp (section, templ, len) == 0
24848 && (section[len] == 0 || section[len] == '.'));
24852 rs6000_elf_in_small_data_p (const_tree decl)
24854 if (rs6000_sdata == SDATA_NONE)
24857 /* We want to merge strings, so we never consider them small data. */
24858 if (TREE_CODE (decl) == STRING_CST)
24861 /* Functions are never in the small data area. */
24862 if (TREE_CODE (decl) == FUNCTION_DECL)
24865 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24867 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24868 if (compare_section_name (section, ".sdata")
24869 || compare_section_name (section, ".sdata2")
24870 || compare_section_name (section, ".gnu.linkonce.s")
24871 || compare_section_name (section, ".sbss")
24872 || compare_section_name (section, ".sbss2")
24873 || compare_section_name (section, ".gnu.linkonce.sb")
24874 || strcmp (section, ".PPC.EMB.sdata0") == 0
24875 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24880 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24883 && size <= g_switch_value
24884 /* If it's not public, and we're not going to reference it there,
24885 there's no need to put it in the small data section. */
24886 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24893 #endif /* USING_ELFOS_H */
24895 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24898 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24900 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24903 /* Return a REG that occurs in ADDR with coefficient 1.
24904 ADDR can be effectively incremented by incrementing REG.
24906 r0 is special and we must not select it as an address
24907 register by this routine since our caller will try to
24908 increment the returned register via an "la" instruction. */
24911 find_addr_reg (rtx addr)
24913 while (GET_CODE (addr) == PLUS)
24915 if (GET_CODE (XEXP (addr, 0)) == REG
24916 && REGNO (XEXP (addr, 0)) != 0)
24917 addr = XEXP (addr, 0);
24918 else if (GET_CODE (XEXP (addr, 1)) == REG
24919 && REGNO (XEXP (addr, 1)) != 0)
24920 addr = XEXP (addr, 1);
24921 else if (CONSTANT_P (XEXP (addr, 0)))
24922 addr = XEXP (addr, 1);
24923 else if (CONSTANT_P (XEXP (addr, 1)))
24924 addr = XEXP (addr, 0);
24926 gcc_unreachable ();
24928 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24933 rs6000_fatal_bad_address (rtx op)
24935 fatal_insn ("bad address", op);
24940 typedef struct branch_island_d {
24941 tree function_name;
24946 DEF_VEC_O(branch_island);
24947 DEF_VEC_ALLOC_O(branch_island,gc);
24949 static VEC(branch_island,gc) *branch_islands;
24951 /* Remember to generate a branch island for far calls to the given
24955 add_compiler_branch_island (tree label_name, tree function_name,
24958 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
24960 bi->function_name = function_name;
24961 bi->label_name = label_name;
24962 bi->line_number = line_number;
24965 /* Generate far-jump branch islands for everything recorded in
24966 branch_islands. Invoked immediately after the last instruction of
24967 the epilogue has been emitted; the branch islands must be appended
24968 to, and contiguous with, the function body. Mach-O stubs are
24969 generated in machopic_output_stub(). */
24972 macho_branch_islands (void)
24976 while (!VEC_empty (branch_island, branch_islands))
24978 branch_island *bi = VEC_last (branch_island, branch_islands);
24979 const char *label = IDENTIFIER_POINTER (bi->label_name);
24980 const char *name = IDENTIFIER_POINTER (bi->function_name);
24981 char name_buf[512];
24982 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24983 if (name[0] == '*' || name[0] == '&')
24984 strcpy (name_buf, name+1);
24988 strcpy (name_buf+1, name);
24990 strcpy (tmp_buf, "\n");
24991 strcat (tmp_buf, label);
24992 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24993 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24994 dbxout_stabd (N_SLINE, bi->line_number);
24995 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24998 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24999 strcat (tmp_buf, label);
25000 strcat (tmp_buf, "_pic\n");
25001 strcat (tmp_buf, label);
25002 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25004 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25005 strcat (tmp_buf, name_buf);
25006 strcat (tmp_buf, " - ");
25007 strcat (tmp_buf, label);
25008 strcat (tmp_buf, "_pic)\n");
25010 strcat (tmp_buf, "\tmtlr r0\n");
25012 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25013 strcat (tmp_buf, name_buf);
25014 strcat (tmp_buf, " - ");
25015 strcat (tmp_buf, label);
25016 strcat (tmp_buf, "_pic)\n");
25018 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25022 strcat (tmp_buf, ":\nlis r12,hi16(");
25023 strcat (tmp_buf, name_buf);
25024 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25025 strcat (tmp_buf, name_buf);
25026 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25028 output_asm_insn (tmp_buf, 0);
25029 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25030 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25031 dbxout_stabd (N_SLINE, bi->line_number);
25032 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25033 VEC_pop (branch_island, branch_islands);
25037 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25038 already there or not. */
25041 no_previous_def (tree function_name)
25046 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25047 if (function_name == bi->function_name)
25052 /* GET_PREV_LABEL gets the label name from the previous definition of
25056 get_prev_label (tree function_name)
25061 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25062 if (function_name == bi->function_name)
25063 return bi->label_name;
25067 /* INSN is either a function call or a millicode call. It may have an
25068 unconditional jump in its delay slot.
25070 CALL_DEST is the routine we are calling. */
25073 output_call (rtx insn, rtx *operands, int dest_operand_number,
25074 int cookie_operand_number)
25076 static char buf[256];
25077 if (darwin_emit_branch_islands
25078 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25079 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25082 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25084 if (no_previous_def (funname))
25086 rtx label_rtx = gen_label_rtx ();
25087 char *label_buf, temp_buf[256];
25088 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25089 CODE_LABEL_NUMBER (label_rtx));
25090 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25091 labelname = get_identifier (label_buf);
25092 add_compiler_branch_island (labelname, funname, insn_line (insn));
25095 labelname = get_prev_label (funname);
25097 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25098 instruction will reach 'foo', otherwise link as 'bl L42'".
25099 "L42" should be a 'branch island', that will do a far jump to
25100 'foo'. Branch islands are generated in
25101 macho_branch_islands(). */
25102 sprintf (buf, "jbsr %%z%d,%.246s",
25103 dest_operand_number, IDENTIFIER_POINTER (labelname));
25106 sprintf (buf, "bl %%z%d", dest_operand_number);
25110 /* Generate PIC and indirect symbol stubs. */
25113 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25115 unsigned int length;
25116 char *symbol_name, *lazy_ptr_name;
25117 char *local_label_0;
25118 static int label = 0;
25120 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25121 symb = (*targetm.strip_name_encoding) (symb);
25124 length = strlen (symb);
25125 symbol_name = XALLOCAVEC (char, length + 32);
25126 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25128 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25129 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25132 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25134 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25138 fprintf (file, "\t.align 5\n");
25140 fprintf (file, "%s:\n", stub);
25141 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25144 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25145 sprintf (local_label_0, "\"L%011d$spb\"", label);
25147 fprintf (file, "\tmflr r0\n");
25148 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25149 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25150 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25151 lazy_ptr_name, local_label_0);
25152 fprintf (file, "\tmtlr r0\n");
25153 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25154 (TARGET_64BIT ? "ldu" : "lwzu"),
25155 lazy_ptr_name, local_label_0);
25156 fprintf (file, "\tmtctr r12\n");
25157 fprintf (file, "\tbctr\n");
25161 fprintf (file, "\t.align 4\n");
25163 fprintf (file, "%s:\n", stub);
25164 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25166 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25167 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25168 (TARGET_64BIT ? "ldu" : "lwzu"),
25170 fprintf (file, "\tmtctr r12\n");
25171 fprintf (file, "\tbctr\n");
25174 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25175 fprintf (file, "%s:\n", lazy_ptr_name);
25176 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25177 fprintf (file, "%sdyld_stub_binding_helper\n",
25178 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25181 /* Legitimize PIC addresses. If the address is already
25182 position-independent, we return ORIG. Newly generated
25183 position-independent addresses go into a reg. This is REG if non
25184 zero, otherwise we allocate register(s) as necessary. */
25186 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25189 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25194 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25195 reg = gen_reg_rtx (Pmode);
25197 if (GET_CODE (orig) == CONST)
25201 if (GET_CODE (XEXP (orig, 0)) == PLUS
25202 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25205 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25207 /* Use a different reg for the intermediate value, as
25208 it will be marked UNCHANGING. */
25209 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25210 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25213 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25216 if (GET_CODE (offset) == CONST_INT)
25218 if (SMALL_INT (offset))
25219 return plus_constant (base, INTVAL (offset));
25220 else if (! reload_in_progress && ! reload_completed)
25221 offset = force_reg (Pmode, offset);
25224 rtx mem = force_const_mem (Pmode, orig);
25225 return machopic_legitimize_pic_address (mem, Pmode, reg);
25228 return gen_rtx_PLUS (Pmode, base, offset);
25231 /* Fall back on generic machopic code. */
25232 return machopic_legitimize_pic_address (orig, mode, reg);
25235 /* Output a .machine directive for the Darwin assembler, and call
25236 the generic start_file routine. */
25239 rs6000_darwin_file_start (void)
25241 static const struct
25247 { "ppc64", "ppc64", MASK_64BIT },
25248 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25249 { "power4", "ppc970", 0 },
25250 { "G5", "ppc970", 0 },
25251 { "7450", "ppc7450", 0 },
25252 { "7400", "ppc7400", MASK_ALTIVEC },
25253 { "G4", "ppc7400", 0 },
25254 { "750", "ppc750", 0 },
25255 { "740", "ppc750", 0 },
25256 { "G3", "ppc750", 0 },
25257 { "604e", "ppc604e", 0 },
25258 { "604", "ppc604", 0 },
25259 { "603e", "ppc603", 0 },
25260 { "603", "ppc603", 0 },
25261 { "601", "ppc601", 0 },
25262 { NULL, "ppc", 0 } };
25263 const char *cpu_id = "";
25266 rs6000_file_start ();
25267 darwin_file_start ();
25269 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25270 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25271 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25272 && rs6000_select[i].string[0] != '\0')
25273 cpu_id = rs6000_select[i].string;
25275 /* Look through the mapping array. Pick the first name that either
25276 matches the argument, has a bit set in IF_SET that is also set
25277 in the target flags, or has a NULL name. */
25280 while (mapping[i].arg != NULL
25281 && strcmp (mapping[i].arg, cpu_id) != 0
25282 && (mapping[i].if_set & target_flags) == 0)
25285 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25288 #endif /* TARGET_MACHO */
25292 rs6000_elf_reloc_rw_mask (void)
25296 else if (DEFAULT_ABI == ABI_AIX)
25302 /* Record an element in the table of global constructors. SYMBOL is
25303 a SYMBOL_REF of the function to be called; PRIORITY is a number
25304 between 0 and MAX_INIT_PRIORITY.
25306 This differs from default_named_section_asm_out_constructor in
25307 that we have special handling for -mrelocatable. */
25310 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25312 const char *section = ".ctors";
25315 if (priority != DEFAULT_INIT_PRIORITY)
25317 sprintf (buf, ".ctors.%.5u",
25318 /* Invert the numbering so the linker puts us in the proper
25319 order; constructors are run from right to left, and the
25320 linker sorts in increasing order. */
25321 MAX_INIT_PRIORITY - priority);
25325 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25326 assemble_align (POINTER_SIZE);
25328 if (TARGET_RELOCATABLE)
25330 fputs ("\t.long (", asm_out_file);
25331 output_addr_const (asm_out_file, symbol);
25332 fputs (")@fixup\n", asm_out_file);
25335 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25339 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25341 const char *section = ".dtors";
25344 if (priority != DEFAULT_INIT_PRIORITY)
25346 sprintf (buf, ".dtors.%.5u",
25347 /* Invert the numbering so the linker puts us in the proper
25348 order; constructors are run from right to left, and the
25349 linker sorts in increasing order. */
25350 MAX_INIT_PRIORITY - priority);
25354 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25355 assemble_align (POINTER_SIZE);
25357 if (TARGET_RELOCATABLE)
25359 fputs ("\t.long (", asm_out_file);
25360 output_addr_const (asm_out_file, symbol);
25361 fputs (")@fixup\n", asm_out_file);
25364 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25368 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25372 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25373 ASM_OUTPUT_LABEL (file, name);
25374 fputs (DOUBLE_INT_ASM_OP, file);
25375 rs6000_output_function_entry (file, name);
25376 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25379 fputs ("\t.size\t", file);
25380 assemble_name (file, name);
25381 fputs (",24\n\t.type\t.", file);
25382 assemble_name (file, name);
25383 fputs (",@function\n", file);
25384 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25386 fputs ("\t.globl\t.", file);
25387 assemble_name (file, name);
25392 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25393 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25394 rs6000_output_function_entry (file, name);
25395 fputs (":\n", file);
25399 if (TARGET_RELOCATABLE
25400 && !TARGET_SECURE_PLT
25401 && (get_pool_size () != 0 || crtl->profile)
25406 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25408 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25409 fprintf (file, "\t.long ");
25410 assemble_name (file, buf);
25412 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25413 assemble_name (file, buf);
25417 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25418 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25420 if (DEFAULT_ABI == ABI_AIX)
25422 const char *desc_name, *orig_name;
25424 orig_name = (*targetm.strip_name_encoding) (name);
25425 desc_name = orig_name;
25426 while (*desc_name == '.')
25429 if (TREE_PUBLIC (decl))
25430 fprintf (file, "\t.globl %s\n", desc_name);
25432 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25433 fprintf (file, "%s:\n", desc_name);
25434 fprintf (file, "\t.long %s\n", orig_name);
25435 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25436 if (DEFAULT_ABI == ABI_AIX)
25437 fputs ("\t.long 0\n", file);
25438 fprintf (file, "\t.previous\n");
25440 ASM_OUTPUT_LABEL (file, name);
25444 rs6000_elf_end_indicate_exec_stack (void)
25447 file_end_indicate_exec_stack ();
25453 rs6000_xcoff_asm_output_anchor (rtx symbol)
25457 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25458 SYMBOL_REF_BLOCK_OFFSET (symbol));
25459 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25463 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25465 fputs (GLOBAL_ASM_OP, stream);
25466 RS6000_OUTPUT_BASENAME (stream, name);
25467 putc ('\n', stream);
25470 /* A get_unnamed_decl callback, used for read-only sections. PTR
25471 points to the section string variable. */
25474 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25476 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25477 *(const char *const *) directive,
25478 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25481 /* Likewise for read-write sections. */
25484 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25486 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25487 *(const char *const *) directive,
25488 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25491 /* A get_unnamed_section callback, used for switching to toc_section. */
25494 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25496 if (TARGET_MINIMAL_TOC)
25498 /* toc_section is always selected at least once from
25499 rs6000_xcoff_file_start, so this is guaranteed to
25500 always be defined once and only once in each file. */
25501 if (!toc_initialized)
25503 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25504 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25505 toc_initialized = 1;
25507 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25508 (TARGET_32BIT ? "" : ",3"));
25511 fputs ("\t.toc\n", asm_out_file);
25514 /* Implement TARGET_ASM_INIT_SECTIONS. */
25517 rs6000_xcoff_asm_init_sections (void)
25519 read_only_data_section
25520 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25521 &xcoff_read_only_section_name);
25523 private_data_section
25524 = get_unnamed_section (SECTION_WRITE,
25525 rs6000_xcoff_output_readwrite_section_asm_op,
25526 &xcoff_private_data_section_name);
25528 read_only_private_data_section
25529 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25530 &xcoff_private_data_section_name);
25533 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25535 readonly_data_section = read_only_data_section;
25536 exception_section = data_section;
25540 rs6000_xcoff_reloc_rw_mask (void)
25546 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25547 tree decl ATTRIBUTE_UNUSED)
25550 static const char * const suffix[3] = { "PR", "RO", "RW" };
25552 if (flags & SECTION_CODE)
25554 else if (flags & SECTION_WRITE)
25559 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25560 (flags & SECTION_CODE) ? "." : "",
25561 name, suffix[smclass], flags & SECTION_ENTSIZE);
25565 rs6000_xcoff_select_section (tree decl, int reloc,
25566 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25568 if (decl_readonly_section (decl, reloc))
25570 if (TREE_PUBLIC (decl))
25571 return read_only_data_section;
25573 return read_only_private_data_section;
25577 if (TREE_PUBLIC (decl))
25578 return data_section;
25580 return private_data_section;
25585 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25589 /* Use select_section for private and uninitialized data. */
25590 if (!TREE_PUBLIC (decl)
25591 || DECL_COMMON (decl)
25592 || DECL_INITIAL (decl) == NULL_TREE
25593 || DECL_INITIAL (decl) == error_mark_node
25594 || (flag_zero_initialized_in_bss
25595 && initializer_zerop (DECL_INITIAL (decl))))
25598 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25599 name = (*targetm.strip_name_encoding) (name);
25600 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25603 /* Select section for constant in constant pool.
25605 On RS/6000, all constants are in the private read-only data area.
25606 However, if this is being placed in the TOC it must be output as a
25610 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25611 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25613 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25614 return toc_section;
25616 return read_only_private_data_section;
25619 /* Remove any trailing [DS] or the like from the symbol name. */
25621 static const char *
25622 rs6000_xcoff_strip_name_encoding (const char *name)
25627 len = strlen (name);
25628 if (name[len - 1] == ']')
25629 return ggc_alloc_string (name, len - 4);
25634 /* Section attributes. AIX is always PIC. */
25636 static unsigned int
25637 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25639 unsigned int align;
25640 unsigned int flags = default_section_type_flags (decl, name, reloc);
25642 /* Align to at least UNIT size. */
25643 if (flags & SECTION_CODE)
25644 align = MIN_UNITS_PER_WORD;
25646 /* Increase alignment of large objects if not already stricter. */
25647 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25648 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25649 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25651 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25654 /* Output at beginning of assembler file.
25656 Initialize the section names for the RS/6000 at this point.
25658 Specify filename, including full path, to assembler.
25660 We want to go into the TOC section so at least one .toc will be emitted.
25661 Also, in order to output proper .bs/.es pairs, we need at least one static
25662 [RW] section emitted.
25664 Finally, declare mcount when profiling to make the assembler happy. */
25667 rs6000_xcoff_file_start (void)
25669 rs6000_gen_section_name (&xcoff_bss_section_name,
25670 main_input_filename, ".bss_");
25671 rs6000_gen_section_name (&xcoff_private_data_section_name,
25672 main_input_filename, ".rw_");
25673 rs6000_gen_section_name (&xcoff_read_only_section_name,
25674 main_input_filename, ".ro_");
25676 fputs ("\t.file\t", asm_out_file);
25677 output_quoted_string (asm_out_file, main_input_filename);
25678 fputc ('\n', asm_out_file);
25679 if (write_symbols != NO_DEBUG)
25680 switch_to_section (private_data_section);
25681 switch_to_section (text_section);
25683 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25684 rs6000_file_start ();
25687 /* Output at end of assembler file.
25688 On the RS/6000, referencing data should automatically pull in text. */
25691 rs6000_xcoff_file_end (void)
25693 switch_to_section (text_section);
25694 fputs ("_section_.text:\n", asm_out_file);
25695 switch_to_section (data_section);
25696 fputs (TARGET_32BIT
25697 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25700 #endif /* TARGET_XCOFF */
25702 /* Compute a (partial) cost for rtx X. Return true if the complete
25703 cost has been computed, and false if subexpressions should be
25704 scanned. In either case, *TOTAL contains the cost result. */
25707 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25710 enum machine_mode mode = GET_MODE (x);
25714 /* On the RS/6000, if it is valid in the insn, it is free. */
25716 if (((outer_code == SET
25717 || outer_code == PLUS
25718 || outer_code == MINUS)
25719 && (satisfies_constraint_I (x)
25720 || satisfies_constraint_L (x)))
25721 || (outer_code == AND
25722 && (satisfies_constraint_K (x)
25724 ? satisfies_constraint_L (x)
25725 : satisfies_constraint_J (x))
25726 || mask_operand (x, mode)
25728 && mask64_operand (x, DImode))))
25729 || ((outer_code == IOR || outer_code == XOR)
25730 && (satisfies_constraint_K (x)
25732 ? satisfies_constraint_L (x)
25733 : satisfies_constraint_J (x))))
25734 || outer_code == ASHIFT
25735 || outer_code == ASHIFTRT
25736 || outer_code == LSHIFTRT
25737 || outer_code == ROTATE
25738 || outer_code == ROTATERT
25739 || outer_code == ZERO_EXTRACT
25740 || (outer_code == MULT
25741 && satisfies_constraint_I (x))
25742 || ((outer_code == DIV || outer_code == UDIV
25743 || outer_code == MOD || outer_code == UMOD)
25744 && exact_log2 (INTVAL (x)) >= 0)
25745 || (outer_code == COMPARE
25746 && (satisfies_constraint_I (x)
25747 || satisfies_constraint_K (x)))
25748 || ((outer_code == EQ || outer_code == NE)
25749 && (satisfies_constraint_I (x)
25750 || satisfies_constraint_K (x)
25752 ? satisfies_constraint_L (x)
25753 : satisfies_constraint_J (x))))
25754 || (outer_code == GTU
25755 && satisfies_constraint_I (x))
25756 || (outer_code == LTU
25757 && satisfies_constraint_P (x)))
25762 else if ((outer_code == PLUS
25763 && reg_or_add_cint_operand (x, VOIDmode))
25764 || (outer_code == MINUS
25765 && reg_or_sub_cint_operand (x, VOIDmode))
25766 || ((outer_code == SET
25767 || outer_code == IOR
25768 || outer_code == XOR)
25770 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25772 *total = COSTS_N_INSNS (1);
25778 if (mode == DImode && code == CONST_DOUBLE)
25780 if ((outer_code == IOR || outer_code == XOR)
25781 && CONST_DOUBLE_HIGH (x) == 0
25782 && (CONST_DOUBLE_LOW (x)
25783 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25788 else if ((outer_code == AND && and64_2_operand (x, DImode))
25789 || ((outer_code == SET
25790 || outer_code == IOR
25791 || outer_code == XOR)
25792 && CONST_DOUBLE_HIGH (x) == 0))
25794 *total = COSTS_N_INSNS (1);
25804 /* When optimizing for size, MEM should be slightly more expensive
25805 than generating address, e.g., (plus (reg) (const)).
25806 L1 cache latency is about two instructions. */
25807 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25815 if (mode == DFmode)
25817 if (GET_CODE (XEXP (x, 0)) == MULT)
25819 /* FNMA accounted in outer NEG. */
25820 if (outer_code == NEG)
25821 *total = rs6000_cost->dmul - rs6000_cost->fp;
25823 *total = rs6000_cost->dmul;
25826 *total = rs6000_cost->fp;
25828 else if (mode == SFmode)
25830 /* FNMA accounted in outer NEG. */
25831 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25834 *total = rs6000_cost->fp;
25837 *total = COSTS_N_INSNS (1);
25841 if (mode == DFmode)
25843 if (GET_CODE (XEXP (x, 0)) == MULT
25844 || GET_CODE (XEXP (x, 1)) == MULT)
25846 /* FNMA accounted in outer NEG. */
25847 if (outer_code == NEG)
25848 *total = rs6000_cost->dmul - rs6000_cost->fp;
25850 *total = rs6000_cost->dmul;
25853 *total = rs6000_cost->fp;
25855 else if (mode == SFmode)
25857 /* FNMA accounted in outer NEG. */
25858 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25861 *total = rs6000_cost->fp;
25864 *total = COSTS_N_INSNS (1);
25868 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25869 && satisfies_constraint_I (XEXP (x, 1)))
25871 if (INTVAL (XEXP (x, 1)) >= -256
25872 && INTVAL (XEXP (x, 1)) <= 255)
25873 *total = rs6000_cost->mulsi_const9;
25875 *total = rs6000_cost->mulsi_const;
25877 /* FMA accounted in outer PLUS/MINUS. */
25878 else if ((mode == DFmode || mode == SFmode)
25879 && (outer_code == PLUS || outer_code == MINUS))
25881 else if (mode == DFmode)
25882 *total = rs6000_cost->dmul;
25883 else if (mode == SFmode)
25884 *total = rs6000_cost->fp;
25885 else if (mode == DImode)
25886 *total = rs6000_cost->muldi;
25888 *total = rs6000_cost->mulsi;
25893 if (FLOAT_MODE_P (mode))
25895 *total = mode == DFmode ? rs6000_cost->ddiv
25896 : rs6000_cost->sdiv;
25903 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25904 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25906 if (code == DIV || code == MOD)
25908 *total = COSTS_N_INSNS (2);
25911 *total = COSTS_N_INSNS (1);
25915 if (GET_MODE (XEXP (x, 1)) == DImode)
25916 *total = rs6000_cost->divdi;
25918 *total = rs6000_cost->divsi;
25920 /* Add in shift and subtract for MOD. */
25921 if (code == MOD || code == UMOD)
25922 *total += COSTS_N_INSNS (2);
25927 *total = COSTS_N_INSNS (4);
25931 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25935 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25939 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25951 *total = COSTS_N_INSNS (1);
25959 /* Handle mul_highpart. */
25960 if (outer_code == TRUNCATE
25961 && GET_CODE (XEXP (x, 0)) == MULT)
25963 if (mode == DImode)
25964 *total = rs6000_cost->muldi;
25966 *total = rs6000_cost->mulsi;
25969 else if (outer_code == AND)
25972 *total = COSTS_N_INSNS (1);
25977 if (GET_CODE (XEXP (x, 0)) == MEM)
25980 *total = COSTS_N_INSNS (1);
25986 if (!FLOAT_MODE_P (mode))
25988 *total = COSTS_N_INSNS (1);
25994 case UNSIGNED_FLOAT:
25997 case FLOAT_TRUNCATE:
25998 *total = rs6000_cost->fp;
26002 if (mode == DFmode)
26005 *total = rs6000_cost->fp;
26009 switch (XINT (x, 1))
26012 *total = rs6000_cost->fp;
26024 *total = COSTS_N_INSNS (1);
26027 else if (FLOAT_MODE_P (mode)
26028 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26030 *total = rs6000_cost->fp;
26038 /* Carry bit requires mode == Pmode.
26039 NEG or PLUS already counted so only add one. */
26041 && (outer_code == NEG || outer_code == PLUS))
26043 *total = COSTS_N_INSNS (1);
26046 if (outer_code == SET)
26048 if (XEXP (x, 1) == const0_rtx)
26050 if (TARGET_ISEL && !TARGET_MFCRF)
26051 *total = COSTS_N_INSNS (8);
26053 *total = COSTS_N_INSNS (2);
26056 else if (mode == Pmode)
26058 *total = COSTS_N_INSNS (3);
26067 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26069 if (TARGET_ISEL && !TARGET_MFCRF)
26070 *total = COSTS_N_INSNS (8);
26072 *total = COSTS_N_INSNS (2);
26076 if (outer_code == COMPARE)
26090 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26093 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26096 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26099 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26100 "total = %d, speed = %s, x:\n",
26101 ret ? "complete" : "scan inner",
26102 GET_RTX_NAME (code),
26103 GET_RTX_NAME (outer_code),
26105 speed ? "true" : "false");
26112 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26115 rs6000_debug_address_cost (rtx x, bool speed)
26117 int ret = TARGET_ADDRESS_COST (x, speed);
26119 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26120 ret, speed ? "true" : "false");
26127 /* A C expression returning the cost of moving data from a register of class
26128 CLASS1 to one of CLASS2. */
26131 rs6000_register_move_cost (enum machine_mode mode,
26132 reg_class_t from, reg_class_t to)
26136 /* Moves from/to GENERAL_REGS. */
26137 if (reg_classes_intersect_p (to, GENERAL_REGS)
26138 || reg_classes_intersect_p (from, GENERAL_REGS))
26140 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26143 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26144 ret = (rs6000_memory_move_cost (mode, from, false)
26145 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26147 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26149 else if (from == CR_REGS)
26152 /* Power6 has slower LR/CTR moves so make them more expensive than
26153 memory in order to bias spills to memory .*/
26154 else if (rs6000_cpu == PROCESSOR_POWER6
26155 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26156 ret = 6 * hard_regno_nregs[0][mode];
26159 /* A move will cost one instruction per GPR moved. */
26160 ret = 2 * hard_regno_nregs[0][mode];
26163 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26164 else if (VECTOR_UNIT_VSX_P (mode)
26165 && reg_classes_intersect_p (to, VSX_REGS)
26166 && reg_classes_intersect_p (from, VSX_REGS))
26167 ret = 2 * hard_regno_nregs[32][mode];
26169 /* Moving between two similar registers is just one instruction. */
26170 else if (reg_classes_intersect_p (to, from))
26171 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26173 /* Everything else has to go through GENERAL_REGS. */
26175 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26176 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26178 if (TARGET_DEBUG_COST)
26180 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26181 ret, GET_MODE_NAME (mode), reg_class_names[from],
26182 reg_class_names[to]);
26187 /* A C expressions returning the cost of moving data of MODE from a register to
26191 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26192 bool in ATTRIBUTE_UNUSED)
26196 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26197 ret = 4 * hard_regno_nregs[0][mode];
26198 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26199 ret = 4 * hard_regno_nregs[32][mode];
26200 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26201 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26203 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26205 if (TARGET_DEBUG_COST)
26207 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26208 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26213 /* Returns a code for a target-specific builtin that implements
26214 reciprocal of the function, or NULL_TREE if not available. */
26217 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26218 bool sqrt ATTRIBUTE_UNUSED)
26220 if (optimize_insn_for_size_p ())
26226 case VSX_BUILTIN_XVSQRTDP:
26227 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26230 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26232 case VSX_BUILTIN_XVSQRTSP:
26233 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26236 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26245 case BUILT_IN_SQRT:
26246 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26249 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26251 case BUILT_IN_SQRTF:
26252 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26255 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26262 /* Load up a constant. If the mode is a vector mode, splat the value across
26263 all of the vector elements. */
26266 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26270 if (mode == SFmode || mode == DFmode)
26272 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26273 reg = force_reg (mode, d);
26275 else if (mode == V4SFmode)
26277 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26278 rtvec v = gen_rtvec (4, d, d, d, d);
26279 reg = gen_reg_rtx (mode);
26280 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26282 else if (mode == V2DFmode)
26284 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26285 rtvec v = gen_rtvec (2, d, d);
26286 reg = gen_reg_rtx (mode);
26287 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26290 gcc_unreachable ();
26295 /* Generate a FMADD instruction:
26296 dst = (m1 * m2) + a
26298 generating different RTL based on the fused multiply/add switch. */
26301 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26303 enum machine_mode mode = GET_MODE (dst);
26305 if (!TARGET_FUSED_MADD)
26307 /* For the simple ops, use the generator function, rather than assuming
26308 that the RTL is standard. */
26309 enum insn_code mcode = optab_handler (smul_optab, mode);
26310 enum insn_code acode = optab_handler (add_optab, mode);
26311 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26312 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26313 rtx mreg = gen_reg_rtx (mode);
26315 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26316 emit_insn (gen_mul (mreg, m1, m2));
26317 emit_insn (gen_add (dst, mreg, a));
26321 emit_insn (gen_rtx_SET (VOIDmode, dst,
26322 gen_rtx_PLUS (mode,
26323 gen_rtx_MULT (mode, m1, m2),
26327 /* Generate a FMSUB instruction:
26328 dst = (m1 * m2) - a
26330 generating different RTL based on the fused multiply/add switch. */
26333 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26335 enum machine_mode mode = GET_MODE (dst);
26337 if (!TARGET_FUSED_MADD
26338 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26340 /* For the simple ops, use the generator function, rather than assuming
26341 that the RTL is standard. */
26342 enum insn_code mcode = optab_handler (smul_optab, mode);
26343 enum insn_code scode = optab_handler (add_optab, mode);
26344 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26345 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26346 rtx mreg = gen_reg_rtx (mode);
26348 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26349 emit_insn (gen_mul (mreg, m1, m2));
26350 emit_insn (gen_sub (dst, mreg, a));
26354 emit_insn (gen_rtx_SET (VOIDmode, dst,
26355 gen_rtx_MINUS (mode,
26356 gen_rtx_MULT (mode, m1, m2),
26360 /* Generate a FNMSUB instruction:
26361 dst = - ((m1 * m2) - a)
26363 Which is equivalent to (except in the prescence of -0.0):
26364 dst = a - (m1 * m2)
26366 generating different RTL based on the fast-math and fused multiply/add
26370 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26372 enum machine_mode mode = GET_MODE (dst);
26374 if (!TARGET_FUSED_MADD)
26376 /* For the simple ops, use the generator function, rather than assuming
26377 that the RTL is standard. */
26378 enum insn_code mcode = optab_handler (smul_optab, mode);
26379 enum insn_code scode = optab_handler (sub_optab, mode);
26380 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26381 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26382 rtx mreg = gen_reg_rtx (mode);
26384 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26385 emit_insn (gen_mul (mreg, m1, m2));
26386 emit_insn (gen_sub (dst, a, mreg));
26391 rtx m = gen_rtx_MULT (mode, m1, m2);
26393 if (!HONOR_SIGNED_ZEROS (mode))
26394 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26397 emit_insn (gen_rtx_SET (VOIDmode, dst,
26399 gen_rtx_MINUS (mode, m, a))));
26403 /* Newton-Raphson approximation of floating point divide with just 2 passes
26404 (either single precision floating point, or newer machines with higher
26405 accuracy estimates). Support both scalar and vector divide. Assumes no
26406 trapping math and finite arguments. */
26409 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26411 enum machine_mode mode = GET_MODE (dst);
26412 rtx x0, e0, e1, y1, u0, v0;
26413 enum insn_code code = optab_handler (smul_optab, mode);
26414 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26415 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26417 gcc_assert (code != CODE_FOR_nothing);
26419 /* x0 = 1./d estimate */
26420 x0 = gen_reg_rtx (mode);
26421 emit_insn (gen_rtx_SET (VOIDmode, x0,
26422 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26425 e0 = gen_reg_rtx (mode);
26426 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26428 e1 = gen_reg_rtx (mode);
26429 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26431 y1 = gen_reg_rtx (mode);
26432 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26434 u0 = gen_reg_rtx (mode);
26435 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26437 v0 = gen_reg_rtx (mode);
26438 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26440 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26443 /* Newton-Raphson approximation of floating point divide that has a low
26444 precision estimate. Assumes no trapping math and finite arguments. */
26447 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26449 enum machine_mode mode = GET_MODE (dst);
26450 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26451 enum insn_code code = optab_handler (smul_optab, mode);
26452 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26454 gcc_assert (code != CODE_FOR_nothing);
26456 one = rs6000_load_constant_and_splat (mode, dconst1);
26458 /* x0 = 1./d estimate */
26459 x0 = gen_reg_rtx (mode);
26460 emit_insn (gen_rtx_SET (VOIDmode, x0,
26461 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26464 e0 = gen_reg_rtx (mode);
26465 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26467 y1 = gen_reg_rtx (mode);
26468 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26470 e1 = gen_reg_rtx (mode);
26471 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26473 y2 = gen_reg_rtx (mode);
26474 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26476 e2 = gen_reg_rtx (mode);
26477 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26479 y3 = gen_reg_rtx (mode);
26480 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26482 u0 = gen_reg_rtx (mode);
26483 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26485 v0 = gen_reg_rtx (mode);
26486 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26488 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26491 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26492 add a reg_note saying that this was a division. Support both scalar and
26493 vector divide. Assumes no trapping math and finite arguments. */
26496 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26498 enum machine_mode mode = GET_MODE (dst);
26500 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26501 rs6000_emit_swdiv_high_precision (dst, n, d);
26503 rs6000_emit_swdiv_low_precision (dst, n, d);
26506 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26509 /* Newton-Raphson approximation of single/double-precision floating point
26510 rsqrt. Assumes no trapping math and finite arguments. */
26513 rs6000_emit_swrsqrt (rtx dst, rtx src)
26515 enum machine_mode mode = GET_MODE (src);
26516 rtx x0 = gen_reg_rtx (mode);
26517 rtx y = gen_reg_rtx (mode);
26518 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26519 REAL_VALUE_TYPE dconst3_2;
26522 enum insn_code code = optab_handler (smul_optab, mode);
26523 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26525 gcc_assert (code != CODE_FOR_nothing);
26527 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26528 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26529 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26531 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26533 /* x0 = rsqrt estimate */
26534 emit_insn (gen_rtx_SET (VOIDmode, x0,
26535 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26538 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26539 rs6000_emit_msub (y, src, halfthree, src);
26541 for (i = 0; i < passes; i++)
26543 rtx x1 = gen_reg_rtx (mode);
26544 rtx u = gen_reg_rtx (mode);
26545 rtx v = gen_reg_rtx (mode);
26547 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26548 emit_insn (gen_mul (u, x0, x0));
26549 rs6000_emit_nmsub (v, y, u, halfthree);
26550 emit_insn (gen_mul (x1, x0, v));
26554 emit_move_insn (dst, x0);
26558 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26559 (Power7) targets. DST is the target, and SRC is the argument operand. */
26562 rs6000_emit_popcount (rtx dst, rtx src)
26564 enum machine_mode mode = GET_MODE (dst);
26567 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26568 if (TARGET_POPCNTD)
26570 if (mode == SImode)
26571 emit_insn (gen_popcntdsi2 (dst, src));
26573 emit_insn (gen_popcntddi2 (dst, src));
26577 tmp1 = gen_reg_rtx (mode);
26579 if (mode == SImode)
26581 emit_insn (gen_popcntbsi2 (tmp1, src));
26582 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26584 tmp2 = force_reg (SImode, tmp2);
26585 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26589 emit_insn (gen_popcntbdi2 (tmp1, src));
26590 tmp2 = expand_mult (DImode, tmp1,
26591 GEN_INT ((HOST_WIDE_INT)
26592 0x01010101 << 32 | 0x01010101),
26594 tmp2 = force_reg (DImode, tmp2);
26595 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26600 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26601 target, and SRC is the argument operand. */
26604 rs6000_emit_parity (rtx dst, rtx src)
26606 enum machine_mode mode = GET_MODE (dst);
26609 tmp = gen_reg_rtx (mode);
26611 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26614 if (mode == SImode)
26616 emit_insn (gen_popcntbsi2 (tmp, src));
26617 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26621 emit_insn (gen_popcntbdi2 (tmp, src));
26622 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26627 if (mode == SImode)
26629 /* Is mult+shift >= shift+xor+shift+xor? */
26630 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26632 rtx tmp1, tmp2, tmp3, tmp4;
26634 tmp1 = gen_reg_rtx (SImode);
26635 emit_insn (gen_popcntbsi2 (tmp1, src));
26637 tmp2 = gen_reg_rtx (SImode);
26638 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26639 tmp3 = gen_reg_rtx (SImode);
26640 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26642 tmp4 = gen_reg_rtx (SImode);
26643 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26644 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26647 rs6000_emit_popcount (tmp, src);
26648 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26652 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26653 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26655 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26657 tmp1 = gen_reg_rtx (DImode);
26658 emit_insn (gen_popcntbdi2 (tmp1, src));
26660 tmp2 = gen_reg_rtx (DImode);
26661 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26662 tmp3 = gen_reg_rtx (DImode);
26663 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26665 tmp4 = gen_reg_rtx (DImode);
26666 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26667 tmp5 = gen_reg_rtx (DImode);
26668 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26670 tmp6 = gen_reg_rtx (DImode);
26671 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26672 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26675 rs6000_emit_popcount (tmp, src);
26676 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26680 /* Return an RTX representing where to find the function value of a
26681 function returning MODE. */
26683 rs6000_complex_function_value (enum machine_mode mode)
26685 unsigned int regno;
26687 enum machine_mode inner = GET_MODE_INNER (mode);
26688 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26690 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26691 regno = FP_ARG_RETURN;
26694 regno = GP_ARG_RETURN;
26696 /* 32-bit is OK since it'll go in r3/r4. */
26697 if (TARGET_32BIT && inner_bytes >= 4)
26698 return gen_rtx_REG (mode, regno);
26701 if (inner_bytes >= 8)
26702 return gen_rtx_REG (mode, regno);
26704 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26706 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26707 GEN_INT (inner_bytes));
26708 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26711 /* Target hook for TARGET_FUNCTION_VALUE.
26713 On the SPE, both FPs and vectors are returned in r3.
26715 On RS/6000 an integer value is in r3 and a floating-point value is in
26716 fp1, unless -msoft-float. */
26719 rs6000_function_value (const_tree valtype,
26720 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26721 bool outgoing ATTRIBUTE_UNUSED)
26723 enum machine_mode mode;
26724 unsigned int regno;
26726 /* Special handling for structs in darwin64. */
26728 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26730 CUMULATIVE_ARGS valcum;
26734 valcum.fregno = FP_ARG_MIN_REG;
26735 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26736 /* Do a trial code generation as if this were going to be passed as
26737 an argument; if any part goes in memory, we return NULL. */
26738 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26741 /* Otherwise fall through to standard ABI rules. */
26744 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26746 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26747 return gen_rtx_PARALLEL (DImode,
26749 gen_rtx_EXPR_LIST (VOIDmode,
26750 gen_rtx_REG (SImode, GP_ARG_RETURN),
26752 gen_rtx_EXPR_LIST (VOIDmode,
26753 gen_rtx_REG (SImode,
26754 GP_ARG_RETURN + 1),
26757 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26759 return gen_rtx_PARALLEL (DCmode,
26761 gen_rtx_EXPR_LIST (VOIDmode,
26762 gen_rtx_REG (SImode, GP_ARG_RETURN),
26764 gen_rtx_EXPR_LIST (VOIDmode,
26765 gen_rtx_REG (SImode,
26766 GP_ARG_RETURN + 1),
26768 gen_rtx_EXPR_LIST (VOIDmode,
26769 gen_rtx_REG (SImode,
26770 GP_ARG_RETURN + 2),
26772 gen_rtx_EXPR_LIST (VOIDmode,
26773 gen_rtx_REG (SImode,
26774 GP_ARG_RETURN + 3),
26778 mode = TYPE_MODE (valtype);
26779 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26780 || POINTER_TYPE_P (valtype))
26781 mode = TARGET_32BIT ? SImode : DImode;
26783 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26784 /* _Decimal128 must use an even/odd register pair. */
26785 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26786 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26787 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26788 regno = FP_ARG_RETURN;
26789 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26790 && targetm.calls.split_complex_arg)
26791 return rs6000_complex_function_value (mode);
26792 else if (TREE_CODE (valtype) == VECTOR_TYPE
26793 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26794 && ALTIVEC_VECTOR_MODE (mode))
26795 regno = ALTIVEC_ARG_RETURN;
26796 else if (TREE_CODE (valtype) == VECTOR_TYPE
26797 && TARGET_VSX && TARGET_ALTIVEC_ABI
26798 && VSX_VECTOR_MODE (mode))
26799 regno = ALTIVEC_ARG_RETURN;
26800 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26801 && (mode == DFmode || mode == DCmode
26802 || mode == TFmode || mode == TCmode))
26803 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26805 regno = GP_ARG_RETURN;
26807 return gen_rtx_REG (mode, regno);
26810 /* Define how to find the value returned by a library function
26811 assuming the value has mode MODE. */
26813 rs6000_libcall_value (enum machine_mode mode)
26815 unsigned int regno;
26817 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26819 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26820 return gen_rtx_PARALLEL (DImode,
26822 gen_rtx_EXPR_LIST (VOIDmode,
26823 gen_rtx_REG (SImode, GP_ARG_RETURN),
26825 gen_rtx_EXPR_LIST (VOIDmode,
26826 gen_rtx_REG (SImode,
26827 GP_ARG_RETURN + 1),
26831 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26832 /* _Decimal128 must use an even/odd register pair. */
26833 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26834 else if (SCALAR_FLOAT_MODE_P (mode)
26835 && TARGET_HARD_FLOAT && TARGET_FPRS
26836 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26837 regno = FP_ARG_RETURN;
26838 else if (ALTIVEC_VECTOR_MODE (mode)
26839 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26840 regno = ALTIVEC_ARG_RETURN;
26841 else if (VSX_VECTOR_MODE (mode)
26842 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26843 regno = ALTIVEC_ARG_RETURN;
26844 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26845 return rs6000_complex_function_value (mode);
26846 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26847 && (mode == DFmode || mode == DCmode
26848 || mode == TFmode || mode == TCmode))
26849 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26851 regno = GP_ARG_RETURN;
26853 return gen_rtx_REG (mode, regno);
26857 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26858 Frame pointer elimination is automatically handled.
26860 For the RS/6000, if frame pointer elimination is being done, we would like
26861 to convert ap into fp, not sp.
26863 We need r30 if -mminimal-toc was specified, and there are constant pool
26867 rs6000_can_eliminate (const int from, const int to)
26869 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26870 ? ! frame_pointer_needed
26871 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26872 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26876 /* Define the offset between two registers, FROM to be eliminated and its
26877 replacement TO, at the start of a routine. */
26879 rs6000_initial_elimination_offset (int from, int to)
26881 rs6000_stack_t *info = rs6000_stack_info ();
26882 HOST_WIDE_INT offset;
26884 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26885 offset = info->push_p ? 0 : -info->total_size;
26886 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26888 offset = info->push_p ? 0 : -info->total_size;
26889 if (FRAME_GROWS_DOWNWARD)
26890 offset += info->fixed_size + info->vars_size + info->parm_size;
26892 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26893 offset = FRAME_GROWS_DOWNWARD
26894 ? info->fixed_size + info->vars_size + info->parm_size
26896 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26897 offset = info->total_size;
26898 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26899 offset = info->push_p ? info->total_size : 0;
26900 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26903 gcc_unreachable ();
26909 rs6000_dwarf_register_span (rtx reg)
26913 unsigned regno = REGNO (reg);
26914 enum machine_mode mode = GET_MODE (reg);
26918 && (SPE_VECTOR_MODE (GET_MODE (reg))
26919 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26920 && mode != SFmode && mode != SDmode && mode != SCmode)))
26925 regno = REGNO (reg);
26927 /* The duality of the SPE register size wreaks all kinds of havoc.
26928 This is a way of distinguishing r0 in 32-bits from r0 in
26930 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26931 gcc_assert (words <= 4);
26932 for (i = 0; i < words; i++, regno++)
26934 if (BYTES_BIG_ENDIAN)
26936 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26937 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26941 parts[2 * i] = gen_rtx_REG (SImode, regno);
26942 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26946 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26949 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26952 rs6000_init_dwarf_reg_sizes_extra (tree address)
26957 enum machine_mode mode = TYPE_MODE (char_type_node);
26958 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26959 rtx mem = gen_rtx_MEM (BLKmode, addr);
26960 rtx value = gen_int_mode (4, mode);
26962 for (i = 1201; i < 1232; i++)
26964 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26965 HOST_WIDE_INT offset
26966 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26968 emit_move_insn (adjust_address (mem, mode, offset), value);
26973 /* Map internal gcc register numbers to DWARF2 register numbers. */
26976 rs6000_dbx_register_number (unsigned int regno)
26978 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26980 if (regno == MQ_REGNO)
26982 if (regno == LR_REGNO)
26984 if (regno == CTR_REGNO)
26986 if (CR_REGNO_P (regno))
26987 return regno - CR0_REGNO + 86;
26988 if (regno == CA_REGNO)
26989 return 101; /* XER */
26990 if (ALTIVEC_REGNO_P (regno))
26991 return regno - FIRST_ALTIVEC_REGNO + 1124;
26992 if (regno == VRSAVE_REGNO)
26994 if (regno == VSCR_REGNO)
26996 if (regno == SPE_ACC_REGNO)
26998 if (regno == SPEFSCR_REGNO)
27000 /* SPE high reg number. We get these values of regno from
27001 rs6000_dwarf_register_span. */
27002 gcc_assert (regno >= 1200 && regno < 1232);
27006 /* target hook eh_return_filter_mode */
27007 static enum machine_mode
27008 rs6000_eh_return_filter_mode (void)
27010 return TARGET_32BIT ? SImode : word_mode;
27013 /* Target hook for scalar_mode_supported_p. */
27015 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27017 if (DECIMAL_FLOAT_MODE_P (mode))
27018 return default_decimal_float_supported_p ();
27020 return default_scalar_mode_supported_p (mode);
27023 /* Target hook for vector_mode_supported_p. */
27025 rs6000_vector_mode_supported_p (enum machine_mode mode)
27028 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27031 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27034 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27041 /* Target hook for invalid_arg_for_unprototyped_fn. */
27042 static const char *
27043 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27045 return (!rs6000_darwin64_abi
27047 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27048 && (funcdecl == NULL_TREE
27049 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27050 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27051 ? N_("AltiVec argument passed to unprototyped function")
27055 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27056 setup by using __stack_chk_fail_local hidden function instead of
27057 calling __stack_chk_fail directly. Otherwise it is better to call
27058 __stack_chk_fail directly. */
27061 rs6000_stack_protect_fail (void)
27063 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27064 ? default_hidden_stack_protect_fail ()
27065 : default_external_stack_protect_fail ();
27069 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27070 int num_operands ATTRIBUTE_UNUSED)
27072 if (rs6000_warn_cell_microcode)
27075 int insn_code_number = recog_memoized (insn);
27076 location_t location = locator_location (INSN_LOCATOR (insn));
27078 /* Punt on insns we cannot recognize. */
27079 if (insn_code_number < 0)
27082 temp = get_insn_template (insn_code_number, insn);
27084 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27085 warning_at (location, OPT_mwarn_cell_microcode,
27086 "emitting microcode insn %s\t[%s] #%d",
27087 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27088 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27089 warning_at (location, OPT_mwarn_cell_microcode,
27090 "emitting conditional microcode insn %s\t[%s] #%d",
27091 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27096 /* Allocate a stack temp and fixup the address so it meets the particular
27097 memory requirements (either offetable or REG+REG addressing). */
27100 rs6000_allocate_stack_temp (enum machine_mode mode,
27101 bool offsettable_p,
27104 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27105 rtx addr = XEXP (stack, 0);
27106 int strict_p = (reload_in_progress || reload_completed);
27108 if (!legitimate_indirect_address_p (addr, strict_p))
27111 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27112 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27114 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27115 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27121 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27122 to such a form to deal with memory reference instructions like STFIWX that
27123 only take reg+reg addressing. */
27126 rs6000_address_for_fpconvert (rtx x)
27128 int strict_p = (reload_in_progress || reload_completed);
27131 gcc_assert (MEM_P (x));
27132 addr = XEXP (x, 0);
27133 if (! legitimate_indirect_address_p (addr, strict_p)
27134 && ! legitimate_indexed_address_p (addr, strict_p))
27135 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27140 /* Expand 32-bit int -> floating point conversions. Return true if
27144 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27146 enum machine_mode dmode = GET_MODE (dest);
27147 rtx (*func_si) (rtx, rtx, rtx, rtx);
27148 rtx (*func_si_mem) (rtx, rtx);
27149 rtx (*func_di) (rtx, rtx);
27152 gcc_assert (GET_MODE (src) == SImode);
27154 if (dmode == SFmode)
27158 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27159 func_si = gen_floatunssisf2_lfiwzx;
27160 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27161 func_di = gen_floatunsdisf2;
27165 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27166 func_si = gen_floatsisf2_lfiwax;
27167 func_si_mem = gen_floatsisf2_lfiwax_mem;
27168 func_di = gen_floatdisf2;
27172 else if (dmode == DFmode)
27176 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27177 func_si = gen_floatunssidf2_lfiwzx;
27178 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27179 func_di = gen_floatunsdidf2;
27183 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27184 func_si = gen_floatsidf2_lfiwax;
27185 func_si_mem = gen_floatsidf2_lfiwax_mem;
27186 func_di = gen_floatdidf2;
27191 gcc_unreachable ();
27195 src = rs6000_address_for_fpconvert (src);
27196 emit_insn (func_si_mem (dest, src));
27198 else if (!TARGET_MFPGPR)
27200 reg = gen_reg_rtx (DImode);
27201 stack = rs6000_allocate_stack_temp (SImode, false, true);
27202 emit_insn (func_si (dest, src, stack, reg));
27207 src = force_reg (SImode, src);
27208 reg = convert_to_mode (DImode, src, unsigned_p);
27209 emit_insn (func_di (dest, reg));
27213 #include "gt-rs6000.h"