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 reload_completed; /* stack info won't change from here on */
77 int first_gp_reg_save; /* first callee saved GP register used */
78 int first_fp_reg_save; /* first callee saved FP register used */
79 int first_altivec_reg_save; /* first callee saved AltiVec register used */
80 int lr_save_p; /* true if the link reg needs to be saved */
81 int cr_save_p; /* true if the CR reg needs to be saved */
82 unsigned int vrsave_mask; /* mask of vec registers to save */
83 int push_p; /* true if we need to allocate stack space */
84 int calls_p; /* true if the function makes any calls */
85 int world_save_p; /* true if we're saving *everything*:
86 r13-r31, cr, f14-f31, vrsave, v20-v31 */
87 enum rs6000_abi abi; /* which ABI to use */
88 int gp_save_offset; /* offset to save GP regs from initial SP */
89 int fp_save_offset; /* offset to save FP regs from initial SP */
90 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
91 int lr_save_offset; /* offset to save LR from initial SP */
92 int cr_save_offset; /* offset to save CR from initial SP */
93 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
94 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
95 int varargs_save_offset; /* offset to save the varargs registers */
96 int ehrd_offset; /* offset to EH return data */
97 int reg_size; /* register size (4 or 8) */
98 HOST_WIDE_INT vars_size; /* variable save area size */
99 int parm_size; /* outgoing parameter size */
100 int save_size; /* save area size */
101 int fixed_size; /* fixed size of stack frame */
102 int gp_size; /* size of saved GP registers */
103 int fp_size; /* size of saved FP registers */
104 int altivec_size; /* size of saved AltiVec registers */
105 int cr_size; /* size to hold CR if not in save_size */
106 int vrsave_size; /* size to hold VRSAVE if not in save_size */
107 int altivec_padding_size; /* size of altivec alignment padding if
109 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
110 int spe_padding_size;
111 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
112 int spe_64bit_regs_used;
116 /* A C structure for machine-specific, per-function data.
117 This is added to the cfun structure. */
118 typedef struct GTY(()) machine_function
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p;
124 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
125 int ra_needs_full_frame;
126 /* Flags if __builtin_return_address (0) was used. */
128 /* Cache lr_save_p after expansion of builtin_eh_return. */
130 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
131 varargs save area. */
132 HOST_WIDE_INT varargs_save_offset;
133 /* Temporary stack slot to use for SDmode copies. This slot is
134 64-bits wide and is allocated early enough so that the offset
135 does not overflow the 16-bit load/store offset field. */
136 rtx sdmode_stack_slot;
139 /* Target cpu type */
141 enum processor_type rs6000_cpu;
142 struct rs6000_cpu_select rs6000_select[3] =
144 /* switch name, tune arch */
145 { (const char *)0, "--with-cpu=", 1, 1 },
146 { (const char *)0, "-mcpu=", 1, 1 },
147 { (const char *)0, "-mtune=", 1, 0 },
150 /* Always emit branch hint bits. */
151 static GTY(()) bool rs6000_always_hint;
153 /* Schedule instructions for group formation. */
154 static GTY(()) bool rs6000_sched_groups;
156 /* Align branch targets. */
157 static GTY(()) bool rs6000_align_branch_targets;
159 /* Support for -msched-costly-dep option. */
160 const char *rs6000_sched_costly_dep_str;
161 enum rs6000_dependence_cost rs6000_sched_costly_dep;
163 /* Support for -minsert-sched-nops option. */
164 const char *rs6000_sched_insert_nops_str;
165 enum rs6000_nop_insertion rs6000_sched_insert_nops;
167 /* Support targetm.vectorize.builtin_mask_for_load. */
168 static GTY(()) tree altivec_builtin_mask_for_load;
170 /* Size of long double. */
171 int rs6000_long_double_type_size;
173 /* IEEE quad extended precision long double. */
176 /* Nonzero to use AltiVec ABI. */
177 int rs6000_altivec_abi;
179 /* Nonzero if we want SPE SIMD instructions. */
182 /* Nonzero if we want SPE ABI extensions. */
185 /* Nonzero if floating point operations are done in the GPRs. */
186 int rs6000_float_gprs = 0;
188 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
189 int rs6000_darwin64_abi;
191 /* Set to nonzero once AIX common-mode calls have been defined. */
192 static GTY(()) int common_mode_defined;
194 /* Label number of label created for -mrelocatable, to call to so we can
195 get the address of the GOT section */
196 static int rs6000_pic_labelno;
199 /* Which abi to adhere to */
200 const char *rs6000_abi_name;
202 /* Semantics of the small data area */
203 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
205 /* Which small data model to use */
206 const char *rs6000_sdata_name = (char *)0;
208 /* Counter for labels which are to be placed in .fixup. */
209 int fixuplabelno = 0;
212 /* Bit size of immediate TLS offsets and string from which it is decoded. */
213 int rs6000_tls_size = 32;
214 const char *rs6000_tls_size_string;
216 /* ABI enumeration available for subtarget to use. */
217 enum rs6000_abi rs6000_current_abi;
219 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
223 const char *rs6000_debug_name;
224 int rs6000_debug_stack; /* debug stack applications */
225 int rs6000_debug_arg; /* debug argument handling */
226 int rs6000_debug_reg; /* debug register classes */
227 int rs6000_debug_addr; /* debug memory addressing */
228 int rs6000_debug_cost; /* debug rtx_costs */
230 /* Specify the machine mode that pointers have. After generation of rtl, the
231 compiler makes no further distinction between pointers and any other objects
232 of this machine mode. The type is unsigned since not all things that
233 include rs6000.h also include machmode.h. */
234 unsigned rs6000_pmode;
236 /* Width in bits of a pointer. */
237 unsigned rs6000_pointer_size;
240 /* Value is TRUE if register/mode pair is acceptable. */
241 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
243 /* Maximum number of registers needed for a given register class and mode. */
244 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
246 /* How many registers are needed for a given register and mode. */
247 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
249 /* Map register number to register class. */
250 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
252 /* Reload functions based on the type and the vector unit. */
253 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
255 /* Built in types. */
256 tree rs6000_builtin_types[RS6000_BTI_MAX];
257 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
259 const char *rs6000_traceback_name;
261 traceback_default = 0,
267 /* Flag to say the TOC is initialized */
269 char toc_label_name[10];
271 /* Cached value of rs6000_variable_issue. This is cached in
272 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
273 static short cached_can_issue_more;
275 static GTY(()) section *read_only_data_section;
276 static GTY(()) section *private_data_section;
277 static GTY(()) section *read_only_private_data_section;
278 static GTY(()) section *sdata2_section;
279 static GTY(()) section *toc_section;
281 /* Control alignment for fields within structures. */
282 /* String from -malign-XXXXX. */
283 int rs6000_alignment_flags;
285 /* Code model for 64-bit linux. */
286 enum rs6000_cmodel cmodel;
288 /* True for any options that were explicitly set. */
290 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
291 bool alignment; /* True if -malign- was used. */
292 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
293 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
294 bool spe; /* True if -mspe= was used. */
295 bool float_gprs; /* True if -mfloat-gprs= was used. */
296 bool long_double; /* True if -mlong-double- was used. */
297 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
298 bool vrsave; /* True if -mvrsave was used. */
299 bool cmodel; /* True if -mcmodel was used. */
300 } rs6000_explicit_options;
302 struct builtin_description
304 /* mask is not const because we're going to alter it below. This
305 nonsense will go away when we rewrite the -march infrastructure
306 to give us more target flag bits. */
308 const enum insn_code icode;
309 const char *const name;
310 const enum rs6000_builtins code;
313 /* Describe the vector unit used for modes. */
314 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
315 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
317 /* Register classes for various constraints that are based on the target
319 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
321 /* Describe the alignment of a vector. */
322 int rs6000_vector_align[NUM_MACHINE_MODES];
324 /* Map selected modes to types for builtins. */
325 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
327 /* What modes to automatically generate reciprocal divide estimate (fre) and
328 reciprocal sqrt (frsqrte) for. */
329 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
331 /* Masks to determine which reciprocal esitmate instructions to generate
333 enum rs6000_recip_mask {
334 RECIP_SF_DIV = 0x001, /* Use divide estimate */
335 RECIP_DF_DIV = 0x002,
336 RECIP_V4SF_DIV = 0x004,
337 RECIP_V2DF_DIV = 0x008,
339 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
340 RECIP_DF_RSQRT = 0x020,
341 RECIP_V4SF_RSQRT = 0x040,
342 RECIP_V2DF_RSQRT = 0x080,
344 /* Various combination of flags for -mrecip=xxx. */
346 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
347 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
348 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
350 RECIP_HIGH_PRECISION = RECIP_ALL,
352 /* On low precision machines like the power5, don't enable double precision
353 reciprocal square root estimate, since it isn't accurate enough. */
354 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
357 static unsigned int rs6000_recip_control;
358 static const char *rs6000_recip_name;
360 /* -mrecip options. */
363 const char *string; /* option name */
364 unsigned int mask; /* mask bits to set */
365 } recip_options[] = {
366 { "all", RECIP_ALL },
367 { "none", RECIP_NONE },
368 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
370 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
371 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
372 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
373 | RECIP_V2DF_RSQRT) },
374 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
375 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
378 /* 2 argument gen function typedef. */
379 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
382 /* Target cpu costs. */
384 struct processor_costs {
385 const int mulsi; /* cost of SImode multiplication. */
386 const int mulsi_const; /* cost of SImode multiplication by constant. */
387 const int mulsi_const9; /* cost of SImode mult by short constant. */
388 const int muldi; /* cost of DImode multiplication. */
389 const int divsi; /* cost of SImode division. */
390 const int divdi; /* cost of DImode division. */
391 const int fp; /* cost of simple SFmode and DFmode insns. */
392 const int dmul; /* cost of DFmode multiplication (and fmadd). */
393 const int sdiv; /* cost of SFmode division (fdivs). */
394 const int ddiv; /* cost of DFmode division (fdiv). */
395 const int cache_line_size; /* cache line size in bytes. */
396 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
397 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
398 const int simultaneous_prefetches; /* number of parallel prefetch
402 const struct processor_costs *rs6000_cost;
404 /* Processor costs (relative to an add) */
406 /* Instruction size costs on 32bit processors. */
408 struct processor_costs size32_cost = {
409 COSTS_N_INSNS (1), /* mulsi */
410 COSTS_N_INSNS (1), /* mulsi_const */
411 COSTS_N_INSNS (1), /* mulsi_const9 */
412 COSTS_N_INSNS (1), /* muldi */
413 COSTS_N_INSNS (1), /* divsi */
414 COSTS_N_INSNS (1), /* divdi */
415 COSTS_N_INSNS (1), /* fp */
416 COSTS_N_INSNS (1), /* dmul */
417 COSTS_N_INSNS (1), /* sdiv */
418 COSTS_N_INSNS (1), /* ddiv */
425 /* Instruction size costs on 64bit processors. */
427 struct processor_costs size64_cost = {
428 COSTS_N_INSNS (1), /* mulsi */
429 COSTS_N_INSNS (1), /* mulsi_const */
430 COSTS_N_INSNS (1), /* mulsi_const9 */
431 COSTS_N_INSNS (1), /* muldi */
432 COSTS_N_INSNS (1), /* divsi */
433 COSTS_N_INSNS (1), /* divdi */
434 COSTS_N_INSNS (1), /* fp */
435 COSTS_N_INSNS (1), /* dmul */
436 COSTS_N_INSNS (1), /* sdiv */
437 COSTS_N_INSNS (1), /* ddiv */
444 /* Instruction costs on RIOS1 processors. */
446 struct processor_costs rios1_cost = {
447 COSTS_N_INSNS (5), /* mulsi */
448 COSTS_N_INSNS (4), /* mulsi_const */
449 COSTS_N_INSNS (3), /* mulsi_const9 */
450 COSTS_N_INSNS (5), /* muldi */
451 COSTS_N_INSNS (19), /* divsi */
452 COSTS_N_INSNS (19), /* divdi */
453 COSTS_N_INSNS (2), /* fp */
454 COSTS_N_INSNS (2), /* dmul */
455 COSTS_N_INSNS (19), /* sdiv */
456 COSTS_N_INSNS (19), /* ddiv */
457 128, /* cache line size */
463 /* Instruction costs on RIOS2 processors. */
465 struct processor_costs rios2_cost = {
466 COSTS_N_INSNS (2), /* mulsi */
467 COSTS_N_INSNS (2), /* mulsi_const */
468 COSTS_N_INSNS (2), /* mulsi_const9 */
469 COSTS_N_INSNS (2), /* muldi */
470 COSTS_N_INSNS (13), /* divsi */
471 COSTS_N_INSNS (13), /* divdi */
472 COSTS_N_INSNS (2), /* fp */
473 COSTS_N_INSNS (2), /* dmul */
474 COSTS_N_INSNS (17), /* sdiv */
475 COSTS_N_INSNS (17), /* ddiv */
476 256, /* cache line size */
482 /* Instruction costs on RS64A processors. */
484 struct processor_costs rs64a_cost = {
485 COSTS_N_INSNS (20), /* mulsi */
486 COSTS_N_INSNS (12), /* mulsi_const */
487 COSTS_N_INSNS (8), /* mulsi_const9 */
488 COSTS_N_INSNS (34), /* muldi */
489 COSTS_N_INSNS (65), /* divsi */
490 COSTS_N_INSNS (67), /* divdi */
491 COSTS_N_INSNS (4), /* fp */
492 COSTS_N_INSNS (4), /* dmul */
493 COSTS_N_INSNS (31), /* sdiv */
494 COSTS_N_INSNS (31), /* ddiv */
495 128, /* cache line size */
501 /* Instruction costs on MPCCORE processors. */
503 struct processor_costs mpccore_cost = {
504 COSTS_N_INSNS (2), /* mulsi */
505 COSTS_N_INSNS (2), /* mulsi_const */
506 COSTS_N_INSNS (2), /* mulsi_const9 */
507 COSTS_N_INSNS (2), /* muldi */
508 COSTS_N_INSNS (6), /* divsi */
509 COSTS_N_INSNS (6), /* divdi */
510 COSTS_N_INSNS (4), /* fp */
511 COSTS_N_INSNS (5), /* dmul */
512 COSTS_N_INSNS (10), /* sdiv */
513 COSTS_N_INSNS (17), /* ddiv */
514 32, /* cache line size */
520 /* Instruction costs on PPC403 processors. */
522 struct processor_costs ppc403_cost = {
523 COSTS_N_INSNS (4), /* mulsi */
524 COSTS_N_INSNS (4), /* mulsi_const */
525 COSTS_N_INSNS (4), /* mulsi_const9 */
526 COSTS_N_INSNS (4), /* muldi */
527 COSTS_N_INSNS (33), /* divsi */
528 COSTS_N_INSNS (33), /* divdi */
529 COSTS_N_INSNS (11), /* fp */
530 COSTS_N_INSNS (11), /* dmul */
531 COSTS_N_INSNS (11), /* sdiv */
532 COSTS_N_INSNS (11), /* ddiv */
533 32, /* cache line size */
539 /* Instruction costs on PPC405 processors. */
541 struct processor_costs ppc405_cost = {
542 COSTS_N_INSNS (5), /* mulsi */
543 COSTS_N_INSNS (4), /* mulsi_const */
544 COSTS_N_INSNS (3), /* mulsi_const9 */
545 COSTS_N_INSNS (5), /* muldi */
546 COSTS_N_INSNS (35), /* divsi */
547 COSTS_N_INSNS (35), /* divdi */
548 COSTS_N_INSNS (11), /* fp */
549 COSTS_N_INSNS (11), /* dmul */
550 COSTS_N_INSNS (11), /* sdiv */
551 COSTS_N_INSNS (11), /* ddiv */
552 32, /* cache line size */
558 /* Instruction costs on PPC440 processors. */
560 struct processor_costs ppc440_cost = {
561 COSTS_N_INSNS (3), /* mulsi */
562 COSTS_N_INSNS (2), /* mulsi_const */
563 COSTS_N_INSNS (2), /* mulsi_const9 */
564 COSTS_N_INSNS (3), /* muldi */
565 COSTS_N_INSNS (34), /* divsi */
566 COSTS_N_INSNS (34), /* divdi */
567 COSTS_N_INSNS (5), /* fp */
568 COSTS_N_INSNS (5), /* dmul */
569 COSTS_N_INSNS (19), /* sdiv */
570 COSTS_N_INSNS (33), /* ddiv */
571 32, /* cache line size */
577 /* Instruction costs on PPC476 processors. */
579 struct processor_costs ppc476_cost = {
580 COSTS_N_INSNS (4), /* mulsi */
581 COSTS_N_INSNS (4), /* mulsi_const */
582 COSTS_N_INSNS (4), /* mulsi_const9 */
583 COSTS_N_INSNS (4), /* muldi */
584 COSTS_N_INSNS (11), /* divsi */
585 COSTS_N_INSNS (11), /* divdi */
586 COSTS_N_INSNS (6), /* fp */
587 COSTS_N_INSNS (6), /* dmul */
588 COSTS_N_INSNS (19), /* sdiv */
589 COSTS_N_INSNS (33), /* ddiv */
590 32, /* l1 cache line size */
596 /* Instruction costs on PPC601 processors. */
598 struct processor_costs ppc601_cost = {
599 COSTS_N_INSNS (5), /* mulsi */
600 COSTS_N_INSNS (5), /* mulsi_const */
601 COSTS_N_INSNS (5), /* mulsi_const9 */
602 COSTS_N_INSNS (5), /* muldi */
603 COSTS_N_INSNS (36), /* divsi */
604 COSTS_N_INSNS (36), /* divdi */
605 COSTS_N_INSNS (4), /* fp */
606 COSTS_N_INSNS (5), /* dmul */
607 COSTS_N_INSNS (17), /* sdiv */
608 COSTS_N_INSNS (31), /* ddiv */
609 32, /* cache line size */
615 /* Instruction costs on PPC603 processors. */
617 struct processor_costs ppc603_cost = {
618 COSTS_N_INSNS (5), /* mulsi */
619 COSTS_N_INSNS (3), /* mulsi_const */
620 COSTS_N_INSNS (2), /* mulsi_const9 */
621 COSTS_N_INSNS (5), /* muldi */
622 COSTS_N_INSNS (37), /* divsi */
623 COSTS_N_INSNS (37), /* divdi */
624 COSTS_N_INSNS (3), /* fp */
625 COSTS_N_INSNS (4), /* dmul */
626 COSTS_N_INSNS (18), /* sdiv */
627 COSTS_N_INSNS (33), /* ddiv */
628 32, /* cache line size */
634 /* Instruction costs on PPC604 processors. */
636 struct processor_costs ppc604_cost = {
637 COSTS_N_INSNS (4), /* mulsi */
638 COSTS_N_INSNS (4), /* mulsi_const */
639 COSTS_N_INSNS (4), /* mulsi_const9 */
640 COSTS_N_INSNS (4), /* muldi */
641 COSTS_N_INSNS (20), /* divsi */
642 COSTS_N_INSNS (20), /* divdi */
643 COSTS_N_INSNS (3), /* fp */
644 COSTS_N_INSNS (3), /* dmul */
645 COSTS_N_INSNS (18), /* sdiv */
646 COSTS_N_INSNS (32), /* ddiv */
647 32, /* cache line size */
653 /* Instruction costs on PPC604e processors. */
655 struct processor_costs ppc604e_cost = {
656 COSTS_N_INSNS (2), /* mulsi */
657 COSTS_N_INSNS (2), /* mulsi_const */
658 COSTS_N_INSNS (2), /* mulsi_const9 */
659 COSTS_N_INSNS (2), /* muldi */
660 COSTS_N_INSNS (20), /* divsi */
661 COSTS_N_INSNS (20), /* divdi */
662 COSTS_N_INSNS (3), /* fp */
663 COSTS_N_INSNS (3), /* dmul */
664 COSTS_N_INSNS (18), /* sdiv */
665 COSTS_N_INSNS (32), /* ddiv */
666 32, /* cache line size */
672 /* Instruction costs on PPC620 processors. */
674 struct processor_costs ppc620_cost = {
675 COSTS_N_INSNS (5), /* mulsi */
676 COSTS_N_INSNS (4), /* mulsi_const */
677 COSTS_N_INSNS (3), /* mulsi_const9 */
678 COSTS_N_INSNS (7), /* muldi */
679 COSTS_N_INSNS (21), /* divsi */
680 COSTS_N_INSNS (37), /* divdi */
681 COSTS_N_INSNS (3), /* fp */
682 COSTS_N_INSNS (3), /* dmul */
683 COSTS_N_INSNS (18), /* sdiv */
684 COSTS_N_INSNS (32), /* ddiv */
685 128, /* cache line size */
691 /* Instruction costs on PPC630 processors. */
693 struct processor_costs ppc630_cost = {
694 COSTS_N_INSNS (5), /* mulsi */
695 COSTS_N_INSNS (4), /* mulsi_const */
696 COSTS_N_INSNS (3), /* mulsi_const9 */
697 COSTS_N_INSNS (7), /* muldi */
698 COSTS_N_INSNS (21), /* divsi */
699 COSTS_N_INSNS (37), /* divdi */
700 COSTS_N_INSNS (3), /* fp */
701 COSTS_N_INSNS (3), /* dmul */
702 COSTS_N_INSNS (17), /* sdiv */
703 COSTS_N_INSNS (21), /* ddiv */
704 128, /* cache line size */
710 /* Instruction costs on Cell processor. */
711 /* COSTS_N_INSNS (1) ~ one add. */
713 struct processor_costs ppccell_cost = {
714 COSTS_N_INSNS (9/2)+2, /* mulsi */
715 COSTS_N_INSNS (6/2), /* mulsi_const */
716 COSTS_N_INSNS (6/2), /* mulsi_const9 */
717 COSTS_N_INSNS (15/2)+2, /* muldi */
718 COSTS_N_INSNS (38/2), /* divsi */
719 COSTS_N_INSNS (70/2), /* divdi */
720 COSTS_N_INSNS (10/2), /* fp */
721 COSTS_N_INSNS (10/2), /* dmul */
722 COSTS_N_INSNS (74/2), /* sdiv */
723 COSTS_N_INSNS (74/2), /* ddiv */
724 128, /* cache line size */
730 /* Instruction costs on PPC750 and PPC7400 processors. */
732 struct processor_costs ppc750_cost = {
733 COSTS_N_INSNS (5), /* mulsi */
734 COSTS_N_INSNS (3), /* mulsi_const */
735 COSTS_N_INSNS (2), /* mulsi_const9 */
736 COSTS_N_INSNS (5), /* muldi */
737 COSTS_N_INSNS (17), /* divsi */
738 COSTS_N_INSNS (17), /* divdi */
739 COSTS_N_INSNS (3), /* fp */
740 COSTS_N_INSNS (3), /* dmul */
741 COSTS_N_INSNS (17), /* sdiv */
742 COSTS_N_INSNS (31), /* ddiv */
743 32, /* cache line size */
749 /* Instruction costs on PPC7450 processors. */
751 struct processor_costs ppc7450_cost = {
752 COSTS_N_INSNS (4), /* mulsi */
753 COSTS_N_INSNS (3), /* mulsi_const */
754 COSTS_N_INSNS (3), /* mulsi_const9 */
755 COSTS_N_INSNS (4), /* muldi */
756 COSTS_N_INSNS (23), /* divsi */
757 COSTS_N_INSNS (23), /* divdi */
758 COSTS_N_INSNS (5), /* fp */
759 COSTS_N_INSNS (5), /* dmul */
760 COSTS_N_INSNS (21), /* sdiv */
761 COSTS_N_INSNS (35), /* ddiv */
762 32, /* cache line size */
768 /* Instruction costs on PPC8540 processors. */
770 struct processor_costs ppc8540_cost = {
771 COSTS_N_INSNS (4), /* mulsi */
772 COSTS_N_INSNS (4), /* mulsi_const */
773 COSTS_N_INSNS (4), /* mulsi_const9 */
774 COSTS_N_INSNS (4), /* muldi */
775 COSTS_N_INSNS (19), /* divsi */
776 COSTS_N_INSNS (19), /* divdi */
777 COSTS_N_INSNS (4), /* fp */
778 COSTS_N_INSNS (4), /* dmul */
779 COSTS_N_INSNS (29), /* sdiv */
780 COSTS_N_INSNS (29), /* ddiv */
781 32, /* cache line size */
784 1, /* prefetch streams /*/
787 /* Instruction costs on E300C2 and E300C3 cores. */
789 struct processor_costs ppce300c2c3_cost = {
790 COSTS_N_INSNS (4), /* mulsi */
791 COSTS_N_INSNS (4), /* mulsi_const */
792 COSTS_N_INSNS (4), /* mulsi_const9 */
793 COSTS_N_INSNS (4), /* muldi */
794 COSTS_N_INSNS (19), /* divsi */
795 COSTS_N_INSNS (19), /* divdi */
796 COSTS_N_INSNS (3), /* fp */
797 COSTS_N_INSNS (4), /* dmul */
798 COSTS_N_INSNS (18), /* sdiv */
799 COSTS_N_INSNS (33), /* ddiv */
803 1, /* prefetch streams /*/
806 /* Instruction costs on PPCE500MC processors. */
808 struct processor_costs ppce500mc_cost = {
809 COSTS_N_INSNS (4), /* mulsi */
810 COSTS_N_INSNS (4), /* mulsi_const */
811 COSTS_N_INSNS (4), /* mulsi_const9 */
812 COSTS_N_INSNS (4), /* muldi */
813 COSTS_N_INSNS (14), /* divsi */
814 COSTS_N_INSNS (14), /* divdi */
815 COSTS_N_INSNS (8), /* fp */
816 COSTS_N_INSNS (10), /* dmul */
817 COSTS_N_INSNS (36), /* sdiv */
818 COSTS_N_INSNS (66), /* ddiv */
819 64, /* cache line size */
822 1, /* prefetch streams /*/
825 /* Instruction costs on PPCE500MC64 processors. */
827 struct processor_costs ppce500mc64_cost = {
828 COSTS_N_INSNS (4), /* mulsi */
829 COSTS_N_INSNS (4), /* mulsi_const */
830 COSTS_N_INSNS (4), /* mulsi_const9 */
831 COSTS_N_INSNS (4), /* muldi */
832 COSTS_N_INSNS (14), /* divsi */
833 COSTS_N_INSNS (14), /* divdi */
834 COSTS_N_INSNS (4), /* fp */
835 COSTS_N_INSNS (10), /* dmul */
836 COSTS_N_INSNS (36), /* sdiv */
837 COSTS_N_INSNS (66), /* ddiv */
838 64, /* cache line size */
841 1, /* prefetch streams /*/
844 /* Instruction costs on AppliedMicro Titan processors. */
846 struct processor_costs titan_cost = {
847 COSTS_N_INSNS (5), /* mulsi */
848 COSTS_N_INSNS (5), /* mulsi_const */
849 COSTS_N_INSNS (5), /* mulsi_const9 */
850 COSTS_N_INSNS (5), /* muldi */
851 COSTS_N_INSNS (18), /* divsi */
852 COSTS_N_INSNS (18), /* divdi */
853 COSTS_N_INSNS (10), /* fp */
854 COSTS_N_INSNS (10), /* dmul */
855 COSTS_N_INSNS (46), /* sdiv */
856 COSTS_N_INSNS (72), /* ddiv */
857 32, /* cache line size */
860 1, /* prefetch streams /*/
863 /* Instruction costs on POWER4 and POWER5 processors. */
865 struct processor_costs power4_cost = {
866 COSTS_N_INSNS (3), /* mulsi */
867 COSTS_N_INSNS (2), /* mulsi_const */
868 COSTS_N_INSNS (2), /* mulsi_const9 */
869 COSTS_N_INSNS (4), /* muldi */
870 COSTS_N_INSNS (18), /* divsi */
871 COSTS_N_INSNS (34), /* divdi */
872 COSTS_N_INSNS (3), /* fp */
873 COSTS_N_INSNS (3), /* dmul */
874 COSTS_N_INSNS (17), /* sdiv */
875 COSTS_N_INSNS (17), /* ddiv */
876 128, /* cache line size */
879 8, /* prefetch streams /*/
882 /* Instruction costs on POWER6 processors. */
884 struct processor_costs power6_cost = {
885 COSTS_N_INSNS (8), /* mulsi */
886 COSTS_N_INSNS (8), /* mulsi_const */
887 COSTS_N_INSNS (8), /* mulsi_const9 */
888 COSTS_N_INSNS (8), /* muldi */
889 COSTS_N_INSNS (22), /* divsi */
890 COSTS_N_INSNS (28), /* divdi */
891 COSTS_N_INSNS (3), /* fp */
892 COSTS_N_INSNS (3), /* dmul */
893 COSTS_N_INSNS (13), /* sdiv */
894 COSTS_N_INSNS (16), /* ddiv */
895 128, /* cache line size */
898 16, /* prefetch streams */
901 /* Instruction costs on POWER7 processors. */
903 struct processor_costs power7_cost = {
904 COSTS_N_INSNS (2), /* mulsi */
905 COSTS_N_INSNS (2), /* mulsi_const */
906 COSTS_N_INSNS (2), /* mulsi_const9 */
907 COSTS_N_INSNS (2), /* muldi */
908 COSTS_N_INSNS (18), /* divsi */
909 COSTS_N_INSNS (34), /* divdi */
910 COSTS_N_INSNS (3), /* fp */
911 COSTS_N_INSNS (3), /* dmul */
912 COSTS_N_INSNS (13), /* sdiv */
913 COSTS_N_INSNS (16), /* ddiv */
914 128, /* cache line size */
917 12, /* prefetch streams */
920 /* Instruction costs on POWER A2 processors. */
922 struct processor_costs ppca2_cost = {
923 COSTS_N_INSNS (16), /* mulsi */
924 COSTS_N_INSNS (16), /* mulsi_const */
925 COSTS_N_INSNS (16), /* mulsi_const9 */
926 COSTS_N_INSNS (16), /* muldi */
927 COSTS_N_INSNS (22), /* divsi */
928 COSTS_N_INSNS (28), /* divdi */
929 COSTS_N_INSNS (3), /* fp */
930 COSTS_N_INSNS (3), /* dmul */
931 COSTS_N_INSNS (59), /* sdiv */
932 COSTS_N_INSNS (72), /* ddiv */
936 16, /* prefetch streams */
940 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
941 #undef RS6000_BUILTIN
942 #undef RS6000_BUILTIN_EQUATE
943 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
944 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
946 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
948 #include "rs6000-builtin.def"
951 #undef RS6000_BUILTIN
952 #undef RS6000_BUILTIN_EQUATE
954 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
955 static tree (*rs6000_veclib_handler) (tree, tree, tree);
958 static bool rs6000_function_ok_for_sibcall (tree, tree);
959 static const char *rs6000_invalid_within_doloop (const_rtx);
960 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
961 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
962 static rtx rs6000_generate_compare (rtx, enum machine_mode);
963 static void rs6000_emit_stack_tie (void);
964 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
965 static bool spe_func_has_64bit_regs_p (void);
966 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
968 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
969 static unsigned rs6000_hash_constant (rtx);
970 static unsigned toc_hash_function (const void *);
971 static int toc_hash_eq (const void *, const void *);
972 static bool reg_offset_addressing_ok_p (enum machine_mode);
973 static bool virtual_stack_registers_memory_p (rtx);
974 static bool constant_pool_expr_p (rtx);
975 static bool legitimate_small_data_p (enum machine_mode, rtx);
976 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
977 static struct machine_function * rs6000_init_machine_status (void);
978 static bool rs6000_assemble_integer (rtx, unsigned int, int);
979 static bool no_global_regs_above (int, bool);
980 #ifdef HAVE_GAS_HIDDEN
981 static void rs6000_assemble_visibility (tree, int);
983 static int rs6000_ra_ever_killed (void);
984 static bool rs6000_attribute_takes_identifier_p (const_tree);
985 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
986 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
987 static bool rs6000_ms_bitfield_layout_p (const_tree);
988 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
989 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
990 static const char *rs6000_mangle_type (const_tree);
991 static void rs6000_set_default_type_attributes (tree);
992 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
993 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
994 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
995 enum machine_mode, bool, bool, bool);
996 static bool rs6000_reg_live_or_pic_offset_p (int);
997 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
998 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
999 static void rs6000_restore_saved_cr (rtx, int);
1000 static bool rs6000_output_addr_const_extra (FILE *, rtx);
1001 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
1002 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
1003 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
1005 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1006 static bool rs6000_return_in_memory (const_tree, const_tree);
1007 static rtx rs6000_function_value (const_tree, const_tree, bool);
1008 static void rs6000_file_start (void);
1010 static int rs6000_elf_reloc_rw_mask (void);
1011 static void rs6000_elf_asm_out_constructor (rtx, int);
1012 static void rs6000_elf_asm_out_destructor (rtx, int);
1013 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1014 static void rs6000_elf_asm_init_sections (void);
1015 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1016 unsigned HOST_WIDE_INT);
1017 static void rs6000_elf_encode_section_info (tree, rtx, int)
1020 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1021 static void rs6000_alloc_sdmode_stack_slot (void);
1022 static void rs6000_instantiate_decls (void);
1024 static void rs6000_xcoff_asm_output_anchor (rtx);
1025 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1026 static void rs6000_xcoff_asm_init_sections (void);
1027 static int rs6000_xcoff_reloc_rw_mask (void);
1028 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1029 static section *rs6000_xcoff_select_section (tree, int,
1030 unsigned HOST_WIDE_INT);
1031 static void rs6000_xcoff_unique_section (tree, int);
1032 static section *rs6000_xcoff_select_rtx_section
1033 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1034 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1035 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1036 static void rs6000_xcoff_file_start (void);
1037 static void rs6000_xcoff_file_end (void);
1039 static int rs6000_variable_issue (FILE *, int, rtx, int);
1040 static int rs6000_register_move_cost (enum machine_mode,
1041 reg_class_t, reg_class_t);
1042 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1043 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1044 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1045 static int rs6000_debug_address_cost (rtx, bool);
1046 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1047 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1048 static void rs6000_sched_init (FILE *, int, int);
1049 static bool is_microcoded_insn (rtx);
1050 static bool is_nonpipeline_insn (rtx);
1051 static bool is_cracked_insn (rtx);
1052 static bool is_branch_slot_insn (rtx);
1053 static bool is_load_insn (rtx);
1054 static rtx get_store_dest (rtx pat);
1055 static bool is_store_insn (rtx);
1056 static bool set_to_load_agen (rtx,rtx);
1057 static bool adjacent_mem_locations (rtx,rtx);
1058 static int rs6000_adjust_priority (rtx, int);
1059 static int rs6000_issue_rate (void);
1060 static bool rs6000_is_costly_dependence (dep_t, int, int);
1061 static rtx get_next_active_insn (rtx, rtx);
1062 static bool insn_terminates_group_p (rtx , enum group_termination);
1063 static bool insn_must_be_first_in_group (rtx);
1064 static bool insn_must_be_last_in_group (rtx);
1065 static bool is_costly_group (rtx *, rtx);
1066 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1067 static int redefine_groups (FILE *, int, rtx, rtx);
1068 static int pad_groups (FILE *, int, rtx, rtx);
1069 static void rs6000_sched_finish (FILE *, int);
1070 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1071 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1072 static int rs6000_use_sched_lookahead (void);
1073 static int rs6000_use_sched_lookahead_guard (rtx);
1074 static void * rs6000_alloc_sched_context (void);
1075 static void rs6000_init_sched_context (void *, bool);
1076 static void rs6000_set_sched_context (void *);
1077 static void rs6000_free_sched_context (void *);
1078 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1079 static tree rs6000_builtin_mask_for_load (void);
1080 static tree rs6000_builtin_mul_widen_even (tree);
1081 static tree rs6000_builtin_mul_widen_odd (tree);
1082 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1083 static tree rs6000_builtin_vec_perm (tree, tree *);
1084 static bool rs6000_builtin_support_vector_misalignment (enum
1088 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1090 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1092 static void def_builtin (int, const char *, tree, int);
1093 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1094 static void rs6000_init_builtins (void);
1095 static tree rs6000_builtin_decl (unsigned, bool);
1097 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1098 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1099 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1100 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1101 static void altivec_init_builtins (void);
1102 static unsigned builtin_hash_function (const void *);
1103 static int builtin_hash_eq (const void *, const void *);
1104 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1105 enum machine_mode, enum machine_mode,
1106 enum rs6000_builtins, const char *name);
1107 static void rs6000_common_init_builtins (void);
1108 static void rs6000_init_libfuncs (void);
1110 static void paired_init_builtins (void);
1111 static rtx paired_expand_builtin (tree, rtx, bool *);
1112 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1113 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1114 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1116 static void enable_mask_for_builtins (struct builtin_description *, int,
1117 enum rs6000_builtins,
1118 enum rs6000_builtins);
1119 static void spe_init_builtins (void);
1120 static rtx spe_expand_builtin (tree, rtx, bool *);
1121 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1122 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1123 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1124 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1125 static rs6000_stack_t *rs6000_stack_info (void);
1126 static void debug_stack_info (rs6000_stack_t *);
1128 static rtx altivec_expand_builtin (tree, rtx, bool *);
1129 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1130 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1131 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1132 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1133 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1134 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1135 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1136 static rtx altivec_expand_vec_set_builtin (tree);
1137 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1138 static int get_element_number (tree, tree);
1139 static void rs6000_option_override (void);
1140 static void rs6000_option_init_struct (struct gcc_options *);
1141 static void rs6000_option_default_params (void);
1142 static bool rs6000_handle_option (size_t, const char *, int);
1143 static void rs6000_parse_tls_size_option (void);
1144 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1145 static int first_altivec_reg_to_save (void);
1146 static unsigned int compute_vrsave_mask (void);
1147 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1148 static void is_altivec_return_reg (rtx, void *);
1149 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1150 int easy_vector_constant (rtx, enum machine_mode);
1151 static rtx rs6000_dwarf_register_span (rtx);
1152 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1153 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1154 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1155 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1156 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1157 static rtx rs6000_delegitimize_address (rtx);
1158 static rtx rs6000_tls_get_addr (void);
1159 static rtx rs6000_got_sym (void);
1160 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1161 static const char *rs6000_get_some_local_dynamic_name (void);
1162 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1163 static rtx rs6000_complex_function_value (enum machine_mode);
1164 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1165 enum machine_mode, const_tree);
1166 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1167 HOST_WIDE_INT, int);
1168 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1171 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1174 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1175 const_tree, HOST_WIDE_INT,
1177 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1178 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1179 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1181 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1183 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1184 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1185 enum machine_mode, tree,
1187 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1189 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1191 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1193 static void macho_branch_islands (void);
1194 static int no_previous_def (tree function_name);
1195 static tree get_prev_label (tree function_name);
1196 static void rs6000_darwin_file_start (void);
1199 static tree rs6000_build_builtin_va_list (void);
1200 static void rs6000_va_start (tree, rtx);
1201 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1202 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1203 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1204 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1205 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1206 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1208 static tree rs6000_stack_protect_fail (void);
1210 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1213 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1216 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1218 = rs6000_legitimize_reload_address;
1220 static bool rs6000_mode_dependent_address_p (const_rtx);
1221 static bool rs6000_mode_dependent_address (const_rtx);
1222 static bool rs6000_debug_mode_dependent_address (const_rtx);
1223 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1224 = rs6000_mode_dependent_address;
1226 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1227 enum machine_mode, rtx);
1228 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1231 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1232 enum machine_mode, rtx)
1233 = rs6000_secondary_reload_class;
1235 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1236 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1238 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1239 = rs6000_preferred_reload_class;
1241 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1244 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1248 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1250 = rs6000_secondary_memory_needed;
1252 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1255 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1259 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1262 = rs6000_cannot_change_mode_class;
1264 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1266 struct secondary_reload_info *);
1268 static const reg_class_t *rs6000_ira_cover_classes (void);
1270 const int INSN_NOT_AVAILABLE = -1;
1271 static enum machine_mode rs6000_eh_return_filter_mode (void);
1272 static bool rs6000_can_eliminate (const int, const int);
1273 static void rs6000_trampoline_init (rtx, tree, rtx);
1275 /* Hash table stuff for keeping track of TOC entries. */
1277 struct GTY(()) toc_hash_struct
1279 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1280 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1282 enum machine_mode key_mode;
1286 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1288 /* Hash table to keep track of the argument types for builtin functions. */
1290 struct GTY(()) builtin_hash_struct
1293 enum machine_mode mode[4]; /* return value + 3 arguments. */
1294 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1297 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1299 /* Default register names. */
1300 char rs6000_reg_names[][8] =
1302 "0", "1", "2", "3", "4", "5", "6", "7",
1303 "8", "9", "10", "11", "12", "13", "14", "15",
1304 "16", "17", "18", "19", "20", "21", "22", "23",
1305 "24", "25", "26", "27", "28", "29", "30", "31",
1306 "0", "1", "2", "3", "4", "5", "6", "7",
1307 "8", "9", "10", "11", "12", "13", "14", "15",
1308 "16", "17", "18", "19", "20", "21", "22", "23",
1309 "24", "25", "26", "27", "28", "29", "30", "31",
1310 "mq", "lr", "ctr","ap",
1311 "0", "1", "2", "3", "4", "5", "6", "7",
1313 /* AltiVec registers. */
1314 "0", "1", "2", "3", "4", "5", "6", "7",
1315 "8", "9", "10", "11", "12", "13", "14", "15",
1316 "16", "17", "18", "19", "20", "21", "22", "23",
1317 "24", "25", "26", "27", "28", "29", "30", "31",
1319 /* SPE registers. */
1320 "spe_acc", "spefscr",
1321 /* Soft frame pointer. */
1325 #ifdef TARGET_REGNAMES
1326 static const char alt_reg_names[][8] =
1328 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1329 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1330 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1331 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1332 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1333 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1334 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1335 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1336 "mq", "lr", "ctr", "ap",
1337 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1339 /* AltiVec registers. */
1340 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1341 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1342 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1343 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1345 /* SPE registers. */
1346 "spe_acc", "spefscr",
1347 /* Soft frame pointer. */
1352 /* Table of valid machine attributes. */
1354 static const struct attribute_spec rs6000_attribute_table[] =
1356 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1357 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1358 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1359 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1360 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1361 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1362 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1363 SUBTARGET_ATTRIBUTE_TABLE,
1365 { NULL, 0, 0, false, false, false, NULL }
1368 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1369 static const struct default_options rs6000_option_optimization_table[] =
1371 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1372 { OPT_LEVELS_NONE, 0, NULL, 0 }
1375 #ifndef MASK_STRICT_ALIGN
1376 #define MASK_STRICT_ALIGN 0
1378 #ifndef TARGET_PROFILE_KERNEL
1379 #define TARGET_PROFILE_KERNEL 0
1382 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1383 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1385 /* Initialize the GCC target structure. */
1386 #undef TARGET_ATTRIBUTE_TABLE
1387 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1388 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1389 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1390 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1391 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1393 #undef TARGET_ASM_ALIGNED_DI_OP
1394 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1396 /* Default unaligned ops are only provided for ELF. Find the ops needed
1397 for non-ELF systems. */
1398 #ifndef OBJECT_FORMAT_ELF
1400 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1402 #undef TARGET_ASM_UNALIGNED_HI_OP
1403 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1404 #undef TARGET_ASM_UNALIGNED_SI_OP
1405 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1406 #undef TARGET_ASM_UNALIGNED_DI_OP
1407 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1410 #undef TARGET_ASM_UNALIGNED_HI_OP
1411 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1412 #undef TARGET_ASM_UNALIGNED_SI_OP
1413 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1414 #undef TARGET_ASM_UNALIGNED_DI_OP
1415 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1416 #undef TARGET_ASM_ALIGNED_DI_OP
1417 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1421 /* This hook deals with fixups for relocatable code and DI-mode objects
1423 #undef TARGET_ASM_INTEGER
1424 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1426 #ifdef HAVE_GAS_HIDDEN
1427 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1428 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1431 #undef TARGET_HAVE_TLS
1432 #define TARGET_HAVE_TLS HAVE_AS_TLS
1434 #undef TARGET_CANNOT_FORCE_CONST_MEM
1435 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1437 #undef TARGET_DELEGITIMIZE_ADDRESS
1438 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1440 #undef TARGET_ASM_FUNCTION_PROLOGUE
1441 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1442 #undef TARGET_ASM_FUNCTION_EPILOGUE
1443 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1445 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1446 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1448 #undef TARGET_LEGITIMIZE_ADDRESS
1449 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1451 #undef TARGET_SCHED_VARIABLE_ISSUE
1452 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1454 #undef TARGET_SCHED_ISSUE_RATE
1455 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1456 #undef TARGET_SCHED_ADJUST_COST
1457 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1458 #undef TARGET_SCHED_ADJUST_PRIORITY
1459 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1460 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1461 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1462 #undef TARGET_SCHED_INIT
1463 #define TARGET_SCHED_INIT rs6000_sched_init
1464 #undef TARGET_SCHED_FINISH
1465 #define TARGET_SCHED_FINISH rs6000_sched_finish
1466 #undef TARGET_SCHED_REORDER
1467 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1468 #undef TARGET_SCHED_REORDER2
1469 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1471 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1472 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1474 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1475 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1477 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1478 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1479 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1480 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1481 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1482 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1483 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1484 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1486 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1487 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1488 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1489 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1490 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1491 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1492 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1493 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1494 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1495 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1496 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1497 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1498 rs6000_builtin_support_vector_misalignment
1499 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1500 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1501 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1502 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1503 rs6000_builtin_vectorization_cost
1504 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1505 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1506 rs6000_preferred_simd_mode
1508 #undef TARGET_INIT_BUILTINS
1509 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1510 #undef TARGET_BUILTIN_DECL
1511 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1513 #undef TARGET_EXPAND_BUILTIN
1514 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1516 #undef TARGET_MANGLE_TYPE
1517 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1519 #undef TARGET_INIT_LIBFUNCS
1520 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1523 #undef TARGET_BINDS_LOCAL_P
1524 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1527 #undef TARGET_MS_BITFIELD_LAYOUT_P
1528 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1530 #undef TARGET_ASM_OUTPUT_MI_THUNK
1531 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1533 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1534 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1536 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1537 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1539 #undef TARGET_INVALID_WITHIN_DOLOOP
1540 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1542 #undef TARGET_REGISTER_MOVE_COST
1543 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1544 #undef TARGET_MEMORY_MOVE_COST
1545 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1546 #undef TARGET_RTX_COSTS
1547 #define TARGET_RTX_COSTS rs6000_rtx_costs
1548 #undef TARGET_ADDRESS_COST
1549 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1551 #undef TARGET_DWARF_REGISTER_SPAN
1552 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1554 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1555 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1557 /* On rs6000, function arguments are promoted, as are function return
1559 #undef TARGET_PROMOTE_FUNCTION_MODE
1560 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1562 #undef TARGET_RETURN_IN_MEMORY
1563 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1565 #undef TARGET_SETUP_INCOMING_VARARGS
1566 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1568 /* Always strict argument naming on rs6000. */
1569 #undef TARGET_STRICT_ARGUMENT_NAMING
1570 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1571 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1572 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1573 #undef TARGET_SPLIT_COMPLEX_ARG
1574 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1575 #undef TARGET_MUST_PASS_IN_STACK
1576 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1577 #undef TARGET_PASS_BY_REFERENCE
1578 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1579 #undef TARGET_ARG_PARTIAL_BYTES
1580 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1581 #undef TARGET_FUNCTION_ARG_ADVANCE
1582 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1583 #undef TARGET_FUNCTION_ARG
1584 #define TARGET_FUNCTION_ARG rs6000_function_arg
1586 #undef TARGET_BUILD_BUILTIN_VA_LIST
1587 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1589 #undef TARGET_EXPAND_BUILTIN_VA_START
1590 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1592 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1593 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1595 #undef TARGET_EH_RETURN_FILTER_MODE
1596 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1598 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1599 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1601 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1602 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1604 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1605 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1607 #undef TARGET_HANDLE_OPTION
1608 #define TARGET_HANDLE_OPTION rs6000_handle_option
1610 #undef TARGET_OPTION_OVERRIDE
1611 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1613 #undef TARGET_OPTION_INIT_STRUCT
1614 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1616 #undef TARGET_OPTION_DEFAULT_PARAMS
1617 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1619 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1620 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1622 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1623 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1624 rs6000_builtin_vectorized_function
1626 #undef TARGET_DEFAULT_TARGET_FLAGS
1627 #define TARGET_DEFAULT_TARGET_FLAGS \
1630 #undef TARGET_STACK_PROTECT_FAIL
1631 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1633 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1634 The PowerPC architecture requires only weak consistency among
1635 processors--that is, memory accesses between processors need not be
1636 sequentially consistent and memory accesses among processors can occur
1637 in any order. The ability to order memory accesses weakly provides
1638 opportunities for more efficient use of the system bus. Unless a
1639 dependency exists, the 604e allows read operations to precede store
1641 #undef TARGET_RELAXED_ORDERING
1642 #define TARGET_RELAXED_ORDERING true
1645 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1646 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1649 /* Use a 32-bit anchor range. This leads to sequences like:
1651 addis tmp,anchor,high
1654 where tmp itself acts as an anchor, and can be shared between
1655 accesses to the same 64k page. */
1656 #undef TARGET_MIN_ANCHOR_OFFSET
1657 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1658 #undef TARGET_MAX_ANCHOR_OFFSET
1659 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1660 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1661 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1663 #undef TARGET_BUILTIN_RECIPROCAL
1664 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1666 #undef TARGET_EXPAND_TO_RTL_HOOK
1667 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1669 #undef TARGET_INSTANTIATE_DECLS
1670 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1672 #undef TARGET_SECONDARY_RELOAD
1673 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1675 #undef TARGET_IRA_COVER_CLASSES
1676 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1678 #undef TARGET_LEGITIMATE_ADDRESS_P
1679 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1681 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1682 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1684 #undef TARGET_CAN_ELIMINATE
1685 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1687 #undef TARGET_TRAMPOLINE_INIT
1688 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1690 #undef TARGET_FUNCTION_VALUE
1691 #define TARGET_FUNCTION_VALUE rs6000_function_value
1693 struct gcc_target targetm = TARGET_INITIALIZER;
1695 /* Return number of consecutive hard regs needed starting at reg REGNO
1696 to hold something of mode MODE.
1697 This is ordinarily the length in words of a value of mode MODE
1698 but can be less for certain modes in special long registers.
1700 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1701 scalar instructions. The upper 32 bits are only available to the
1704 POWER and PowerPC GPRs hold 32 bits worth;
1705 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1708 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1710 unsigned HOST_WIDE_INT reg_size;
1712 if (FP_REGNO_P (regno))
1713 reg_size = (VECTOR_MEM_VSX_P (mode)
1714 ? UNITS_PER_VSX_WORD
1715 : UNITS_PER_FP_WORD);
1717 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1718 reg_size = UNITS_PER_SPE_WORD;
1720 else if (ALTIVEC_REGNO_P (regno))
1721 reg_size = UNITS_PER_ALTIVEC_WORD;
1723 /* The value returned for SCmode in the E500 double case is 2 for
1724 ABI compatibility; storing an SCmode value in a single register
1725 would require function_arg and rs6000_spe_function_arg to handle
1726 SCmode so as to pass the value correctly in a pair of
1728 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1729 && !DECIMAL_FLOAT_MODE_P (mode))
1730 reg_size = UNITS_PER_FP_WORD;
1733 reg_size = UNITS_PER_WORD;
1735 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1738 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1741 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1743 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1745 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1746 implementations. Don't allow an item to be split between a FP register
1747 and an Altivec register. */
1748 if (VECTOR_MEM_VSX_P (mode))
1750 if (FP_REGNO_P (regno))
1751 return FP_REGNO_P (last_regno);
1753 if (ALTIVEC_REGNO_P (regno))
1754 return ALTIVEC_REGNO_P (last_regno);
1757 /* The GPRs can hold any mode, but values bigger than one register
1758 cannot go past R31. */
1759 if (INT_REGNO_P (regno))
1760 return INT_REGNO_P (last_regno);
1762 /* The float registers (except for VSX vector modes) can only hold floating
1763 modes and DImode. This excludes the 32-bit decimal float mode for
1765 if (FP_REGNO_P (regno))
1767 if (SCALAR_FLOAT_MODE_P (mode)
1768 && (mode != TDmode || (regno % 2) == 0)
1769 && FP_REGNO_P (last_regno))
1772 if (GET_MODE_CLASS (mode) == MODE_INT
1773 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1776 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1777 && PAIRED_VECTOR_MODE (mode))
1783 /* The CR register can only hold CC modes. */
1784 if (CR_REGNO_P (regno))
1785 return GET_MODE_CLASS (mode) == MODE_CC;
1787 if (CA_REGNO_P (regno))
1788 return mode == BImode;
1790 /* AltiVec only in AldyVec registers. */
1791 if (ALTIVEC_REGNO_P (regno))
1792 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1794 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1795 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1798 /* We cannot put TImode anywhere except general register and it must be able
1799 to fit within the register set. In the future, allow TImode in the
1800 Altivec or VSX registers. */
1802 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1805 /* Print interesting facts about registers. */
1807 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1811 for (r = first_regno; r <= last_regno; ++r)
1813 const char *comma = "";
1816 if (first_regno == last_regno)
1817 fprintf (stderr, "%s:\t", reg_name);
1819 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1822 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1823 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1827 fprintf (stderr, ",\n\t");
1832 if (rs6000_hard_regno_nregs[m][r] > 1)
1833 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1834 rs6000_hard_regno_nregs[m][r]);
1836 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1841 if (call_used_regs[r])
1845 fprintf (stderr, ",\n\t");
1850 len += fprintf (stderr, "%s%s", comma, "call-used");
1858 fprintf (stderr, ",\n\t");
1863 len += fprintf (stderr, "%s%s", comma, "fixed");
1869 fprintf (stderr, ",\n\t");
1873 fprintf (stderr, "%sregno = %d\n", comma, r);
1877 /* Print various interesting information with -mdebug=reg. */
1879 rs6000_debug_reg_global (void)
1881 const char *nl = (const char *)0;
1883 char costly_num[20];
1885 const char *costly_str;
1886 const char *nop_str;
1888 /* Map enum rs6000_vector to string. */
1889 static const char *rs6000_debug_vector_unit[] = {
1898 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1899 LAST_VIRTUAL_REGISTER);
1900 rs6000_debug_reg_print (0, 31, "gr");
1901 rs6000_debug_reg_print (32, 63, "fp");
1902 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1905 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1906 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1907 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1908 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1909 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1910 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1911 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1912 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1913 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1917 "d reg_class = %s\n"
1918 "f reg_class = %s\n"
1919 "v reg_class = %s\n"
1920 "wa reg_class = %s\n"
1921 "wd reg_class = %s\n"
1922 "wf reg_class = %s\n"
1923 "ws reg_class = %s\n\n",
1924 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1925 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1926 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1927 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1928 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1929 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1930 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1932 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1933 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1936 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1938 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1939 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1945 if (rs6000_recip_control)
1947 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1949 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1950 if (rs6000_recip_bits[m])
1953 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1955 (RS6000_RECIP_AUTO_RE_P (m)
1957 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1958 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1960 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1963 fputs ("\n", stderr);
1966 switch (rs6000_sched_costly_dep)
1968 case max_dep_latency:
1969 costly_str = "max_dep_latency";
1973 costly_str = "no_dep_costly";
1976 case all_deps_costly:
1977 costly_str = "all_deps_costly";
1980 case true_store_to_load_dep_costly:
1981 costly_str = "true_store_to_load_dep_costly";
1984 case store_to_load_dep_costly:
1985 costly_str = "store_to_load_dep_costly";
1989 costly_str = costly_num;
1990 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1994 switch (rs6000_sched_insert_nops)
1996 case sched_finish_regroup_exact:
1997 nop_str = "sched_finish_regroup_exact";
2000 case sched_finish_pad_groups:
2001 nop_str = "sched_finish_pad_groups";
2004 case sched_finish_none:
2005 nop_str = "sched_finish_none";
2010 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2015 "always_hint = %s\n"
2016 "align_branch_targets = %s\n"
2017 "sched_restricted_insns_priority = %d\n"
2018 "sched_costly_dep = %s\n"
2019 "sched_insert_nops = %s\n\n",
2020 rs6000_always_hint ? "true" : "false",
2021 rs6000_align_branch_targets ? "true" : "false",
2022 (int)rs6000_sched_restricted_insns_priority,
2023 costly_str, nop_str);
2026 /* Initialize the various global tables that are based on register size. */
2028 rs6000_init_hard_regno_mode_ok (void)
2034 /* Precalculate REGNO_REG_CLASS. */
2035 rs6000_regno_regclass[0] = GENERAL_REGS;
2036 for (r = 1; r < 32; ++r)
2037 rs6000_regno_regclass[r] = BASE_REGS;
2039 for (r = 32; r < 64; ++r)
2040 rs6000_regno_regclass[r] = FLOAT_REGS;
2042 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2043 rs6000_regno_regclass[r] = NO_REGS;
2045 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2046 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2048 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2049 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2050 rs6000_regno_regclass[r] = CR_REGS;
2052 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2053 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2054 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2055 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2056 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2057 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2058 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2059 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2060 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2061 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2063 /* Precalculate vector information, this must be set up before the
2064 rs6000_hard_regno_nregs_internal below. */
2065 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2067 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2068 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2069 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2072 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2073 rs6000_constraints[c] = NO_REGS;
2075 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2076 believes it can use native alignment or still uses 128-bit alignment. */
2077 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2088 /* V2DF mode, VSX only. */
2091 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2092 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2093 rs6000_vector_align[V2DFmode] = align64;
2096 /* V4SF mode, either VSX or Altivec. */
2099 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2100 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2101 rs6000_vector_align[V4SFmode] = align32;
2103 else if (TARGET_ALTIVEC)
2105 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2106 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2107 rs6000_vector_align[V4SFmode] = align32;
2110 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2114 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2115 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2116 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2117 rs6000_vector_align[V4SImode] = align32;
2118 rs6000_vector_align[V8HImode] = align32;
2119 rs6000_vector_align[V16QImode] = align32;
2123 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2124 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2125 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2129 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2130 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2131 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2135 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2136 Altivec doesn't have 64-bit support. */
2139 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2140 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2141 rs6000_vector_align[V2DImode] = align64;
2144 /* DFmode, see if we want to use the VSX unit. */
2145 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2147 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2148 rs6000_vector_mem[DFmode]
2149 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2150 rs6000_vector_align[DFmode] = align64;
2153 /* TODO add SPE and paired floating point vector support. */
2155 /* Register class constaints for the constraints that depend on compile
2157 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2158 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2160 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2161 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2165 /* At present, we just use VSX_REGS, but we have different constraints
2166 based on the use, in case we want to fine tune the default register
2167 class used. wa = any VSX register, wf = register class to use for
2168 V4SF, wd = register class to use for V2DF, and ws = register classs to
2169 use for DF scalars. */
2170 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2171 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2172 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2173 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2179 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2181 /* Set up the reload helper functions. */
2182 if (TARGET_VSX || TARGET_ALTIVEC)
2186 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2187 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2188 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2189 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2190 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2191 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2192 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2193 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2194 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2195 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2196 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2197 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2201 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2202 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2203 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2204 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2205 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2206 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2207 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2208 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2209 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2210 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2211 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2212 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2216 /* Precalculate HARD_REGNO_NREGS. */
2217 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2218 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2219 rs6000_hard_regno_nregs[m][r]
2220 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2222 /* Precalculate HARD_REGNO_MODE_OK. */
2223 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2224 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2225 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2226 rs6000_hard_regno_mode_ok_p[m][r] = true;
2228 /* Precalculate CLASS_MAX_NREGS sizes. */
2229 for (c = 0; c < LIM_REG_CLASSES; ++c)
2233 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2234 reg_size = UNITS_PER_VSX_WORD;
2236 else if (c == ALTIVEC_REGS)
2237 reg_size = UNITS_PER_ALTIVEC_WORD;
2239 else if (c == FLOAT_REGS)
2240 reg_size = UNITS_PER_FP_WORD;
2243 reg_size = UNITS_PER_WORD;
2245 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2246 rs6000_class_max_nregs[m][c]
2247 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2250 if (TARGET_E500_DOUBLE)
2251 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2253 /* Calculate which modes to automatically generate code to use a the
2254 reciprocal divide and square root instructions. In the future, possibly
2255 automatically generate the instructions even if the user did not specify
2256 -mrecip. The older machines double precision reciprocal sqrt estimate is
2257 not accurate enough. */
2258 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2260 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2262 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2263 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2264 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2265 if (VECTOR_UNIT_VSX_P (V2DFmode))
2266 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2268 if (TARGET_FRSQRTES)
2269 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2271 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2272 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2273 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2274 if (VECTOR_UNIT_VSX_P (V2DFmode))
2275 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2277 if (rs6000_recip_control)
2279 if (!TARGET_FUSED_MADD)
2280 warning (0, "-mrecip requires -mfused-madd");
2281 if (!flag_finite_math_only)
2282 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2283 if (flag_trapping_math)
2284 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2285 if (!flag_reciprocal_math)
2286 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2287 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2288 && flag_reciprocal_math)
2290 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2291 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2292 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2294 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2295 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2296 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2298 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2299 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2300 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2302 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2303 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2304 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2306 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2307 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2308 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2310 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2311 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2312 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2314 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2315 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2316 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2318 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2319 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2320 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2324 if (TARGET_DEBUG_REG)
2325 rs6000_debug_reg_global ();
2327 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2329 "SImode variable mult cost = %d\n"
2330 "SImode constant mult cost = %d\n"
2331 "SImode short constant mult cost = %d\n"
2332 "DImode multipliciation cost = %d\n"
2333 "SImode division cost = %d\n"
2334 "DImode division cost = %d\n"
2335 "Simple fp operation cost = %d\n"
2336 "DFmode multiplication cost = %d\n"
2337 "SFmode division cost = %d\n"
2338 "DFmode division cost = %d\n"
2339 "cache line size = %d\n"
2340 "l1 cache size = %d\n"
2341 "l2 cache size = %d\n"
2342 "simultaneous prefetches = %d\n"
2345 rs6000_cost->mulsi_const,
2346 rs6000_cost->mulsi_const9,
2354 rs6000_cost->cache_line_size,
2355 rs6000_cost->l1_cache_size,
2356 rs6000_cost->l2_cache_size,
2357 rs6000_cost->simultaneous_prefetches);
2361 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2364 darwin_rs6000_override_options (void)
2366 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2368 rs6000_altivec_abi = 1;
2369 TARGET_ALTIVEC_VRSAVE = 1;
2371 if (DEFAULT_ABI == ABI_DARWIN
2373 darwin_one_byte_bool = 1;
2375 if (TARGET_64BIT && ! TARGET_POWERPC64)
2377 target_flags |= MASK_POWERPC64;
2378 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2382 rs6000_default_long_calls = 1;
2383 target_flags |= MASK_SOFT_FLOAT;
2386 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2388 if (!flag_mkernel && !flag_apple_kext
2390 && ! (target_flags_explicit & MASK_ALTIVEC))
2391 target_flags |= MASK_ALTIVEC;
2393 /* Unless the user (not the configurer) has explicitly overridden
2394 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2395 G4 unless targetting the kernel. */
2398 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2399 && ! (target_flags_explicit & MASK_ALTIVEC)
2400 && ! rs6000_select[1].string)
2402 target_flags |= MASK_ALTIVEC;
2407 /* If not otherwise specified by a target, make 'long double' equivalent to
2410 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2411 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2414 /* Override command line options. Mostly we process the processor
2415 type and sometimes adjust other TARGET_ options. */
2418 rs6000_option_override_internal (const char *default_cpu)
2421 struct rs6000_cpu_select *ptr;
2424 /* Simplifications for entries below. */
2427 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2428 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2431 /* This table occasionally claims that a processor does not support
2432 a particular feature even though it does, but the feature is slower
2433 than the alternative. Thus, it shouldn't be relied on as a
2434 complete description of the processor's support.
2436 Please keep this list in order, and don't forget to update the
2437 documentation in invoke.texi when adding a new processor or
2441 const char *const name; /* Canonical processor name. */
2442 const enum processor_type processor; /* Processor type enum value. */
2443 const int target_enable; /* Target flags to enable. */
2444 } const processor_target_table[]
2445 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2446 {"403", PROCESSOR_PPC403,
2447 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2448 {"405", PROCESSOR_PPC405,
2449 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2450 {"405fp", PROCESSOR_PPC405,
2451 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2452 {"440", PROCESSOR_PPC440,
2453 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2454 {"440fp", PROCESSOR_PPC440,
2455 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2456 {"464", PROCESSOR_PPC440,
2457 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2458 {"464fp", PROCESSOR_PPC440,
2459 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2460 {"476", PROCESSOR_PPC476,
2461 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2462 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2463 {"476fp", PROCESSOR_PPC476,
2464 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2465 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2466 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2467 {"601", PROCESSOR_PPC601,
2468 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2469 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2470 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2471 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2472 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2473 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2474 {"620", PROCESSOR_PPC620,
2475 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2476 {"630", PROCESSOR_PPC630,
2477 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2478 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2479 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2480 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2481 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2482 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2483 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2484 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2485 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2487 /* 8548 has a dummy entry for now. */
2488 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2490 {"a2", PROCESSOR_PPCA2,
2491 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2492 | MASK_CMPB | MASK_NO_UPDATE },
2493 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2494 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2495 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2497 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2498 | MASK_PPC_GFXOPT | MASK_ISEL},
2499 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2500 {"970", PROCESSOR_POWER4,
2501 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2502 {"cell", PROCESSOR_CELL,
2503 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2504 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2505 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2506 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2507 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2508 {"G5", PROCESSOR_POWER4,
2509 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2510 {"titan", PROCESSOR_TITAN,
2511 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2512 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2513 {"power2", PROCESSOR_POWER,
2514 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2515 {"power3", PROCESSOR_PPC630,
2516 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2517 {"power4", PROCESSOR_POWER4,
2518 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2520 {"power5", PROCESSOR_POWER5,
2521 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2522 | MASK_MFCRF | MASK_POPCNTB},
2523 {"power5+", PROCESSOR_POWER5,
2524 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2525 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2526 {"power6", PROCESSOR_POWER6,
2527 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2528 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2529 | MASK_RECIP_PRECISION},
2530 {"power6x", PROCESSOR_POWER6,
2531 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2532 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2533 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2534 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
2535 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2536 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2537 | MASK_VSX | MASK_RECIP_PRECISION},
2538 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2539 {"powerpc64", PROCESSOR_POWERPC64,
2540 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2541 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2542 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2543 {"rios2", PROCESSOR_RIOS2,
2544 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2545 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2546 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2547 {"rs64", PROCESSOR_RS64A,
2548 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2551 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2553 /* Some OSs don't support saving the high part of 64-bit registers on
2554 context switch. Other OSs don't support saving Altivec registers.
2555 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2556 settings; if the user wants either, the user must explicitly specify
2557 them and we won't interfere with the user's specification. */
2560 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2561 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2562 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2563 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2564 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2565 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2566 | MASK_RECIP_PRECISION)
2569 /* Masks for instructions set at various powerpc ISAs. */
2571 ISA_2_1_MASKS = MASK_MFCRF,
2572 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2574 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2575 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2576 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2577 masks by server and embedded. */
2578 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2579 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2580 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2582 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2583 altivec is a win so enable it. */
2584 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2585 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2589 /* Numerous experiment shows that IRA based loop pressure
2590 calculation works better for RTL loop invariant motion on targets
2591 with enough (>= 32) registers. It is an expensive optimization.
2592 So it is on only for peak performance. */
2594 flag_ira_loop_pressure = 1;
2596 /* Set the pointer size. */
2599 rs6000_pmode = (int)DImode;
2600 rs6000_pointer_size = 64;
2604 rs6000_pmode = (int)SImode;
2605 rs6000_pointer_size = 32;
2608 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2609 #ifdef OS_MISSING_POWERPC64
2610 if (OS_MISSING_POWERPC64)
2611 set_masks &= ~MASK_POWERPC64;
2613 #ifdef OS_MISSING_ALTIVEC
2614 if (OS_MISSING_ALTIVEC)
2615 set_masks &= ~MASK_ALTIVEC;
2618 /* Don't override by the processor default if given explicitly. */
2619 set_masks &= ~target_flags_explicit;
2621 /* Identify the processor type. */
2622 rs6000_select[0].string = default_cpu;
2623 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2625 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2627 ptr = &rs6000_select[i];
2628 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2630 for (j = 0; j < ptt_size; j++)
2631 if (! strcmp (ptr->string, processor_target_table[j].name))
2633 if (ptr->set_tune_p)
2634 rs6000_cpu = processor_target_table[j].processor;
2636 if (ptr->set_arch_p)
2638 target_flags &= ~set_masks;
2639 target_flags |= (processor_target_table[j].target_enable
2646 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2650 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2651 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2654 error ("AltiVec not supported in this target");
2656 error ("Spe not supported in this target");
2659 /* Disable Cell microcode if we are optimizing for the Cell
2660 and not optimizing for size. */
2661 if (rs6000_gen_cell_microcode == -1)
2662 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2665 /* If we are optimizing big endian systems for space and it's OK to
2666 use instructions that would be microcoded on the Cell, use the
2667 load/store multiple and string instructions. */
2668 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2669 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2671 /* Don't allow -mmultiple or -mstring on little endian systems
2672 unless the cpu is a 750, because the hardware doesn't support the
2673 instructions used in little endian mode, and causes an alignment
2674 trap. The 750 does not cause an alignment trap (except when the
2675 target is unaligned). */
2677 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2679 if (TARGET_MULTIPLE)
2681 target_flags &= ~MASK_MULTIPLE;
2682 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2683 warning (0, "-mmultiple is not supported on little endian systems");
2688 target_flags &= ~MASK_STRING;
2689 if ((target_flags_explicit & MASK_STRING) != 0)
2690 warning (0, "-mstring is not supported on little endian systems");
2694 /* Add some warnings for VSX. */
2697 const char *msg = NULL;
2698 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2699 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2701 if (target_flags_explicit & MASK_VSX)
2702 msg = N_("-mvsx requires hardware floating point");
2704 target_flags &= ~ MASK_VSX;
2706 else if (TARGET_PAIRED_FLOAT)
2707 msg = N_("-mvsx and -mpaired are incompatible");
2708 /* The hardware will allow VSX and little endian, but until we make sure
2709 things like vector select, etc. work don't allow VSX on little endian
2710 systems at this point. */
2711 else if (!BYTES_BIG_ENDIAN)
2712 msg = N_("-mvsx used with little endian code");
2713 else if (TARGET_AVOID_XFORM > 0)
2714 msg = N_("-mvsx needs indexed addressing");
2715 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2717 if (target_flags_explicit & MASK_VSX)
2718 msg = N_("-mvsx and -mno-altivec are incompatible");
2720 msg = N_("-mno-altivec disables vsx");
2726 target_flags &= ~ MASK_VSX;
2727 target_flags_explicit |= MASK_VSX;
2731 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2732 unless the user explicitly used the -mno-<option> to disable the code. */
2734 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2735 else if (TARGET_POPCNTD)
2736 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2737 else if (TARGET_DFP)
2738 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2739 else if (TARGET_CMPB)
2740 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2741 else if (TARGET_POPCNTB || TARGET_FPRND)
2742 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2743 else if (TARGET_ALTIVEC)
2744 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2746 /* E500mc does "better" if we inline more aggressively. Respect the
2747 user's opinion, though. */
2748 if (rs6000_block_move_inline_limit == 0
2749 && (rs6000_cpu == PROCESSOR_PPCE500MC
2750 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2751 rs6000_block_move_inline_limit = 128;
2753 /* store_one_arg depends on expand_block_move to handle at least the
2754 size of reg_parm_stack_space. */
2755 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2756 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2758 /* Set debug flags */
2759 if (rs6000_debug_name)
2761 if (! strcmp (rs6000_debug_name, "all"))
2762 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2763 = rs6000_debug_addr = rs6000_debug_cost = 1;
2764 else if (! strcmp (rs6000_debug_name, "stack"))
2765 rs6000_debug_stack = 1;
2766 else if (! strcmp (rs6000_debug_name, "arg"))
2767 rs6000_debug_arg = 1;
2768 else if (! strcmp (rs6000_debug_name, "reg"))
2769 rs6000_debug_reg = 1;
2770 else if (! strcmp (rs6000_debug_name, "addr"))
2771 rs6000_debug_addr = 1;
2772 else if (! strcmp (rs6000_debug_name, "cost"))
2773 rs6000_debug_cost = 1;
2775 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2777 /* If the appropriate debug option is enabled, replace the target hooks
2778 with debug versions that call the real version and then prints
2779 debugging information. */
2780 if (TARGET_DEBUG_COST)
2782 targetm.rtx_costs = rs6000_debug_rtx_costs;
2783 targetm.address_cost = rs6000_debug_address_cost;
2784 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2787 if (TARGET_DEBUG_ADDR)
2789 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2790 targetm.legitimize_address = rs6000_debug_legitimize_address;
2791 rs6000_secondary_reload_class_ptr
2792 = rs6000_debug_secondary_reload_class;
2793 rs6000_secondary_memory_needed_ptr
2794 = rs6000_debug_secondary_memory_needed;
2795 rs6000_cannot_change_mode_class_ptr
2796 = rs6000_debug_cannot_change_mode_class;
2797 rs6000_preferred_reload_class_ptr
2798 = rs6000_debug_preferred_reload_class;
2799 rs6000_legitimize_reload_address_ptr
2800 = rs6000_debug_legitimize_reload_address;
2801 rs6000_mode_dependent_address_ptr
2802 = rs6000_debug_mode_dependent_address;
2806 if (rs6000_traceback_name)
2808 if (! strncmp (rs6000_traceback_name, "full", 4))
2809 rs6000_traceback = traceback_full;
2810 else if (! strncmp (rs6000_traceback_name, "part", 4))
2811 rs6000_traceback = traceback_part;
2812 else if (! strncmp (rs6000_traceback_name, "no", 2))
2813 rs6000_traceback = traceback_none;
2815 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2816 rs6000_traceback_name);
2819 if (rs6000_veclibabi_name)
2821 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2822 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2824 error ("unknown vectorization library ABI type (%s) for "
2825 "-mveclibabi= switch", rs6000_veclibabi_name);
2828 if (!rs6000_explicit_options.long_double)
2829 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2831 #ifndef POWERPC_LINUX
2832 if (!rs6000_explicit_options.ieee)
2833 rs6000_ieeequad = 1;
2836 /* Enable Altivec ABI for AIX -maltivec. */
2837 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2838 rs6000_altivec_abi = 1;
2840 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2841 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2842 be explicitly overridden in either case. */
2845 if (!rs6000_explicit_options.altivec_abi
2846 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2847 rs6000_altivec_abi = 1;
2849 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2850 if (!rs6000_explicit_options.vrsave)
2851 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2854 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2855 So far, the only darwin64 targets are also MACH-O. */
2857 && DEFAULT_ABI == ABI_DARWIN
2860 rs6000_darwin64_abi = 1;
2861 /* Default to natural alignment, for better performance. */
2862 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2865 /* Place FP constants in the constant pool instead of TOC
2866 if section anchors enabled. */
2867 if (flag_section_anchors)
2868 TARGET_NO_FP_IN_TOC = 1;
2870 /* Handle -mtls-size option. */
2871 rs6000_parse_tls_size_option ();
2873 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2874 SUBTARGET_OVERRIDE_OPTIONS;
2876 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2877 SUBSUBTARGET_OVERRIDE_OPTIONS;
2879 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2880 SUB3TARGET_OVERRIDE_OPTIONS;
2883 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2884 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2886 /* The e500 and e500mc do not have string instructions, and we set
2887 MASK_STRING above when optimizing for size. */
2888 if ((target_flags & MASK_STRING) != 0)
2889 target_flags = target_flags & ~MASK_STRING;
2891 else if (rs6000_select[1].string != NULL)
2893 /* For the powerpc-eabispe configuration, we set all these by
2894 default, so let's unset them if we manually set another
2895 CPU that is not the E500. */
2896 if (!rs6000_explicit_options.spe_abi)
2898 if (!rs6000_explicit_options.spe)
2900 if (!rs6000_explicit_options.float_gprs)
2901 rs6000_float_gprs = 0;
2902 if (!(target_flags_explicit & MASK_ISEL))
2903 target_flags &= ~MASK_ISEL;
2906 /* Detect invalid option combinations with E500. */
2909 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2910 && rs6000_cpu != PROCESSOR_POWER5
2911 && rs6000_cpu != PROCESSOR_POWER6
2912 && rs6000_cpu != PROCESSOR_POWER7
2913 && rs6000_cpu != PROCESSOR_PPCA2
2914 && rs6000_cpu != PROCESSOR_CELL);
2915 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2916 || rs6000_cpu == PROCESSOR_POWER5
2917 || rs6000_cpu == PROCESSOR_POWER7);
2918 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2919 || rs6000_cpu == PROCESSOR_POWER5
2920 || rs6000_cpu == PROCESSOR_POWER6
2921 || rs6000_cpu == PROCESSOR_POWER7
2922 || rs6000_cpu == PROCESSOR_PPCE500MC
2923 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2925 /* Allow debug switches to override the above settings. */
2926 if (TARGET_ALWAYS_HINT > 0)
2927 rs6000_always_hint = TARGET_ALWAYS_HINT;
2929 if (TARGET_SCHED_GROUPS > 0)
2930 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2932 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2933 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2935 rs6000_sched_restricted_insns_priority
2936 = (rs6000_sched_groups ? 1 : 0);
2938 /* Handle -msched-costly-dep option. */
2939 rs6000_sched_costly_dep
2940 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2942 if (rs6000_sched_costly_dep_str)
2944 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2945 rs6000_sched_costly_dep = no_dep_costly;
2946 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2947 rs6000_sched_costly_dep = all_deps_costly;
2948 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2949 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2950 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2951 rs6000_sched_costly_dep = store_to_load_dep_costly;
2953 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2954 atoi (rs6000_sched_costly_dep_str));
2957 /* Handle -minsert-sched-nops option. */
2958 rs6000_sched_insert_nops
2959 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2961 if (rs6000_sched_insert_nops_str)
2963 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2964 rs6000_sched_insert_nops = sched_finish_none;
2965 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2966 rs6000_sched_insert_nops = sched_finish_pad_groups;
2967 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2968 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2970 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2971 atoi (rs6000_sched_insert_nops_str));
2974 #ifdef TARGET_REGNAMES
2975 /* If the user desires alternate register names, copy in the
2976 alternate names now. */
2977 if (TARGET_REGNAMES)
2978 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2981 /* Set aix_struct_return last, after the ABI is determined.
2982 If -maix-struct-return or -msvr4-struct-return was explicitly
2983 used, don't override with the ABI default. */
2984 if (!rs6000_explicit_options.aix_struct_ret)
2985 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2988 /* IBM XL compiler defaults to unsigned bitfields. */
2989 if (TARGET_XL_COMPAT)
2990 flag_signed_bitfields = 0;
2993 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2994 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2997 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2999 /* We can only guarantee the availability of DI pseudo-ops when
3000 assembling for 64-bit targets. */
3003 targetm.asm_out.aligned_op.di = NULL;
3004 targetm.asm_out.unaligned_op.di = NULL;
3007 /* Set branch target alignment, if not optimizing for size. */
3010 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3011 aligned 8byte to avoid misprediction by the branch predictor. */
3012 if (rs6000_cpu == PROCESSOR_TITAN
3013 || rs6000_cpu == PROCESSOR_CELL)
3015 if (align_functions <= 0)
3016 align_functions = 8;
3017 if (align_jumps <= 0)
3019 if (align_loops <= 0)
3022 if (rs6000_align_branch_targets)
3024 if (align_functions <= 0)
3025 align_functions = 16;
3026 if (align_jumps <= 0)
3028 if (align_loops <= 0)
3031 if (align_jumps_max_skip <= 0)
3032 align_jumps_max_skip = 15;
3033 if (align_loops_max_skip <= 0)
3034 align_loops_max_skip = 15;
3037 /* Arrange to save and restore machine status around nested functions. */
3038 init_machine_status = rs6000_init_machine_status;
3040 /* We should always be splitting complex arguments, but we can't break
3041 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3042 if (DEFAULT_ABI != ABI_AIX)
3043 targetm.calls.split_complex_arg = NULL;
3045 /* Initialize rs6000_cost with the appropriate target costs. */
3047 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3051 case PROCESSOR_RIOS1:
3052 rs6000_cost = &rios1_cost;
3055 case PROCESSOR_RIOS2:
3056 rs6000_cost = &rios2_cost;
3059 case PROCESSOR_RS64A:
3060 rs6000_cost = &rs64a_cost;
3063 case PROCESSOR_MPCCORE:
3064 rs6000_cost = &mpccore_cost;
3067 case PROCESSOR_PPC403:
3068 rs6000_cost = &ppc403_cost;
3071 case PROCESSOR_PPC405:
3072 rs6000_cost = &ppc405_cost;
3075 case PROCESSOR_PPC440:
3076 rs6000_cost = &ppc440_cost;
3079 case PROCESSOR_PPC476:
3080 rs6000_cost = &ppc476_cost;
3083 case PROCESSOR_PPC601:
3084 rs6000_cost = &ppc601_cost;
3087 case PROCESSOR_PPC603:
3088 rs6000_cost = &ppc603_cost;
3091 case PROCESSOR_PPC604:
3092 rs6000_cost = &ppc604_cost;
3095 case PROCESSOR_PPC604e:
3096 rs6000_cost = &ppc604e_cost;
3099 case PROCESSOR_PPC620:
3100 rs6000_cost = &ppc620_cost;
3103 case PROCESSOR_PPC630:
3104 rs6000_cost = &ppc630_cost;
3107 case PROCESSOR_CELL:
3108 rs6000_cost = &ppccell_cost;
3111 case PROCESSOR_PPC750:
3112 case PROCESSOR_PPC7400:
3113 rs6000_cost = &ppc750_cost;
3116 case PROCESSOR_PPC7450:
3117 rs6000_cost = &ppc7450_cost;
3120 case PROCESSOR_PPC8540:
3121 rs6000_cost = &ppc8540_cost;
3124 case PROCESSOR_PPCE300C2:
3125 case PROCESSOR_PPCE300C3:
3126 rs6000_cost = &ppce300c2c3_cost;
3129 case PROCESSOR_PPCE500MC:
3130 rs6000_cost = &ppce500mc_cost;
3133 case PROCESSOR_PPCE500MC64:
3134 rs6000_cost = &ppce500mc64_cost;
3137 case PROCESSOR_TITAN:
3138 rs6000_cost = &titan_cost;
3141 case PROCESSOR_POWER4:
3142 case PROCESSOR_POWER5:
3143 rs6000_cost = &power4_cost;
3146 case PROCESSOR_POWER6:
3147 rs6000_cost = &power6_cost;
3150 case PROCESSOR_POWER7:
3151 rs6000_cost = &power7_cost;
3154 case PROCESSOR_PPCA2:
3155 rs6000_cost = &ppca2_cost;
3162 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3163 rs6000_cost->simultaneous_prefetches,
3164 global_options.x_param_values,
3165 global_options_set.x_param_values);
3166 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3167 global_options.x_param_values,
3168 global_options_set.x_param_values);
3169 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3170 rs6000_cost->cache_line_size,
3171 global_options.x_param_values,
3172 global_options_set.x_param_values);
3173 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3174 global_options.x_param_values,
3175 global_options_set.x_param_values);
3177 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3178 can be optimized to ap = __builtin_next_arg (0). */
3179 if (DEFAULT_ABI != ABI_V4)
3180 targetm.expand_builtin_va_start = NULL;
3182 /* Set up single/double float flags.
3183 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3184 then set both flags. */
3185 if (TARGET_HARD_FLOAT && TARGET_FPRS
3186 && rs6000_single_float == 0 && rs6000_double_float == 0)
3187 rs6000_single_float = rs6000_double_float = 1;
3189 /* Reset single and double FP flags if target is E500. */
3192 rs6000_single_float = rs6000_double_float = 0;
3193 if (TARGET_E500_SINGLE)
3194 rs6000_single_float = 1;
3195 if (TARGET_E500_DOUBLE)
3196 rs6000_single_float = rs6000_double_float = 1;
3199 /* If not explicitly specified via option, decide whether to generate indexed
3200 load/store instructions. */
3201 if (TARGET_AVOID_XFORM == -1)
3202 /* Avoid indexed addressing when targeting Power6 in order to avoid
3203 the DERAT mispredict penalty. */
3204 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3206 /* Set the -mrecip options. */
3207 if (rs6000_recip_name)
3209 char *p = ASTRDUP (rs6000_recip_name);
3211 unsigned int mask, i;
3214 while ((q = strtok (p, ",")) != NULL)
3225 if (!strcmp (q, "default"))
3226 mask = ((TARGET_RECIP_PRECISION)
3227 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3230 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3231 if (!strcmp (q, recip_options[i].string))
3233 mask = recip_options[i].mask;
3237 if (i == ARRAY_SIZE (recip_options))
3239 error ("Unknown option for -mrecip=%s", q);
3246 rs6000_recip_control &= ~mask;
3248 rs6000_recip_control |= mask;
3252 rs6000_init_hard_regno_mode_ok ();
3255 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3256 define the target cpu type. */
3259 rs6000_option_override (void)
3261 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT);
3264 /* Implement targetm.vectorize.builtin_mask_for_load. */
3266 rs6000_builtin_mask_for_load (void)
3268 if (TARGET_ALTIVEC || TARGET_VSX)
3269 return altivec_builtin_mask_for_load;
3274 /* Implement targetm.vectorize.builtin_conversion.
3275 Returns a decl of a function that implements conversion of an integer vector
3276 into a floating-point vector, or vice-versa. DEST_TYPE is the
3277 destination type and SRC_TYPE the source type of the conversion.
3278 Return NULL_TREE if it is not available. */
3280 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3282 enum tree_code code = (enum tree_code) tcode;
3286 case FIX_TRUNC_EXPR:
3287 switch (TYPE_MODE (dest_type))
3290 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3293 return TYPE_UNSIGNED (dest_type)
3294 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3295 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3298 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3301 return TYPE_UNSIGNED (dest_type)
3302 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3303 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3310 switch (TYPE_MODE (src_type))
3313 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3316 return TYPE_UNSIGNED (src_type)
3317 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3318 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3321 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3324 return TYPE_UNSIGNED (src_type)
3325 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3326 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3337 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3339 rs6000_builtin_mul_widen_even (tree type)
3341 if (!TARGET_ALTIVEC)
3344 switch (TYPE_MODE (type))
3347 return TYPE_UNSIGNED (type)
3348 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3349 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3352 return TYPE_UNSIGNED (type)
3353 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3354 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3360 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3362 rs6000_builtin_mul_widen_odd (tree type)
3364 if (!TARGET_ALTIVEC)
3367 switch (TYPE_MODE (type))
3370 return TYPE_UNSIGNED (type)
3371 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3372 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3375 return TYPE_UNSIGNED (type)
3376 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3377 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3384 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3385 after applying N number of iterations. This routine does not determine
3386 how may iterations are required to reach desired alignment. */
3389 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3396 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3399 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3409 /* Assuming that all other types are naturally aligned. CHECKME! */
3414 /* Return true if the vector misalignment factor is supported by the
3417 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3424 /* Return if movmisalign pattern is not supported for this mode. */
3425 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3428 if (misalignment == -1)
3430 /* Misalignment factor is unknown at compile time but we know
3431 it's word aligned. */
3432 if (rs6000_vector_alignment_reachable (type, is_packed))
3434 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3436 if (element_size == 64 || element_size == 32)
3443 /* VSX supports word-aligned vector. */
3444 if (misalignment % 4 == 0)
3450 /* Implement targetm.vectorize.builtin_vec_perm. */
3452 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3454 tree inner_type = TREE_TYPE (type);
3455 bool uns_p = TYPE_UNSIGNED (inner_type);
3458 *mask_element_type = unsigned_char_type_node;
3460 switch (TYPE_MODE (type))
3464 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3465 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3470 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3471 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3476 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3477 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3481 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3485 if (!TARGET_ALLOW_DF_PERMUTE)
3488 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3492 if (!TARGET_ALLOW_DF_PERMUTE)
3496 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3497 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3509 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3511 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3512 tree vectype, int misalign)
3516 switch (type_of_cost)
3526 case cond_branch_not_taken:
3530 case cond_branch_taken:
3533 case unaligned_load:
3534 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3536 elements = TYPE_VECTOR_SUBPARTS (vectype);
3538 /* Double word aligned. */
3546 /* Double word aligned. */
3550 /* Unknown misalignment. */
3563 /* Misaligned loads are not supported. */
3568 case unaligned_store:
3569 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3571 elements = TYPE_VECTOR_SUBPARTS (vectype);
3573 /* Double word aligned. */
3581 /* Double word aligned. */
3585 /* Unknown misalignment. */
3598 /* Misaligned stores are not supported. */
3608 /* Implement targetm.vectorize.preferred_simd_mode. */
3610 static enum machine_mode
3611 rs6000_preferred_simd_mode (enum machine_mode mode)
3620 if (TARGET_ALTIVEC || TARGET_VSX)
3644 if (TARGET_PAIRED_FLOAT
3650 /* Handle generic options of the form -mfoo=yes/no.
3651 NAME is the option name.
3652 VALUE is the option value.
3653 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3654 whether the option value is 'yes' or 'no' respectively. */
3656 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3660 else if (!strcmp (value, "yes"))
3662 else if (!strcmp (value, "no"))
3665 error ("unknown -m%s= option specified: '%s'", name, value);
3668 /* Validate and record the size specified with the -mtls-size option. */
3671 rs6000_parse_tls_size_option (void)
3673 if (rs6000_tls_size_string == 0)
3675 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3676 rs6000_tls_size = 16;
3677 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3678 rs6000_tls_size = 32;
3679 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3680 rs6000_tls_size = 64;
3682 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3685 /* Implement TARGET_OPTION_INIT_STRUCT. */
3688 rs6000_option_init_struct (struct gcc_options *opts)
3690 if (DEFAULT_ABI == ABI_DARWIN)
3691 /* The Darwin libraries never set errno, so we might as well
3692 avoid calling them when that's the only reason we would. */
3693 opts->x_flag_errno_math = 0;
3695 /* Enable section anchors by default. */
3697 opts->x_flag_section_anchors = 1;
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];
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_XVMADDDP];
3950 if (VECTOR_UNIT_VSX_P (V4SFmode)
3951 && out_mode == SFmode && out_n == 4
3952 && in_mode == SFmode && in_n == 4)
3953 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3954 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3955 && out_mode == SFmode && out_n == 4
3956 && in_mode == SFmode && in_n == 4)
3957 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
3959 case BUILT_IN_TRUNC:
3960 if (VECTOR_UNIT_VSX_P (V2DFmode)
3961 && out_mode == DFmode && out_n == 2
3962 && in_mode == DFmode && in_n == 2)
3963 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3965 case BUILT_IN_TRUNCF:
3966 if (out_mode != SFmode || out_n != 4
3967 || in_mode != SFmode || in_n != 4)
3969 if (VECTOR_UNIT_VSX_P (V4SFmode))
3970 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3971 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3972 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3974 case BUILT_IN_NEARBYINT:
3975 if (VECTOR_UNIT_VSX_P (V2DFmode)
3976 && flag_unsafe_math_optimizations
3977 && out_mode == DFmode && out_n == 2
3978 && in_mode == DFmode && in_n == 2)
3979 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3981 case BUILT_IN_NEARBYINTF:
3982 if (VECTOR_UNIT_VSX_P (V4SFmode)
3983 && flag_unsafe_math_optimizations
3984 && out_mode == SFmode && out_n == 4
3985 && in_mode == SFmode && in_n == 4)
3986 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3989 if (VECTOR_UNIT_VSX_P (V2DFmode)
3990 && !flag_trapping_math
3991 && out_mode == DFmode && out_n == 2
3992 && in_mode == DFmode && in_n == 2)
3993 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3995 case BUILT_IN_RINTF:
3996 if (VECTOR_UNIT_VSX_P (V4SFmode)
3997 && !flag_trapping_math
3998 && out_mode == SFmode && out_n == 4
3999 && in_mode == SFmode && in_n == 4)
4000 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4007 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4009 enum rs6000_builtins fn
4010 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4013 case RS6000_BUILTIN_RSQRTF:
4014 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4015 && out_mode == SFmode && out_n == 4
4016 && in_mode == SFmode && in_n == 4)
4017 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4019 case RS6000_BUILTIN_RSQRT:
4020 if (VECTOR_UNIT_VSX_P (V2DFmode)
4021 && out_mode == DFmode && out_n == 2
4022 && in_mode == DFmode && in_n == 2)
4023 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4025 case RS6000_BUILTIN_RECIPF:
4026 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4027 && out_mode == SFmode && out_n == 4
4028 && in_mode == SFmode && in_n == 4)
4029 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4031 case RS6000_BUILTIN_RECIP:
4032 if (VECTOR_UNIT_VSX_P (V2DFmode)
4033 && out_mode == DFmode && out_n == 2
4034 && in_mode == DFmode && in_n == 2)
4035 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4042 /* Generate calls to libmass if appropriate. */
4043 if (rs6000_veclib_handler)
4044 return rs6000_veclib_handler (fndecl, type_out, type_in);
4050 /* Implement TARGET_HANDLE_OPTION. */
4053 rs6000_handle_option (size_t code, const char *arg, int value)
4055 enum fpu_type_t fpu_type = FPU_NONE;
4061 target_flags &= ~(MASK_POWER | MASK_POWER2
4062 | MASK_MULTIPLE | MASK_STRING);
4063 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4064 | MASK_MULTIPLE | MASK_STRING);
4066 case OPT_mno_powerpc:
4067 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4068 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4069 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4070 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4073 target_flags &= ~MASK_MINIMAL_TOC;
4074 TARGET_NO_FP_IN_TOC = 0;
4075 TARGET_NO_SUM_IN_TOC = 0;
4076 target_flags_explicit |= MASK_MINIMAL_TOC;
4077 #ifdef TARGET_USES_SYSV4_OPT
4078 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4079 just the same as -mminimal-toc. */
4080 target_flags |= MASK_MINIMAL_TOC;
4081 target_flags_explicit |= MASK_MINIMAL_TOC;
4085 #ifdef TARGET_USES_SYSV4_OPT
4087 /* Make -mtoc behave like -mminimal-toc. */
4088 target_flags |= MASK_MINIMAL_TOC;
4089 target_flags_explicit |= MASK_MINIMAL_TOC;
4093 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4095 if (strcmp (arg, "small") == 0)
4096 cmodel = CMODEL_SMALL;
4097 else if (strcmp (arg, "medium") == 0)
4098 cmodel = CMODEL_MEDIUM;
4099 else if (strcmp (arg, "large") == 0)
4100 cmodel = CMODEL_LARGE;
4103 error ("invalid option for -mcmodel: '%s'", arg);
4106 rs6000_explicit_options.cmodel = true;
4109 #ifdef TARGET_USES_AIX64_OPT
4114 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4115 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4116 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4119 #ifdef TARGET_USES_AIX64_OPT
4124 target_flags &= ~MASK_POWERPC64;
4125 target_flags_explicit |= MASK_POWERPC64;
4128 case OPT_minsert_sched_nops_:
4129 rs6000_sched_insert_nops_str = arg;
4132 case OPT_mminimal_toc:
4135 TARGET_NO_FP_IN_TOC = 0;
4136 TARGET_NO_SUM_IN_TOC = 0;
4143 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4144 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4151 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4152 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4156 case OPT_mpowerpc_gpopt:
4157 case OPT_mpowerpc_gfxopt:
4160 target_flags |= MASK_POWERPC;
4161 target_flags_explicit |= MASK_POWERPC;
4165 case OPT_maix_struct_return:
4166 case OPT_msvr4_struct_return:
4167 rs6000_explicit_options.aix_struct_ret = true;
4171 rs6000_explicit_options.vrsave = true;
4172 TARGET_ALTIVEC_VRSAVE = value;
4176 rs6000_explicit_options.vrsave = true;
4177 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4181 target_flags_explicit |= MASK_ISEL;
4183 rs6000_parse_yes_no_option ("isel", arg, &isel);
4185 target_flags |= MASK_ISEL;
4187 target_flags &= ~MASK_ISEL;
4191 rs6000_explicit_options.spe = true;
4196 rs6000_explicit_options.spe = true;
4197 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4201 rs6000_debug_name = arg;
4204 #ifdef TARGET_USES_SYSV4_OPT
4206 rs6000_abi_name = arg;
4210 rs6000_sdata_name = arg;
4213 case OPT_mtls_size_:
4214 rs6000_tls_size_string = arg;
4217 case OPT_mrelocatable:
4220 target_flags |= MASK_MINIMAL_TOC;
4221 target_flags_explicit |= MASK_MINIMAL_TOC;
4222 TARGET_NO_FP_IN_TOC = 1;
4226 case OPT_mrelocatable_lib:
4229 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4230 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4231 TARGET_NO_FP_IN_TOC = 1;
4235 target_flags &= ~MASK_RELOCATABLE;
4236 target_flags_explicit |= MASK_RELOCATABLE;
4242 if (!strcmp (arg, "altivec"))
4244 rs6000_explicit_options.altivec_abi = true;
4245 rs6000_altivec_abi = 1;
4247 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4250 else if (! strcmp (arg, "no-altivec"))
4252 rs6000_explicit_options.altivec_abi = true;
4253 rs6000_altivec_abi = 0;
4255 else if (! strcmp (arg, "spe"))
4257 rs6000_explicit_options.spe_abi = true;
4259 rs6000_altivec_abi = 0;
4260 if (!TARGET_SPE_ABI)
4261 error ("not configured for ABI: '%s'", arg);
4263 else if (! strcmp (arg, "no-spe"))
4265 rs6000_explicit_options.spe_abi = true;
4269 /* These are here for testing during development only, do not
4270 document in the manual please. */
4271 else if (! strcmp (arg, "d64"))
4273 rs6000_darwin64_abi = 1;
4274 warning (0, "Using darwin64 ABI");
4276 else if (! strcmp (arg, "d32"))
4278 rs6000_darwin64_abi = 0;
4279 warning (0, "Using old darwin ABI");
4282 else if (! strcmp (arg, "ibmlongdouble"))
4284 rs6000_explicit_options.ieee = true;
4285 rs6000_ieeequad = 0;
4286 warning (0, "Using IBM extended precision long double");
4288 else if (! strcmp (arg, "ieeelongdouble"))
4290 rs6000_explicit_options.ieee = true;
4291 rs6000_ieeequad = 1;
4292 warning (0, "Using IEEE extended precision long double");
4297 error ("unknown ABI specified: '%s'", arg);
4303 rs6000_select[1].string = arg;
4307 rs6000_select[2].string = arg;
4310 case OPT_mtraceback_:
4311 rs6000_traceback_name = arg;
4314 case OPT_mfloat_gprs_:
4315 rs6000_explicit_options.float_gprs = true;
4316 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4317 rs6000_float_gprs = 1;
4318 else if (! strcmp (arg, "double"))
4319 rs6000_float_gprs = 2;
4320 else if (! strcmp (arg, "no"))
4321 rs6000_float_gprs = 0;
4324 error ("invalid option for -mfloat-gprs: '%s'", arg);
4329 case OPT_mlong_double_:
4330 rs6000_explicit_options.long_double = true;
4331 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4332 if (value != 64 && value != 128)
4334 error ("Unknown switch -mlong-double-%s", arg);
4335 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4339 rs6000_long_double_type_size = value;
4342 case OPT_msched_costly_dep_:
4343 rs6000_sched_costly_dep_str = arg;
4347 rs6000_explicit_options.alignment = true;
4348 if (! strcmp (arg, "power"))
4350 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4351 some C library functions, so warn about it. The flag may be
4352 useful for performance studies from time to time though, so
4353 don't disable it entirely. */
4354 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4355 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4356 " it is incompatible with the installed C and C++ libraries");
4357 rs6000_alignment_flags = MASK_ALIGN_POWER;
4359 else if (! strcmp (arg, "natural"))
4360 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4363 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4368 case OPT_msingle_float:
4369 if (!TARGET_SINGLE_FPU)
4370 warning (0, "-msingle-float option equivalent to -mhard-float");
4371 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4372 rs6000_double_float = 0;
4373 target_flags &= ~MASK_SOFT_FLOAT;
4374 target_flags_explicit |= MASK_SOFT_FLOAT;
4377 case OPT_mdouble_float:
4378 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4379 rs6000_single_float = 1;
4380 target_flags &= ~MASK_SOFT_FLOAT;
4381 target_flags_explicit |= MASK_SOFT_FLOAT;
4384 case OPT_msimple_fpu:
4385 if (!TARGET_SINGLE_FPU)
4386 warning (0, "-msimple-fpu option ignored");
4389 case OPT_mhard_float:
4390 /* -mhard_float implies -msingle-float and -mdouble-float. */
4391 rs6000_single_float = rs6000_double_float = 1;
4394 case OPT_msoft_float:
4395 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4396 rs6000_single_float = rs6000_double_float = 0;
4400 fpu_type = rs6000_parse_fpu_option(arg);
4401 if (fpu_type != FPU_NONE)
4402 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4404 target_flags &= ~MASK_SOFT_FLOAT;
4405 target_flags_explicit |= MASK_SOFT_FLOAT;
4406 rs6000_xilinx_fpu = 1;
4407 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4408 rs6000_single_float = 1;
4409 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4410 rs6000_single_float = rs6000_double_float = 1;
4411 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4412 rs6000_simple_fpu = 1;
4416 /* -mfpu=none is equivalent to -msoft-float */
4417 target_flags |= MASK_SOFT_FLOAT;
4418 target_flags_explicit |= MASK_SOFT_FLOAT;
4419 rs6000_single_float = rs6000_double_float = 0;
4423 rs6000_recip_name = (value) ? "default" : "none";
4427 rs6000_recip_name = arg;
4433 /* Do anything needed at the start of the asm file. */
4436 rs6000_file_start (void)
4440 const char *start = buffer;
4441 struct rs6000_cpu_select *ptr;
4442 const char *default_cpu = TARGET_CPU_DEFAULT;
4443 FILE *file = asm_out_file;
4445 default_file_start ();
4447 #ifdef TARGET_BI_ARCH
4448 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4452 if (flag_verbose_asm)
4454 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4455 rs6000_select[0].string = default_cpu;
4457 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4459 ptr = &rs6000_select[i];
4460 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4462 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4467 if (PPC405_ERRATUM77)
4469 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4473 #ifdef USING_ELFOS_H
4474 switch (rs6000_sdata)
4476 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4477 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4478 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4479 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4482 if (rs6000_sdata && g_switch_value)
4484 fprintf (file, "%s -G %d", start,
4494 #ifdef HAVE_AS_GNU_ATTRIBUTE
4495 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4497 fprintf (file, "\t.gnu_attribute 4, %d\n",
4498 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4499 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4501 fprintf (file, "\t.gnu_attribute 8, %d\n",
4502 (TARGET_ALTIVEC_ABI ? 2
4503 : TARGET_SPE_ABI ? 3
4505 fprintf (file, "\t.gnu_attribute 12, %d\n",
4506 aix_struct_return ? 2 : 1);
4511 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4513 switch_to_section (toc_section);
4514 switch_to_section (text_section);
4519 /* Return nonzero if this function is known to have a null epilogue. */
4522 direct_return (void)
4524 if (reload_completed)
4526 rs6000_stack_t *info = rs6000_stack_info ();
4528 if (info->first_gp_reg_save == 32
4529 && info->first_fp_reg_save == 64
4530 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4531 && ! info->lr_save_p
4532 && ! info->cr_save_p
4533 && info->vrsave_mask == 0
4541 /* Return the number of instructions it takes to form a constant in an
4542 integer register. */
4545 num_insns_constant_wide (HOST_WIDE_INT value)
4547 /* signed constant loadable with {cal|addi} */
4548 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4551 /* constant loadable with {cau|addis} */
4552 else if ((value & 0xffff) == 0
4553 && (value >> 31 == -1 || value >> 31 == 0))
4556 #if HOST_BITS_PER_WIDE_INT == 64
4557 else if (TARGET_POWERPC64)
4559 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4560 HOST_WIDE_INT high = value >> 31;
4562 if (high == 0 || high == -1)
4568 return num_insns_constant_wide (high) + 1;
4570 return num_insns_constant_wide (low) + 1;
4572 return (num_insns_constant_wide (high)
4573 + num_insns_constant_wide (low) + 1);
4582 num_insns_constant (rtx op, enum machine_mode mode)
4584 HOST_WIDE_INT low, high;
4586 switch (GET_CODE (op))
4589 #if HOST_BITS_PER_WIDE_INT == 64
4590 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4591 && mask64_operand (op, mode))
4595 return num_insns_constant_wide (INTVAL (op));
4598 if (mode == SFmode || mode == SDmode)
4603 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4604 if (DECIMAL_FLOAT_MODE_P (mode))
4605 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4607 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4608 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4611 if (mode == VOIDmode || mode == DImode)
4613 high = CONST_DOUBLE_HIGH (op);
4614 low = CONST_DOUBLE_LOW (op);
4621 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4622 if (DECIMAL_FLOAT_MODE_P (mode))
4623 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4625 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4626 high = l[WORDS_BIG_ENDIAN == 0];
4627 low = l[WORDS_BIG_ENDIAN != 0];
4631 return (num_insns_constant_wide (low)
4632 + num_insns_constant_wide (high));
4635 if ((high == 0 && low >= 0)
4636 || (high == -1 && low < 0))
4637 return num_insns_constant_wide (low);
4639 else if (mask64_operand (op, mode))
4643 return num_insns_constant_wide (high) + 1;
4646 return (num_insns_constant_wide (high)
4647 + num_insns_constant_wide (low) + 1);
4655 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4656 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4657 corresponding element of the vector, but for V4SFmode and V2SFmode,
4658 the corresponding "float" is interpreted as an SImode integer. */
4661 const_vector_elt_as_int (rtx op, unsigned int elt)
4663 rtx tmp = CONST_VECTOR_ELT (op, elt);
4664 if (GET_MODE (op) == V4SFmode
4665 || GET_MODE (op) == V2SFmode)
4666 tmp = gen_lowpart (SImode, tmp);
4667 return INTVAL (tmp);
4670 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4671 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4672 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4673 all items are set to the same value and contain COPIES replicas of the
4674 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4675 operand and the others are set to the value of the operand's msb. */
4678 vspltis_constant (rtx op, unsigned step, unsigned copies)
4680 enum machine_mode mode = GET_MODE (op);
4681 enum machine_mode inner = GET_MODE_INNER (mode);
4684 unsigned nunits = GET_MODE_NUNITS (mode);
4685 unsigned bitsize = GET_MODE_BITSIZE (inner);
4686 unsigned mask = GET_MODE_MASK (inner);
4688 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4689 HOST_WIDE_INT splat_val = val;
4690 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4692 /* Construct the value to be splatted, if possible. If not, return 0. */
4693 for (i = 2; i <= copies; i *= 2)
4695 HOST_WIDE_INT small_val;
4697 small_val = splat_val >> bitsize;
4699 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4701 splat_val = small_val;
4704 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4705 if (EASY_VECTOR_15 (splat_val))
4708 /* Also check if we can splat, and then add the result to itself. Do so if
4709 the value is positive, of if the splat instruction is using OP's mode;
4710 for splat_val < 0, the splat and the add should use the same mode. */
4711 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4712 && (splat_val >= 0 || (step == 1 && copies == 1)))
4715 /* Also check if are loading up the most significant bit which can be done by
4716 loading up -1 and shifting the value left by -1. */
4717 else if (EASY_VECTOR_MSB (splat_val, inner))
4723 /* Check if VAL is present in every STEP-th element, and the
4724 other elements are filled with its most significant bit. */
4725 for (i = 0; i < nunits - 1; ++i)
4727 HOST_WIDE_INT desired_val;
4728 if (((i + 1) & (step - 1)) == 0)
4731 desired_val = msb_val;
4733 if (desired_val != const_vector_elt_as_int (op, i))
4741 /* Return true if OP is of the given MODE and can be synthesized
4742 with a vspltisb, vspltish or vspltisw. */
4745 easy_altivec_constant (rtx op, enum machine_mode mode)
4747 unsigned step, copies;
4749 if (mode == VOIDmode)
4750 mode = GET_MODE (op);
4751 else if (mode != GET_MODE (op))
4754 /* Start with a vspltisw. */
4755 step = GET_MODE_NUNITS (mode) / 4;
4758 if (vspltis_constant (op, step, copies))
4761 /* Then try with a vspltish. */
4767 if (vspltis_constant (op, step, copies))
4770 /* And finally a vspltisb. */
4776 if (vspltis_constant (op, step, copies))
4782 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4783 result is OP. Abort if it is not possible. */
4786 gen_easy_altivec_constant (rtx op)
4788 enum machine_mode mode = GET_MODE (op);
4789 int nunits = GET_MODE_NUNITS (mode);
4790 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4791 unsigned step = nunits / 4;
4792 unsigned copies = 1;
4794 /* Start with a vspltisw. */
4795 if (vspltis_constant (op, step, copies))
4796 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4798 /* Then try with a vspltish. */
4804 if (vspltis_constant (op, step, copies))
4805 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4807 /* And finally a vspltisb. */
4813 if (vspltis_constant (op, step, copies))
4814 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4820 output_vec_const_move (rtx *operands)
4823 enum machine_mode mode;
4828 mode = GET_MODE (dest);
4830 if (TARGET_VSX && zero_constant (vec, mode))
4831 return "xxlxor %x0,%x0,%x0";
4836 if (zero_constant (vec, mode))
4837 return "vxor %0,%0,%0";
4839 splat_vec = gen_easy_altivec_constant (vec);
4840 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4841 operands[1] = XEXP (splat_vec, 0);
4842 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4845 switch (GET_MODE (splat_vec))
4848 return "vspltisw %0,%1";
4851 return "vspltish %0,%1";
4854 return "vspltisb %0,%1";
4861 gcc_assert (TARGET_SPE);
4863 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4864 pattern of V1DI, V4HI, and V2SF.
4866 FIXME: We should probably return # and add post reload
4867 splitters for these, but this way is so easy ;-). */
4868 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4869 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4870 operands[1] = CONST_VECTOR_ELT (vec, 0);
4871 operands[2] = CONST_VECTOR_ELT (vec, 1);
4873 return "li %0,%1\n\tevmergelo %0,%0,%0";
4875 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4878 /* Initialize TARGET of vector PAIRED to VALS. */
4881 paired_expand_vector_init (rtx target, rtx vals)
4883 enum machine_mode mode = GET_MODE (target);
4884 int n_elts = GET_MODE_NUNITS (mode);
4886 rtx x, new_rtx, tmp, constant_op, op1, op2;
4889 for (i = 0; i < n_elts; ++i)
4891 x = XVECEXP (vals, 0, i);
4892 if (!CONSTANT_P (x))
4897 /* Load from constant pool. */
4898 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4904 /* The vector is initialized only with non-constants. */
4905 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4906 XVECEXP (vals, 0, 1));
4908 emit_move_insn (target, new_rtx);
4912 /* One field is non-constant and the other one is a constant. Load the
4913 constant from the constant pool and use ps_merge instruction to
4914 construct the whole vector. */
4915 op1 = XVECEXP (vals, 0, 0);
4916 op2 = XVECEXP (vals, 0, 1);
4918 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4920 tmp = gen_reg_rtx (GET_MODE (constant_op));
4921 emit_move_insn (tmp, constant_op);
4923 if (CONSTANT_P (op1))
4924 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4926 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4928 emit_move_insn (target, new_rtx);
4932 paired_expand_vector_move (rtx operands[])
4934 rtx op0 = operands[0], op1 = operands[1];
4936 emit_move_insn (op0, op1);
4939 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4940 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4941 operands for the relation operation COND. This is a recursive
4945 paired_emit_vector_compare (enum rtx_code rcode,
4946 rtx dest, rtx op0, rtx op1,
4947 rtx cc_op0, rtx cc_op1)
4949 rtx tmp = gen_reg_rtx (V2SFmode);
4952 gcc_assert (TARGET_PAIRED_FLOAT);
4953 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4959 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4963 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4964 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4968 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4971 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4974 tmp1 = gen_reg_rtx (V2SFmode);
4975 max = gen_reg_rtx (V2SFmode);
4976 min = gen_reg_rtx (V2SFmode);
4977 gen_reg_rtx (V2SFmode);
4979 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4980 emit_insn (gen_selv2sf4
4981 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4982 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4983 emit_insn (gen_selv2sf4
4984 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4985 emit_insn (gen_subv2sf3 (tmp1, min, max));
4986 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4989 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4992 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4995 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4998 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5001 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5010 /* Emit vector conditional expression.
5011 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5012 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5015 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5016 rtx cond, rtx cc_op0, rtx cc_op1)
5018 enum rtx_code rcode = GET_CODE (cond);
5020 if (!TARGET_PAIRED_FLOAT)
5023 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5028 /* Initialize vector TARGET to VALS. */
5031 rs6000_expand_vector_init (rtx target, rtx vals)
5033 enum machine_mode mode = GET_MODE (target);
5034 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5035 int n_elts = GET_MODE_NUNITS (mode);
5036 int n_var = 0, one_var = -1;
5037 bool all_same = true, all_const_zero = true;
5041 for (i = 0; i < n_elts; ++i)
5043 x = XVECEXP (vals, 0, i);
5044 if (!CONSTANT_P (x))
5045 ++n_var, one_var = i;
5046 else if (x != CONST0_RTX (inner_mode))
5047 all_const_zero = false;
5049 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5055 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5056 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5057 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5059 /* Zero register. */
5060 emit_insn (gen_rtx_SET (VOIDmode, target,
5061 gen_rtx_XOR (mode, target, target)));
5064 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5066 /* Splat immediate. */
5067 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5072 /* Load from constant pool. */
5073 emit_move_insn (target, const_vec);
5078 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5079 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5083 rtx element = XVECEXP (vals, 0, 0);
5084 if (mode == V2DFmode)
5085 emit_insn (gen_vsx_splat_v2df (target, element));
5087 emit_insn (gen_vsx_splat_v2di (target, element));
5091 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5092 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5093 if (mode == V2DFmode)
5094 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5096 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5101 /* With single precision floating point on VSX, know that internally single
5102 precision is actually represented as a double, and either make 2 V2DF
5103 vectors, and convert these vectors to single precision, or do one
5104 conversion, and splat the result to the other elements. */
5105 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5109 rtx freg = gen_reg_rtx (V4SFmode);
5110 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5112 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5113 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5117 rtx dbl_even = gen_reg_rtx (V2DFmode);
5118 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5119 rtx flt_even = gen_reg_rtx (V4SFmode);
5120 rtx flt_odd = gen_reg_rtx (V4SFmode);
5122 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5123 copy_to_reg (XVECEXP (vals, 0, 0)),
5124 copy_to_reg (XVECEXP (vals, 0, 1))));
5125 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5126 copy_to_reg (XVECEXP (vals, 0, 2)),
5127 copy_to_reg (XVECEXP (vals, 0, 3))));
5128 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5129 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5130 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5135 /* Store value to stack temp. Load vector element. Splat. However, splat
5136 of 64-bit items is not supported on Altivec. */
5137 if (all_same && GET_MODE_SIZE (mode) <= 4)
5139 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5140 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5141 XVECEXP (vals, 0, 0));
5142 x = gen_rtx_UNSPEC (VOIDmode,
5143 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5144 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5146 gen_rtx_SET (VOIDmode,
5149 x = gen_rtx_VEC_SELECT (inner_mode, target,
5150 gen_rtx_PARALLEL (VOIDmode,
5151 gen_rtvec (1, const0_rtx)));
5152 emit_insn (gen_rtx_SET (VOIDmode, target,
5153 gen_rtx_VEC_DUPLICATE (mode, x)));
5157 /* One field is non-constant. Load constant then overwrite
5161 rtx copy = copy_rtx (vals);
5163 /* Load constant part of vector, substitute neighboring value for
5165 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5166 rs6000_expand_vector_init (target, copy);
5168 /* Insert variable. */
5169 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5173 /* Construct the vector in memory one field at a time
5174 and load the whole vector. */
5175 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5176 for (i = 0; i < n_elts; i++)
5177 emit_move_insn (adjust_address_nv (mem, inner_mode,
5178 i * GET_MODE_SIZE (inner_mode)),
5179 XVECEXP (vals, 0, i));
5180 emit_move_insn (target, mem);
5183 /* Set field ELT of TARGET to VAL. */
5186 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5188 enum machine_mode mode = GET_MODE (target);
5189 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5190 rtx reg = gen_reg_rtx (mode);
5192 int width = GET_MODE_SIZE (inner_mode);
5195 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5197 rtx (*set_func) (rtx, rtx, rtx, rtx)
5198 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5199 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5203 /* Load single variable value. */
5204 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5205 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5206 x = gen_rtx_UNSPEC (VOIDmode,
5207 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5208 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5210 gen_rtx_SET (VOIDmode,
5214 /* Linear sequence. */
5215 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5216 for (i = 0; i < 16; ++i)
5217 XVECEXP (mask, 0, i) = GEN_INT (i);
5219 /* Set permute mask to insert element into target. */
5220 for (i = 0; i < width; ++i)
5221 XVECEXP (mask, 0, elt*width + i)
5222 = GEN_INT (i + 0x10);
5223 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5224 x = gen_rtx_UNSPEC (mode,
5225 gen_rtvec (3, target, reg,
5226 force_reg (V16QImode, x)),
5228 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5231 /* Extract field ELT from VEC into TARGET. */
5234 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5236 enum machine_mode mode = GET_MODE (vec);
5237 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5240 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5242 rtx (*extract_func) (rtx, rtx, rtx)
5243 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5244 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5248 /* Allocate mode-sized buffer. */
5249 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5251 /* Add offset to field within buffer matching vector element. */
5252 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5254 /* Store single field into mode-sized buffer. */
5255 x = gen_rtx_UNSPEC (VOIDmode,
5256 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5257 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5259 gen_rtx_SET (VOIDmode,
5262 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5265 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5266 implement ANDing by the mask IN. */
5268 build_mask64_2_operands (rtx in, rtx *out)
5270 #if HOST_BITS_PER_WIDE_INT >= 64
5271 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5274 gcc_assert (GET_CODE (in) == CONST_INT);
5279 /* Assume c initially something like 0x00fff000000fffff. The idea
5280 is to rotate the word so that the middle ^^^^^^ group of zeros
5281 is at the MS end and can be cleared with an rldicl mask. We then
5282 rotate back and clear off the MS ^^ group of zeros with a
5284 c = ~c; /* c == 0xff000ffffff00000 */
5285 lsb = c & -c; /* lsb == 0x0000000000100000 */
5286 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5287 c = ~c; /* c == 0x00fff000000fffff */
5288 c &= -lsb; /* c == 0x00fff00000000000 */
5289 lsb = c & -c; /* lsb == 0x0000100000000000 */
5290 c = ~c; /* c == 0xff000fffffffffff */
5291 c &= -lsb; /* c == 0xff00000000000000 */
5293 while ((lsb >>= 1) != 0)
5294 shift++; /* shift == 44 on exit from loop */
5295 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5296 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5297 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5301 /* Assume c initially something like 0xff000f0000000000. The idea
5302 is to rotate the word so that the ^^^ middle group of zeros
5303 is at the LS end and can be cleared with an rldicr mask. We then
5304 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5306 lsb = c & -c; /* lsb == 0x0000010000000000 */
5307 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5308 c = ~c; /* c == 0x00fff0ffffffffff */
5309 c &= -lsb; /* c == 0x00fff00000000000 */
5310 lsb = c & -c; /* lsb == 0x0000100000000000 */
5311 c = ~c; /* c == 0xff000fffffffffff */
5312 c &= -lsb; /* c == 0xff00000000000000 */
5314 while ((lsb >>= 1) != 0)
5315 shift++; /* shift == 44 on exit from loop */
5316 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5317 m1 >>= shift; /* m1 == 0x0000000000000fff */
5318 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5321 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5322 masks will be all 1's. We are guaranteed more than one transition. */
5323 out[0] = GEN_INT (64 - shift);
5324 out[1] = GEN_INT (m1);
5325 out[2] = GEN_INT (shift);
5326 out[3] = GEN_INT (m2);
5334 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5337 invalid_e500_subreg (rtx op, enum machine_mode mode)
5339 if (TARGET_E500_DOUBLE)
5341 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5342 subreg:TI and reg:TF. Decimal float modes are like integer
5343 modes (only low part of each register used) for this
5345 if (GET_CODE (op) == SUBREG
5346 && (mode == SImode || mode == DImode || mode == TImode
5347 || mode == DDmode || mode == TDmode)
5348 && REG_P (SUBREG_REG (op))
5349 && (GET_MODE (SUBREG_REG (op)) == DFmode
5350 || GET_MODE (SUBREG_REG (op)) == TFmode))
5353 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5355 if (GET_CODE (op) == SUBREG
5356 && (mode == DFmode || mode == TFmode)
5357 && REG_P (SUBREG_REG (op))
5358 && (GET_MODE (SUBREG_REG (op)) == DImode
5359 || GET_MODE (SUBREG_REG (op)) == TImode
5360 || GET_MODE (SUBREG_REG (op)) == DDmode
5361 || GET_MODE (SUBREG_REG (op)) == TDmode))
5366 && GET_CODE (op) == SUBREG
5368 && REG_P (SUBREG_REG (op))
5369 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5375 /* AIX increases natural record alignment to doubleword if the first
5376 field is an FP double while the FP fields remain word aligned. */
5379 rs6000_special_round_type_align (tree type, unsigned int computed,
5380 unsigned int specified)
5382 unsigned int align = MAX (computed, specified);
5383 tree field = TYPE_FIELDS (type);
5385 /* Skip all non field decls */
5386 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5387 field = DECL_CHAIN (field);
5389 if (field != NULL && field != type)
5391 type = TREE_TYPE (field);
5392 while (TREE_CODE (type) == ARRAY_TYPE)
5393 type = TREE_TYPE (type);
5395 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5396 align = MAX (align, 64);
5402 /* Darwin increases record alignment to the natural alignment of
5406 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5407 unsigned int specified)
5409 unsigned int align = MAX (computed, specified);
5411 if (TYPE_PACKED (type))
5414 /* Find the first field, looking down into aggregates. */
5416 tree field = TYPE_FIELDS (type);
5417 /* Skip all non field decls */
5418 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5419 field = DECL_CHAIN (field);
5422 /* A packed field does not contribute any extra alignment. */
5423 if (DECL_PACKED (field))
5425 type = TREE_TYPE (field);
5426 while (TREE_CODE (type) == ARRAY_TYPE)
5427 type = TREE_TYPE (type);
5428 } while (AGGREGATE_TYPE_P (type));
5430 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5431 align = MAX (align, TYPE_ALIGN (type));
5436 /* Return 1 for an operand in small memory on V.4/eabi. */
5439 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5440 enum machine_mode mode ATTRIBUTE_UNUSED)
5445 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5448 if (DEFAULT_ABI != ABI_V4)
5451 /* Vector and float memory instructions have a limited offset on the
5452 SPE, so using a vector or float variable directly as an operand is
5455 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5458 if (GET_CODE (op) == SYMBOL_REF)
5461 else if (GET_CODE (op) != CONST
5462 || GET_CODE (XEXP (op, 0)) != PLUS
5463 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5464 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5469 rtx sum = XEXP (op, 0);
5470 HOST_WIDE_INT summand;
5472 /* We have to be careful here, because it is the referenced address
5473 that must be 32k from _SDA_BASE_, not just the symbol. */
5474 summand = INTVAL (XEXP (sum, 1));
5475 if (summand < 0 || summand > g_switch_value)
5478 sym_ref = XEXP (sum, 0);
5481 return SYMBOL_REF_SMALL_P (sym_ref);
5487 /* Return true if either operand is a general purpose register. */
5490 gpr_or_gpr_p (rtx op0, rtx op1)
5492 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5493 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5497 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5500 reg_offset_addressing_ok_p (enum machine_mode mode)
5510 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5511 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5519 /* Paired vector modes. Only reg+reg addressing is valid. */
5520 if (TARGET_PAIRED_FLOAT)
5532 virtual_stack_registers_memory_p (rtx op)
5536 if (GET_CODE (op) == REG)
5537 regnum = REGNO (op);
5539 else if (GET_CODE (op) == PLUS
5540 && GET_CODE (XEXP (op, 0)) == REG
5541 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5542 regnum = REGNO (XEXP (op, 0));
5547 return (regnum >= FIRST_VIRTUAL_REGISTER
5548 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5552 constant_pool_expr_p (rtx op)
5556 split_const (op, &base, &offset);
5557 return (GET_CODE (base) == SYMBOL_REF
5558 && CONSTANT_POOL_ADDRESS_P (base)
5559 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5562 static rtx tocrel_base, tocrel_offset;
5565 toc_relative_expr_p (rtx op)
5567 if (GET_CODE (op) != CONST)
5570 split_const (op, &tocrel_base, &tocrel_offset);
5571 return (GET_CODE (tocrel_base) == UNSPEC
5572 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5576 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5579 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5580 && GET_CODE (XEXP (x, 0)) == REG
5581 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5582 || ((TARGET_MINIMAL_TOC
5583 || TARGET_CMODEL != CMODEL_SMALL)
5584 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5585 && toc_relative_expr_p (XEXP (x, 1)));
5589 legitimate_small_data_p (enum machine_mode mode, rtx x)
5591 return (DEFAULT_ABI == ABI_V4
5592 && !flag_pic && !TARGET_TOC
5593 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5594 && small_data_operand (x, mode));
5597 /* SPE offset addressing is limited to 5-bits worth of double words. */
5598 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5601 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5603 unsigned HOST_WIDE_INT offset, extra;
5605 if (GET_CODE (x) != PLUS)
5607 if (GET_CODE (XEXP (x, 0)) != REG)
5609 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5611 if (!reg_offset_addressing_ok_p (mode))
5612 return virtual_stack_registers_memory_p (x);
5613 if (legitimate_constant_pool_address_p (x, strict))
5615 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5618 offset = INTVAL (XEXP (x, 1));
5626 /* SPE vector modes. */
5627 return SPE_CONST_OFFSET_OK (offset);
5630 if (TARGET_E500_DOUBLE)
5631 return SPE_CONST_OFFSET_OK (offset);
5633 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5635 if (VECTOR_MEM_VSX_P (DFmode))
5640 /* On e500v2, we may have:
5642 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5644 Which gets addressed with evldd instructions. */
5645 if (TARGET_E500_DOUBLE)
5646 return SPE_CONST_OFFSET_OK (offset);
5648 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5650 else if (offset & 3)
5655 if (TARGET_E500_DOUBLE)
5656 return (SPE_CONST_OFFSET_OK (offset)
5657 && SPE_CONST_OFFSET_OK (offset + 8));
5661 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5663 else if (offset & 3)
5674 return (offset < 0x10000) && (offset + extra < 0x10000);
5678 legitimate_indexed_address_p (rtx x, int strict)
5682 if (GET_CODE (x) != PLUS)
5688 /* Recognize the rtl generated by reload which we know will later be
5689 replaced with proper base and index regs. */
5691 && reload_in_progress
5692 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5696 return (REG_P (op0) && REG_P (op1)
5697 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5698 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5699 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5700 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5704 avoiding_indexed_address_p (enum machine_mode mode)
5706 /* Avoid indexed addressing for modes that have non-indexed
5707 load/store instruction forms. */
5708 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5712 legitimate_indirect_address_p (rtx x, int strict)
5714 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5718 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5720 if (!TARGET_MACHO || !flag_pic
5721 || mode != SImode || GET_CODE (x) != MEM)
5725 if (GET_CODE (x) != LO_SUM)
5727 if (GET_CODE (XEXP (x, 0)) != REG)
5729 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5733 return CONSTANT_P (x);
5737 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5739 if (GET_CODE (x) != LO_SUM)
5741 if (GET_CODE (XEXP (x, 0)) != REG)
5743 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5745 /* Restrict addressing for DI because of our SUBREG hackery. */
5746 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5747 || mode == DDmode || mode == TDmode
5752 if (TARGET_ELF || TARGET_MACHO)
5754 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5758 if (GET_MODE_NUNITS (mode) != 1)
5760 if (GET_MODE_BITSIZE (mode) > 64
5761 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5762 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5763 && (mode == DFmode || mode == DDmode))))
5766 return CONSTANT_P (x);
5773 /* Try machine-dependent ways of modifying an illegitimate address
5774 to be legitimate. If we find one, return the new, valid address.
5775 This is used from only one place: `memory_address' in explow.c.
5777 OLDX is the address as it was before break_out_memory_refs was
5778 called. In some cases it is useful to look at this to decide what
5781 It is always safe for this function to do nothing. It exists to
5782 recognize opportunities to optimize the output.
5784 On RS/6000, first check for the sum of a register with a constant
5785 integer that is out of range. If so, generate code to add the
5786 constant with the low-order 16 bits masked to the register and force
5787 this result into another register (this can be done with `cau').
5788 Then generate an address of REG+(CONST&0xffff), allowing for the
5789 possibility of bit 16 being a one.
5791 Then check for the sum of a register and something not constant, try to
5792 load the other things into a register and return the sum. */
5795 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5796 enum machine_mode mode)
5798 unsigned int extra = 0;
5800 if (!reg_offset_addressing_ok_p (mode))
5802 if (virtual_stack_registers_memory_p (x))
5805 /* In theory we should not be seeing addresses of the form reg+0,
5806 but just in case it is generated, optimize it away. */
5807 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5808 return force_reg (Pmode, XEXP (x, 0));
5810 /* Make sure both operands are registers. */
5811 else if (GET_CODE (x) == PLUS)
5812 return gen_rtx_PLUS (Pmode,
5813 force_reg (Pmode, XEXP (x, 0)),
5814 force_reg (Pmode, XEXP (x, 1)));
5816 return force_reg (Pmode, x);
5818 if (GET_CODE (x) == SYMBOL_REF)
5820 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5822 return rs6000_legitimize_tls_address (x, model);
5832 if (!TARGET_POWERPC64)
5840 extra = TARGET_POWERPC64 ? 8 : 12;
5846 if (GET_CODE (x) == PLUS
5847 && GET_CODE (XEXP (x, 0)) == REG
5848 && GET_CODE (XEXP (x, 1)) == CONST_INT
5849 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5851 && !((TARGET_POWERPC64
5852 && (mode == DImode || mode == TImode)
5853 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5854 || SPE_VECTOR_MODE (mode)
5855 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5856 || mode == DImode || mode == DDmode
5857 || mode == TDmode))))
5859 HOST_WIDE_INT high_int, low_int;
5861 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5862 if (low_int >= 0x8000 - extra)
5864 high_int = INTVAL (XEXP (x, 1)) - low_int;
5865 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5866 GEN_INT (high_int)), 0);
5867 return plus_constant (sum, low_int);
5869 else if (GET_CODE (x) == PLUS
5870 && GET_CODE (XEXP (x, 0)) == REG
5871 && GET_CODE (XEXP (x, 1)) != CONST_INT
5872 && GET_MODE_NUNITS (mode) == 1
5873 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5875 || ((mode != DImode && mode != DFmode && mode != DDmode)
5876 || (TARGET_E500_DOUBLE && mode != DDmode)))
5877 && (TARGET_POWERPC64 || mode != DImode)
5878 && !avoiding_indexed_address_p (mode)
5883 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5884 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5886 else if (SPE_VECTOR_MODE (mode)
5887 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5888 || mode == DDmode || mode == TDmode
5889 || mode == DImode)))
5893 /* We accept [reg + reg] and [reg + OFFSET]. */
5895 if (GET_CODE (x) == PLUS)
5897 rtx op1 = XEXP (x, 0);
5898 rtx op2 = XEXP (x, 1);
5901 op1 = force_reg (Pmode, op1);
5903 if (GET_CODE (op2) != REG
5904 && (GET_CODE (op2) != CONST_INT
5905 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5906 || (GET_MODE_SIZE (mode) > 8
5907 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5908 op2 = force_reg (Pmode, op2);
5910 /* We can't always do [reg + reg] for these, because [reg +
5911 reg + offset] is not a legitimate addressing mode. */
5912 y = gen_rtx_PLUS (Pmode, op1, op2);
5914 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5915 return force_reg (Pmode, y);
5920 return force_reg (Pmode, x);
5926 && GET_CODE (x) != CONST_INT
5927 && GET_CODE (x) != CONST_DOUBLE
5929 && GET_MODE_NUNITS (mode) == 1
5930 && (GET_MODE_BITSIZE (mode) <= 32
5931 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5932 && (mode == DFmode || mode == DDmode))))
5934 rtx reg = gen_reg_rtx (Pmode);
5935 emit_insn (gen_elf_high (reg, x));
5936 return gen_rtx_LO_SUM (Pmode, reg, x);
5938 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5941 && ! MACHO_DYNAMIC_NO_PIC_P
5943 && GET_CODE (x) != CONST_INT
5944 && GET_CODE (x) != CONST_DOUBLE
5946 && GET_MODE_NUNITS (mode) == 1
5947 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5948 || (mode != DFmode && mode != DDmode))
5952 rtx reg = gen_reg_rtx (Pmode);
5953 emit_insn (gen_macho_high (reg, x));
5954 return gen_rtx_LO_SUM (Pmode, reg, x);
5957 && GET_CODE (x) == SYMBOL_REF
5958 && constant_pool_expr_p (x)
5959 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5961 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
5962 return create_TOC_reference (x, reg);
5968 /* Debug version of rs6000_legitimize_address. */
5970 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5976 ret = rs6000_legitimize_address (x, oldx, mode);
5977 insns = get_insns ();
5983 "\nrs6000_legitimize_address: mode %s, old code %s, "
5984 "new code %s, modified\n",
5985 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5986 GET_RTX_NAME (GET_CODE (ret)));
5988 fprintf (stderr, "Original address:\n");
5991 fprintf (stderr, "oldx:\n");
5994 fprintf (stderr, "New address:\n");
5999 fprintf (stderr, "Insns added:\n");
6000 debug_rtx_list (insns, 20);
6006 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6007 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6018 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6019 We need to emit DTP-relative relocations. */
6022 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6027 fputs ("\t.long\t", file);
6030 fputs (DOUBLE_INT_ASM_OP, file);
6035 output_addr_const (file, x);
6036 fputs ("@dtprel+0x8000", file);
6039 /* In the name of slightly smaller debug output, and to cater to
6040 general assembler lossage, recognize various UNSPEC sequences
6041 and turn them back into a direct symbol reference. */
6044 rs6000_delegitimize_address (rtx orig_x)
6048 orig_x = delegitimize_mem_from_attrs (orig_x);
6053 if ((GET_CODE (x) == PLUS
6054 || GET_CODE (x) == LO_SUM)
6055 && GET_CODE (XEXP (x, 0)) == REG
6056 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6057 || TARGET_MINIMAL_TOC
6058 || TARGET_CMODEL != CMODEL_SMALL)
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_TOCREL)
6065 y = XVECEXP (y, 0, 0);
6066 if (!MEM_P (orig_x))
6069 return replace_equiv_address_nv (orig_x, y);
6074 && GET_CODE (orig_x) == LO_SUM
6075 && GET_CODE (XEXP (x, 1)) == CONST)
6077 y = XEXP (XEXP (x, 1), 0);
6078 if (GET_CODE (y) == UNSPEC
6079 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6080 return XVECEXP (y, 0, 0);
6086 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6088 static GTY(()) rtx rs6000_tls_symbol;
6090 rs6000_tls_get_addr (void)
6092 if (!rs6000_tls_symbol)
6093 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6095 return rs6000_tls_symbol;
6098 /* Construct the SYMBOL_REF for TLS GOT references. */
6100 static GTY(()) rtx rs6000_got_symbol;
6102 rs6000_got_sym (void)
6104 if (!rs6000_got_symbol)
6106 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6107 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6108 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6111 return rs6000_got_symbol;
6114 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6115 this (thread-local) address. */
6118 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6122 dest = gen_reg_rtx (Pmode);
6123 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6129 tlsreg = gen_rtx_REG (Pmode, 13);
6130 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6134 tlsreg = gen_rtx_REG (Pmode, 2);
6135 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6139 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6143 tmp = gen_reg_rtx (Pmode);
6146 tlsreg = gen_rtx_REG (Pmode, 13);
6147 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6151 tlsreg = gen_rtx_REG (Pmode, 2);
6152 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6156 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6158 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6163 rtx r3, got, tga, tmp1, tmp2, call_insn;
6165 /* We currently use relocations like @got@tlsgd for tls, which
6166 means the linker will handle allocation of tls entries, placing
6167 them in the .got section. So use a pointer to the .got section,
6168 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6169 or to secondary GOT sections used by 32-bit -fPIC. */
6171 got = gen_rtx_REG (Pmode, 2);
6175 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6178 rtx gsym = rs6000_got_sym ();
6179 got = gen_reg_rtx (Pmode);
6181 rs6000_emit_move (got, gsym, Pmode);
6186 tmp1 = gen_reg_rtx (Pmode);
6187 tmp2 = gen_reg_rtx (Pmode);
6188 mem = gen_const_mem (Pmode, tmp1);
6189 lab = gen_label_rtx ();
6190 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6191 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6192 emit_move_insn (tmp2, mem);
6193 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6194 set_unique_reg_note (last, REG_EQUAL, gsym);
6199 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6201 r3 = gen_rtx_REG (Pmode, 3);
6202 tga = rs6000_tls_get_addr ();
6203 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6205 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6206 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6207 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6208 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6209 else if (DEFAULT_ABI == ABI_V4)
6210 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6213 call_insn = last_call_insn ();
6214 PATTERN (call_insn) = insn;
6215 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6216 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6217 pic_offset_table_rtx);
6219 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6221 r3 = gen_rtx_REG (Pmode, 3);
6222 tga = rs6000_tls_get_addr ();
6223 tmp1 = gen_reg_rtx (Pmode);
6224 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6226 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6227 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6228 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6229 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6230 else if (DEFAULT_ABI == ABI_V4)
6231 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6234 call_insn = last_call_insn ();
6235 PATTERN (call_insn) = insn;
6236 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6237 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6238 pic_offset_table_rtx);
6240 if (rs6000_tls_size == 16)
6243 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6245 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6247 else if (rs6000_tls_size == 32)
6249 tmp2 = gen_reg_rtx (Pmode);
6251 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6253 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6256 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6258 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6262 tmp2 = gen_reg_rtx (Pmode);
6264 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6266 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6268 insn = gen_rtx_SET (Pmode, dest,
6269 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6275 /* IE, or 64-bit offset LE. */
6276 tmp2 = gen_reg_rtx (Pmode);
6278 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6280 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6283 insn = gen_tls_tls_64 (dest, tmp2, addr);
6285 insn = gen_tls_tls_32 (dest, tmp2, addr);
6293 /* Return 1 if X contains a thread-local symbol. */
6296 rs6000_tls_referenced_p (rtx x)
6298 if (! TARGET_HAVE_TLS)
6301 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6304 /* Return 1 if *X is a thread-local symbol. This is the same as
6305 rs6000_tls_symbol_ref except for the type of the unused argument. */
6308 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6310 return RS6000_SYMBOL_REF_TLS_P (*x);
6313 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6314 replace the input X, or the original X if no replacement is called for.
6315 The output parameter *WIN is 1 if the calling macro should goto WIN,
6318 For RS/6000, we wish to handle large displacements off a base
6319 register by splitting the addend across an addiu/addis and the mem insn.
6320 This cuts number of extra insns needed from 3 to 1.
6322 On Darwin, we use this to generate code for floating point constants.
6323 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6324 The Darwin code is inside #if TARGET_MACHO because only then are the
6325 machopic_* functions defined. */
6327 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6328 int opnum, int type,
6329 int ind_levels ATTRIBUTE_UNUSED, int *win)
6331 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6333 /* We must recognize output that we have already generated ourselves. */
6334 if (GET_CODE (x) == PLUS
6335 && GET_CODE (XEXP (x, 0)) == PLUS
6336 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6337 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6338 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6340 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6341 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6342 opnum, (enum reload_type)type);
6347 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6348 if (GET_CODE (x) == LO_SUM
6349 && GET_CODE (XEXP (x, 0)) == HIGH)
6351 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6352 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6353 opnum, (enum reload_type)type);
6359 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6360 && GET_CODE (x) == LO_SUM
6361 && GET_CODE (XEXP (x, 0)) == PLUS
6362 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6363 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6364 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6365 && machopic_operand_p (XEXP (x, 1)))
6367 /* Result of previous invocation of this function on Darwin
6368 floating point constant. */
6369 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6370 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6371 opnum, (enum reload_type)type);
6377 if (TARGET_CMODEL != CMODEL_SMALL
6378 && GET_CODE (x) == LO_SUM
6379 && GET_CODE (XEXP (x, 0)) == PLUS
6380 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6381 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6382 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6383 && GET_CODE (XEXP (x, 1)) == CONST
6384 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6385 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6386 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6388 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6389 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6390 opnum, (enum reload_type) type);
6395 /* Force ld/std non-word aligned offset into base register by wrapping
6397 if (GET_CODE (x) == PLUS
6398 && GET_CODE (XEXP (x, 0)) == REG
6399 && REGNO (XEXP (x, 0)) < 32
6400 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6401 && GET_CODE (XEXP (x, 1)) == CONST_INT
6403 && (INTVAL (XEXP (x, 1)) & 3) != 0
6404 && VECTOR_MEM_NONE_P (mode)
6405 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6406 && TARGET_POWERPC64)
6408 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6409 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6410 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6411 opnum, (enum reload_type) type);
6416 if (GET_CODE (x) == PLUS
6417 && GET_CODE (XEXP (x, 0)) == REG
6418 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6419 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6420 && GET_CODE (XEXP (x, 1)) == CONST_INT
6422 && !SPE_VECTOR_MODE (mode)
6423 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6424 || mode == DDmode || mode == TDmode
6426 && VECTOR_MEM_NONE_P (mode))
6428 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6429 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6431 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6433 /* Check for 32-bit overflow. */
6434 if (high + low != val)
6440 /* Reload the high part into a base reg; leave the low part
6441 in the mem directly. */
6443 x = gen_rtx_PLUS (GET_MODE (x),
6444 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6448 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6449 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6450 opnum, (enum reload_type)type);
6455 if (GET_CODE (x) == SYMBOL_REF
6457 && VECTOR_MEM_NONE_P (mode)
6458 && !SPE_VECTOR_MODE (mode)
6460 && DEFAULT_ABI == ABI_DARWIN
6461 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6463 && DEFAULT_ABI == ABI_V4
6466 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6467 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6471 && (mode != DImode || TARGET_POWERPC64)
6472 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6473 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6478 rtx offset = machopic_gen_offset (x);
6479 x = gen_rtx_LO_SUM (GET_MODE (x),
6480 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6481 gen_rtx_HIGH (Pmode, offset)), offset);
6485 x = gen_rtx_LO_SUM (GET_MODE (x),
6486 gen_rtx_HIGH (Pmode, x), x);
6488 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6489 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6490 opnum, (enum reload_type)type);
6495 /* Reload an offset address wrapped by an AND that represents the
6496 masking of the lower bits. Strip the outer AND and let reload
6497 convert the offset address into an indirect address. For VSX,
6498 force reload to create the address with an AND in a separate
6499 register, because we can't guarantee an altivec register will
6501 if (VECTOR_MEM_ALTIVEC_P (mode)
6502 && GET_CODE (x) == AND
6503 && GET_CODE (XEXP (x, 0)) == PLUS
6504 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6505 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6506 && GET_CODE (XEXP (x, 1)) == CONST_INT
6507 && INTVAL (XEXP (x, 1)) == -16)
6516 && GET_CODE (x) == SYMBOL_REF
6517 && constant_pool_expr_p (x)
6518 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6520 x = create_TOC_reference (x, NULL_RTX);
6521 if (TARGET_CMODEL != CMODEL_SMALL)
6522 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6523 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6524 opnum, (enum reload_type) type);
6532 /* Debug version of rs6000_legitimize_reload_address. */
6534 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6535 int opnum, int type,
6536 int ind_levels, int *win)
6538 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6541 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6542 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6543 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6547 fprintf (stderr, "Same address returned\n");
6549 fprintf (stderr, "NULL returned\n");
6552 fprintf (stderr, "New address:\n");
6559 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6560 that is a valid memory address for an instruction.
6561 The MODE argument is the machine mode for the MEM expression
6562 that wants to use this address.
6564 On the RS/6000, there are four valid address: a SYMBOL_REF that
6565 refers to a constant pool entry of an address (or the sum of it
6566 plus a constant), a short (16-bit signed) constant plus a register,
6567 the sum of two registers, or a register indirect, possibly with an
6568 auto-increment. For DFmode, DDmode and DImode with a constant plus
6569 register, we must ensure that both words are addressable or PowerPC64
6570 with offset word aligned.
6572 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6573 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6574 because adjacent memory cells are accessed by adding word-sized offsets
6575 during assembly output. */
6577 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6579 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6581 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6582 if (VECTOR_MEM_ALTIVEC_P (mode)
6583 && GET_CODE (x) == AND
6584 && GET_CODE (XEXP (x, 1)) == CONST_INT
6585 && INTVAL (XEXP (x, 1)) == -16)
6588 if (RS6000_SYMBOL_REF_TLS_P (x))
6590 if (legitimate_indirect_address_p (x, reg_ok_strict))
6592 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6593 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6594 && !SPE_VECTOR_MODE (mode)
6597 /* Restrict addressing for DI because of our SUBREG hackery. */
6598 && !(TARGET_E500_DOUBLE
6599 && (mode == DFmode || mode == DDmode || mode == DImode))
6601 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6603 if (virtual_stack_registers_memory_p (x))
6605 if (reg_offset_p && legitimate_small_data_p (mode, x))
6607 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6609 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6612 && GET_CODE (x) == PLUS
6613 && GET_CODE (XEXP (x, 0)) == REG
6614 && (XEXP (x, 0) == virtual_stack_vars_rtx
6615 || XEXP (x, 0) == arg_pointer_rtx)
6616 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6618 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6623 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6625 || (mode != DFmode && mode != DDmode)
6626 || (TARGET_E500_DOUBLE && mode != DDmode))
6627 && (TARGET_POWERPC64 || mode != DImode)
6628 && !avoiding_indexed_address_p (mode)
6629 && legitimate_indexed_address_p (x, reg_ok_strict))
6631 if (GET_CODE (x) == PRE_MODIFY
6635 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6637 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6638 && (TARGET_POWERPC64 || mode != DImode)
6639 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6640 && !SPE_VECTOR_MODE (mode)
6641 /* Restrict addressing for DI because of our SUBREG hackery. */
6642 && !(TARGET_E500_DOUBLE
6643 && (mode == DFmode || mode == DDmode || mode == DImode))
6645 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6646 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6647 || (!avoiding_indexed_address_p (mode)
6648 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6649 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6651 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6656 /* Debug version of rs6000_legitimate_address_p. */
6658 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6661 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6663 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6664 "strict = %d, code = %s\n",
6665 ret ? "true" : "false",
6666 GET_MODE_NAME (mode),
6668 GET_RTX_NAME (GET_CODE (x)));
6674 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6677 rs6000_mode_dependent_address_p (const_rtx addr)
6679 return rs6000_mode_dependent_address_ptr (addr);
6682 /* Go to LABEL if ADDR (a legitimate address expression)
6683 has an effect that depends on the machine mode it is used for.
6685 On the RS/6000 this is true of all integral offsets (since AltiVec
6686 and VSX modes don't allow them) or is a pre-increment or decrement.
6688 ??? Except that due to conceptual problems in offsettable_address_p
6689 we can't really report the problems of integral offsets. So leave
6690 this assuming that the adjustable offset must be valid for the
6691 sub-words of a TFmode operand, which is what we had before. */
6694 rs6000_mode_dependent_address (const_rtx addr)
6696 switch (GET_CODE (addr))
6699 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6700 is considered a legitimate address before reload, so there
6701 are no offset restrictions in that case. Note that this
6702 condition is safe in strict mode because any address involving
6703 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6704 been rejected as illegitimate. */
6705 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6706 && XEXP (addr, 0) != arg_pointer_rtx
6707 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6709 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6710 return val + 12 + 0x8000 >= 0x10000;
6715 /* Anything in the constant pool is sufficiently aligned that
6716 all bytes have the same high part address. */
6717 return !legitimate_constant_pool_address_p (addr, false);
6719 /* Auto-increment cases are now treated generically in recog.c. */
6721 return TARGET_UPDATE;
6723 /* AND is only allowed in Altivec loads. */
6734 /* Debug version of rs6000_mode_dependent_address. */
6736 rs6000_debug_mode_dependent_address (const_rtx addr)
6738 bool ret = rs6000_mode_dependent_address (addr);
6740 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6741 ret ? "true" : "false");
6747 /* Implement FIND_BASE_TERM. */
6750 rs6000_find_base_term (rtx op)
6754 split_const (op, &base, &offset);
6755 if (GET_CODE (base) == UNSPEC)
6756 switch (XINT (base, 1))
6759 case UNSPEC_MACHOPIC_OFFSET:
6760 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6761 for aliasing purposes. */
6762 return XVECEXP (base, 0, 0);
6768 /* More elaborate version of recog's offsettable_memref_p predicate
6769 that works around the ??? note of rs6000_mode_dependent_address.
6770 In particular it accepts
6772 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6774 in 32-bit mode, that the recog predicate rejects. */
6777 rs6000_offsettable_memref_p (rtx op)
6782 /* First mimic offsettable_memref_p. */
6783 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6786 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6787 the latter predicate knows nothing about the mode of the memory
6788 reference and, therefore, assumes that it is the largest supported
6789 mode (TFmode). As a consequence, legitimate offsettable memory
6790 references are rejected. rs6000_legitimate_offset_address_p contains
6791 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6792 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6795 /* Change register usage conditional on target flags. */
6797 rs6000_conditional_register_usage (void)
6801 /* Set MQ register fixed (already call_used) if not POWER
6802 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6807 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6809 fixed_regs[13] = call_used_regs[13]
6810 = call_really_used_regs[13] = 1;
6812 /* Conditionally disable FPRs. */
6813 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6814 for (i = 32; i < 64; i++)
6815 fixed_regs[i] = call_used_regs[i]
6816 = call_really_used_regs[i] = 1;
6818 /* The TOC register is not killed across calls in a way that is
6819 visible to the compiler. */
6820 if (DEFAULT_ABI == ABI_AIX)
6821 call_really_used_regs[2] = 0;
6823 if (DEFAULT_ABI == ABI_V4
6824 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6826 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6828 if (DEFAULT_ABI == ABI_V4
6829 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6831 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6832 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6833 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6835 if (DEFAULT_ABI == ABI_DARWIN
6836 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6837 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6838 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6839 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6841 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6842 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6843 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6847 global_regs[SPEFSCR_REGNO] = 1;
6848 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6849 registers in prologues and epilogues. We no longer use r14
6850 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6851 pool for link-compatibility with older versions of GCC. Once
6852 "old" code has died out, we can return r14 to the allocation
6855 = call_used_regs[14]
6856 = call_really_used_regs[14] = 1;
6859 if (!TARGET_ALTIVEC && !TARGET_VSX)
6861 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6862 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6863 call_really_used_regs[VRSAVE_REGNO] = 1;
6866 if (TARGET_ALTIVEC || TARGET_VSX)
6867 global_regs[VSCR_REGNO] = 1;
6869 if (TARGET_ALTIVEC_ABI)
6871 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6872 call_used_regs[i] = call_really_used_regs[i] = 1;
6874 /* AIX reserves VR20:31 in non-extended ABI mode. */
6876 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6877 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6881 /* Try to output insns to set TARGET equal to the constant C if it can
6882 be done in less than N insns. Do all computations in MODE.
6883 Returns the place where the output has been placed if it can be
6884 done and the insns have been emitted. If it would take more than N
6885 insns, zero is returned and no insns and emitted. */
6888 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6889 rtx source, int n ATTRIBUTE_UNUSED)
6891 rtx result, insn, set;
6892 HOST_WIDE_INT c0, c1;
6899 dest = gen_reg_rtx (mode);
6900 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6904 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6906 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6907 GEN_INT (INTVAL (source)
6908 & (~ (HOST_WIDE_INT) 0xffff))));
6909 emit_insn (gen_rtx_SET (VOIDmode, dest,
6910 gen_rtx_IOR (SImode, copy_rtx (result),
6911 GEN_INT (INTVAL (source) & 0xffff))));
6916 switch (GET_CODE (source))
6919 c0 = INTVAL (source);
6924 #if HOST_BITS_PER_WIDE_INT >= 64
6925 c0 = CONST_DOUBLE_LOW (source);
6928 c0 = CONST_DOUBLE_LOW (source);
6929 c1 = CONST_DOUBLE_HIGH (source);
6937 result = rs6000_emit_set_long_const (dest, c0, c1);
6944 insn = get_last_insn ();
6945 set = single_set (insn);
6946 if (! CONSTANT_P (SET_SRC (set)))
6947 set_unique_reg_note (insn, REG_EQUAL, source);
6952 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6953 fall back to a straight forward decomposition. We do this to avoid
6954 exponential run times encountered when looking for longer sequences
6955 with rs6000_emit_set_const. */
6957 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6959 if (!TARGET_POWERPC64)
6961 rtx operand1, operand2;
6963 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6965 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6967 emit_move_insn (operand1, GEN_INT (c1));
6968 emit_move_insn (operand2, GEN_INT (c2));
6972 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6975 ud2 = (c1 & 0xffff0000) >> 16;
6976 #if HOST_BITS_PER_WIDE_INT >= 64
6980 ud4 = (c2 & 0xffff0000) >> 16;
6982 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6983 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6986 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6988 emit_move_insn (dest, GEN_INT (ud1));
6991 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6992 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6995 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6998 emit_move_insn (dest, GEN_INT (ud2 << 16));
7000 emit_move_insn (copy_rtx (dest),
7001 gen_rtx_IOR (DImode, copy_rtx (dest),
7004 else if (ud3 == 0 && ud4 == 0)
7006 gcc_assert (ud2 & 0x8000);
7007 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7010 emit_move_insn (copy_rtx (dest),
7011 gen_rtx_IOR (DImode, copy_rtx (dest),
7013 emit_move_insn (copy_rtx (dest),
7014 gen_rtx_ZERO_EXTEND (DImode,
7015 gen_lowpart (SImode,
7018 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7019 || (ud4 == 0 && ! (ud3 & 0x8000)))
7022 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7025 emit_move_insn (dest, GEN_INT (ud3 << 16));
7028 emit_move_insn (copy_rtx (dest),
7029 gen_rtx_IOR (DImode, copy_rtx (dest),
7031 emit_move_insn (copy_rtx (dest),
7032 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7035 emit_move_insn (copy_rtx (dest),
7036 gen_rtx_IOR (DImode, copy_rtx (dest),
7042 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7045 emit_move_insn (dest, GEN_INT (ud4 << 16));
7048 emit_move_insn (copy_rtx (dest),
7049 gen_rtx_IOR (DImode, copy_rtx (dest),
7052 emit_move_insn (copy_rtx (dest),
7053 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7056 emit_move_insn (copy_rtx (dest),
7057 gen_rtx_IOR (DImode, copy_rtx (dest),
7058 GEN_INT (ud2 << 16)));
7060 emit_move_insn (copy_rtx (dest),
7061 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7067 /* Helper for the following. Get rid of [r+r] memory refs
7068 in cases where it won't work (TImode, TFmode, TDmode). */
7071 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7073 if (reload_in_progress)
7076 if (GET_CODE (operands[0]) == MEM
7077 && GET_CODE (XEXP (operands[0], 0)) != REG
7078 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7080 = replace_equiv_address (operands[0],
7081 copy_addr_to_reg (XEXP (operands[0], 0)));
7083 if (GET_CODE (operands[1]) == MEM
7084 && GET_CODE (XEXP (operands[1], 0)) != REG
7085 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7087 = replace_equiv_address (operands[1],
7088 copy_addr_to_reg (XEXP (operands[1], 0)));
7091 /* Return true if memory accesses to DECL are known to never straddle
7095 offsettable_ok_by_alignment (tree decl)
7097 unsigned HOST_WIDE_INT dsize, dalign;
7099 /* Presume any compiler generated symbol_ref is suitably aligned. */
7103 if (TREE_CODE (decl) != VAR_DECL
7104 && TREE_CODE (decl) != PARM_DECL
7105 && TREE_CODE (decl) != RESULT_DECL
7106 && TREE_CODE (decl) != FIELD_DECL)
7109 if (!DECL_SIZE_UNIT (decl))
7112 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7115 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7121 dalign = DECL_ALIGN_UNIT (decl);
7122 return dalign >= dsize;
7125 /* Emit a move from SOURCE to DEST in mode MODE. */
7127 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7131 operands[1] = source;
7133 if (TARGET_DEBUG_ADDR)
7136 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7137 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7138 GET_MODE_NAME (mode),
7141 can_create_pseudo_p ());
7143 fprintf (stderr, "source:\n");
7147 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7148 if (GET_CODE (operands[1]) == CONST_DOUBLE
7149 && ! FLOAT_MODE_P (mode)
7150 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7152 /* FIXME. This should never happen. */
7153 /* Since it seems that it does, do the safe thing and convert
7155 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7157 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7158 || FLOAT_MODE_P (mode)
7159 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7160 || CONST_DOUBLE_LOW (operands[1]) < 0)
7161 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7162 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7164 /* Check if GCC is setting up a block move that will end up using FP
7165 registers as temporaries. We must make sure this is acceptable. */
7166 if (GET_CODE (operands[0]) == MEM
7167 && GET_CODE (operands[1]) == MEM
7169 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7170 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7171 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7172 ? 32 : MEM_ALIGN (operands[0])))
7173 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7175 : MEM_ALIGN (operands[1]))))
7176 && ! MEM_VOLATILE_P (operands [0])
7177 && ! MEM_VOLATILE_P (operands [1]))
7179 emit_move_insn (adjust_address (operands[0], SImode, 0),
7180 adjust_address (operands[1], SImode, 0));
7181 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7182 adjust_address (copy_rtx (operands[1]), SImode, 4));
7186 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7187 && !gpc_reg_operand (operands[1], mode))
7188 operands[1] = force_reg (mode, operands[1]);
7190 if (mode == SFmode && ! TARGET_POWERPC
7191 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7192 && GET_CODE (operands[0]) == MEM)
7196 if (reload_in_progress || reload_completed)
7197 regnum = true_regnum (operands[1]);
7198 else if (GET_CODE (operands[1]) == REG)
7199 regnum = REGNO (operands[1]);
7203 /* If operands[1] is a register, on POWER it may have
7204 double-precision data in it, so truncate it to single
7206 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7209 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7210 : gen_reg_rtx (mode));
7211 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7212 operands[1] = newreg;
7216 /* Recognize the case where operand[1] is a reference to thread-local
7217 data and load its address to a register. */
7218 if (rs6000_tls_referenced_p (operands[1]))
7220 enum tls_model model;
7221 rtx tmp = operands[1];
7224 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7226 addend = XEXP (XEXP (tmp, 0), 1);
7227 tmp = XEXP (XEXP (tmp, 0), 0);
7230 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7231 model = SYMBOL_REF_TLS_MODEL (tmp);
7232 gcc_assert (model != 0);
7234 tmp = rs6000_legitimize_tls_address (tmp, model);
7237 tmp = gen_rtx_PLUS (mode, tmp, addend);
7238 tmp = force_operand (tmp, operands[0]);
7243 /* Handle the case where reload calls us with an invalid address. */
7244 if (reload_in_progress && mode == Pmode
7245 && (! general_operand (operands[1], mode)
7246 || ! nonimmediate_operand (operands[0], mode)))
7249 /* 128-bit constant floating-point values on Darwin should really be
7250 loaded as two parts. */
7251 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7252 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7254 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7255 know how to get a DFmode SUBREG of a TFmode. */
7256 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7257 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7258 simplify_gen_subreg (imode, operands[1], mode, 0),
7260 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7261 GET_MODE_SIZE (imode)),
7262 simplify_gen_subreg (imode, operands[1], mode,
7263 GET_MODE_SIZE (imode)),
7268 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7269 cfun->machine->sdmode_stack_slot =
7270 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7272 if (reload_in_progress
7274 && MEM_P (operands[0])
7275 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7276 && REG_P (operands[1]))
7278 if (FP_REGNO_P (REGNO (operands[1])))
7280 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7281 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7282 emit_insn (gen_movsd_store (mem, operands[1]));
7284 else if (INT_REGNO_P (REGNO (operands[1])))
7286 rtx mem = adjust_address_nv (operands[0], mode, 4);
7287 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7288 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7294 if (reload_in_progress
7296 && REG_P (operands[0])
7297 && MEM_P (operands[1])
7298 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7300 if (FP_REGNO_P (REGNO (operands[0])))
7302 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7303 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7304 emit_insn (gen_movsd_load (operands[0], mem));
7306 else if (INT_REGNO_P (REGNO (operands[0])))
7308 rtx mem = adjust_address_nv (operands[1], mode, 4);
7309 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7310 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7317 /* FIXME: In the long term, this switch statement should go away
7318 and be replaced by a sequence of tests based on things like
7324 if (CONSTANT_P (operands[1])
7325 && GET_CODE (operands[1]) != CONST_INT)
7326 operands[1] = force_const_mem (mode, operands[1]);
7331 rs6000_eliminate_indexed_memrefs (operands);
7338 if (CONSTANT_P (operands[1])
7339 && ! easy_fp_constant (operands[1], mode))
7340 operands[1] = force_const_mem (mode, operands[1]);
7353 if (CONSTANT_P (operands[1])
7354 && !easy_vector_constant (operands[1], mode))
7355 operands[1] = force_const_mem (mode, operands[1]);
7360 /* Use default pattern for address of ELF small data */
7363 && DEFAULT_ABI == ABI_V4
7364 && (GET_CODE (operands[1]) == SYMBOL_REF
7365 || GET_CODE (operands[1]) == CONST)
7366 && small_data_operand (operands[1], mode))
7368 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7372 if (DEFAULT_ABI == ABI_V4
7373 && mode == Pmode && mode == SImode
7374 && flag_pic == 1 && got_operand (operands[1], mode))
7376 emit_insn (gen_movsi_got (operands[0], operands[1]));
7380 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7384 && CONSTANT_P (operands[1])
7385 && GET_CODE (operands[1]) != HIGH
7386 && GET_CODE (operands[1]) != CONST_INT)
7388 rtx target = (!can_create_pseudo_p ()
7390 : gen_reg_rtx (mode));
7392 /* If this is a function address on -mcall-aixdesc,
7393 convert it to the address of the descriptor. */
7394 if (DEFAULT_ABI == ABI_AIX
7395 && GET_CODE (operands[1]) == SYMBOL_REF
7396 && XSTR (operands[1], 0)[0] == '.')
7398 const char *name = XSTR (operands[1], 0);
7400 while (*name == '.')
7402 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7403 CONSTANT_POOL_ADDRESS_P (new_ref)
7404 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7405 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7406 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7407 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7408 operands[1] = new_ref;
7411 if (DEFAULT_ABI == ABI_DARWIN)
7414 if (MACHO_DYNAMIC_NO_PIC_P)
7416 /* Take care of any required data indirection. */
7417 operands[1] = rs6000_machopic_legitimize_pic_address (
7418 operands[1], mode, operands[0]);
7419 if (operands[0] != operands[1])
7420 emit_insn (gen_rtx_SET (VOIDmode,
7421 operands[0], operands[1]));
7425 emit_insn (gen_macho_high (target, operands[1]));
7426 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7430 emit_insn (gen_elf_high (target, operands[1]));
7431 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7435 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7436 and we have put it in the TOC, we just need to make a TOC-relative
7439 && GET_CODE (operands[1]) == SYMBOL_REF
7440 && constant_pool_expr_p (operands[1])
7441 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7442 get_pool_mode (operands[1])))
7443 || (TARGET_CMODEL == CMODEL_MEDIUM
7444 && GET_CODE (operands[1]) == SYMBOL_REF
7445 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7446 && SYMBOL_REF_LOCAL_P (operands[1])
7447 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7450 if (TARGET_CMODEL != CMODEL_SMALL)
7452 if (can_create_pseudo_p ())
7453 reg = gen_reg_rtx (Pmode);
7457 operands[1] = create_TOC_reference (operands[1], reg);
7459 else if (mode == Pmode
7460 && CONSTANT_P (operands[1])
7461 && ((GET_CODE (operands[1]) != CONST_INT
7462 && ! easy_fp_constant (operands[1], mode))
7463 || (GET_CODE (operands[1]) == CONST_INT
7464 && (num_insns_constant (operands[1], mode)
7465 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7466 || (GET_CODE (operands[0]) == REG
7467 && FP_REGNO_P (REGNO (operands[0]))))
7468 && GET_CODE (operands[1]) != HIGH
7469 && ! legitimate_constant_pool_address_p (operands[1], false)
7470 && ! toc_relative_expr_p (operands[1])
7471 && (TARGET_CMODEL == CMODEL_SMALL
7472 || can_create_pseudo_p ()
7473 || (REG_P (operands[0])
7474 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7478 /* Darwin uses a special PIC legitimizer. */
7479 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7482 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7484 if (operands[0] != operands[1])
7485 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7490 /* If we are to limit the number of things we put in the TOC and
7491 this is a symbol plus a constant we can add in one insn,
7492 just put the symbol in the TOC and add the constant. Don't do
7493 this if reload is in progress. */
7494 if (GET_CODE (operands[1]) == CONST
7495 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7496 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7497 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7498 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7499 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7500 && ! side_effects_p (operands[0]))
7503 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7504 rtx other = XEXP (XEXP (operands[1], 0), 1);
7506 sym = force_reg (mode, sym);
7507 emit_insn (gen_add3_insn (operands[0], sym, other));
7511 operands[1] = force_const_mem (mode, operands[1]);
7514 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7515 && constant_pool_expr_p (XEXP (operands[1], 0))
7516 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7517 get_pool_constant (XEXP (operands[1], 0)),
7518 get_pool_mode (XEXP (operands[1], 0))))
7522 if (TARGET_CMODEL != CMODEL_SMALL)
7524 if (can_create_pseudo_p ())
7525 reg = gen_reg_rtx (Pmode);
7529 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7530 operands[1] = gen_const_mem (mode, tocref);
7531 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7537 rs6000_eliminate_indexed_memrefs (operands);
7541 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7543 gen_rtx_SET (VOIDmode,
7544 operands[0], operands[1]),
7545 gen_rtx_CLOBBER (VOIDmode,
7546 gen_rtx_SCRATCH (SImode)))));
7552 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7555 /* Above, we may have called force_const_mem which may have returned
7556 an invalid address. If we can, fix this up; otherwise, reload will
7557 have to deal with it. */
7558 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7559 operands[1] = validize_mem (operands[1]);
7562 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7565 /* Nonzero if we can use a floating-point register to pass this arg. */
7566 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7567 (SCALAR_FLOAT_MODE_P (MODE) \
7568 && (CUM)->fregno <= FP_ARG_MAX_REG \
7569 && TARGET_HARD_FLOAT && TARGET_FPRS)
7571 /* Nonzero if we can use an AltiVec register to pass this arg. */
7572 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7573 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7574 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7575 && TARGET_ALTIVEC_ABI \
7578 /* Return a nonzero value to say to return the function value in
7579 memory, just as large structures are always returned. TYPE will be
7580 the data type of the value, and FNTYPE will be the type of the
7581 function doing the returning, or @code{NULL} for libcalls.
7583 The AIX ABI for the RS/6000 specifies that all structures are
7584 returned in memory. The Darwin ABI does the same.
7586 For the Darwin 64 Bit ABI, a function result can be returned in
7587 registers or in memory, depending on the size of the return data
7588 type. If it is returned in registers, the value occupies the same
7589 registers as it would if it were the first and only function
7590 argument. Otherwise, the function places its result in memory at
7591 the location pointed to by GPR3.
7593 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7594 but a draft put them in memory, and GCC used to implement the draft
7595 instead of the final standard. Therefore, aix_struct_return
7596 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7597 compatibility can change DRAFT_V4_STRUCT_RET to override the
7598 default, and -m switches get the final word. See
7599 rs6000_option_override_internal for more details.
7601 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7602 long double support is enabled. These values are returned in memory.
7604 int_size_in_bytes returns -1 for variable size objects, which go in
7605 memory always. The cast to unsigned makes -1 > 8. */
7608 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7610 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7612 && rs6000_darwin64_abi
7613 && TREE_CODE (type) == RECORD_TYPE
7614 && int_size_in_bytes (type) > 0)
7616 CUMULATIVE_ARGS valcum;
7620 valcum.fregno = FP_ARG_MIN_REG;
7621 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7622 /* Do a trial code generation as if this were going to be passed
7623 as an argument; if any part goes in memory, we return NULL. */
7624 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7627 /* Otherwise fall through to more conventional ABI rules. */
7630 if (AGGREGATE_TYPE_P (type)
7631 && (aix_struct_return
7632 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7635 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7636 modes only exist for GCC vector types if -maltivec. */
7637 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7638 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7641 /* Return synthetic vectors in memory. */
7642 if (TREE_CODE (type) == VECTOR_TYPE
7643 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7645 static bool warned_for_return_big_vectors = false;
7646 if (!warned_for_return_big_vectors)
7648 warning (0, "GCC vector returned by reference: "
7649 "non-standard ABI extension with no compatibility guarantee");
7650 warned_for_return_big_vectors = true;
7655 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7661 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7662 for a call to a function whose data type is FNTYPE.
7663 For a library call, FNTYPE is 0.
7665 For incoming args we set the number of arguments in the prototype large
7666 so we never return a PARALLEL. */
7669 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7670 rtx libname ATTRIBUTE_UNUSED, int incoming,
7671 int libcall, int n_named_args)
7673 static CUMULATIVE_ARGS zero_cumulative;
7675 *cum = zero_cumulative;
7677 cum->fregno = FP_ARG_MIN_REG;
7678 cum->vregno = ALTIVEC_ARG_MIN_REG;
7679 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7680 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7681 ? CALL_LIBCALL : CALL_NORMAL);
7682 cum->sysv_gregno = GP_ARG_MIN_REG;
7683 cum->stdarg = stdarg_p (fntype);
7685 cum->nargs_prototype = 0;
7686 if (incoming || cum->prototype)
7687 cum->nargs_prototype = n_named_args;
7689 /* Check for a longcall attribute. */
7690 if ((!fntype && rs6000_default_long_calls)
7692 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7693 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7694 cum->call_cookie |= CALL_LONG;
7696 if (TARGET_DEBUG_ARG)
7698 fprintf (stderr, "\ninit_cumulative_args:");
7701 tree ret_type = TREE_TYPE (fntype);
7702 fprintf (stderr, " ret code = %s,",
7703 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7706 if (cum->call_cookie & CALL_LONG)
7707 fprintf (stderr, " longcall,");
7709 fprintf (stderr, " proto = %d, nargs = %d\n",
7710 cum->prototype, cum->nargs_prototype);
7715 && TARGET_ALTIVEC_ABI
7716 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7718 error ("cannot return value in vector register because"
7719 " altivec instructions are disabled, use -maltivec"
7724 /* Return true if TYPE must be passed on the stack and not in registers. */
7727 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7729 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7730 return must_pass_in_stack_var_size (mode, type);
7732 return must_pass_in_stack_var_size_or_pad (mode, type);
7735 /* If defined, a C expression which determines whether, and in which
7736 direction, to pad out an argument with extra space. The value
7737 should be of type `enum direction': either `upward' to pad above
7738 the argument, `downward' to pad below, or `none' to inhibit
7741 For the AIX ABI structs are always stored left shifted in their
7745 function_arg_padding (enum machine_mode mode, const_tree type)
7747 #ifndef AGGREGATE_PADDING_FIXED
7748 #define AGGREGATE_PADDING_FIXED 0
7750 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7751 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7754 if (!AGGREGATE_PADDING_FIXED)
7756 /* GCC used to pass structures of the same size as integer types as
7757 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7758 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7759 passed padded downward, except that -mstrict-align further
7760 muddied the water in that multi-component structures of 2 and 4
7761 bytes in size were passed padded upward.
7763 The following arranges for best compatibility with previous
7764 versions of gcc, but removes the -mstrict-align dependency. */
7765 if (BYTES_BIG_ENDIAN)
7767 HOST_WIDE_INT size = 0;
7769 if (mode == BLKmode)
7771 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7772 size = int_size_in_bytes (type);
7775 size = GET_MODE_SIZE (mode);
7777 if (size == 1 || size == 2 || size == 4)
7783 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7785 if (type != 0 && AGGREGATE_TYPE_P (type))
7789 /* Fall back to the default. */
7790 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7793 /* If defined, a C expression that gives the alignment boundary, in bits,
7794 of an argument with the specified mode and type. If it is not defined,
7795 PARM_BOUNDARY is used for all arguments.
7797 V.4 wants long longs and doubles to be double word aligned. Just
7798 testing the mode size is a boneheaded way to do this as it means
7799 that other types such as complex int are also double word aligned.
7800 However, we're stuck with this because changing the ABI might break
7801 existing library interfaces.
7803 Doubleword align SPE vectors.
7804 Quadword align Altivec vectors.
7805 Quadword align large synthetic vector types. */
7808 function_arg_boundary (enum machine_mode mode, const_tree type)
7810 if (DEFAULT_ABI == ABI_V4
7811 && (GET_MODE_SIZE (mode) == 8
7812 || (TARGET_HARD_FLOAT
7814 && (mode == TFmode || mode == TDmode))))
7816 else if (SPE_VECTOR_MODE (mode)
7817 || (type && TREE_CODE (type) == VECTOR_TYPE
7818 && int_size_in_bytes (type) >= 8
7819 && int_size_in_bytes (type) < 16))
7821 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7822 || (type && TREE_CODE (type) == VECTOR_TYPE
7823 && int_size_in_bytes (type) >= 16))
7825 else if (TARGET_MACHO
7826 && rs6000_darwin64_abi
7828 && type && TYPE_ALIGN (type) > 64)
7831 return PARM_BOUNDARY;
7834 /* For a function parm of MODE and TYPE, return the starting word in
7835 the parameter area. NWORDS of the parameter area are already used. */
7838 rs6000_parm_start (enum machine_mode mode, const_tree type,
7839 unsigned int nwords)
7842 unsigned int parm_offset;
7844 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7845 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7846 return nwords + (-(parm_offset + nwords) & align);
7849 /* Compute the size (in words) of a function argument. */
7851 static unsigned long
7852 rs6000_arg_size (enum machine_mode mode, const_tree type)
7856 if (mode != BLKmode)
7857 size = GET_MODE_SIZE (mode);
7859 size = int_size_in_bytes (type);
7862 return (size + 3) >> 2;
7864 return (size + 7) >> 3;
7867 /* Use this to flush pending int fields. */
7870 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7871 HOST_WIDE_INT bitpos, int final)
7873 unsigned int startbit, endbit;
7874 int intregs, intoffset;
7875 enum machine_mode mode;
7877 /* Handle the situations where a float is taking up the first half
7878 of the GPR, and the other half is empty (typically due to
7879 alignment restrictions). We can detect this by a 8-byte-aligned
7880 int field, or by seeing that this is the final flush for this
7881 argument. Count the word and continue on. */
7882 if (cum->floats_in_gpr == 1
7883 && (cum->intoffset % 64 == 0
7884 || (cum->intoffset == -1 && final)))
7887 cum->floats_in_gpr = 0;
7890 if (cum->intoffset == -1)
7893 intoffset = cum->intoffset;
7894 cum->intoffset = -1;
7895 cum->floats_in_gpr = 0;
7897 if (intoffset % BITS_PER_WORD != 0)
7899 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7901 if (mode == BLKmode)
7903 /* We couldn't find an appropriate mode, which happens,
7904 e.g., in packed structs when there are 3 bytes to load.
7905 Back intoffset back to the beginning of the word in this
7907 intoffset = intoffset & -BITS_PER_WORD;
7911 startbit = intoffset & -BITS_PER_WORD;
7912 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7913 intregs = (endbit - startbit) / BITS_PER_WORD;
7914 cum->words += intregs;
7915 /* words should be unsigned. */
7916 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7918 int pad = (endbit/BITS_PER_WORD) - cum->words;
7923 /* The darwin64 ABI calls for us to recurse down through structs,
7924 looking for elements passed in registers. Unfortunately, we have
7925 to track int register count here also because of misalignments
7926 in powerpc alignment mode. */
7929 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7931 HOST_WIDE_INT startbitpos)
7935 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7936 if (TREE_CODE (f) == FIELD_DECL)
7938 HOST_WIDE_INT bitpos = startbitpos;
7939 tree ftype = TREE_TYPE (f);
7940 enum machine_mode mode;
7941 if (ftype == error_mark_node)
7943 mode = TYPE_MODE (ftype);
7945 if (DECL_SIZE (f) != 0
7946 && host_integerp (bit_position (f), 1))
7947 bitpos += int_bit_position (f);
7949 /* ??? FIXME: else assume zero offset. */
7951 if (TREE_CODE (ftype) == RECORD_TYPE)
7952 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7953 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7955 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7956 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7957 /* Single-precision floats present a special problem for
7958 us, because they are smaller than an 8-byte GPR, and so
7959 the structure-packing rules combined with the standard
7960 varargs behavior mean that we want to pack float/float
7961 and float/int combinations into a single register's
7962 space. This is complicated by the arg advance flushing,
7963 which works on arbitrarily large groups of int-type
7967 if (cum->floats_in_gpr == 1)
7969 /* Two floats in a word; count the word and reset
7972 cum->floats_in_gpr = 0;
7974 else if (bitpos % 64 == 0)
7976 /* A float at the beginning of an 8-byte word;
7977 count it and put off adjusting cum->words until
7978 we see if a arg advance flush is going to do it
7980 cum->floats_in_gpr++;
7984 /* The float is at the end of a word, preceded
7985 by integer fields, so the arg advance flush
7986 just above has already set cum->words and
7987 everything is taken care of. */
7991 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7993 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7995 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7999 else if (cum->intoffset == -1)
8000 cum->intoffset = bitpos;
8004 /* Check for an item that needs to be considered specially under the darwin 64
8005 bit ABI. These are record types where the mode is BLK or the structure is
8008 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8010 return rs6000_darwin64_abi
8011 && ((mode == BLKmode
8012 && TREE_CODE (type) == RECORD_TYPE
8013 && int_size_in_bytes (type) > 0)
8014 || (type && TREE_CODE (type) == RECORD_TYPE
8015 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8018 /* Update the data in CUM to advance over an argument
8019 of mode MODE and data type TYPE.
8020 (TYPE is null for libcalls where that information may not be available.)
8022 Note that for args passed by reference, function_arg will be called
8023 with MODE and TYPE set to that of the pointer to the arg, not the arg
8027 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8028 const_tree type, bool named, int depth)
8031 /* Only tick off an argument if we're not recursing. */
8033 cum->nargs_prototype--;
8035 if (TARGET_ALTIVEC_ABI
8036 && (ALTIVEC_VECTOR_MODE (mode)
8037 || VSX_VECTOR_MODE (mode)
8038 || (type && TREE_CODE (type) == VECTOR_TYPE
8039 && int_size_in_bytes (type) == 16)))
8043 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8046 if (!TARGET_ALTIVEC)
8047 error ("cannot pass argument in vector register because"
8048 " altivec instructions are disabled, use -maltivec"
8051 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8052 even if it is going to be passed in a vector register.
8053 Darwin does the same for variable-argument functions. */
8054 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8055 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8065 /* Vector parameters must be 16-byte aligned. This places
8066 them at 2 mod 4 in terms of words in 32-bit mode, since
8067 the parameter save area starts at offset 24 from the
8068 stack. In 64-bit mode, they just have to start on an
8069 even word, since the parameter save area is 16-byte
8070 aligned. Space for GPRs is reserved even if the argument
8071 will be passed in memory. */
8073 align = (2 - cum->words) & 3;
8075 align = cum->words & 1;
8076 cum->words += align + rs6000_arg_size (mode, type);
8078 if (TARGET_DEBUG_ARG)
8080 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8082 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8083 cum->nargs_prototype, cum->prototype,
8084 GET_MODE_NAME (mode));
8088 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8090 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8093 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8095 int size = int_size_in_bytes (type);
8096 /* Variable sized types have size == -1 and are
8097 treated as if consisting entirely of ints.
8098 Pad to 16 byte boundary if needed. */
8099 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8100 && (cum->words % 2) != 0)
8102 /* For varargs, we can just go up by the size of the struct. */
8104 cum->words += (size + 7) / 8;
8107 /* It is tempting to say int register count just goes up by
8108 sizeof(type)/8, but this is wrong in a case such as
8109 { int; double; int; } [powerpc alignment]. We have to
8110 grovel through the fields for these too. */
8112 cum->floats_in_gpr = 0;
8113 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8114 rs6000_darwin64_record_arg_advance_flush (cum,
8115 size * BITS_PER_UNIT, 1);
8117 if (TARGET_DEBUG_ARG)
8119 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8120 cum->words, TYPE_ALIGN (type), size);
8122 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8123 cum->nargs_prototype, cum->prototype,
8124 GET_MODE_NAME (mode));
8127 else if (DEFAULT_ABI == ABI_V4)
8129 if (TARGET_HARD_FLOAT && TARGET_FPRS
8130 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8131 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8132 || (mode == TFmode && !TARGET_IEEEQUAD)
8133 || mode == SDmode || mode == DDmode || mode == TDmode))
8135 /* _Decimal128 must use an even/odd register pair. This assumes
8136 that the register number is odd when fregno is odd. */
8137 if (mode == TDmode && (cum->fregno % 2) == 1)
8140 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8141 <= FP_ARG_V4_MAX_REG)
8142 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8145 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8146 if (mode == DFmode || mode == TFmode
8147 || mode == DDmode || mode == TDmode)
8148 cum->words += cum->words & 1;
8149 cum->words += rs6000_arg_size (mode, type);
8154 int n_words = rs6000_arg_size (mode, type);
8155 int gregno = cum->sysv_gregno;
8157 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8158 (r7,r8) or (r9,r10). As does any other 2 word item such
8159 as complex int due to a historical mistake. */
8161 gregno += (1 - gregno) & 1;
8163 /* Multi-reg args are not split between registers and stack. */
8164 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8166 /* Long long and SPE vectors are aligned on the stack.
8167 So are other 2 word items such as complex int due to
8168 a historical mistake. */
8170 cum->words += cum->words & 1;
8171 cum->words += n_words;
8174 /* Note: continuing to accumulate gregno past when we've started
8175 spilling to the stack indicates the fact that we've started
8176 spilling to the stack to expand_builtin_saveregs. */
8177 cum->sysv_gregno = gregno + n_words;
8180 if (TARGET_DEBUG_ARG)
8182 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8183 cum->words, cum->fregno);
8184 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8185 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8186 fprintf (stderr, "mode = %4s, named = %d\n",
8187 GET_MODE_NAME (mode), named);
8192 int n_words = rs6000_arg_size (mode, type);
8193 int start_words = cum->words;
8194 int align_words = rs6000_parm_start (mode, type, start_words);
8196 cum->words = align_words + n_words;
8198 if (SCALAR_FLOAT_MODE_P (mode)
8199 && TARGET_HARD_FLOAT && TARGET_FPRS)
8201 /* _Decimal128 must be passed in an even/odd float register pair.
8202 This assumes that the register number is odd when fregno is
8204 if (mode == TDmode && (cum->fregno % 2) == 1)
8206 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8209 if (TARGET_DEBUG_ARG)
8211 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8212 cum->words, cum->fregno);
8213 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8214 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8215 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8216 named, align_words - start_words, depth);
8222 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8223 const_tree type, bool named)
8225 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8229 spe_build_register_parallel (enum machine_mode mode, int gregno)
8236 r1 = gen_rtx_REG (DImode, gregno);
8237 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8238 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8242 r1 = gen_rtx_REG (DImode, gregno);
8243 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8244 r3 = gen_rtx_REG (DImode, gregno + 2);
8245 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8246 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8249 r1 = gen_rtx_REG (DImode, gregno);
8250 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8251 r3 = gen_rtx_REG (DImode, gregno + 2);
8252 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8253 r5 = gen_rtx_REG (DImode, gregno + 4);
8254 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8255 r7 = gen_rtx_REG (DImode, gregno + 6);
8256 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8257 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8264 /* Determine where to put a SIMD argument on the SPE. */
8266 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8269 int gregno = cum->sysv_gregno;
8271 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8272 are passed and returned in a pair of GPRs for ABI compatibility. */
8273 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8274 || mode == DCmode || mode == TCmode))
8276 int n_words = rs6000_arg_size (mode, type);
8278 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8280 gregno += (1 - gregno) & 1;
8282 /* Multi-reg args are not split between registers and stack. */
8283 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8286 return spe_build_register_parallel (mode, gregno);
8290 int n_words = rs6000_arg_size (mode, type);
8292 /* SPE vectors are put in odd registers. */
8293 if (n_words == 2 && (gregno & 1) == 0)
8296 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8299 enum machine_mode m = SImode;
8301 r1 = gen_rtx_REG (m, gregno);
8302 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8303 r2 = gen_rtx_REG (m, gregno + 1);
8304 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8305 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8312 if (gregno <= GP_ARG_MAX_REG)
8313 return gen_rtx_REG (mode, gregno);
8319 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8320 structure between cum->intoffset and bitpos to integer registers. */
8323 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8324 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8326 enum machine_mode mode;
8328 unsigned int startbit, endbit;
8329 int this_regno, intregs, intoffset;
8332 if (cum->intoffset == -1)
8335 intoffset = cum->intoffset;
8336 cum->intoffset = -1;
8338 /* If this is the trailing part of a word, try to only load that
8339 much into the register. Otherwise load the whole register. Note
8340 that in the latter case we may pick up unwanted bits. It's not a
8341 problem at the moment but may wish to revisit. */
8343 if (intoffset % BITS_PER_WORD != 0)
8345 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8347 if (mode == BLKmode)
8349 /* We couldn't find an appropriate mode, which happens,
8350 e.g., in packed structs when there are 3 bytes to load.
8351 Back intoffset back to the beginning of the word in this
8353 intoffset = intoffset & -BITS_PER_WORD;
8360 startbit = intoffset & -BITS_PER_WORD;
8361 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8362 intregs = (endbit - startbit) / BITS_PER_WORD;
8363 this_regno = cum->words + intoffset / BITS_PER_WORD;
8365 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8368 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8372 intoffset /= BITS_PER_UNIT;
8375 regno = GP_ARG_MIN_REG + this_regno;
8376 reg = gen_rtx_REG (mode, regno);
8378 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8381 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8385 while (intregs > 0);
8388 /* Recursive workhorse for the following. */
8391 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8392 HOST_WIDE_INT startbitpos, rtx rvec[],
8397 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8398 if (TREE_CODE (f) == FIELD_DECL)
8400 HOST_WIDE_INT bitpos = startbitpos;
8401 tree ftype = TREE_TYPE (f);
8402 enum machine_mode mode;
8403 if (ftype == error_mark_node)
8405 mode = TYPE_MODE (ftype);
8407 if (DECL_SIZE (f) != 0
8408 && host_integerp (bit_position (f), 1))
8409 bitpos += int_bit_position (f);
8411 /* ??? FIXME: else assume zero offset. */
8413 if (TREE_CODE (ftype) == RECORD_TYPE)
8414 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8415 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8420 case SCmode: mode = SFmode; break;
8421 case DCmode: mode = DFmode; break;
8422 case TCmode: mode = TFmode; break;
8426 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8428 = gen_rtx_EXPR_LIST (VOIDmode,
8429 gen_rtx_REG (mode, cum->fregno++),
8430 GEN_INT (bitpos / BITS_PER_UNIT));
8431 if (mode == TFmode || mode == TDmode)
8434 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8436 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8438 = gen_rtx_EXPR_LIST (VOIDmode,
8439 gen_rtx_REG (mode, cum->vregno++),
8440 GEN_INT (bitpos / BITS_PER_UNIT));
8442 else if (cum->intoffset == -1)
8443 cum->intoffset = bitpos;
8447 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8448 the register(s) to be used for each field and subfield of a struct
8449 being passed by value, along with the offset of where the
8450 register's value may be found in the block. FP fields go in FP
8451 register, vector fields go in vector registers, and everything
8452 else goes in int registers, packed as in memory.
8454 This code is also used for function return values. RETVAL indicates
8455 whether this is the case.
8457 Much of this is taken from the SPARC V9 port, which has a similar
8458 calling convention. */
8461 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8462 bool named, bool retval)
8464 rtx rvec[FIRST_PSEUDO_REGISTER];
8465 int k = 1, kbase = 1;
8466 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8467 /* This is a copy; modifications are not visible to our caller. */
8468 CUMULATIVE_ARGS copy_cum = *orig_cum;
8469 CUMULATIVE_ARGS *cum = ©_cum;
8471 /* Pad to 16 byte boundary if needed. */
8472 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8473 && (cum->words % 2) != 0)
8480 /* Put entries into rvec[] for individual FP and vector fields, and
8481 for the chunks of memory that go in int regs. Note we start at
8482 element 1; 0 is reserved for an indication of using memory, and
8483 may or may not be filled in below. */
8484 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8485 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8487 /* If any part of the struct went on the stack put all of it there.
8488 This hack is because the generic code for
8489 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8490 parts of the struct are not at the beginning. */
8494 return NULL_RTX; /* doesn't go in registers at all */
8496 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8498 if (k > 1 || cum->use_stack)
8499 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8504 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8507 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8512 rtx rvec[GP_ARG_NUM_REG + 1];
8514 if (align_words >= GP_ARG_NUM_REG)
8517 n_units = rs6000_arg_size (mode, type);
8519 /* Optimize the simple case where the arg fits in one gpr, except in
8520 the case of BLKmode due to assign_parms assuming that registers are
8521 BITS_PER_WORD wide. */
8523 || (n_units == 1 && mode != BLKmode))
8524 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8527 if (align_words + n_units > GP_ARG_NUM_REG)
8528 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8529 using a magic NULL_RTX component.
8530 This is not strictly correct. Only some of the arg belongs in
8531 memory, not all of it. However, the normal scheme using
8532 function_arg_partial_nregs can result in unusual subregs, eg.
8533 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8534 store the whole arg to memory is often more efficient than code
8535 to store pieces, and we know that space is available in the right
8536 place for the whole arg. */
8537 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8542 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8543 rtx off = GEN_INT (i++ * 4);
8544 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8546 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8548 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8551 /* Determine where to put an argument to a function.
8552 Value is zero to push the argument on the stack,
8553 or a hard register in which to store the argument.
8555 MODE is the argument's machine mode.
8556 TYPE is the data type of the argument (as a tree).
8557 This is null for libcalls where that information may
8559 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8560 the preceding args and about the function being called. It is
8561 not modified in this routine.
8562 NAMED is nonzero if this argument is a named parameter
8563 (otherwise it is an extra parameter matching an ellipsis).
8565 On RS/6000 the first eight words of non-FP are normally in registers
8566 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8567 Under V.4, the first 8 FP args are in registers.
8569 If this is floating-point and no prototype is specified, we use
8570 both an FP and integer register (or possibly FP reg and stack). Library
8571 functions (when CALL_LIBCALL is set) always have the proper types for args,
8572 so we can pass the FP value just in one register. emit_library_function
8573 doesn't support PARALLEL anyway.
8575 Note that for args passed by reference, function_arg will be called
8576 with MODE and TYPE set to that of the pointer to the arg, not the arg
8580 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8581 const_tree type, bool named)
8583 enum rs6000_abi abi = DEFAULT_ABI;
8585 /* Return a marker to indicate whether CR1 needs to set or clear the
8586 bit that V.4 uses to say fp args were passed in registers.
8587 Assume that we don't need the marker for software floating point,
8588 or compiler generated library calls. */
8589 if (mode == VOIDmode)
8592 && (cum->call_cookie & CALL_LIBCALL) == 0
8594 || (cum->nargs_prototype < 0
8595 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8597 /* For the SPE, we need to crxor CR6 always. */
8599 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8600 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8601 return GEN_INT (cum->call_cookie
8602 | ((cum->fregno == FP_ARG_MIN_REG)
8603 ? CALL_V4_SET_FP_ARGS
8604 : CALL_V4_CLEAR_FP_ARGS));
8607 return GEN_INT (cum->call_cookie);
8610 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8612 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8613 if (rslt != NULL_RTX)
8615 /* Else fall through to usual handling. */
8618 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8619 if (TARGET_64BIT && ! cum->prototype)
8621 /* Vector parameters get passed in vector register
8622 and also in GPRs or memory, in absence of prototype. */
8625 align_words = (cum->words + 1) & ~1;
8627 if (align_words >= GP_ARG_NUM_REG)
8633 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8635 return gen_rtx_PARALLEL (mode,
8637 gen_rtx_EXPR_LIST (VOIDmode,
8639 gen_rtx_EXPR_LIST (VOIDmode,
8640 gen_rtx_REG (mode, cum->vregno),
8644 return gen_rtx_REG (mode, cum->vregno);
8645 else if (TARGET_ALTIVEC_ABI
8646 && (ALTIVEC_VECTOR_MODE (mode)
8647 || VSX_VECTOR_MODE (mode)
8648 || (type && TREE_CODE (type) == VECTOR_TYPE
8649 && int_size_in_bytes (type) == 16)))
8651 if (named || abi == ABI_V4)
8655 /* Vector parameters to varargs functions under AIX or Darwin
8656 get passed in memory and possibly also in GPRs. */
8657 int align, align_words, n_words;
8658 enum machine_mode part_mode;
8660 /* Vector parameters must be 16-byte aligned. This places them at
8661 2 mod 4 in terms of words in 32-bit mode, since the parameter
8662 save area starts at offset 24 from the stack. In 64-bit mode,
8663 they just have to start on an even word, since the parameter
8664 save area is 16-byte aligned. */
8666 align = (2 - cum->words) & 3;
8668 align = cum->words & 1;
8669 align_words = cum->words + align;
8671 /* Out of registers? Memory, then. */
8672 if (align_words >= GP_ARG_NUM_REG)
8675 if (TARGET_32BIT && TARGET_POWERPC64)
8676 return rs6000_mixed_function_arg (mode, type, align_words);
8678 /* The vector value goes in GPRs. Only the part of the
8679 value in GPRs is reported here. */
8681 n_words = rs6000_arg_size (mode, type);
8682 if (align_words + n_words > GP_ARG_NUM_REG)
8683 /* Fortunately, there are only two possibilities, the value
8684 is either wholly in GPRs or half in GPRs and half not. */
8687 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8690 else if (TARGET_SPE_ABI && TARGET_SPE
8691 && (SPE_VECTOR_MODE (mode)
8692 || (TARGET_E500_DOUBLE && (mode == DFmode
8695 || mode == TCmode))))
8696 return rs6000_spe_function_arg (cum, mode, type);
8698 else if (abi == ABI_V4)
8700 if (TARGET_HARD_FLOAT && TARGET_FPRS
8701 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8702 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8703 || (mode == TFmode && !TARGET_IEEEQUAD)
8704 || mode == SDmode || mode == DDmode || mode == TDmode))
8706 /* _Decimal128 must use an even/odd register pair. This assumes
8707 that the register number is odd when fregno is odd. */
8708 if (mode == TDmode && (cum->fregno % 2) == 1)
8711 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8712 <= FP_ARG_V4_MAX_REG)
8713 return gen_rtx_REG (mode, cum->fregno);
8719 int n_words = rs6000_arg_size (mode, type);
8720 int gregno = cum->sysv_gregno;
8722 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8723 (r7,r8) or (r9,r10). As does any other 2 word item such
8724 as complex int due to a historical mistake. */
8726 gregno += (1 - gregno) & 1;
8728 /* Multi-reg args are not split between registers and stack. */
8729 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8732 if (TARGET_32BIT && TARGET_POWERPC64)
8733 return rs6000_mixed_function_arg (mode, type,
8734 gregno - GP_ARG_MIN_REG);
8735 return gen_rtx_REG (mode, gregno);
8740 int align_words = rs6000_parm_start (mode, type, cum->words);
8742 /* _Decimal128 must be passed in an even/odd float register pair.
8743 This assumes that the register number is odd when fregno is odd. */
8744 if (mode == TDmode && (cum->fregno % 2) == 1)
8747 if (USE_FP_FOR_ARG_P (cum, mode, type))
8749 rtx rvec[GP_ARG_NUM_REG + 1];
8753 enum machine_mode fmode = mode;
8754 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8756 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8758 /* Currently, we only ever need one reg here because complex
8759 doubles are split. */
8760 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8761 && (fmode == TFmode || fmode == TDmode));
8763 /* Long double or _Decimal128 split over regs and memory. */
8764 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8767 /* Do we also need to pass this arg in the parameter save
8770 && (cum->nargs_prototype <= 0
8771 || (DEFAULT_ABI == ABI_AIX
8773 && align_words >= GP_ARG_NUM_REG)));
8775 if (!needs_psave && mode == fmode)
8776 return gen_rtx_REG (fmode, cum->fregno);
8781 /* Describe the part that goes in gprs or the stack.
8782 This piece must come first, before the fprs. */
8783 if (align_words < GP_ARG_NUM_REG)
8785 unsigned long n_words = rs6000_arg_size (mode, type);
8787 if (align_words + n_words > GP_ARG_NUM_REG
8788 || (TARGET_32BIT && TARGET_POWERPC64))
8790 /* If this is partially on the stack, then we only
8791 include the portion actually in registers here. */
8792 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8795 if (align_words + n_words > GP_ARG_NUM_REG)
8796 /* Not all of the arg fits in gprs. Say that it
8797 goes in memory too, using a magic NULL_RTX
8798 component. Also see comment in
8799 rs6000_mixed_function_arg for why the normal
8800 function_arg_partial_nregs scheme doesn't work
8802 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8806 r = gen_rtx_REG (rmode,
8807 GP_ARG_MIN_REG + align_words);
8808 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8809 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8811 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8815 /* The whole arg fits in gprs. */
8816 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8817 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8821 /* It's entirely in memory. */
8822 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8825 /* Describe where this piece goes in the fprs. */
8826 r = gen_rtx_REG (fmode, cum->fregno);
8827 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8829 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8831 else if (align_words < GP_ARG_NUM_REG)
8833 if (TARGET_32BIT && TARGET_POWERPC64)
8834 return rs6000_mixed_function_arg (mode, type, align_words);
8836 if (mode == BLKmode)
8839 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8846 /* For an arg passed partly in registers and partly in memory, this is
8847 the number of bytes passed in registers. For args passed entirely in
8848 registers or entirely in memory, zero. When an arg is described by a
8849 PARALLEL, perhaps using more than one register type, this function
8850 returns the number of bytes used by the first element of the PARALLEL. */
8853 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8854 tree type, bool named)
8859 if (DEFAULT_ABI == ABI_V4)
8862 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8863 && cum->nargs_prototype >= 0)
8866 /* In this complicated case we just disable the partial_nregs code. */
8867 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8870 align_words = rs6000_parm_start (mode, type, cum->words);
8872 if (USE_FP_FOR_ARG_P (cum, mode, type))
8874 /* If we are passing this arg in the fixed parameter save area
8875 (gprs or memory) as well as fprs, then this function should
8876 return the number of partial bytes passed in the parameter
8877 save area rather than partial bytes passed in fprs. */
8879 && (cum->nargs_prototype <= 0
8880 || (DEFAULT_ABI == ABI_AIX
8882 && align_words >= GP_ARG_NUM_REG)))
8884 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8885 > FP_ARG_MAX_REG + 1)
8886 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8887 else if (cum->nargs_prototype >= 0)
8891 if (align_words < GP_ARG_NUM_REG
8892 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8893 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8895 if (ret != 0 && TARGET_DEBUG_ARG)
8896 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8901 /* A C expression that indicates when an argument must be passed by
8902 reference. If nonzero for an argument, a copy of that argument is
8903 made in memory and a pointer to the argument is passed instead of
8904 the argument itself. The pointer is passed in whatever way is
8905 appropriate for passing a pointer to that type.
8907 Under V.4, aggregates and long double are passed by reference.
8909 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8910 reference unless the AltiVec vector extension ABI is in force.
8912 As an extension to all ABIs, variable sized types are passed by
8916 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8917 enum machine_mode mode, const_tree type,
8918 bool named ATTRIBUTE_UNUSED)
8920 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8922 if (TARGET_DEBUG_ARG)
8923 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8930 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8932 if (TARGET_DEBUG_ARG)
8933 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8937 if (int_size_in_bytes (type) < 0)
8939 if (TARGET_DEBUG_ARG)
8940 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8944 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8945 modes only exist for GCC vector types if -maltivec. */
8946 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8948 if (TARGET_DEBUG_ARG)
8949 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8953 /* Pass synthetic vectors in memory. */
8954 if (TREE_CODE (type) == VECTOR_TYPE
8955 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8957 static bool warned_for_pass_big_vectors = false;
8958 if (TARGET_DEBUG_ARG)
8959 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8960 if (!warned_for_pass_big_vectors)
8962 warning (0, "GCC vector passed by reference: "
8963 "non-standard ABI extension with no compatibility guarantee");
8964 warned_for_pass_big_vectors = true;
8973 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8976 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8981 for (i = 0; i < nregs; i++)
8983 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8984 if (reload_completed)
8986 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8989 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8990 i * GET_MODE_SIZE (reg_mode));
8993 tem = replace_equiv_address (tem, XEXP (tem, 0));
8997 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9001 /* Perform any needed actions needed for a function that is receiving a
9002 variable number of arguments.
9006 MODE and TYPE are the mode and type of the current parameter.
9008 PRETEND_SIZE is a variable that should be set to the amount of stack
9009 that must be pushed by the prolog to pretend that our caller pushed
9012 Normally, this macro will push all remaining incoming registers on the
9013 stack and set PRETEND_SIZE to the length of the registers pushed. */
9016 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9017 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9020 CUMULATIVE_ARGS next_cum;
9021 int reg_size = TARGET_32BIT ? 4 : 8;
9022 rtx save_area = NULL_RTX, mem;
9023 int first_reg_offset;
9026 /* Skip the last named argument. */
9028 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9030 if (DEFAULT_ABI == ABI_V4)
9032 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9036 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9037 HOST_WIDE_INT offset = 0;
9039 /* Try to optimize the size of the varargs save area.
9040 The ABI requires that ap.reg_save_area is doubleword
9041 aligned, but we don't need to allocate space for all
9042 the bytes, only those to which we actually will save
9044 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9045 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9046 if (TARGET_HARD_FLOAT && TARGET_FPRS
9047 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9048 && cfun->va_list_fpr_size)
9051 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9052 * UNITS_PER_FP_WORD;
9053 if (cfun->va_list_fpr_size
9054 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9055 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9057 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9058 * UNITS_PER_FP_WORD;
9062 offset = -((first_reg_offset * reg_size) & ~7);
9063 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9065 gpr_reg_num = cfun->va_list_gpr_size;
9066 if (reg_size == 4 && (first_reg_offset & 1))
9069 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9072 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9074 - (int) (GP_ARG_NUM_REG * reg_size);
9076 if (gpr_size + fpr_size)
9079 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9080 gcc_assert (GET_CODE (reg_save_area) == MEM);
9081 reg_save_area = XEXP (reg_save_area, 0);
9082 if (GET_CODE (reg_save_area) == PLUS)
9084 gcc_assert (XEXP (reg_save_area, 0)
9085 == virtual_stack_vars_rtx);
9086 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9087 offset += INTVAL (XEXP (reg_save_area, 1));
9090 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9093 cfun->machine->varargs_save_offset = offset;
9094 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9099 first_reg_offset = next_cum.words;
9100 save_area = virtual_incoming_args_rtx;
9102 if (targetm.calls.must_pass_in_stack (mode, type))
9103 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9106 set = get_varargs_alias_set ();
9107 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9108 && cfun->va_list_gpr_size)
9110 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9112 if (va_list_gpr_counter_field)
9114 /* V4 va_list_gpr_size counts number of registers needed. */
9115 if (nregs > cfun->va_list_gpr_size)
9116 nregs = cfun->va_list_gpr_size;
9120 /* char * va_list instead counts number of bytes needed. */
9121 if (nregs > cfun->va_list_gpr_size / reg_size)
9122 nregs = cfun->va_list_gpr_size / reg_size;
9125 mem = gen_rtx_MEM (BLKmode,
9126 plus_constant (save_area,
9127 first_reg_offset * reg_size));
9128 MEM_NOTRAP_P (mem) = 1;
9129 set_mem_alias_set (mem, set);
9130 set_mem_align (mem, BITS_PER_WORD);
9132 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9136 /* Save FP registers if needed. */
9137 if (DEFAULT_ABI == ABI_V4
9138 && TARGET_HARD_FLOAT && TARGET_FPRS
9140 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9141 && cfun->va_list_fpr_size)
9143 int fregno = next_cum.fregno, nregs;
9144 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9145 rtx lab = gen_label_rtx ();
9146 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9147 * UNITS_PER_FP_WORD);
9150 (gen_rtx_SET (VOIDmode,
9152 gen_rtx_IF_THEN_ELSE (VOIDmode,
9153 gen_rtx_NE (VOIDmode, cr1,
9155 gen_rtx_LABEL_REF (VOIDmode, lab),
9159 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9160 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9162 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9164 plus_constant (save_area, off));
9165 MEM_NOTRAP_P (mem) = 1;
9166 set_mem_alias_set (mem, set);
9167 set_mem_align (mem, GET_MODE_ALIGNMENT (
9168 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9169 ? DFmode : SFmode));
9170 emit_move_insn (mem, gen_rtx_REG (
9171 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9172 ? DFmode : SFmode, fregno));
9179 /* Create the va_list data type. */
9182 rs6000_build_builtin_va_list (void)
9184 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9186 /* For AIX, prefer 'char *' because that's what the system
9187 header files like. */
9188 if (DEFAULT_ABI != ABI_V4)
9189 return build_pointer_type (char_type_node);
9191 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9192 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9193 get_identifier ("__va_list_tag"), record);
9195 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9196 unsigned_char_type_node);
9197 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9198 unsigned_char_type_node);
9199 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9201 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9202 get_identifier ("reserved"), short_unsigned_type_node);
9203 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9204 get_identifier ("overflow_arg_area"),
9206 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9207 get_identifier ("reg_save_area"),
9210 va_list_gpr_counter_field = f_gpr;
9211 va_list_fpr_counter_field = f_fpr;
9213 DECL_FIELD_CONTEXT (f_gpr) = record;
9214 DECL_FIELD_CONTEXT (f_fpr) = record;
9215 DECL_FIELD_CONTEXT (f_res) = record;
9216 DECL_FIELD_CONTEXT (f_ovf) = record;
9217 DECL_FIELD_CONTEXT (f_sav) = record;
9219 TYPE_STUB_DECL (record) = type_decl;
9220 TYPE_NAME (record) = type_decl;
9221 TYPE_FIELDS (record) = f_gpr;
9222 DECL_CHAIN (f_gpr) = f_fpr;
9223 DECL_CHAIN (f_fpr) = f_res;
9224 DECL_CHAIN (f_res) = f_ovf;
9225 DECL_CHAIN (f_ovf) = f_sav;
9227 layout_type (record);
9229 /* The correct type is an array type of one element. */
9230 return build_array_type (record, build_index_type (size_zero_node));
9233 /* Implement va_start. */
9236 rs6000_va_start (tree valist, rtx nextarg)
9238 HOST_WIDE_INT words, n_gpr, n_fpr;
9239 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9240 tree gpr, fpr, ovf, sav, t;
9242 /* Only SVR4 needs something special. */
9243 if (DEFAULT_ABI != ABI_V4)
9245 std_expand_builtin_va_start (valist, nextarg);
9249 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9250 f_fpr = DECL_CHAIN (f_gpr);
9251 f_res = DECL_CHAIN (f_fpr);
9252 f_ovf = DECL_CHAIN (f_res);
9253 f_sav = DECL_CHAIN (f_ovf);
9255 valist = build_va_arg_indirect_ref (valist);
9256 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9257 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9259 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9261 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9264 /* Count number of gp and fp argument registers used. */
9265 words = crtl->args.info.words;
9266 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9268 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9271 if (TARGET_DEBUG_ARG)
9272 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9273 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9274 words, n_gpr, n_fpr);
9276 if (cfun->va_list_gpr_size)
9278 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9279 build_int_cst (NULL_TREE, n_gpr));
9280 TREE_SIDE_EFFECTS (t) = 1;
9281 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9284 if (cfun->va_list_fpr_size)
9286 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9287 build_int_cst (NULL_TREE, n_fpr));
9288 TREE_SIDE_EFFECTS (t) = 1;
9289 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9292 /* Find the overflow area. */
9293 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9295 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9296 size_int (words * UNITS_PER_WORD));
9297 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9298 TREE_SIDE_EFFECTS (t) = 1;
9299 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9301 /* If there were no va_arg invocations, don't set up the register
9303 if (!cfun->va_list_gpr_size
9304 && !cfun->va_list_fpr_size
9305 && n_gpr < GP_ARG_NUM_REG
9306 && n_fpr < FP_ARG_V4_MAX_REG)
9309 /* Find the register save area. */
9310 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9311 if (cfun->machine->varargs_save_offset)
9312 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9313 size_int (cfun->machine->varargs_save_offset));
9314 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9315 TREE_SIDE_EFFECTS (t) = 1;
9316 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9319 /* Implement va_arg. */
9322 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9325 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9326 tree gpr, fpr, ovf, sav, reg, t, u;
9327 int size, rsize, n_reg, sav_ofs, sav_scale;
9328 tree lab_false, lab_over, addr;
9330 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9334 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9336 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9337 return build_va_arg_indirect_ref (t);
9340 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9341 earlier version of gcc, with the property that it always applied alignment
9342 adjustments to the va-args (even for zero-sized types). The cheapest way
9343 to deal with this is to replicate the effect of the part of
9344 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9346 We don't need to check for pass-by-reference because of the test above.
9347 We can return a simplifed answer, since we know there's no offset to add. */
9350 && rs6000_darwin64_abi
9351 && integer_zerop (TYPE_SIZE (type)))
9353 unsigned HOST_WIDE_INT align, boundary;
9354 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9355 align = PARM_BOUNDARY / BITS_PER_UNIT;
9356 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9357 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9358 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9359 boundary /= BITS_PER_UNIT;
9360 if (boundary > align)
9363 /* This updates arg ptr by the amount that would be necessary
9364 to align the zero-sized (but not zero-alignment) item. */
9365 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9366 fold_build2 (POINTER_PLUS_EXPR,
9368 valist_tmp, size_int (boundary - 1)));
9369 gimplify_and_add (t, pre_p);
9371 t = fold_convert (sizetype, valist_tmp);
9372 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9373 fold_convert (TREE_TYPE (valist),
9374 fold_build2 (BIT_AND_EXPR, sizetype, t,
9375 size_int (-boundary))));
9376 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9377 gimplify_and_add (t, pre_p);
9379 /* Since it is zero-sized there's no increment for the item itself. */
9380 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9381 return build_va_arg_indirect_ref (valist_tmp);
9384 if (DEFAULT_ABI != ABI_V4)
9386 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9388 tree elem_type = TREE_TYPE (type);
9389 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9390 int elem_size = GET_MODE_SIZE (elem_mode);
9392 if (elem_size < UNITS_PER_WORD)
9394 tree real_part, imag_part;
9395 gimple_seq post = NULL;
9397 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9399 /* Copy the value into a temporary, lest the formal temporary
9400 be reused out from under us. */
9401 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9402 gimple_seq_add_seq (pre_p, post);
9404 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9407 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9411 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9414 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9415 f_fpr = DECL_CHAIN (f_gpr);
9416 f_res = DECL_CHAIN (f_fpr);
9417 f_ovf = DECL_CHAIN (f_res);
9418 f_sav = DECL_CHAIN (f_ovf);
9420 valist = build_va_arg_indirect_ref (valist);
9421 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9422 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9424 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9426 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9429 size = int_size_in_bytes (type);
9430 rsize = (size + 3) / 4;
9433 if (TARGET_HARD_FLOAT && TARGET_FPRS
9434 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9435 || (TARGET_DOUBLE_FLOAT
9436 && (TYPE_MODE (type) == DFmode
9437 || TYPE_MODE (type) == TFmode
9438 || TYPE_MODE (type) == SDmode
9439 || TYPE_MODE (type) == DDmode
9440 || TYPE_MODE (type) == TDmode))))
9442 /* FP args go in FP registers, if present. */
9444 n_reg = (size + 7) / 8;
9445 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9446 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9447 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9452 /* Otherwise into GP registers. */
9461 /* Pull the value out of the saved registers.... */
9464 addr = create_tmp_var (ptr_type_node, "addr");
9466 /* AltiVec vectors never go in registers when -mabi=altivec. */
9467 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9471 lab_false = create_artificial_label (input_location);
9472 lab_over = create_artificial_label (input_location);
9474 /* Long long and SPE vectors are aligned in the registers.
9475 As are any other 2 gpr item such as complex int due to a
9476 historical mistake. */
9478 if (n_reg == 2 && reg == gpr)
9481 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9482 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9483 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9484 unshare_expr (reg), u);
9486 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9487 reg number is 0 for f1, so we want to make it odd. */
9488 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9490 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9491 build_int_cst (TREE_TYPE (reg), 1));
9492 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9495 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9496 t = build2 (GE_EXPR, boolean_type_node, u, t);
9497 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9498 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9499 gimplify_and_add (t, pre_p);
9503 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9505 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9506 build_int_cst (TREE_TYPE (reg), n_reg));
9507 u = fold_convert (sizetype, u);
9508 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9509 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9511 /* _Decimal32 varargs are located in the second word of the 64-bit
9512 FP register for 32-bit binaries. */
9513 if (!TARGET_POWERPC64
9514 && TARGET_HARD_FLOAT && TARGET_FPRS
9515 && TYPE_MODE (type) == SDmode)
9516 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9518 gimplify_assign (addr, t, pre_p);
9520 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9522 stmt = gimple_build_label (lab_false);
9523 gimple_seq_add_stmt (pre_p, stmt);
9525 if ((n_reg == 2 && !regalign) || n_reg > 2)
9527 /* Ensure that we don't find any more args in regs.
9528 Alignment has taken care of for special cases. */
9529 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9533 /* ... otherwise out of the overflow area. */
9535 /* Care for on-stack alignment if needed. */
9539 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9540 t = fold_convert (sizetype, t);
9541 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9543 t = fold_convert (TREE_TYPE (ovf), t);
9545 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9547 gimplify_assign (unshare_expr (addr), t, pre_p);
9549 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9550 gimplify_assign (unshare_expr (ovf), t, pre_p);
9554 stmt = gimple_build_label (lab_over);
9555 gimple_seq_add_stmt (pre_p, stmt);
9558 if (STRICT_ALIGNMENT
9559 && (TYPE_ALIGN (type)
9560 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9562 /* The value (of type complex double, for example) may not be
9563 aligned in memory in the saved registers, so copy via a
9564 temporary. (This is the same code as used for SPARC.) */
9565 tree tmp = create_tmp_var (type, "va_arg_tmp");
9566 tree dest_addr = build_fold_addr_expr (tmp);
9568 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9569 3, dest_addr, addr, size_int (rsize * 4));
9571 gimplify_and_add (copy, pre_p);
9575 addr = fold_convert (ptrtype, addr);
9576 return build_va_arg_indirect_ref (addr);
9582 def_builtin (int mask, const char *name, tree type, int code)
9584 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9587 if (rs6000_builtin_decls[code])
9588 fatal_error ("internal error: builtin function to %s already processed.",
9591 rs6000_builtin_decls[code] = t =
9592 add_builtin_function (name, type, code, BUILT_IN_MD,
9595 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9596 switch (builtin_classify[code])
9601 /* assume builtin can do anything. */
9602 case RS6000_BTC_MISC:
9605 /* const function, function only depends on the inputs. */
9606 case RS6000_BTC_CONST:
9607 TREE_READONLY (t) = 1;
9608 TREE_NOTHROW (t) = 1;
9611 /* pure function, function can read global memory. */
9612 case RS6000_BTC_PURE:
9613 DECL_PURE_P (t) = 1;
9614 TREE_NOTHROW (t) = 1;
9617 /* Function is a math function. If rounding mode is on, then treat
9618 the function as not reading global memory, but it can have
9619 arbitrary side effects. If it is off, then assume the function is
9620 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9621 attribute in builtin-attribute.def that is used for the math
9623 case RS6000_BTC_FP_PURE:
9624 TREE_NOTHROW (t) = 1;
9625 if (flag_rounding_math)
9627 DECL_PURE_P (t) = 1;
9628 DECL_IS_NOVOPS (t) = 1;
9631 TREE_READONLY (t) = 1;
9637 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9639 static const struct builtin_description bdesc_3arg[] =
9641 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9642 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9643 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9644 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9645 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9646 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9647 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9648 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9649 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9650 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9651 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9652 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9653 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9654 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9655 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9656 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9657 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9658 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9659 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9660 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9661 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9662 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9663 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9664 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9665 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9666 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9667 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9668 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9669 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9670 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9671 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9672 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9673 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9674 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9675 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9677 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9678 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9679 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9680 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9681 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9682 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9683 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9684 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9685 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9686 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9687 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9688 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9689 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9690 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9691 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9693 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9694 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9695 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9696 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9698 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9699 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9700 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9701 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9703 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9704 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9706 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9707 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9708 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9709 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9710 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9711 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9712 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9713 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9714 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9715 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9717 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9718 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9719 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9720 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9721 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9722 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9723 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9724 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9725 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9726 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9728 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9729 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9730 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9731 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9732 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9733 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9734 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9735 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9736 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9738 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9739 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9740 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9741 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9742 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9743 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9744 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9746 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9747 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9748 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9749 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9750 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9751 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9752 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9753 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9754 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9757 /* DST operations: void foo (void *, const int, const char). */
9759 static const struct builtin_description bdesc_dst[] =
9761 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9762 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9763 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9764 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9766 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9767 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9768 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9769 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9772 /* Simple binary operations: VECc = foo (VECa, VECb). */
9774 static struct builtin_description bdesc_2arg[] =
9776 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9777 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9778 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9779 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9780 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9781 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9782 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9783 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9784 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9785 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9786 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9787 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9788 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9789 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9790 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9791 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9792 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9793 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9794 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9795 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9796 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9797 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9798 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9799 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9800 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9801 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9802 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9803 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9804 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9805 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9806 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9807 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9808 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9809 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9810 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9811 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9812 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9813 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9814 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9815 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9816 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9817 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9818 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9819 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9820 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9821 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9822 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9823 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9824 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9825 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9826 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9827 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9828 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9829 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9830 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9831 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9832 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9833 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9834 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9835 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9836 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9837 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9838 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9839 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9840 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9841 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9842 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9843 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9844 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9845 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9846 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9847 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9848 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9849 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9850 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9851 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9852 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9853 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9854 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9855 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9856 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9857 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9858 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9859 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9860 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9861 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9862 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9863 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9864 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9865 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9866 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9867 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9868 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9869 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9870 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9871 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9872 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9873 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9874 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9875 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9876 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9877 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9878 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9879 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9880 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9881 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9882 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9883 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9884 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9885 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9886 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9887 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9888 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9889 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9890 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9891 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9892 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9894 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9895 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9896 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9897 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9898 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9899 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9900 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9901 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9902 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9903 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9904 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9905 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9907 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9908 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9909 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9910 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9911 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9912 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9913 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9914 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9915 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9916 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9917 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9918 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9920 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9921 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9922 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9923 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9924 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9925 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9927 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9928 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9929 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9930 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9931 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9932 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9933 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9934 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9935 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9936 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9937 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9938 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9940 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9941 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9942 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9943 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9944 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9945 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9946 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9947 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9948 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9949 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9950 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9951 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9952 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9953 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9954 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9955 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9956 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9957 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9958 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9959 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9960 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9961 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9962 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9963 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9964 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9965 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9966 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9967 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9968 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9969 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9970 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9971 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9972 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9973 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9974 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9975 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9976 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9977 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9978 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9979 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9980 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9981 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9996 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9997 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10014 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10015 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10049 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10050 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10068 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10070 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10071 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10073 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10074 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10075 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10076 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10077 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10078 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10079 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10080 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10081 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10082 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10084 /* Place holder, leave as first spe builtin. */
10085 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10086 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10087 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10088 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10089 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10090 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10091 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10092 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10093 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10094 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10095 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10096 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10097 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10098 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10099 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10100 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10101 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10102 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10103 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10104 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10105 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10106 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10107 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10108 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10109 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10110 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10111 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10112 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10113 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10114 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10115 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10116 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10117 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10118 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10119 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10120 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10121 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10122 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10123 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10124 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10125 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10126 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10127 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10128 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10129 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10130 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10131 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10132 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10133 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10134 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10135 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10136 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10137 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10138 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10139 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10140 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10141 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10142 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10143 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10144 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10145 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10146 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10147 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10148 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10149 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10150 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10151 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10152 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10153 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10154 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10155 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10156 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10157 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10158 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10159 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10160 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10161 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10162 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10163 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10164 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10165 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10166 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10167 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10168 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10169 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10170 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10171 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10172 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10173 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10174 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10175 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10176 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10177 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10178 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10179 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10180 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10181 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10182 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10183 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10184 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10185 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10186 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10187 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10188 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10189 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10190 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10191 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10192 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10193 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10195 /* SPE binary operations expecting a 5-bit unsigned literal. */
10196 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10198 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10199 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10200 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10201 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10202 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10203 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10204 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10205 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10206 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10207 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10208 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10209 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10210 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10211 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10212 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10213 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10214 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10215 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10216 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10217 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10218 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10219 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10220 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10221 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10222 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10223 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10225 /* Place-holder. Leave as last binary SPE builtin. */
10226 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10229 /* AltiVec predicates. */
10231 struct builtin_description_predicates
10233 const unsigned int mask;
10234 const enum insn_code icode;
10235 const char *const name;
10236 const enum rs6000_builtins code;
10239 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10241 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10242 ALTIVEC_BUILTIN_VCMPBFP_P },
10243 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10244 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10245 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10246 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10247 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10248 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10249 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10250 ALTIVEC_BUILTIN_VCMPEQUW_P },
10251 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10252 ALTIVEC_BUILTIN_VCMPGTSW_P },
10253 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10254 ALTIVEC_BUILTIN_VCMPGTUW_P },
10255 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10256 ALTIVEC_BUILTIN_VCMPEQUH_P },
10257 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10258 ALTIVEC_BUILTIN_VCMPGTSH_P },
10259 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10260 ALTIVEC_BUILTIN_VCMPGTUH_P },
10261 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10262 ALTIVEC_BUILTIN_VCMPEQUB_P },
10263 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10264 ALTIVEC_BUILTIN_VCMPGTSB_P },
10265 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10266 ALTIVEC_BUILTIN_VCMPGTUB_P },
10268 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10269 VSX_BUILTIN_XVCMPEQSP_P },
10270 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10271 VSX_BUILTIN_XVCMPGESP_P },
10272 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10273 VSX_BUILTIN_XVCMPGTSP_P },
10274 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10275 VSX_BUILTIN_XVCMPEQDP_P },
10276 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10277 VSX_BUILTIN_XVCMPGEDP_P },
10278 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10279 VSX_BUILTIN_XVCMPGTDP_P },
10281 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10282 ALTIVEC_BUILTIN_VCMPEQ_P },
10283 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10284 ALTIVEC_BUILTIN_VCMPGT_P },
10285 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10286 ALTIVEC_BUILTIN_VCMPGE_P }
10289 /* SPE predicates. */
10290 static struct builtin_description bdesc_spe_predicates[] =
10292 /* Place-holder. Leave as first. */
10293 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10294 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10295 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10296 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10297 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10298 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10299 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10300 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10301 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10302 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10303 /* Place-holder. Leave as last. */
10304 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10307 /* SPE evsel predicates. */
10308 static struct builtin_description bdesc_spe_evsel[] =
10310 /* Place-holder. Leave as first. */
10311 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10312 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10313 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10314 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10315 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10316 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10317 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10318 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10319 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10320 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10321 /* Place-holder. Leave as last. */
10322 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10325 /* PAIRED predicates. */
10326 static const struct builtin_description bdesc_paired_preds[] =
10328 /* Place-holder. Leave as first. */
10329 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10330 /* Place-holder. Leave as last. */
10331 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10334 /* ABS* operations. */
10336 static const struct builtin_description bdesc_abs[] =
10338 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10339 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10340 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10341 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10342 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10343 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10344 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10345 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10346 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10347 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10348 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10351 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10354 static struct builtin_description bdesc_1arg[] =
10356 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10357 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10358 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10359 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10360 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10361 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10362 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10363 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10364 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10365 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10366 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10367 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10368 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10369 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10370 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10371 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10372 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10373 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10375 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10376 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10377 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10378 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10379 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10380 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10381 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10383 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10384 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10385 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10386 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10387 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10388 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10389 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10391 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10392 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10393 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10394 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10395 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10396 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10398 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10399 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10400 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10401 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10402 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10403 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10405 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10406 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10407 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10408 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10410 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10411 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10412 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10413 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10414 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10415 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10416 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10417 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10418 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10420 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10421 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10422 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10423 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10424 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10425 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10426 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10427 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10428 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10430 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10431 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10432 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10433 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10434 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10457 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10458 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10459 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10461 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10462 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10463 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10464 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10466 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10467 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10468 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10469 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10470 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10471 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10472 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10473 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10474 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10475 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10476 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10477 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10478 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10479 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10480 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10481 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10482 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10483 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10484 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10485 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10486 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10487 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10488 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10489 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10490 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10491 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10492 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10493 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10494 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10495 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10497 /* Place-holder. Leave as last unary SPE builtin. */
10498 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10500 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10501 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10502 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10503 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10504 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10508 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10511 tree arg0 = CALL_EXPR_ARG (exp, 0);
10512 rtx op0 = expand_normal (arg0);
10513 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10514 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10516 if (icode == CODE_FOR_nothing)
10517 /* Builtin not supported on this processor. */
10520 /* If we got invalid arguments bail out before generating bad rtl. */
10521 if (arg0 == error_mark_node)
10524 if (icode == CODE_FOR_altivec_vspltisb
10525 || icode == CODE_FOR_altivec_vspltish
10526 || icode == CODE_FOR_altivec_vspltisw
10527 || icode == CODE_FOR_spe_evsplatfi
10528 || icode == CODE_FOR_spe_evsplati)
10530 /* Only allow 5-bit *signed* literals. */
10531 if (GET_CODE (op0) != CONST_INT
10532 || INTVAL (op0) > 15
10533 || INTVAL (op0) < -16)
10535 error ("argument 1 must be a 5-bit signed literal");
10541 || GET_MODE (target) != tmode
10542 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10543 target = gen_reg_rtx (tmode);
10545 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10546 op0 = copy_to_mode_reg (mode0, op0);
10548 pat = GEN_FCN (icode) (target, op0);
10557 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10559 rtx pat, scratch1, scratch2;
10560 tree arg0 = CALL_EXPR_ARG (exp, 0);
10561 rtx op0 = expand_normal (arg0);
10562 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10563 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10565 /* If we have invalid arguments, bail out before generating bad rtl. */
10566 if (arg0 == error_mark_node)
10570 || GET_MODE (target) != tmode
10571 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10572 target = gen_reg_rtx (tmode);
10574 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10575 op0 = copy_to_mode_reg (mode0, op0);
10577 scratch1 = gen_reg_rtx (mode0);
10578 scratch2 = gen_reg_rtx (mode0);
10580 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10589 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10592 tree arg0 = CALL_EXPR_ARG (exp, 0);
10593 tree arg1 = CALL_EXPR_ARG (exp, 1);
10594 rtx op0 = expand_normal (arg0);
10595 rtx op1 = expand_normal (arg1);
10596 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10597 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10598 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10600 if (icode == CODE_FOR_nothing)
10601 /* Builtin not supported on this processor. */
10604 /* If we got invalid arguments bail out before generating bad rtl. */
10605 if (arg0 == error_mark_node || arg1 == error_mark_node)
10608 if (icode == CODE_FOR_altivec_vcfux
10609 || icode == CODE_FOR_altivec_vcfsx
10610 || icode == CODE_FOR_altivec_vctsxs
10611 || icode == CODE_FOR_altivec_vctuxs
10612 || icode == CODE_FOR_altivec_vspltb
10613 || icode == CODE_FOR_altivec_vsplth
10614 || icode == CODE_FOR_altivec_vspltw
10615 || icode == CODE_FOR_spe_evaddiw
10616 || icode == CODE_FOR_spe_evldd
10617 || icode == CODE_FOR_spe_evldh
10618 || icode == CODE_FOR_spe_evldw
10619 || icode == CODE_FOR_spe_evlhhesplat
10620 || icode == CODE_FOR_spe_evlhhossplat
10621 || icode == CODE_FOR_spe_evlhhousplat
10622 || icode == CODE_FOR_spe_evlwhe
10623 || icode == CODE_FOR_spe_evlwhos
10624 || icode == CODE_FOR_spe_evlwhou
10625 || icode == CODE_FOR_spe_evlwhsplat
10626 || icode == CODE_FOR_spe_evlwwsplat
10627 || icode == CODE_FOR_spe_evrlwi
10628 || icode == CODE_FOR_spe_evslwi
10629 || icode == CODE_FOR_spe_evsrwis
10630 || icode == CODE_FOR_spe_evsubifw
10631 || icode == CODE_FOR_spe_evsrwiu)
10633 /* Only allow 5-bit unsigned literals. */
10635 if (TREE_CODE (arg1) != INTEGER_CST
10636 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10638 error ("argument 2 must be a 5-bit unsigned literal");
10644 || GET_MODE (target) != tmode
10645 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10646 target = gen_reg_rtx (tmode);
10648 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10649 op0 = copy_to_mode_reg (mode0, op0);
10650 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10651 op1 = copy_to_mode_reg (mode1, op1);
10653 pat = GEN_FCN (icode) (target, op0, op1);
10662 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10665 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10666 tree arg0 = CALL_EXPR_ARG (exp, 1);
10667 tree arg1 = CALL_EXPR_ARG (exp, 2);
10668 rtx op0 = expand_normal (arg0);
10669 rtx op1 = expand_normal (arg1);
10670 enum machine_mode tmode = SImode;
10671 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10672 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10675 if (TREE_CODE (cr6_form) != INTEGER_CST)
10677 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10681 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10683 gcc_assert (mode0 == mode1);
10685 /* If we have invalid arguments, bail out before generating bad rtl. */
10686 if (arg0 == error_mark_node || arg1 == error_mark_node)
10690 || GET_MODE (target) != tmode
10691 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10692 target = gen_reg_rtx (tmode);
10694 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10695 op0 = copy_to_mode_reg (mode0, op0);
10696 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10697 op1 = copy_to_mode_reg (mode1, op1);
10699 scratch = gen_reg_rtx (mode0);
10701 pat = GEN_FCN (icode) (scratch, op0, op1);
10706 /* The vec_any* and vec_all* predicates use the same opcodes for two
10707 different operations, but the bits in CR6 will be different
10708 depending on what information we want. So we have to play tricks
10709 with CR6 to get the right bits out.
10711 If you think this is disgusting, look at the specs for the
10712 AltiVec predicates. */
10714 switch (cr6_form_int)
10717 emit_insn (gen_cr6_test_for_zero (target));
10720 emit_insn (gen_cr6_test_for_zero_reverse (target));
10723 emit_insn (gen_cr6_test_for_lt (target));
10726 emit_insn (gen_cr6_test_for_lt_reverse (target));
10729 error ("argument 1 of __builtin_altivec_predicate is out of range");
10737 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10740 tree arg0 = CALL_EXPR_ARG (exp, 0);
10741 tree arg1 = CALL_EXPR_ARG (exp, 1);
10742 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10743 enum machine_mode mode0 = Pmode;
10744 enum machine_mode mode1 = Pmode;
10745 rtx op0 = expand_normal (arg0);
10746 rtx op1 = expand_normal (arg1);
10748 if (icode == CODE_FOR_nothing)
10749 /* Builtin not supported on this processor. */
10752 /* If we got invalid arguments bail out before generating bad rtl. */
10753 if (arg0 == error_mark_node || arg1 == error_mark_node)
10757 || GET_MODE (target) != tmode
10758 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10759 target = gen_reg_rtx (tmode);
10761 op1 = copy_to_mode_reg (mode1, op1);
10763 if (op0 == const0_rtx)
10765 addr = gen_rtx_MEM (tmode, op1);
10769 op0 = copy_to_mode_reg (mode0, op0);
10770 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10773 pat = GEN_FCN (icode) (target, addr);
10783 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10786 tree arg0 = CALL_EXPR_ARG (exp, 0);
10787 tree arg1 = CALL_EXPR_ARG (exp, 1);
10788 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10789 enum machine_mode mode0 = Pmode;
10790 enum machine_mode mode1 = Pmode;
10791 rtx op0 = expand_normal (arg0);
10792 rtx op1 = expand_normal (arg1);
10794 if (icode == CODE_FOR_nothing)
10795 /* Builtin not supported on this processor. */
10798 /* If we got invalid arguments bail out before generating bad rtl. */
10799 if (arg0 == error_mark_node || arg1 == error_mark_node)
10803 || GET_MODE (target) != tmode
10804 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10805 target = gen_reg_rtx (tmode);
10807 op1 = copy_to_mode_reg (mode1, op1);
10809 if (op0 == const0_rtx)
10811 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10815 op0 = copy_to_mode_reg (mode0, op0);
10816 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10819 pat = GEN_FCN (icode) (target, addr);
10829 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10831 tree arg0 = CALL_EXPR_ARG (exp, 0);
10832 tree arg1 = CALL_EXPR_ARG (exp, 1);
10833 tree arg2 = CALL_EXPR_ARG (exp, 2);
10834 rtx op0 = expand_normal (arg0);
10835 rtx op1 = expand_normal (arg1);
10836 rtx op2 = expand_normal (arg2);
10838 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10839 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10840 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10842 /* Invalid arguments. Bail before doing anything stoopid! */
10843 if (arg0 == error_mark_node
10844 || arg1 == error_mark_node
10845 || arg2 == error_mark_node)
10848 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10849 op0 = copy_to_mode_reg (mode2, op0);
10850 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10851 op1 = copy_to_mode_reg (mode0, op1);
10852 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10853 op2 = copy_to_mode_reg (mode1, op2);
10855 pat = GEN_FCN (icode) (op1, op2, op0);
10862 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10864 tree arg0 = CALL_EXPR_ARG (exp, 0);
10865 tree arg1 = CALL_EXPR_ARG (exp, 1);
10866 tree arg2 = CALL_EXPR_ARG (exp, 2);
10867 rtx op0 = expand_normal (arg0);
10868 rtx op1 = expand_normal (arg1);
10869 rtx op2 = expand_normal (arg2);
10871 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10872 enum machine_mode mode1 = Pmode;
10873 enum machine_mode mode2 = Pmode;
10875 /* Invalid arguments. Bail before doing anything stoopid! */
10876 if (arg0 == error_mark_node
10877 || arg1 == error_mark_node
10878 || arg2 == error_mark_node)
10881 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10882 op0 = copy_to_mode_reg (tmode, op0);
10884 op2 = copy_to_mode_reg (mode2, op2);
10886 if (op1 == const0_rtx)
10888 addr = gen_rtx_MEM (tmode, op2);
10892 op1 = copy_to_mode_reg (mode1, op1);
10893 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10896 pat = GEN_FCN (icode) (addr, op0);
10903 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10905 tree arg0 = CALL_EXPR_ARG (exp, 0);
10906 tree arg1 = CALL_EXPR_ARG (exp, 1);
10907 tree arg2 = CALL_EXPR_ARG (exp, 2);
10908 rtx op0 = expand_normal (arg0);
10909 rtx op1 = expand_normal (arg1);
10910 rtx op2 = expand_normal (arg2);
10912 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10913 enum machine_mode mode1 = Pmode;
10914 enum machine_mode mode2 = Pmode;
10916 /* Invalid arguments. Bail before doing anything stoopid! */
10917 if (arg0 == error_mark_node
10918 || arg1 == error_mark_node
10919 || arg2 == error_mark_node)
10922 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10923 op0 = copy_to_mode_reg (tmode, op0);
10925 op2 = copy_to_mode_reg (mode2, op2);
10927 if (op1 == const0_rtx)
10929 addr = gen_rtx_MEM (tmode, op2);
10933 op1 = copy_to_mode_reg (mode1, op1);
10934 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10937 pat = GEN_FCN (icode) (addr, op0);
10944 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10947 tree arg0 = CALL_EXPR_ARG (exp, 0);
10948 tree arg1 = CALL_EXPR_ARG (exp, 1);
10949 tree arg2 = CALL_EXPR_ARG (exp, 2);
10950 rtx op0 = expand_normal (arg0);
10951 rtx op1 = expand_normal (arg1);
10952 rtx op2 = expand_normal (arg2);
10953 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10954 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10955 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10956 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10958 if (icode == CODE_FOR_nothing)
10959 /* Builtin not supported on this processor. */
10962 /* If we got invalid arguments bail out before generating bad rtl. */
10963 if (arg0 == error_mark_node
10964 || arg1 == error_mark_node
10965 || arg2 == error_mark_node)
10968 /* Check and prepare argument depending on the instruction code.
10970 Note that a switch statement instead of the sequence of tests
10971 would be incorrect as many of the CODE_FOR values could be
10972 CODE_FOR_nothing and that would yield multiple alternatives
10973 with identical values. We'd never reach here at runtime in
10975 if (icode == CODE_FOR_altivec_vsldoi_v4sf
10976 || icode == CODE_FOR_altivec_vsldoi_v4si
10977 || icode == CODE_FOR_altivec_vsldoi_v8hi
10978 || icode == CODE_FOR_altivec_vsldoi_v16qi)
10980 /* Only allow 4-bit unsigned literals. */
10982 if (TREE_CODE (arg2) != INTEGER_CST
10983 || TREE_INT_CST_LOW (arg2) & ~0xf)
10985 error ("argument 3 must be a 4-bit unsigned literal");
10989 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
10990 || icode == CODE_FOR_vsx_xxpermdi_v2di
10991 || icode == CODE_FOR_vsx_xxsldwi_v16qi
10992 || icode == CODE_FOR_vsx_xxsldwi_v8hi
10993 || icode == CODE_FOR_vsx_xxsldwi_v4si
10994 || icode == CODE_FOR_vsx_xxsldwi_v4sf
10995 || icode == CODE_FOR_vsx_xxsldwi_v2di
10996 || icode == CODE_FOR_vsx_xxsldwi_v2df)
10998 /* Only allow 2-bit unsigned literals. */
11000 if (TREE_CODE (arg2) != INTEGER_CST
11001 || TREE_INT_CST_LOW (arg2) & ~0x3)
11003 error ("argument 3 must be a 2-bit unsigned literal");
11007 else if (icode == CODE_FOR_vsx_set_v2df
11008 || icode == CODE_FOR_vsx_set_v2di)
11010 /* Only allow 1-bit unsigned literals. */
11012 if (TREE_CODE (arg2) != INTEGER_CST
11013 || TREE_INT_CST_LOW (arg2) & ~0x1)
11015 error ("argument 3 must be a 1-bit unsigned literal");
11021 || GET_MODE (target) != tmode
11022 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11023 target = gen_reg_rtx (tmode);
11025 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11026 op0 = copy_to_mode_reg (mode0, op0);
11027 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11028 op1 = copy_to_mode_reg (mode1, op1);
11029 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11030 op2 = copy_to_mode_reg (mode2, op2);
11032 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11033 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11035 pat = GEN_FCN (icode) (target, op0, op1, op2);
11043 /* Expand the lvx builtins. */
11045 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11047 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11048 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11050 enum machine_mode tmode, mode0;
11052 enum insn_code icode;
11056 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11057 icode = CODE_FOR_vector_load_v16qi;
11059 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11060 icode = CODE_FOR_vector_load_v8hi;
11062 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11063 icode = CODE_FOR_vector_load_v4si;
11065 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11066 icode = CODE_FOR_vector_load_v4sf;
11069 *expandedp = false;
11075 arg0 = CALL_EXPR_ARG (exp, 0);
11076 op0 = expand_normal (arg0);
11077 tmode = insn_data[icode].operand[0].mode;
11078 mode0 = insn_data[icode].operand[1].mode;
11081 || GET_MODE (target) != tmode
11082 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11083 target = gen_reg_rtx (tmode);
11085 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11086 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11088 pat = GEN_FCN (icode) (target, op0);
11095 /* Expand the stvx builtins. */
11097 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11100 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11101 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11103 enum machine_mode mode0, mode1;
11105 enum insn_code icode;
11109 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11110 icode = CODE_FOR_vector_store_v16qi;
11112 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11113 icode = CODE_FOR_vector_store_v8hi;
11115 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11116 icode = CODE_FOR_vector_store_v4si;
11118 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11119 icode = CODE_FOR_vector_store_v4sf;
11122 *expandedp = false;
11126 arg0 = CALL_EXPR_ARG (exp, 0);
11127 arg1 = CALL_EXPR_ARG (exp, 1);
11128 op0 = expand_normal (arg0);
11129 op1 = expand_normal (arg1);
11130 mode0 = insn_data[icode].operand[0].mode;
11131 mode1 = insn_data[icode].operand[1].mode;
11133 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11134 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11135 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11136 op1 = copy_to_mode_reg (mode1, op1);
11138 pat = GEN_FCN (icode) (op0, op1);
11146 /* Expand the dst builtins. */
11148 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11151 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11152 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11153 tree arg0, arg1, arg2;
11154 enum machine_mode mode0, mode1;
11155 rtx pat, op0, op1, op2;
11156 const struct builtin_description *d;
11159 *expandedp = false;
11161 /* Handle DST variants. */
11163 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11164 if (d->code == fcode)
11166 arg0 = CALL_EXPR_ARG (exp, 0);
11167 arg1 = CALL_EXPR_ARG (exp, 1);
11168 arg2 = CALL_EXPR_ARG (exp, 2);
11169 op0 = expand_normal (arg0);
11170 op1 = expand_normal (arg1);
11171 op2 = expand_normal (arg2);
11172 mode0 = insn_data[d->icode].operand[0].mode;
11173 mode1 = insn_data[d->icode].operand[1].mode;
11175 /* Invalid arguments, bail out before generating bad rtl. */
11176 if (arg0 == error_mark_node
11177 || arg1 == error_mark_node
11178 || arg2 == error_mark_node)
11183 if (TREE_CODE (arg2) != INTEGER_CST
11184 || TREE_INT_CST_LOW (arg2) & ~0x3)
11186 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11190 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11191 op0 = copy_to_mode_reg (Pmode, op0);
11192 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11193 op1 = copy_to_mode_reg (mode1, op1);
11195 pat = GEN_FCN (d->icode) (op0, op1, op2);
11205 /* Expand vec_init builtin. */
11207 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11209 enum machine_mode tmode = TYPE_MODE (type);
11210 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11211 int i, n_elt = GET_MODE_NUNITS (tmode);
11212 rtvec v = rtvec_alloc (n_elt);
11214 gcc_assert (VECTOR_MODE_P (tmode));
11215 gcc_assert (n_elt == call_expr_nargs (exp));
11217 for (i = 0; i < n_elt; ++i)
11219 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11220 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11223 if (!target || !register_operand (target, tmode))
11224 target = gen_reg_rtx (tmode);
11226 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11230 /* Return the integer constant in ARG. Constrain it to be in the range
11231 of the subparts of VEC_TYPE; issue an error if not. */
11234 get_element_number (tree vec_type, tree arg)
11236 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11238 if (!host_integerp (arg, 1)
11239 || (elt = tree_low_cst (arg, 1), elt > max))
11241 error ("selector must be an integer constant in the range 0..%wi", max);
11248 /* Expand vec_set builtin. */
11250 altivec_expand_vec_set_builtin (tree exp)
11252 enum machine_mode tmode, mode1;
11253 tree arg0, arg1, arg2;
11257 arg0 = CALL_EXPR_ARG (exp, 0);
11258 arg1 = CALL_EXPR_ARG (exp, 1);
11259 arg2 = CALL_EXPR_ARG (exp, 2);
11261 tmode = TYPE_MODE (TREE_TYPE (arg0));
11262 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11263 gcc_assert (VECTOR_MODE_P (tmode));
11265 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11266 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11267 elt = get_element_number (TREE_TYPE (arg0), arg2);
11269 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11270 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11272 op0 = force_reg (tmode, op0);
11273 op1 = force_reg (mode1, op1);
11275 rs6000_expand_vector_set (op0, op1, elt);
11280 /* Expand vec_ext builtin. */
11282 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11284 enum machine_mode tmode, mode0;
11289 arg0 = CALL_EXPR_ARG (exp, 0);
11290 arg1 = CALL_EXPR_ARG (exp, 1);
11292 op0 = expand_normal (arg0);
11293 elt = get_element_number (TREE_TYPE (arg0), arg1);
11295 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11296 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11297 gcc_assert (VECTOR_MODE_P (mode0));
11299 op0 = force_reg (mode0, op0);
11301 if (optimize || !target || !register_operand (target, tmode))
11302 target = gen_reg_rtx (tmode);
11304 rs6000_expand_vector_extract (target, op0, elt);
11309 /* Expand the builtin in EXP and store the result in TARGET. Store
11310 true in *EXPANDEDP if we found a builtin to expand. */
11312 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11314 const struct builtin_description *d;
11315 const struct builtin_description_predicates *dp;
11317 enum insn_code icode;
11318 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11321 enum machine_mode tmode, mode0;
11322 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11324 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11325 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11326 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11327 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11330 error ("unresolved overload for Altivec builtin %qF", fndecl);
11334 target = altivec_expand_ld_builtin (exp, target, expandedp);
11338 target = altivec_expand_st_builtin (exp, target, expandedp);
11342 target = altivec_expand_dst_builtin (exp, target, expandedp);
11350 case ALTIVEC_BUILTIN_STVX:
11351 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11352 case ALTIVEC_BUILTIN_STVEBX:
11353 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11354 case ALTIVEC_BUILTIN_STVEHX:
11355 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11356 case ALTIVEC_BUILTIN_STVEWX:
11357 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11358 case ALTIVEC_BUILTIN_STVXL:
11359 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11361 case ALTIVEC_BUILTIN_STVLX:
11362 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11363 case ALTIVEC_BUILTIN_STVLXL:
11364 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11365 case ALTIVEC_BUILTIN_STVRX:
11366 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11367 case ALTIVEC_BUILTIN_STVRXL:
11368 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11370 case ALTIVEC_BUILTIN_MFVSCR:
11371 icode = CODE_FOR_altivec_mfvscr;
11372 tmode = insn_data[icode].operand[0].mode;
11375 || GET_MODE (target) != tmode
11376 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11377 target = gen_reg_rtx (tmode);
11379 pat = GEN_FCN (icode) (target);
11385 case ALTIVEC_BUILTIN_MTVSCR:
11386 icode = CODE_FOR_altivec_mtvscr;
11387 arg0 = CALL_EXPR_ARG (exp, 0);
11388 op0 = expand_normal (arg0);
11389 mode0 = insn_data[icode].operand[0].mode;
11391 /* If we got invalid arguments bail out before generating bad rtl. */
11392 if (arg0 == error_mark_node)
11395 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11396 op0 = copy_to_mode_reg (mode0, op0);
11398 pat = GEN_FCN (icode) (op0);
11403 case ALTIVEC_BUILTIN_DSSALL:
11404 emit_insn (gen_altivec_dssall ());
11407 case ALTIVEC_BUILTIN_DSS:
11408 icode = CODE_FOR_altivec_dss;
11409 arg0 = CALL_EXPR_ARG (exp, 0);
11411 op0 = expand_normal (arg0);
11412 mode0 = insn_data[icode].operand[0].mode;
11414 /* If we got invalid arguments bail out before generating bad rtl. */
11415 if (arg0 == error_mark_node)
11418 if (TREE_CODE (arg0) != INTEGER_CST
11419 || TREE_INT_CST_LOW (arg0) & ~0x3)
11421 error ("argument to dss must be a 2-bit unsigned literal");
11425 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11426 op0 = copy_to_mode_reg (mode0, op0);
11428 emit_insn (gen_altivec_dss (op0));
11431 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11432 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11433 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11434 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11435 case VSX_BUILTIN_VEC_INIT_V2DF:
11436 case VSX_BUILTIN_VEC_INIT_V2DI:
11437 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11439 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11440 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11441 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11442 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11443 case VSX_BUILTIN_VEC_SET_V2DF:
11444 case VSX_BUILTIN_VEC_SET_V2DI:
11445 return altivec_expand_vec_set_builtin (exp);
11447 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11448 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11449 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11450 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11451 case VSX_BUILTIN_VEC_EXT_V2DF:
11452 case VSX_BUILTIN_VEC_EXT_V2DI:
11453 return altivec_expand_vec_ext_builtin (exp, target);
11457 /* Fall through. */
11460 /* Expand abs* operations. */
11462 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11463 if (d->code == fcode)
11464 return altivec_expand_abs_builtin (d->icode, exp, target);
11466 /* Expand the AltiVec predicates. */
11467 dp = bdesc_altivec_preds;
11468 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11469 if (dp->code == fcode)
11470 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11472 /* LV* are funky. We initialized them differently. */
11475 case ALTIVEC_BUILTIN_LVSL:
11476 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11477 exp, target, false);
11478 case ALTIVEC_BUILTIN_LVSR:
11479 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11480 exp, target, false);
11481 case ALTIVEC_BUILTIN_LVEBX:
11482 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11483 exp, target, false);
11484 case ALTIVEC_BUILTIN_LVEHX:
11485 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11486 exp, target, false);
11487 case ALTIVEC_BUILTIN_LVEWX:
11488 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11489 exp, target, false);
11490 case ALTIVEC_BUILTIN_LVXL:
11491 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11492 exp, target, false);
11493 case ALTIVEC_BUILTIN_LVX:
11494 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11495 exp, target, false);
11496 case ALTIVEC_BUILTIN_LVLX:
11497 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11498 exp, target, true);
11499 case ALTIVEC_BUILTIN_LVLXL:
11500 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11501 exp, target, true);
11502 case ALTIVEC_BUILTIN_LVRX:
11503 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11504 exp, target, true);
11505 case ALTIVEC_BUILTIN_LVRXL:
11506 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11507 exp, target, true);
11510 /* Fall through. */
11513 *expandedp = false;
11517 /* Expand the builtin in EXP and store the result in TARGET. Store
11518 true in *EXPANDEDP if we found a builtin to expand. */
11520 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11522 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11523 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11524 const struct builtin_description *d;
11531 case PAIRED_BUILTIN_STX:
11532 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11533 case PAIRED_BUILTIN_LX:
11534 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11537 /* Fall through. */
11540 /* Expand the paired predicates. */
11541 d = bdesc_paired_preds;
11542 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11543 if (d->code == fcode)
11544 return paired_expand_predicate_builtin (d->icode, exp, target);
11546 *expandedp = false;
11550 /* Binops that need to be initialized manually, but can be expanded
11551 automagically by rs6000_expand_binop_builtin. */
11552 static struct builtin_description bdesc_2arg_spe[] =
11554 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11555 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11556 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11557 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11558 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11559 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11560 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11561 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11562 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11563 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11564 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11565 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11566 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11567 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11568 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11569 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11570 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11571 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11572 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11573 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11574 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11575 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11578 /* Expand the builtin in EXP and store the result in TARGET. Store
11579 true in *EXPANDEDP if we found a builtin to expand.
11581 This expands the SPE builtins that are not simple unary and binary
11584 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11586 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11588 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11589 enum insn_code icode;
11590 enum machine_mode tmode, mode0;
11592 struct builtin_description *d;
11597 /* Syntax check for a 5-bit unsigned immediate. */
11600 case SPE_BUILTIN_EVSTDD:
11601 case SPE_BUILTIN_EVSTDH:
11602 case SPE_BUILTIN_EVSTDW:
11603 case SPE_BUILTIN_EVSTWHE:
11604 case SPE_BUILTIN_EVSTWHO:
11605 case SPE_BUILTIN_EVSTWWE:
11606 case SPE_BUILTIN_EVSTWWO:
11607 arg1 = CALL_EXPR_ARG (exp, 2);
11608 if (TREE_CODE (arg1) != INTEGER_CST
11609 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11611 error ("argument 2 must be a 5-bit unsigned literal");
11619 /* The evsplat*i instructions are not quite generic. */
11622 case SPE_BUILTIN_EVSPLATFI:
11623 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11625 case SPE_BUILTIN_EVSPLATI:
11626 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11632 d = (struct builtin_description *) bdesc_2arg_spe;
11633 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11634 if (d->code == fcode)
11635 return rs6000_expand_binop_builtin (d->icode, exp, target);
11637 d = (struct builtin_description *) bdesc_spe_predicates;
11638 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11639 if (d->code == fcode)
11640 return spe_expand_predicate_builtin (d->icode, exp, target);
11642 d = (struct builtin_description *) bdesc_spe_evsel;
11643 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11644 if (d->code == fcode)
11645 return spe_expand_evsel_builtin (d->icode, exp, target);
11649 case SPE_BUILTIN_EVSTDDX:
11650 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11651 case SPE_BUILTIN_EVSTDHX:
11652 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11653 case SPE_BUILTIN_EVSTDWX:
11654 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11655 case SPE_BUILTIN_EVSTWHEX:
11656 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11657 case SPE_BUILTIN_EVSTWHOX:
11658 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11659 case SPE_BUILTIN_EVSTWWEX:
11660 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11661 case SPE_BUILTIN_EVSTWWOX:
11662 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11663 case SPE_BUILTIN_EVSTDD:
11664 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11665 case SPE_BUILTIN_EVSTDH:
11666 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11667 case SPE_BUILTIN_EVSTDW:
11668 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11669 case SPE_BUILTIN_EVSTWHE:
11670 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11671 case SPE_BUILTIN_EVSTWHO:
11672 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11673 case SPE_BUILTIN_EVSTWWE:
11674 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11675 case SPE_BUILTIN_EVSTWWO:
11676 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11677 case SPE_BUILTIN_MFSPEFSCR:
11678 icode = CODE_FOR_spe_mfspefscr;
11679 tmode = insn_data[icode].operand[0].mode;
11682 || GET_MODE (target) != tmode
11683 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11684 target = gen_reg_rtx (tmode);
11686 pat = GEN_FCN (icode) (target);
11691 case SPE_BUILTIN_MTSPEFSCR:
11692 icode = CODE_FOR_spe_mtspefscr;
11693 arg0 = CALL_EXPR_ARG (exp, 0);
11694 op0 = expand_normal (arg0);
11695 mode0 = insn_data[icode].operand[0].mode;
11697 if (arg0 == error_mark_node)
11700 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11701 op0 = copy_to_mode_reg (mode0, op0);
11703 pat = GEN_FCN (icode) (op0);
11711 *expandedp = false;
11716 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11718 rtx pat, scratch, tmp;
11719 tree form = CALL_EXPR_ARG (exp, 0);
11720 tree arg0 = CALL_EXPR_ARG (exp, 1);
11721 tree arg1 = CALL_EXPR_ARG (exp, 2);
11722 rtx op0 = expand_normal (arg0);
11723 rtx op1 = expand_normal (arg1);
11724 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11725 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11727 enum rtx_code code;
11729 if (TREE_CODE (form) != INTEGER_CST)
11731 error ("argument 1 of __builtin_paired_predicate must be a constant");
11735 form_int = TREE_INT_CST_LOW (form);
11737 gcc_assert (mode0 == mode1);
11739 if (arg0 == error_mark_node || arg1 == error_mark_node)
11743 || GET_MODE (target) != SImode
11744 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11745 target = gen_reg_rtx (SImode);
11746 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11747 op0 = copy_to_mode_reg (mode0, op0);
11748 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11749 op1 = copy_to_mode_reg (mode1, op1);
11751 scratch = gen_reg_rtx (CCFPmode);
11753 pat = GEN_FCN (icode) (scratch, op0, op1);
11775 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11778 error ("argument 1 of __builtin_paired_predicate is out of range");
11782 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11783 emit_move_insn (target, tmp);
11788 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11790 rtx pat, scratch, tmp;
11791 tree form = CALL_EXPR_ARG (exp, 0);
11792 tree arg0 = CALL_EXPR_ARG (exp, 1);
11793 tree arg1 = CALL_EXPR_ARG (exp, 2);
11794 rtx op0 = expand_normal (arg0);
11795 rtx op1 = expand_normal (arg1);
11796 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11797 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11799 enum rtx_code code;
11801 if (TREE_CODE (form) != INTEGER_CST)
11803 error ("argument 1 of __builtin_spe_predicate must be a constant");
11807 form_int = TREE_INT_CST_LOW (form);
11809 gcc_assert (mode0 == mode1);
11811 if (arg0 == error_mark_node || arg1 == error_mark_node)
11815 || GET_MODE (target) != SImode
11816 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11817 target = gen_reg_rtx (SImode);
11819 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11820 op0 = copy_to_mode_reg (mode0, op0);
11821 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11822 op1 = copy_to_mode_reg (mode1, op1);
11824 scratch = gen_reg_rtx (CCmode);
11826 pat = GEN_FCN (icode) (scratch, op0, op1);
11831 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11832 _lower_. We use one compare, but look in different bits of the
11833 CR for each variant.
11835 There are 2 elements in each SPE simd type (upper/lower). The CR
11836 bits are set as follows:
11838 BIT0 | BIT 1 | BIT 2 | BIT 3
11839 U | L | (U | L) | (U & L)
11841 So, for an "all" relationship, BIT 3 would be set.
11842 For an "any" relationship, BIT 2 would be set. Etc.
11844 Following traditional nomenclature, these bits map to:
11846 BIT0 | BIT 1 | BIT 2 | BIT 3
11849 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11854 /* All variant. OV bit. */
11856 /* We need to get to the OV bit, which is the ORDERED bit. We
11857 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11858 that's ugly and will make validate_condition_mode die.
11859 So let's just use another pattern. */
11860 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11862 /* Any variant. EQ bit. */
11866 /* Upper variant. LT bit. */
11870 /* Lower variant. GT bit. */
11875 error ("argument 1 of __builtin_spe_predicate is out of range");
11879 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11880 emit_move_insn (target, tmp);
11885 /* The evsel builtins look like this:
11887 e = __builtin_spe_evsel_OP (a, b, c, d);
11889 and work like this:
11891 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11892 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11896 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11899 tree arg0 = CALL_EXPR_ARG (exp, 0);
11900 tree arg1 = CALL_EXPR_ARG (exp, 1);
11901 tree arg2 = CALL_EXPR_ARG (exp, 2);
11902 tree arg3 = CALL_EXPR_ARG (exp, 3);
11903 rtx op0 = expand_normal (arg0);
11904 rtx op1 = expand_normal (arg1);
11905 rtx op2 = expand_normal (arg2);
11906 rtx op3 = expand_normal (arg3);
11907 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11908 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11910 gcc_assert (mode0 == mode1);
11912 if (arg0 == error_mark_node || arg1 == error_mark_node
11913 || arg2 == error_mark_node || arg3 == error_mark_node)
11917 || GET_MODE (target) != mode0
11918 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11919 target = gen_reg_rtx (mode0);
11921 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11922 op0 = copy_to_mode_reg (mode0, op0);
11923 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11924 op1 = copy_to_mode_reg (mode0, op1);
11925 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11926 op2 = copy_to_mode_reg (mode0, op2);
11927 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11928 op3 = copy_to_mode_reg (mode0, op3);
11930 /* Generate the compare. */
11931 scratch = gen_reg_rtx (CCmode);
11932 pat = GEN_FCN (icode) (scratch, op0, op1);
11937 if (mode0 == V2SImode)
11938 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11940 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11945 /* Expand an expression EXP that calls a built-in function,
11946 with result going to TARGET if that's convenient
11947 (and in mode MODE if that's convenient).
11948 SUBTARGET may be used as the target for computing one of EXP's operands.
11949 IGNORE is nonzero if the value is to be ignored. */
11952 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11953 enum machine_mode mode ATTRIBUTE_UNUSED,
11954 int ignore ATTRIBUTE_UNUSED)
11956 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11957 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11958 const struct builtin_description *d;
11965 case RS6000_BUILTIN_RECIP:
11966 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11968 case RS6000_BUILTIN_RECIPF:
11969 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11971 case RS6000_BUILTIN_RSQRTF:
11972 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11974 case RS6000_BUILTIN_RSQRT:
11975 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11977 case RS6000_BUILTIN_BSWAP_HI:
11978 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11980 case POWER7_BUILTIN_BPERMD:
11981 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11982 ? CODE_FOR_bpermd_di
11983 : CODE_FOR_bpermd_si), exp, target);
11985 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11986 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11988 int icode = (int) CODE_FOR_altivec_lvsr;
11989 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11990 enum machine_mode mode = insn_data[icode].operand[1].mode;
11994 gcc_assert (TARGET_ALTIVEC);
11996 arg = CALL_EXPR_ARG (exp, 0);
11997 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
11998 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11999 addr = memory_address (mode, op);
12000 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12004 /* For the load case need to negate the address. */
12005 op = gen_reg_rtx (GET_MODE (addr));
12006 emit_insn (gen_rtx_SET (VOIDmode, op,
12007 gen_rtx_NEG (GET_MODE (addr), addr)));
12009 op = gen_rtx_MEM (mode, op);
12012 || GET_MODE (target) != tmode
12013 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12014 target = gen_reg_rtx (tmode);
12016 /*pat = gen_altivec_lvsr (target, op);*/
12017 pat = GEN_FCN (icode) (target, op);
12025 case ALTIVEC_BUILTIN_VCFUX:
12026 case ALTIVEC_BUILTIN_VCFSX:
12027 case ALTIVEC_BUILTIN_VCTUXS:
12028 case ALTIVEC_BUILTIN_VCTSXS:
12029 /* FIXME: There's got to be a nicer way to handle this case than
12030 constructing a new CALL_EXPR. */
12031 if (call_expr_nargs (exp) == 1)
12033 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12034 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12042 if (TARGET_ALTIVEC)
12044 ret = altivec_expand_builtin (exp, target, &success);
12051 ret = spe_expand_builtin (exp, target, &success);
12056 if (TARGET_PAIRED_FLOAT)
12058 ret = paired_expand_builtin (exp, target, &success);
12064 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12066 /* Handle simple unary operations. */
12067 d = (struct builtin_description *) bdesc_1arg;
12068 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12069 if (d->code == fcode)
12070 return rs6000_expand_unop_builtin (d->icode, exp, target);
12072 /* Handle simple binary operations. */
12073 d = (struct builtin_description *) bdesc_2arg;
12074 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12075 if (d->code == fcode)
12076 return rs6000_expand_binop_builtin (d->icode, exp, target);
12078 /* Handle simple ternary operations. */
12080 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12081 if (d->code == fcode)
12082 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12084 gcc_unreachable ();
12088 rs6000_init_builtins (void)
12093 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12094 V2SF_type_node = build_vector_type (float_type_node, 2);
12095 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12096 V2DF_type_node = build_vector_type (double_type_node, 2);
12097 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12098 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12099 V4SF_type_node = build_vector_type (float_type_node, 4);
12100 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12101 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12103 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12104 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12105 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12106 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12108 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12109 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12110 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12111 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12113 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12114 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12115 'vector unsigned short'. */
12117 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12118 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12119 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12120 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12121 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12123 long_integer_type_internal_node = long_integer_type_node;
12124 long_unsigned_type_internal_node = long_unsigned_type_node;
12125 intQI_type_internal_node = intQI_type_node;
12126 uintQI_type_internal_node = unsigned_intQI_type_node;
12127 intHI_type_internal_node = intHI_type_node;
12128 uintHI_type_internal_node = unsigned_intHI_type_node;
12129 intSI_type_internal_node = intSI_type_node;
12130 uintSI_type_internal_node = unsigned_intSI_type_node;
12131 intDI_type_internal_node = intDI_type_node;
12132 uintDI_type_internal_node = unsigned_intDI_type_node;
12133 float_type_internal_node = float_type_node;
12134 double_type_internal_node = float_type_node;
12135 void_type_internal_node = void_type_node;
12137 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12139 builtin_mode_to_type[QImode][0] = integer_type_node;
12140 builtin_mode_to_type[HImode][0] = integer_type_node;
12141 builtin_mode_to_type[SImode][0] = intSI_type_node;
12142 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12143 builtin_mode_to_type[DImode][0] = intDI_type_node;
12144 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12145 builtin_mode_to_type[SFmode][0] = float_type_node;
12146 builtin_mode_to_type[DFmode][0] = double_type_node;
12147 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12148 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12149 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12150 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12151 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12152 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12153 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12154 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12155 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12156 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12157 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12158 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12159 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12161 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12162 get_identifier ("__bool char"),
12163 bool_char_type_node);
12164 TYPE_NAME (bool_char_type_node) = tdecl;
12165 (*lang_hooks.decls.pushdecl) (tdecl);
12166 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12167 get_identifier ("__bool short"),
12168 bool_short_type_node);
12169 TYPE_NAME (bool_short_type_node) = tdecl;
12170 (*lang_hooks.decls.pushdecl) (tdecl);
12171 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12172 get_identifier ("__bool int"),
12173 bool_int_type_node);
12174 TYPE_NAME (bool_int_type_node) = tdecl;
12175 (*lang_hooks.decls.pushdecl) (tdecl);
12176 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12178 TYPE_NAME (pixel_type_node) = tdecl;
12179 (*lang_hooks.decls.pushdecl) (tdecl);
12181 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12182 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12183 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12184 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12185 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12187 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12188 get_identifier ("__vector unsigned char"),
12189 unsigned_V16QI_type_node);
12190 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12191 (*lang_hooks.decls.pushdecl) (tdecl);
12192 tdecl = build_decl (BUILTINS_LOCATION,
12193 TYPE_DECL, get_identifier ("__vector signed char"),
12195 TYPE_NAME (V16QI_type_node) = tdecl;
12196 (*lang_hooks.decls.pushdecl) (tdecl);
12197 tdecl = build_decl (BUILTINS_LOCATION,
12198 TYPE_DECL, get_identifier ("__vector __bool char"),
12199 bool_V16QI_type_node);
12200 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12201 (*lang_hooks.decls.pushdecl) (tdecl);
12203 tdecl = build_decl (BUILTINS_LOCATION,
12204 TYPE_DECL, get_identifier ("__vector unsigned short"),
12205 unsigned_V8HI_type_node);
12206 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12207 (*lang_hooks.decls.pushdecl) (tdecl);
12208 tdecl = build_decl (BUILTINS_LOCATION,
12209 TYPE_DECL, get_identifier ("__vector signed short"),
12211 TYPE_NAME (V8HI_type_node) = tdecl;
12212 (*lang_hooks.decls.pushdecl) (tdecl);
12213 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12214 get_identifier ("__vector __bool short"),
12215 bool_V8HI_type_node);
12216 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12217 (*lang_hooks.decls.pushdecl) (tdecl);
12219 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12220 get_identifier ("__vector unsigned int"),
12221 unsigned_V4SI_type_node);
12222 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12223 (*lang_hooks.decls.pushdecl) (tdecl);
12224 tdecl = build_decl (BUILTINS_LOCATION,
12225 TYPE_DECL, get_identifier ("__vector signed int"),
12227 TYPE_NAME (V4SI_type_node) = tdecl;
12228 (*lang_hooks.decls.pushdecl) (tdecl);
12229 tdecl = build_decl (BUILTINS_LOCATION,
12230 TYPE_DECL, get_identifier ("__vector __bool int"),
12231 bool_V4SI_type_node);
12232 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12233 (*lang_hooks.decls.pushdecl) (tdecl);
12235 tdecl = build_decl (BUILTINS_LOCATION,
12236 TYPE_DECL, get_identifier ("__vector float"),
12238 TYPE_NAME (V4SF_type_node) = tdecl;
12239 (*lang_hooks.decls.pushdecl) (tdecl);
12240 tdecl = build_decl (BUILTINS_LOCATION,
12241 TYPE_DECL, get_identifier ("__vector __pixel"),
12242 pixel_V8HI_type_node);
12243 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12244 (*lang_hooks.decls.pushdecl) (tdecl);
12248 tdecl = build_decl (BUILTINS_LOCATION,
12249 TYPE_DECL, get_identifier ("__vector double"),
12251 TYPE_NAME (V2DF_type_node) = tdecl;
12252 (*lang_hooks.decls.pushdecl) (tdecl);
12254 tdecl = build_decl (BUILTINS_LOCATION,
12255 TYPE_DECL, get_identifier ("__vector long"),
12257 TYPE_NAME (V2DI_type_node) = tdecl;
12258 (*lang_hooks.decls.pushdecl) (tdecl);
12260 tdecl = build_decl (BUILTINS_LOCATION,
12261 TYPE_DECL, get_identifier ("__vector unsigned long"),
12262 unsigned_V2DI_type_node);
12263 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12264 (*lang_hooks.decls.pushdecl) (tdecl);
12266 tdecl = build_decl (BUILTINS_LOCATION,
12267 TYPE_DECL, get_identifier ("__vector __bool long"),
12268 bool_V2DI_type_node);
12269 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12270 (*lang_hooks.decls.pushdecl) (tdecl);
12273 if (TARGET_PAIRED_FLOAT)
12274 paired_init_builtins ();
12276 spe_init_builtins ();
12277 if (TARGET_ALTIVEC)
12278 altivec_init_builtins ();
12279 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12280 rs6000_common_init_builtins ();
12283 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12284 RS6000_BUILTIN_RECIP,
12285 "__builtin_recipdiv");
12286 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12287 RS6000_BUILTIN_RECIP);
12291 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12292 RS6000_BUILTIN_RECIPF,
12293 "__builtin_recipdivf");
12294 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12295 RS6000_BUILTIN_RECIPF);
12297 if (TARGET_FRSQRTE)
12299 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12300 RS6000_BUILTIN_RSQRT,
12301 "__builtin_rsqrt");
12302 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12303 RS6000_BUILTIN_RSQRT);
12305 if (TARGET_FRSQRTES)
12307 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12308 RS6000_BUILTIN_RSQRTF,
12309 "__builtin_rsqrtf");
12310 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12311 RS6000_BUILTIN_RSQRTF);
12313 if (TARGET_POPCNTD)
12315 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12316 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12317 POWER7_BUILTIN_BPERMD,
12318 "__builtin_bpermd");
12319 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12320 POWER7_BUILTIN_BPERMD);
12322 if (TARGET_POWERPC)
12324 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12325 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12326 unsigned_intHI_type_node,
12328 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12329 RS6000_BUILTIN_BSWAP_HI);
12333 /* AIX libm provides clog as __clog. */
12334 if (built_in_decls [BUILT_IN_CLOG])
12335 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12338 #ifdef SUBTARGET_INIT_BUILTINS
12339 SUBTARGET_INIT_BUILTINS;
12343 /* Returns the rs6000 builtin decl for CODE. */
12346 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12348 if (code >= RS6000_BUILTIN_COUNT)
12349 return error_mark_node;
12351 return rs6000_builtin_decls[code];
12354 /* Search through a set of builtins and enable the mask bits.
12355 DESC is an array of builtins.
12356 SIZE is the total number of builtins.
12357 START is the builtin enum at which to start.
12358 END is the builtin enum at which to end. */
12360 enable_mask_for_builtins (struct builtin_description *desc, int size,
12361 enum rs6000_builtins start,
12362 enum rs6000_builtins end)
12366 for (i = 0; i < size; ++i)
12367 if (desc[i].code == start)
12373 for (; i < size; ++i)
12375 /* Flip all the bits on. */
12376 desc[i].mask = target_flags;
12377 if (desc[i].code == end)
12383 spe_init_builtins (void)
12385 tree endlink = void_list_node;
12386 tree puint_type_node = build_pointer_type (unsigned_type_node);
12387 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12388 struct builtin_description *d;
12391 tree v2si_ftype_4_v2si
12392 = build_function_type
12393 (opaque_V2SI_type_node,
12394 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12395 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12396 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12397 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12400 tree v2sf_ftype_4_v2sf
12401 = build_function_type
12402 (opaque_V2SF_type_node,
12403 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12404 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12405 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12406 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12409 tree int_ftype_int_v2si_v2si
12410 = build_function_type
12411 (integer_type_node,
12412 tree_cons (NULL_TREE, integer_type_node,
12413 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12414 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12417 tree int_ftype_int_v2sf_v2sf
12418 = build_function_type
12419 (integer_type_node,
12420 tree_cons (NULL_TREE, integer_type_node,
12421 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12422 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12425 tree void_ftype_v2si_puint_int
12426 = build_function_type (void_type_node,
12427 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12428 tree_cons (NULL_TREE, puint_type_node,
12429 tree_cons (NULL_TREE,
12433 tree void_ftype_v2si_puint_char
12434 = build_function_type (void_type_node,
12435 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12436 tree_cons (NULL_TREE, puint_type_node,
12437 tree_cons (NULL_TREE,
12441 tree void_ftype_v2si_pv2si_int
12442 = build_function_type (void_type_node,
12443 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12444 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12445 tree_cons (NULL_TREE,
12449 tree void_ftype_v2si_pv2si_char
12450 = build_function_type (void_type_node,
12451 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12452 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12453 tree_cons (NULL_TREE,
12457 tree void_ftype_int
12458 = build_function_type (void_type_node,
12459 tree_cons (NULL_TREE, integer_type_node, endlink));
12461 tree int_ftype_void
12462 = build_function_type (integer_type_node, endlink);
12464 tree v2si_ftype_pv2si_int
12465 = build_function_type (opaque_V2SI_type_node,
12466 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12467 tree_cons (NULL_TREE, integer_type_node,
12470 tree v2si_ftype_puint_int
12471 = build_function_type (opaque_V2SI_type_node,
12472 tree_cons (NULL_TREE, puint_type_node,
12473 tree_cons (NULL_TREE, integer_type_node,
12476 tree v2si_ftype_pushort_int
12477 = build_function_type (opaque_V2SI_type_node,
12478 tree_cons (NULL_TREE, pushort_type_node,
12479 tree_cons (NULL_TREE, integer_type_node,
12482 tree v2si_ftype_signed_char
12483 = build_function_type (opaque_V2SI_type_node,
12484 tree_cons (NULL_TREE, signed_char_type_node,
12487 /* The initialization of the simple binary and unary builtins is
12488 done in rs6000_common_init_builtins, but we have to enable the
12489 mask bits here manually because we have run out of `target_flags'
12490 bits. We really need to redesign this mask business. */
12492 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12493 ARRAY_SIZE (bdesc_2arg),
12494 SPE_BUILTIN_EVADDW,
12495 SPE_BUILTIN_EVXOR);
12496 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12497 ARRAY_SIZE (bdesc_1arg),
12499 SPE_BUILTIN_EVSUBFUSIAAW);
12500 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12501 ARRAY_SIZE (bdesc_spe_predicates),
12502 SPE_BUILTIN_EVCMPEQ,
12503 SPE_BUILTIN_EVFSTSTLT);
12504 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12505 ARRAY_SIZE (bdesc_spe_evsel),
12506 SPE_BUILTIN_EVSEL_CMPGTS,
12507 SPE_BUILTIN_EVSEL_FSTSTEQ);
12509 (*lang_hooks.decls.pushdecl)
12510 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12511 get_identifier ("__ev64_opaque__"),
12512 opaque_V2SI_type_node));
12514 /* Initialize irregular SPE builtins. */
12516 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12517 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12518 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12519 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12520 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12521 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12522 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12523 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12524 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12525 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12526 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12527 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12528 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12529 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12530 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12531 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12532 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12533 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12536 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12537 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12538 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12539 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12540 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12541 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12542 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12543 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12544 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12545 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12546 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12547 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12548 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12549 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12550 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12551 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12552 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12553 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12554 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12555 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12556 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12557 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12560 d = (struct builtin_description *) bdesc_spe_predicates;
12561 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12565 switch (insn_data[d->icode].operand[1].mode)
12568 type = int_ftype_int_v2si_v2si;
12571 type = int_ftype_int_v2sf_v2sf;
12574 gcc_unreachable ();
12577 def_builtin (d->mask, d->name, type, d->code);
12580 /* Evsel predicates. */
12581 d = (struct builtin_description *) bdesc_spe_evsel;
12582 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12586 switch (insn_data[d->icode].operand[1].mode)
12589 type = v2si_ftype_4_v2si;
12592 type = v2sf_ftype_4_v2sf;
12595 gcc_unreachable ();
12598 def_builtin (d->mask, d->name, type, d->code);
12603 paired_init_builtins (void)
12605 const struct builtin_description *d;
12607 tree endlink = void_list_node;
12609 tree int_ftype_int_v2sf_v2sf
12610 = build_function_type
12611 (integer_type_node,
12612 tree_cons (NULL_TREE, integer_type_node,
12613 tree_cons (NULL_TREE, V2SF_type_node,
12614 tree_cons (NULL_TREE, V2SF_type_node,
12616 tree pcfloat_type_node =
12617 build_pointer_type (build_qualified_type
12618 (float_type_node, TYPE_QUAL_CONST));
12620 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12621 long_integer_type_node,
12624 tree void_ftype_v2sf_long_pcfloat =
12625 build_function_type_list (void_type_node,
12627 long_integer_type_node,
12632 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12633 PAIRED_BUILTIN_LX);
12636 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12637 PAIRED_BUILTIN_STX);
12640 d = bdesc_paired_preds;
12641 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12645 switch (insn_data[d->icode].operand[1].mode)
12648 type = int_ftype_int_v2sf_v2sf;
12651 gcc_unreachable ();
12654 def_builtin (d->mask, d->name, type, d->code);
12659 altivec_init_builtins (void)
12661 const struct builtin_description *d;
12662 const struct builtin_description_predicates *dp;
12666 tree pfloat_type_node = build_pointer_type (float_type_node);
12667 tree pint_type_node = build_pointer_type (integer_type_node);
12668 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12669 tree pchar_type_node = build_pointer_type (char_type_node);
12671 tree pvoid_type_node = build_pointer_type (void_type_node);
12673 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12674 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12675 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12676 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12678 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12680 tree int_ftype_opaque
12681 = build_function_type_list (integer_type_node,
12682 opaque_V4SI_type_node, NULL_TREE);
12683 tree opaque_ftype_opaque
12684 = build_function_type (integer_type_node,
12686 tree opaque_ftype_opaque_int
12687 = build_function_type_list (opaque_V4SI_type_node,
12688 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12689 tree opaque_ftype_opaque_opaque_int
12690 = build_function_type_list (opaque_V4SI_type_node,
12691 opaque_V4SI_type_node, opaque_V4SI_type_node,
12692 integer_type_node, NULL_TREE);
12693 tree int_ftype_int_opaque_opaque
12694 = build_function_type_list (integer_type_node,
12695 integer_type_node, opaque_V4SI_type_node,
12696 opaque_V4SI_type_node, NULL_TREE);
12697 tree int_ftype_int_v4si_v4si
12698 = build_function_type_list (integer_type_node,
12699 integer_type_node, V4SI_type_node,
12700 V4SI_type_node, NULL_TREE);
12701 tree v4sf_ftype_pcfloat
12702 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12703 tree void_ftype_pfloat_v4sf
12704 = build_function_type_list (void_type_node,
12705 pfloat_type_node, V4SF_type_node, NULL_TREE);
12706 tree v4si_ftype_pcint
12707 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12708 tree void_ftype_pint_v4si
12709 = build_function_type_list (void_type_node,
12710 pint_type_node, V4SI_type_node, NULL_TREE);
12711 tree v8hi_ftype_pcshort
12712 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12713 tree void_ftype_pshort_v8hi
12714 = build_function_type_list (void_type_node,
12715 pshort_type_node, V8HI_type_node, NULL_TREE);
12716 tree v16qi_ftype_pcchar
12717 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12718 tree void_ftype_pchar_v16qi
12719 = build_function_type_list (void_type_node,
12720 pchar_type_node, V16QI_type_node, NULL_TREE);
12721 tree void_ftype_v4si
12722 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12723 tree v8hi_ftype_void
12724 = build_function_type (V8HI_type_node, void_list_node);
12725 tree void_ftype_void
12726 = build_function_type (void_type_node, void_list_node);
12727 tree void_ftype_int
12728 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12730 tree opaque_ftype_long_pcvoid
12731 = build_function_type_list (opaque_V4SI_type_node,
12732 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12733 tree v16qi_ftype_long_pcvoid
12734 = build_function_type_list (V16QI_type_node,
12735 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12736 tree v8hi_ftype_long_pcvoid
12737 = build_function_type_list (V8HI_type_node,
12738 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12739 tree v4si_ftype_long_pcvoid
12740 = build_function_type_list (V4SI_type_node,
12741 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12743 tree void_ftype_opaque_long_pvoid
12744 = build_function_type_list (void_type_node,
12745 opaque_V4SI_type_node, long_integer_type_node,
12746 pvoid_type_node, NULL_TREE);
12747 tree void_ftype_v4si_long_pvoid
12748 = build_function_type_list (void_type_node,
12749 V4SI_type_node, long_integer_type_node,
12750 pvoid_type_node, NULL_TREE);
12751 tree void_ftype_v16qi_long_pvoid
12752 = build_function_type_list (void_type_node,
12753 V16QI_type_node, long_integer_type_node,
12754 pvoid_type_node, NULL_TREE);
12755 tree void_ftype_v8hi_long_pvoid
12756 = build_function_type_list (void_type_node,
12757 V8HI_type_node, long_integer_type_node,
12758 pvoid_type_node, NULL_TREE);
12759 tree int_ftype_int_v8hi_v8hi
12760 = build_function_type_list (integer_type_node,
12761 integer_type_node, V8HI_type_node,
12762 V8HI_type_node, NULL_TREE);
12763 tree int_ftype_int_v16qi_v16qi
12764 = build_function_type_list (integer_type_node,
12765 integer_type_node, V16QI_type_node,
12766 V16QI_type_node, NULL_TREE);
12767 tree int_ftype_int_v4sf_v4sf
12768 = build_function_type_list (integer_type_node,
12769 integer_type_node, V4SF_type_node,
12770 V4SF_type_node, NULL_TREE);
12771 tree int_ftype_int_v2df_v2df
12772 = build_function_type_list (integer_type_node,
12773 integer_type_node, V2DF_type_node,
12774 V2DF_type_node, NULL_TREE);
12775 tree v4si_ftype_v4si
12776 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12777 tree v8hi_ftype_v8hi
12778 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12779 tree v16qi_ftype_v16qi
12780 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12781 tree v4sf_ftype_v4sf
12782 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12783 tree v2df_ftype_v2df
12784 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12785 tree void_ftype_pcvoid_int_int
12786 = build_function_type_list (void_type_node,
12787 pcvoid_type_node, integer_type_node,
12788 integer_type_node, NULL_TREE);
12790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12791 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12793 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12795 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12797 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12799 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12801 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12802 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12803 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12804 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12805 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12806 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12807 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12808 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12809 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12810 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12811 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12812 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12813 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12814 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12815 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12816 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12817 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12818 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12819 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12820 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12821 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12822 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12823 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12824 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12825 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12826 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12827 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12828 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12829 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12830 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12831 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12832 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12833 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12834 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12835 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12837 if (rs6000_cpu == PROCESSOR_CELL)
12839 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12840 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12841 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12842 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12844 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12845 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12846 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12847 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12849 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12850 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12851 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12852 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12854 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12855 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12856 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12857 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12859 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12860 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12861 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12863 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12864 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12865 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12866 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12867 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12868 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12869 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12870 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12871 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12872 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12873 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12874 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12876 /* Add the DST variants. */
12878 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12879 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12881 /* Initialize the predicates. */
12882 dp = bdesc_altivec_preds;
12883 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12885 enum machine_mode mode1;
12887 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12888 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12889 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12890 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12895 mode1 = insn_data[dp->icode].operand[1].mode;
12900 type = int_ftype_int_opaque_opaque;
12903 type = int_ftype_int_v4si_v4si;
12906 type = int_ftype_int_v8hi_v8hi;
12909 type = int_ftype_int_v16qi_v16qi;
12912 type = int_ftype_int_v4sf_v4sf;
12915 type = int_ftype_int_v2df_v2df;
12918 gcc_unreachable ();
12921 def_builtin (dp->mask, dp->name, type, dp->code);
12924 /* Initialize the abs* operators. */
12926 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12928 enum machine_mode mode0;
12931 mode0 = insn_data[d->icode].operand[0].mode;
12936 type = v4si_ftype_v4si;
12939 type = v8hi_ftype_v8hi;
12942 type = v16qi_ftype_v16qi;
12945 type = v4sf_ftype_v4sf;
12948 type = v2df_ftype_v2df;
12951 gcc_unreachable ();
12954 def_builtin (d->mask, d->name, type, d->code);
12957 if (TARGET_ALTIVEC)
12961 /* Initialize target builtin that implements
12962 targetm.vectorize.builtin_mask_for_load. */
12964 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12965 v16qi_ftype_long_pcvoid,
12966 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12967 BUILT_IN_MD, NULL, NULL_TREE);
12968 TREE_READONLY (decl) = 1;
12969 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12970 altivec_builtin_mask_for_load = decl;
12973 /* Access to the vec_init patterns. */
12974 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12975 integer_type_node, integer_type_node,
12976 integer_type_node, NULL_TREE);
12977 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12978 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12980 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12981 short_integer_type_node,
12982 short_integer_type_node,
12983 short_integer_type_node,
12984 short_integer_type_node,
12985 short_integer_type_node,
12986 short_integer_type_node,
12987 short_integer_type_node, NULL_TREE);
12988 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12989 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12991 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12992 char_type_node, char_type_node,
12993 char_type_node, char_type_node,
12994 char_type_node, char_type_node,
12995 char_type_node, char_type_node,
12996 char_type_node, char_type_node,
12997 char_type_node, char_type_node,
12998 char_type_node, char_type_node,
12999 char_type_node, NULL_TREE);
13000 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13001 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13003 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13004 float_type_node, float_type_node,
13005 float_type_node, NULL_TREE);
13006 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13007 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13011 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13012 double_type_node, NULL_TREE);
13013 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13014 VSX_BUILTIN_VEC_INIT_V2DF);
13016 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13017 intDI_type_node, NULL_TREE);
13018 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13019 VSX_BUILTIN_VEC_INIT_V2DI);
13022 /* Access to the vec_set patterns. */
13023 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13025 integer_type_node, NULL_TREE);
13026 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13027 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13029 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13031 integer_type_node, NULL_TREE);
13032 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13033 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13035 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13037 integer_type_node, NULL_TREE);
13038 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13039 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13041 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13043 integer_type_node, NULL_TREE);
13044 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13045 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13049 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13051 integer_type_node, NULL_TREE);
13052 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13053 VSX_BUILTIN_VEC_SET_V2DF);
13055 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13057 integer_type_node, NULL_TREE);
13058 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13059 VSX_BUILTIN_VEC_SET_V2DI);
13062 /* Access to the vec_extract patterns. */
13063 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13064 integer_type_node, NULL_TREE);
13065 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13066 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13068 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13069 integer_type_node, NULL_TREE);
13070 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13071 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13073 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13074 integer_type_node, NULL_TREE);
13075 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13076 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13078 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13079 integer_type_node, NULL_TREE);
13080 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13081 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13085 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13086 integer_type_node, NULL_TREE);
13087 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13088 VSX_BUILTIN_VEC_EXT_V2DF);
13090 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13091 integer_type_node, NULL_TREE);
13092 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13093 VSX_BUILTIN_VEC_EXT_V2DI);
13097 /* Hash function for builtin functions with up to 3 arguments and a return
13100 builtin_hash_function (const void *hash_entry)
13104 const struct builtin_hash_struct *bh =
13105 (const struct builtin_hash_struct *) hash_entry;
13107 for (i = 0; i < 4; i++)
13109 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13110 ret = (ret * 2) + bh->uns_p[i];
13116 /* Compare builtin hash entries H1 and H2 for equivalence. */
13118 builtin_hash_eq (const void *h1, const void *h2)
13120 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13121 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13123 return ((p1->mode[0] == p2->mode[0])
13124 && (p1->mode[1] == p2->mode[1])
13125 && (p1->mode[2] == p2->mode[2])
13126 && (p1->mode[3] == p2->mode[3])
13127 && (p1->uns_p[0] == p2->uns_p[0])
13128 && (p1->uns_p[1] == p2->uns_p[1])
13129 && (p1->uns_p[2] == p2->uns_p[2])
13130 && (p1->uns_p[3] == p2->uns_p[3]));
13133 /* Map types for builtin functions with an explicit return type and up to 3
13134 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13135 of the argument. */
13137 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13138 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13139 enum rs6000_builtins builtin, const char *name)
13141 struct builtin_hash_struct h;
13142 struct builtin_hash_struct *h2;
13146 tree ret_type = NULL_TREE;
13147 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13150 /* Create builtin_hash_table. */
13151 if (builtin_hash_table == NULL)
13152 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13153 builtin_hash_eq, NULL);
13155 h.type = NULL_TREE;
13156 h.mode[0] = mode_ret;
13157 h.mode[1] = mode_arg0;
13158 h.mode[2] = mode_arg1;
13159 h.mode[3] = mode_arg2;
13165 /* If the builtin is a type that produces unsigned results or takes unsigned
13166 arguments, and it is returned as a decl for the vectorizer (such as
13167 widening multiplies, permute), make sure the arguments and return value
13168 are type correct. */
13171 /* unsigned 2 argument functions. */
13172 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13173 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13174 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13175 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13181 /* unsigned 3 argument functions. */
13182 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13183 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13184 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13185 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13186 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13187 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13188 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13189 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13190 case VSX_BUILTIN_VPERM_16QI_UNS:
13191 case VSX_BUILTIN_VPERM_8HI_UNS:
13192 case VSX_BUILTIN_VPERM_4SI_UNS:
13193 case VSX_BUILTIN_VPERM_2DI_UNS:
13194 case VSX_BUILTIN_XXSEL_16QI_UNS:
13195 case VSX_BUILTIN_XXSEL_8HI_UNS:
13196 case VSX_BUILTIN_XXSEL_4SI_UNS:
13197 case VSX_BUILTIN_XXSEL_2DI_UNS:
13204 /* signed permute functions with unsigned char mask. */
13205 case ALTIVEC_BUILTIN_VPERM_16QI:
13206 case ALTIVEC_BUILTIN_VPERM_8HI:
13207 case ALTIVEC_BUILTIN_VPERM_4SI:
13208 case ALTIVEC_BUILTIN_VPERM_4SF:
13209 case ALTIVEC_BUILTIN_VPERM_2DI:
13210 case ALTIVEC_BUILTIN_VPERM_2DF:
13211 case VSX_BUILTIN_VPERM_16QI:
13212 case VSX_BUILTIN_VPERM_8HI:
13213 case VSX_BUILTIN_VPERM_4SI:
13214 case VSX_BUILTIN_VPERM_4SF:
13215 case VSX_BUILTIN_VPERM_2DI:
13216 case VSX_BUILTIN_VPERM_2DF:
13220 /* unsigned args, signed return. */
13221 case VSX_BUILTIN_XVCVUXDDP_UNS:
13222 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13226 /* signed args, unsigned return. */
13227 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13228 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13236 /* Figure out how many args are present. */
13237 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13241 fatal_error ("internal error: builtin function %s had no type", name);
13243 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13244 if (!ret_type && h.uns_p[0])
13245 ret_type = builtin_mode_to_type[h.mode[0]][0];
13248 fatal_error ("internal error: builtin function %s had an unexpected "
13249 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13251 for (i = 0; i < num_args; i++)
13253 int m = (int) h.mode[i+1];
13254 int uns_p = h.uns_p[i+1];
13256 arg_type[i] = builtin_mode_to_type[m][uns_p];
13257 if (!arg_type[i] && uns_p)
13258 arg_type[i] = builtin_mode_to_type[m][0];
13261 fatal_error ("internal error: builtin function %s, argument %d "
13262 "had unexpected argument type %s", name, i,
13263 GET_MODE_NAME (m));
13266 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13267 if (*found == NULL)
13269 h2 = ggc_alloc_builtin_hash_struct ();
13271 *found = (void *)h2;
13272 args = void_list_node;
13274 for (i = num_args - 1; i >= 0; i--)
13275 args = tree_cons (NULL_TREE, arg_type[i], args);
13277 h2->type = build_function_type (ret_type, args);
13280 return ((struct builtin_hash_struct *)(*found))->type;
13284 rs6000_common_init_builtins (void)
13286 const struct builtin_description *d;
13289 tree opaque_ftype_opaque = NULL_TREE;
13290 tree opaque_ftype_opaque_opaque = NULL_TREE;
13291 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13292 tree v2si_ftype_qi = NULL_TREE;
13293 tree v2si_ftype_v2si_qi = NULL_TREE;
13294 tree v2si_ftype_int_qi = NULL_TREE;
13296 if (!TARGET_PAIRED_FLOAT)
13298 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13299 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13302 /* Add the ternary operators. */
13304 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13307 int mask = d->mask;
13309 if ((mask != 0 && (mask & target_flags) == 0)
13310 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13313 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13314 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13315 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13316 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13318 if (! (type = opaque_ftype_opaque_opaque_opaque))
13319 type = opaque_ftype_opaque_opaque_opaque
13320 = build_function_type_list (opaque_V4SI_type_node,
13321 opaque_V4SI_type_node,
13322 opaque_V4SI_type_node,
13323 opaque_V4SI_type_node,
13328 enum insn_code icode = d->icode;
13329 if (d->name == 0 || icode == CODE_FOR_nothing)
13332 type = builtin_function_type (insn_data[icode].operand[0].mode,
13333 insn_data[icode].operand[1].mode,
13334 insn_data[icode].operand[2].mode,
13335 insn_data[icode].operand[3].mode,
13339 def_builtin (d->mask, d->name, type, d->code);
13342 /* Add the binary operators. */
13344 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13346 enum machine_mode mode0, mode1, mode2;
13348 int mask = d->mask;
13350 if ((mask != 0 && (mask & target_flags) == 0)
13351 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13354 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13355 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13356 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13357 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13359 if (! (type = opaque_ftype_opaque_opaque))
13360 type = opaque_ftype_opaque_opaque
13361 = build_function_type_list (opaque_V4SI_type_node,
13362 opaque_V4SI_type_node,
13363 opaque_V4SI_type_node,
13368 enum insn_code icode = d->icode;
13369 if (d->name == 0 || icode == CODE_FOR_nothing)
13372 mode0 = insn_data[icode].operand[0].mode;
13373 mode1 = insn_data[icode].operand[1].mode;
13374 mode2 = insn_data[icode].operand[2].mode;
13376 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13378 if (! (type = v2si_ftype_v2si_qi))
13379 type = v2si_ftype_v2si_qi
13380 = build_function_type_list (opaque_V2SI_type_node,
13381 opaque_V2SI_type_node,
13386 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13387 && mode2 == QImode)
13389 if (! (type = v2si_ftype_int_qi))
13390 type = v2si_ftype_int_qi
13391 = build_function_type_list (opaque_V2SI_type_node,
13398 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13402 def_builtin (d->mask, d->name, type, d->code);
13405 /* Add the simple unary operators. */
13406 d = (struct builtin_description *) bdesc_1arg;
13407 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13409 enum machine_mode mode0, mode1;
13411 int mask = d->mask;
13413 if ((mask != 0 && (mask & target_flags) == 0)
13414 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13417 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13418 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13419 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13420 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13422 if (! (type = opaque_ftype_opaque))
13423 type = opaque_ftype_opaque
13424 = build_function_type_list (opaque_V4SI_type_node,
13425 opaque_V4SI_type_node,
13430 enum insn_code icode = d->icode;
13431 if (d->name == 0 || icode == CODE_FOR_nothing)
13434 mode0 = insn_data[icode].operand[0].mode;
13435 mode1 = insn_data[icode].operand[1].mode;
13437 if (mode0 == V2SImode && mode1 == QImode)
13439 if (! (type = v2si_ftype_qi))
13440 type = v2si_ftype_qi
13441 = build_function_type_list (opaque_V2SI_type_node,
13447 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13451 def_builtin (d->mask, d->name, type, d->code);
13456 rs6000_init_libfuncs (void)
13458 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13459 && !TARGET_POWER2 && !TARGET_POWERPC)
13461 /* AIX library routines for float->int conversion. */
13462 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13463 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13464 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13465 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13468 if (!TARGET_IEEEQUAD)
13469 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13470 if (!TARGET_XL_COMPAT)
13472 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13473 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13474 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13475 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13477 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13479 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13480 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13481 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13482 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13483 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13484 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13485 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13487 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13488 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13489 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13490 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13491 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13492 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13493 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13494 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13497 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13498 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13502 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13503 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13504 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13505 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13509 /* 32-bit SVR4 quad floating point routines. */
13511 set_optab_libfunc (add_optab, TFmode, "_q_add");
13512 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13513 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13514 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13515 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13516 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13517 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13519 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13520 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13521 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13522 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13523 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13524 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13526 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13527 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13528 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13529 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13530 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13531 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13532 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13533 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13538 /* Expand a block clear operation, and return 1 if successful. Return 0
13539 if we should let the compiler generate normal code.
13541 operands[0] is the destination
13542 operands[1] is the length
13543 operands[3] is the alignment */
13546 expand_block_clear (rtx operands[])
13548 rtx orig_dest = operands[0];
13549 rtx bytes_rtx = operands[1];
13550 rtx align_rtx = operands[3];
13551 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13552 HOST_WIDE_INT align;
13553 HOST_WIDE_INT bytes;
13558 /* If this is not a fixed size move, just call memcpy */
13562 /* This must be a fixed size alignment */
13563 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13564 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13566 /* Anything to clear? */
13567 bytes = INTVAL (bytes_rtx);
13571 /* Use the builtin memset after a point, to avoid huge code bloat.
13572 When optimize_size, avoid any significant code bloat; calling
13573 memset is about 4 instructions, so allow for one instruction to
13574 load zero and three to do clearing. */
13575 if (TARGET_ALTIVEC && align >= 128)
13577 else if (TARGET_POWERPC64 && align >= 32)
13579 else if (TARGET_SPE && align >= 64)
13584 if (optimize_size && bytes > 3 * clear_step)
13586 if (! optimize_size && bytes > 8 * clear_step)
13589 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13591 enum machine_mode mode = BLKmode;
13594 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13599 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13604 else if (bytes >= 8 && TARGET_POWERPC64
13605 /* 64-bit loads and stores require word-aligned
13607 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13612 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13613 { /* move 4 bytes */
13617 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13618 { /* move 2 bytes */
13622 else /* move 1 byte at a time */
13628 dest = adjust_address (orig_dest, mode, offset);
13630 emit_move_insn (dest, CONST0_RTX (mode));
13637 /* Expand a block move operation, and return 1 if successful. Return 0
13638 if we should let the compiler generate normal code.
13640 operands[0] is the destination
13641 operands[1] is the source
13642 operands[2] is the length
13643 operands[3] is the alignment */
13645 #define MAX_MOVE_REG 4
13648 expand_block_move (rtx operands[])
13650 rtx orig_dest = operands[0];
13651 rtx orig_src = operands[1];
13652 rtx bytes_rtx = operands[2];
13653 rtx align_rtx = operands[3];
13654 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13659 rtx stores[MAX_MOVE_REG];
13662 /* If this is not a fixed size move, just call memcpy */
13666 /* This must be a fixed size alignment */
13667 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13668 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13670 /* Anything to move? */
13671 bytes = INTVAL (bytes_rtx);
13675 if (bytes > rs6000_block_move_inline_limit)
13678 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13681 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13682 rtx (*mov) (rtx, rtx);
13684 enum machine_mode mode = BLKmode;
13687 /* Altivec first, since it will be faster than a string move
13688 when it applies, and usually not significantly larger. */
13689 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13693 gen_func.mov = gen_movv4si;
13695 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13699 gen_func.mov = gen_movv2si;
13701 else if (TARGET_STRING
13702 && bytes > 24 /* move up to 32 bytes at a time */
13708 && ! fixed_regs[10]
13709 && ! fixed_regs[11]
13710 && ! fixed_regs[12])
13712 move_bytes = (bytes > 32) ? 32 : bytes;
13713 gen_func.movmemsi = gen_movmemsi_8reg;
13715 else if (TARGET_STRING
13716 && bytes > 16 /* move up to 24 bytes at a time */
13722 && ! fixed_regs[10])
13724 move_bytes = (bytes > 24) ? 24 : bytes;
13725 gen_func.movmemsi = gen_movmemsi_6reg;
13727 else if (TARGET_STRING
13728 && bytes > 8 /* move up to 16 bytes at a time */
13732 && ! fixed_regs[8])
13734 move_bytes = (bytes > 16) ? 16 : bytes;
13735 gen_func.movmemsi = gen_movmemsi_4reg;
13737 else if (bytes >= 8 && TARGET_POWERPC64
13738 /* 64-bit loads and stores require word-aligned
13740 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13744 gen_func.mov = gen_movdi;
13746 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13747 { /* move up to 8 bytes at a time */
13748 move_bytes = (bytes > 8) ? 8 : bytes;
13749 gen_func.movmemsi = gen_movmemsi_2reg;
13751 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13752 { /* move 4 bytes */
13755 gen_func.mov = gen_movsi;
13757 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13758 { /* move 2 bytes */
13761 gen_func.mov = gen_movhi;
13763 else if (TARGET_STRING && bytes > 1)
13764 { /* move up to 4 bytes at a time */
13765 move_bytes = (bytes > 4) ? 4 : bytes;
13766 gen_func.movmemsi = gen_movmemsi_1reg;
13768 else /* move 1 byte at a time */
13772 gen_func.mov = gen_movqi;
13775 src = adjust_address (orig_src, mode, offset);
13776 dest = adjust_address (orig_dest, mode, offset);
13778 if (mode != BLKmode)
13780 rtx tmp_reg = gen_reg_rtx (mode);
13782 emit_insn ((*gen_func.mov) (tmp_reg, src));
13783 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13786 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13789 for (i = 0; i < num_reg; i++)
13790 emit_insn (stores[i]);
13794 if (mode == BLKmode)
13796 /* Move the address into scratch registers. The movmemsi
13797 patterns require zero offset. */
13798 if (!REG_P (XEXP (src, 0)))
13800 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13801 src = replace_equiv_address (src, src_reg);
13803 set_mem_size (src, GEN_INT (move_bytes));
13805 if (!REG_P (XEXP (dest, 0)))
13807 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13808 dest = replace_equiv_address (dest, dest_reg);
13810 set_mem_size (dest, GEN_INT (move_bytes));
13812 emit_insn ((*gen_func.movmemsi) (dest, src,
13813 GEN_INT (move_bytes & 31),
13822 /* Return a string to perform a load_multiple operation.
13823 operands[0] is the vector.
13824 operands[1] is the source address.
13825 operands[2] is the first destination register. */
13828 rs6000_output_load_multiple (rtx operands[3])
13830 /* We have to handle the case where the pseudo used to contain the address
13831 is assigned to one of the output registers. */
13833 int words = XVECLEN (operands[0], 0);
13836 if (XVECLEN (operands[0], 0) == 1)
13837 return "{l|lwz} %2,0(%1)";
13839 for (i = 0; i < words; i++)
13840 if (refers_to_regno_p (REGNO (operands[2]) + i,
13841 REGNO (operands[2]) + i + 1, operands[1], 0))
13845 xop[0] = GEN_INT (4 * (words-1));
13846 xop[1] = operands[1];
13847 xop[2] = operands[2];
13848 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13853 xop[0] = GEN_INT (4 * (words-1));
13854 xop[1] = operands[1];
13855 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13856 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);
13861 for (j = 0; j < words; j++)
13864 xop[0] = GEN_INT (j * 4);
13865 xop[1] = operands[1];
13866 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13867 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13869 xop[0] = GEN_INT (i * 4);
13870 xop[1] = operands[1];
13871 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13876 return "{lsi|lswi} %2,%1,%N0";
13880 /* A validation routine: say whether CODE, a condition code, and MODE
13881 match. The other alternatives either don't make sense or should
13882 never be generated. */
13885 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13887 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13888 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13889 && GET_MODE_CLASS (mode) == MODE_CC);
13891 /* These don't make sense. */
13892 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13893 || mode != CCUNSmode);
13895 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13896 || mode == CCUNSmode);
13898 gcc_assert (mode == CCFPmode
13899 || (code != ORDERED && code != UNORDERED
13900 && code != UNEQ && code != LTGT
13901 && code != UNGT && code != UNLT
13902 && code != UNGE && code != UNLE));
13904 /* These should never be generated except for
13905 flag_finite_math_only. */
13906 gcc_assert (mode != CCFPmode
13907 || flag_finite_math_only
13908 || (code != LE && code != GE
13909 && code != UNEQ && code != LTGT
13910 && code != UNGT && code != UNLT));
13912 /* These are invalid; the information is not there. */
13913 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13917 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13918 mask required to convert the result of a rotate insn into a shift
13919 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13922 includes_lshift_p (rtx shiftop, rtx andop)
13924 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13926 shift_mask <<= INTVAL (shiftop);
13928 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13931 /* Similar, but for right shift. */
13934 includes_rshift_p (rtx shiftop, rtx andop)
13936 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13938 shift_mask >>= INTVAL (shiftop);
13940 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13943 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13944 to perform a left shift. It must have exactly SHIFTOP least
13945 significant 0's, then one or more 1's, then zero or more 0's. */
13948 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13950 if (GET_CODE (andop) == CONST_INT)
13952 HOST_WIDE_INT c, lsb, shift_mask;
13954 c = INTVAL (andop);
13955 if (c == 0 || c == ~0)
13959 shift_mask <<= INTVAL (shiftop);
13961 /* Find the least significant one bit. */
13964 /* It must coincide with the LSB of the shift mask. */
13965 if (-lsb != shift_mask)
13968 /* Invert to look for the next transition (if any). */
13971 /* Remove the low group of ones (originally low group of zeros). */
13974 /* Again find the lsb, and check we have all 1's above. */
13978 else if (GET_CODE (andop) == CONST_DOUBLE
13979 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13981 HOST_WIDE_INT low, high, lsb;
13982 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13984 low = CONST_DOUBLE_LOW (andop);
13985 if (HOST_BITS_PER_WIDE_INT < 64)
13986 high = CONST_DOUBLE_HIGH (andop);
13988 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13989 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13992 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13994 shift_mask_high = ~0;
13995 if (INTVAL (shiftop) > 32)
13996 shift_mask_high <<= INTVAL (shiftop) - 32;
13998 lsb = high & -high;
14000 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14006 lsb = high & -high;
14007 return high == -lsb;
14010 shift_mask_low = ~0;
14011 shift_mask_low <<= INTVAL (shiftop);
14015 if (-lsb != shift_mask_low)
14018 if (HOST_BITS_PER_WIDE_INT < 64)
14023 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14025 lsb = high & -high;
14026 return high == -lsb;
14030 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14036 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14037 to perform a left shift. It must have SHIFTOP or more least
14038 significant 0's, with the remainder of the word 1's. */
14041 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14043 if (GET_CODE (andop) == CONST_INT)
14045 HOST_WIDE_INT c, lsb, shift_mask;
14048 shift_mask <<= INTVAL (shiftop);
14049 c = INTVAL (andop);
14051 /* Find the least significant one bit. */
14054 /* It must be covered by the shift mask.
14055 This test also rejects c == 0. */
14056 if ((lsb & shift_mask) == 0)
14059 /* Check we have all 1's above the transition, and reject all 1's. */
14060 return c == -lsb && lsb != 1;
14062 else if (GET_CODE (andop) == CONST_DOUBLE
14063 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14065 HOST_WIDE_INT low, lsb, shift_mask_low;
14067 low = CONST_DOUBLE_LOW (andop);
14069 if (HOST_BITS_PER_WIDE_INT < 64)
14071 HOST_WIDE_INT high, shift_mask_high;
14073 high = CONST_DOUBLE_HIGH (andop);
14077 shift_mask_high = ~0;
14078 if (INTVAL (shiftop) > 32)
14079 shift_mask_high <<= INTVAL (shiftop) - 32;
14081 lsb = high & -high;
14083 if ((lsb & shift_mask_high) == 0)
14086 return high == -lsb;
14092 shift_mask_low = ~0;
14093 shift_mask_low <<= INTVAL (shiftop);
14097 if ((lsb & shift_mask_low) == 0)
14100 return low == -lsb && lsb != 1;
14106 /* Return 1 if operands will generate a valid arguments to rlwimi
14107 instruction for insert with right shift in 64-bit mode. The mask may
14108 not start on the first bit or stop on the last bit because wrap-around
14109 effects of instruction do not correspond to semantics of RTL insn. */
14112 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14114 if (INTVAL (startop) > 32
14115 && INTVAL (startop) < 64
14116 && INTVAL (sizeop) > 1
14117 && INTVAL (sizeop) + INTVAL (startop) < 64
14118 && INTVAL (shiftop) > 0
14119 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14120 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14126 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14127 for lfq and stfq insns iff the registers are hard registers. */
14130 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14132 /* We might have been passed a SUBREG. */
14133 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14136 /* We might have been passed non floating point registers. */
14137 if (!FP_REGNO_P (REGNO (reg1))
14138 || !FP_REGNO_P (REGNO (reg2)))
14141 return (REGNO (reg1) == REGNO (reg2) - 1);
14144 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14145 addr1 and addr2 must be in consecutive memory locations
14146 (addr2 == addr1 + 8). */
14149 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14152 unsigned int reg1, reg2;
14153 int offset1, offset2;
14155 /* The mems cannot be volatile. */
14156 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14159 addr1 = XEXP (mem1, 0);
14160 addr2 = XEXP (mem2, 0);
14162 /* Extract an offset (if used) from the first addr. */
14163 if (GET_CODE (addr1) == PLUS)
14165 /* If not a REG, return zero. */
14166 if (GET_CODE (XEXP (addr1, 0)) != REG)
14170 reg1 = REGNO (XEXP (addr1, 0));
14171 /* The offset must be constant! */
14172 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14174 offset1 = INTVAL (XEXP (addr1, 1));
14177 else if (GET_CODE (addr1) != REG)
14181 reg1 = REGNO (addr1);
14182 /* This was a simple (mem (reg)) expression. Offset is 0. */
14186 /* And now for the second addr. */
14187 if (GET_CODE (addr2) == PLUS)
14189 /* If not a REG, return zero. */
14190 if (GET_CODE (XEXP (addr2, 0)) != REG)
14194 reg2 = REGNO (XEXP (addr2, 0));
14195 /* The offset must be constant. */
14196 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14198 offset2 = INTVAL (XEXP (addr2, 1));
14201 else if (GET_CODE (addr2) != REG)
14205 reg2 = REGNO (addr2);
14206 /* This was a simple (mem (reg)) expression. Offset is 0. */
14210 /* Both of these must have the same base register. */
14214 /* The offset for the second addr must be 8 more than the first addr. */
14215 if (offset2 != offset1 + 8)
14218 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14225 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14227 static bool eliminated = false;
14230 if (mode != SDmode)
14231 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14234 rtx mem = cfun->machine->sdmode_stack_slot;
14235 gcc_assert (mem != NULL_RTX);
14239 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14240 cfun->machine->sdmode_stack_slot = mem;
14246 if (TARGET_DEBUG_ADDR)
14248 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14249 GET_MODE_NAME (mode));
14251 fprintf (stderr, "\tNULL_RTX\n");
14260 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14262 /* Don't walk into types. */
14263 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14265 *walk_subtrees = 0;
14269 switch (TREE_CODE (*tp))
14278 case VIEW_CONVERT_EXPR:
14279 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14289 enum reload_reg_type {
14291 VECTOR_REGISTER_TYPE,
14292 OTHER_REGISTER_TYPE
14295 static enum reload_reg_type
14296 rs6000_reload_register_type (enum reg_class rclass)
14302 return GPR_REGISTER_TYPE;
14307 return VECTOR_REGISTER_TYPE;
14310 return OTHER_REGISTER_TYPE;
14314 /* Inform reload about cases where moving X with a mode MODE to a register in
14315 RCLASS requires an extra scratch or immediate register. Return the class
14316 needed for the immediate register.
14318 For VSX and Altivec, we may need a register to convert sp+offset into
14322 rs6000_secondary_reload (bool in_p,
14324 reg_class_t rclass_i,
14325 enum machine_mode mode,
14326 secondary_reload_info *sri)
14328 enum reg_class rclass = (enum reg_class) rclass_i;
14329 reg_class_t ret = ALL_REGS;
14330 enum insn_code icode;
14331 bool default_p = false;
14333 sri->icode = CODE_FOR_nothing;
14335 /* Convert vector loads and stores into gprs to use an additional base
14337 icode = rs6000_vector_reload[mode][in_p != false];
14338 if (icode != CODE_FOR_nothing)
14341 sri->icode = CODE_FOR_nothing;
14342 sri->extra_cost = 0;
14344 if (GET_CODE (x) == MEM)
14346 rtx addr = XEXP (x, 0);
14348 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14349 an extra register in that case, but it would need an extra
14350 register if the addressing is reg+reg or (reg+reg)&(-16). */
14351 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14353 if (!legitimate_indirect_address_p (addr, false)
14354 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14356 sri->icode = icode;
14357 /* account for splitting the loads, and converting the
14358 address from reg+reg to reg. */
14359 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14360 + ((GET_CODE (addr) == AND) ? 1 : 0));
14363 /* Loads to and stores from vector registers can only do reg+reg
14364 addressing. Altivec registers can also do (reg+reg)&(-16). */
14365 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14366 || rclass == FLOAT_REGS || rclass == NO_REGS)
14368 if (!VECTOR_MEM_ALTIVEC_P (mode)
14369 && GET_CODE (addr) == AND
14370 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14371 && INTVAL (XEXP (addr, 1)) == -16
14372 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14373 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14375 sri->icode = icode;
14376 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14379 else if (!legitimate_indirect_address_p (addr, false)
14380 && (rclass == NO_REGS
14381 || !legitimate_indexed_address_p (addr, false)))
14383 sri->icode = icode;
14384 sri->extra_cost = 1;
14387 icode = CODE_FOR_nothing;
14389 /* Any other loads, including to pseudo registers which haven't been
14390 assigned to a register yet, default to require a scratch
14394 sri->icode = icode;
14395 sri->extra_cost = 2;
14398 else if (REG_P (x))
14400 int regno = true_regnum (x);
14402 icode = CODE_FOR_nothing;
14403 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14407 enum reg_class xclass = REGNO_REG_CLASS (regno);
14408 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14409 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14411 /* If memory is needed, use default_secondary_reload to create the
14413 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14426 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14428 gcc_assert (ret != ALL_REGS);
14430 if (TARGET_DEBUG_ADDR)
14433 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14435 reg_class_names[ret],
14436 in_p ? "true" : "false",
14437 reg_class_names[rclass],
14438 GET_MODE_NAME (mode));
14441 fprintf (stderr, ", default secondary reload");
14443 if (sri->icode != CODE_FOR_nothing)
14444 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14445 insn_data[sri->icode].name, sri->extra_cost);
14447 fprintf (stderr, "\n");
14455 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14456 to SP+reg addressing. */
14459 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14461 int regno = true_regnum (reg);
14462 enum machine_mode mode = GET_MODE (reg);
14463 enum reg_class rclass;
14465 rtx and_op2 = NULL_RTX;
14468 rtx scratch_or_premodify = scratch;
14472 if (TARGET_DEBUG_ADDR)
14474 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14475 store_p ? "store" : "load");
14476 fprintf (stderr, "reg:\n");
14478 fprintf (stderr, "mem:\n");
14480 fprintf (stderr, "scratch:\n");
14481 debug_rtx (scratch);
14484 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14485 gcc_assert (GET_CODE (mem) == MEM);
14486 rclass = REGNO_REG_CLASS (regno);
14487 addr = XEXP (mem, 0);
14491 /* GPRs can handle reg + small constant, all other addresses need to use
14492 the scratch register. */
14495 if (GET_CODE (addr) == AND)
14497 and_op2 = XEXP (addr, 1);
14498 addr = XEXP (addr, 0);
14501 if (GET_CODE (addr) == PRE_MODIFY)
14503 scratch_or_premodify = XEXP (addr, 0);
14504 gcc_assert (REG_P (scratch_or_premodify));
14505 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14506 addr = XEXP (addr, 1);
14509 if (GET_CODE (addr) == PLUS
14510 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14511 || and_op2 != NULL_RTX))
14513 addr_op1 = XEXP (addr, 0);
14514 addr_op2 = XEXP (addr, 1);
14515 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14517 if (!REG_P (addr_op2)
14518 && (GET_CODE (addr_op2) != CONST_INT
14519 || !satisfies_constraint_I (addr_op2)))
14521 if (TARGET_DEBUG_ADDR)
14524 "\nMove plus addr to register %s, mode = %s: ",
14525 rs6000_reg_names[REGNO (scratch)],
14526 GET_MODE_NAME (mode));
14527 debug_rtx (addr_op2);
14529 rs6000_emit_move (scratch, addr_op2, Pmode);
14530 addr_op2 = scratch;
14533 emit_insn (gen_rtx_SET (VOIDmode,
14534 scratch_or_premodify,
14535 gen_rtx_PLUS (Pmode,
14539 addr = scratch_or_premodify;
14540 scratch_or_premodify = scratch;
14542 else if (!legitimate_indirect_address_p (addr, false)
14543 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14545 if (TARGET_DEBUG_ADDR)
14547 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14548 rs6000_reg_names[REGNO (scratch_or_premodify)],
14549 GET_MODE_NAME (mode));
14552 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14553 addr = scratch_or_premodify;
14554 scratch_or_premodify = scratch;
14558 /* Float/Altivec registers can only handle reg+reg addressing. Move
14559 other addresses into a scratch register. */
14564 /* With float regs, we need to handle the AND ourselves, since we can't
14565 use the Altivec instruction with an implicit AND -16. Allow scalar
14566 loads to float registers to use reg+offset even if VSX. */
14567 if (GET_CODE (addr) == AND
14568 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14569 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14570 || INTVAL (XEXP (addr, 1)) != -16
14571 || !VECTOR_MEM_ALTIVEC_P (mode)))
14573 and_op2 = XEXP (addr, 1);
14574 addr = XEXP (addr, 0);
14577 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14578 as the address later. */
14579 if (GET_CODE (addr) == PRE_MODIFY
14580 && (!VECTOR_MEM_VSX_P (mode)
14581 || and_op2 != NULL_RTX
14582 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14584 scratch_or_premodify = XEXP (addr, 0);
14585 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14587 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14588 addr = XEXP (addr, 1);
14591 if (legitimate_indirect_address_p (addr, false) /* reg */
14592 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14593 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14594 || (GET_CODE (addr) == AND /* Altivec memory */
14595 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14596 && INTVAL (XEXP (addr, 1)) == -16
14597 && VECTOR_MEM_ALTIVEC_P (mode))
14598 || (rclass == FLOAT_REGS /* legacy float mem */
14599 && GET_MODE_SIZE (mode) == 8
14600 && and_op2 == NULL_RTX
14601 && scratch_or_premodify == scratch
14602 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14605 else if (GET_CODE (addr) == PLUS)
14607 addr_op1 = XEXP (addr, 0);
14608 addr_op2 = XEXP (addr, 1);
14609 gcc_assert (REG_P (addr_op1));
14611 if (TARGET_DEBUG_ADDR)
14613 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14614 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14615 debug_rtx (addr_op2);
14617 rs6000_emit_move (scratch, addr_op2, Pmode);
14618 emit_insn (gen_rtx_SET (VOIDmode,
14619 scratch_or_premodify,
14620 gen_rtx_PLUS (Pmode,
14623 addr = scratch_or_premodify;
14624 scratch_or_premodify = scratch;
14627 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14628 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14630 if (TARGET_DEBUG_ADDR)
14632 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14633 rs6000_reg_names[REGNO (scratch_or_premodify)],
14634 GET_MODE_NAME (mode));
14638 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14639 addr = scratch_or_premodify;
14640 scratch_or_premodify = scratch;
14644 gcc_unreachable ();
14649 gcc_unreachable ();
14652 /* If the original address involved a pre-modify that we couldn't use the VSX
14653 memory instruction with update, and we haven't taken care of already,
14654 store the address in the pre-modify register and use that as the
14656 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14658 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14659 addr = scratch_or_premodify;
14662 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14663 memory instruction, recreate the AND now, including the clobber which is
14664 generated by the general ANDSI3/ANDDI3 patterns for the
14665 andi. instruction. */
14666 if (and_op2 != NULL_RTX)
14668 if (! legitimate_indirect_address_p (addr, false))
14670 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14674 if (TARGET_DEBUG_ADDR)
14676 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14677 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14678 debug_rtx (and_op2);
14681 and_rtx = gen_rtx_SET (VOIDmode,
14683 gen_rtx_AND (Pmode,
14687 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14688 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14689 gen_rtvec (2, and_rtx, cc_clobber)));
14693 /* Adjust the address if it changed. */
14694 if (addr != XEXP (mem, 0))
14696 mem = change_address (mem, mode, addr);
14697 if (TARGET_DEBUG_ADDR)
14698 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14701 /* Now create the move. */
14703 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14705 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14710 /* Target hook to return the cover classes for Integrated Register Allocator.
14711 Cover classes is a set of non-intersected register classes covering all hard
14712 registers used for register allocation purpose. Any move between two
14713 registers of a cover class should be cheaper than load or store of the
14714 registers. The value is array of register classes with LIM_REG_CLASSES used
14717 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14718 account for the Altivec and Floating registers being subsets of the VSX
14719 register set under VSX, but distinct register sets on pre-VSX machines. */
14721 static const reg_class_t *
14722 rs6000_ira_cover_classes (void)
14724 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14725 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14727 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14730 /* Allocate a 64-bit stack slot to be used for copying SDmode
14731 values through if this function has any SDmode references. */
14734 rs6000_alloc_sdmode_stack_slot (void)
14738 gimple_stmt_iterator gsi;
14740 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14743 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14745 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14748 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14749 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14755 /* Check for any SDmode parameters of the function. */
14756 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14758 if (TREE_TYPE (t) == error_mark_node)
14761 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14762 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14764 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14765 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14773 rs6000_instantiate_decls (void)
14775 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14776 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14779 /* Given an rtx X being reloaded into a reg required to be
14780 in class CLASS, return the class of reg to actually use.
14781 In general this is just CLASS; but on some machines
14782 in some cases it is preferable to use a more restrictive class.
14784 On the RS/6000, we have to return NO_REGS when we want to reload a
14785 floating-point CONST_DOUBLE to force it to be copied to memory.
14787 We also don't want to reload integer values into floating-point
14788 registers if we can at all help it. In fact, this can
14789 cause reload to die, if it tries to generate a reload of CTR
14790 into a FP register and discovers it doesn't have the memory location
14793 ??? Would it be a good idea to have reload do the converse, that is
14794 try to reload floating modes into FP registers if possible?
14797 static enum reg_class
14798 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14800 enum machine_mode mode = GET_MODE (x);
14802 if (VECTOR_UNIT_VSX_P (mode)
14803 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14806 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14807 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14808 && easy_vector_constant (x, mode))
14809 return ALTIVEC_REGS;
14811 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14814 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14815 return GENERAL_REGS;
14817 /* For VSX, prefer the traditional registers for 64-bit values because we can
14818 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14819 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14820 prefer Altivec loads.. */
14821 if (rclass == VSX_REGS)
14823 if (GET_MODE_SIZE (mode) <= 8)
14826 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14827 return ALTIVEC_REGS;
14835 /* Debug version of rs6000_preferred_reload_class. */
14836 static enum reg_class
14837 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14839 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14842 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14844 reg_class_names[ret], reg_class_names[rclass],
14845 GET_MODE_NAME (GET_MODE (x)));
14851 /* If we are copying between FP or AltiVec registers and anything else, we need
14852 a memory location. The exception is when we are targeting ppc64 and the
14853 move to/from fpr to gpr instructions are available. Also, under VSX, you
14854 can copy vector registers from the FP register set to the Altivec register
14855 set and vice versa. */
14858 rs6000_secondary_memory_needed (enum reg_class class1,
14859 enum reg_class class2,
14860 enum machine_mode mode)
14862 if (class1 == class2)
14865 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14866 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14867 between these classes. But we need memory for other things that can go in
14868 FLOAT_REGS like SFmode. */
14870 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14871 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14872 || class1 == FLOAT_REGS))
14873 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14874 && class2 != FLOAT_REGS);
14876 if (class1 == VSX_REGS || class2 == VSX_REGS)
14879 if (class1 == FLOAT_REGS
14880 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14881 || ((mode != DFmode)
14882 && (mode != DDmode)
14883 && (mode != DImode))))
14886 if (class2 == FLOAT_REGS
14887 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14888 || ((mode != DFmode)
14889 && (mode != DDmode)
14890 && (mode != DImode))))
14893 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14899 /* Debug version of rs6000_secondary_memory_needed. */
14901 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14902 enum reg_class class2,
14903 enum machine_mode mode)
14905 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14908 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14909 "class2 = %s, mode = %s\n",
14910 ret ? "true" : "false", reg_class_names[class1],
14911 reg_class_names[class2], GET_MODE_NAME (mode));
14916 /* Return the register class of a scratch register needed to copy IN into
14917 or out of a register in RCLASS in MODE. If it can be done directly,
14918 NO_REGS is returned. */
14920 static enum reg_class
14921 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14926 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14928 && MACHOPIC_INDIRECT
14932 /* We cannot copy a symbolic operand directly into anything
14933 other than BASE_REGS for TARGET_ELF. So indicate that a
14934 register from BASE_REGS is needed as an intermediate
14937 On Darwin, pic addresses require a load from memory, which
14938 needs a base register. */
14939 if (rclass != BASE_REGS
14940 && (GET_CODE (in) == SYMBOL_REF
14941 || GET_CODE (in) == HIGH
14942 || GET_CODE (in) == LABEL_REF
14943 || GET_CODE (in) == CONST))
14947 if (GET_CODE (in) == REG)
14949 regno = REGNO (in);
14950 if (regno >= FIRST_PSEUDO_REGISTER)
14952 regno = true_regnum (in);
14953 if (regno >= FIRST_PSEUDO_REGISTER)
14957 else if (GET_CODE (in) == SUBREG)
14959 regno = true_regnum (in);
14960 if (regno >= FIRST_PSEUDO_REGISTER)
14966 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14968 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14969 || (regno >= 0 && INT_REGNO_P (regno)))
14972 /* Constants, memory, and FP registers can go into FP registers. */
14973 if ((regno == -1 || FP_REGNO_P (regno))
14974 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14975 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14977 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14980 && (regno == -1 || VSX_REGNO_P (regno))
14981 && VSX_REG_CLASS_P (rclass))
14984 /* Memory, and AltiVec registers can go into AltiVec registers. */
14985 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14986 && rclass == ALTIVEC_REGS)
14989 /* We can copy among the CR registers. */
14990 if ((rclass == CR_REGS || rclass == CR0_REGS)
14991 && regno >= 0 && CR_REGNO_P (regno))
14994 /* Otherwise, we need GENERAL_REGS. */
14995 return GENERAL_REGS;
14998 /* Debug version of rs6000_secondary_reload_class. */
14999 static enum reg_class
15000 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15001 enum machine_mode mode, rtx in)
15003 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15005 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15006 "mode = %s, input rtx:\n",
15007 reg_class_names[ret], reg_class_names[rclass],
15008 GET_MODE_NAME (mode));
15014 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15017 rs6000_cannot_change_mode_class (enum machine_mode from,
15018 enum machine_mode to,
15019 enum reg_class rclass)
15021 unsigned from_size = GET_MODE_SIZE (from);
15022 unsigned to_size = GET_MODE_SIZE (to);
15024 if (from_size != to_size)
15026 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15027 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15028 && reg_classes_intersect_p (xclass, rclass));
15031 if (TARGET_E500_DOUBLE
15032 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15033 || (((to) == TFmode) + ((from) == TFmode)) == 1
15034 || (((to) == DDmode) + ((from) == DDmode)) == 1
15035 || (((to) == TDmode) + ((from) == TDmode)) == 1
15036 || (((to) == DImode) + ((from) == DImode)) == 1))
15039 /* Since the VSX register set includes traditional floating point registers
15040 and altivec registers, just check for the size being different instead of
15041 trying to check whether the modes are vector modes. Otherwise it won't
15042 allow say DF and DI to change classes. */
15043 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15044 return (from_size != 8 && from_size != 16);
15046 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15047 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15050 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15051 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15057 /* Debug version of rs6000_cannot_change_mode_class. */
15059 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15060 enum machine_mode to,
15061 enum reg_class rclass)
15063 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15066 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15067 "to = %s, rclass = %s\n",
15068 ret ? "true" : "false",
15069 GET_MODE_NAME (from), GET_MODE_NAME (to),
15070 reg_class_names[rclass]);
15075 /* Given a comparison operation, return the bit number in CCR to test. We
15076 know this is a valid comparison.
15078 SCC_P is 1 if this is for an scc. That means that %D will have been
15079 used instead of %C, so the bits will be in different places.
15081 Return -1 if OP isn't a valid comparison for some reason. */
15084 ccr_bit (rtx op, int scc_p)
15086 enum rtx_code code = GET_CODE (op);
15087 enum machine_mode cc_mode;
15092 if (!COMPARISON_P (op))
15095 reg = XEXP (op, 0);
15097 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15099 cc_mode = GET_MODE (reg);
15100 cc_regnum = REGNO (reg);
15101 base_bit = 4 * (cc_regnum - CR0_REGNO);
15103 validate_condition_mode (code, cc_mode);
15105 /* When generating a sCOND operation, only positive conditions are
15108 || code == EQ || code == GT || code == LT || code == UNORDERED
15109 || code == GTU || code == LTU);
15114 return scc_p ? base_bit + 3 : base_bit + 2;
15116 return base_bit + 2;
15117 case GT: case GTU: case UNLE:
15118 return base_bit + 1;
15119 case LT: case LTU: case UNGE:
15121 case ORDERED: case UNORDERED:
15122 return base_bit + 3;
15125 /* If scc, we will have done a cror to put the bit in the
15126 unordered position. So test that bit. For integer, this is ! LT
15127 unless this is an scc insn. */
15128 return scc_p ? base_bit + 3 : base_bit;
15131 return scc_p ? base_bit + 3 : base_bit + 1;
15134 gcc_unreachable ();
15138 /* Return the GOT register. */
15141 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15143 /* The second flow pass currently (June 1999) can't update
15144 regs_ever_live without disturbing other parts of the compiler, so
15145 update it here to make the prolog/epilogue code happy. */
15146 if (!can_create_pseudo_p ()
15147 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15148 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15150 crtl->uses_pic_offset_table = 1;
15152 return pic_offset_table_rtx;
15155 static rs6000_stack_t stack_info;
15157 /* Function to init struct machine_function.
15158 This will be called, via a pointer variable,
15159 from push_function_context. */
15161 static struct machine_function *
15162 rs6000_init_machine_status (void)
15164 stack_info.reload_completed = 0;
15165 return ggc_alloc_cleared_machine_function ();
15168 /* These macros test for integers and extract the low-order bits. */
15170 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15171 && GET_MODE (X) == VOIDmode)
15173 #define INT_LOWPART(X) \
15174 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15177 extract_MB (rtx op)
15180 unsigned long val = INT_LOWPART (op);
15182 /* If the high bit is zero, the value is the first 1 bit we find
15184 if ((val & 0x80000000) == 0)
15186 gcc_assert (val & 0xffffffff);
15189 while (((val <<= 1) & 0x80000000) == 0)
15194 /* If the high bit is set and the low bit is not, or the mask is all
15195 1's, the value is zero. */
15196 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15199 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15202 while (((val >>= 1) & 1) != 0)
15209 extract_ME (rtx op)
15212 unsigned long val = INT_LOWPART (op);
15214 /* If the low bit is zero, the value is the first 1 bit we find from
15216 if ((val & 1) == 0)
15218 gcc_assert (val & 0xffffffff);
15221 while (((val >>= 1) & 1) == 0)
15227 /* If the low bit is set and the high bit is not, or the mask is all
15228 1's, the value is 31. */
15229 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15232 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15235 while (((val <<= 1) & 0x80000000) != 0)
15241 /* Locate some local-dynamic symbol still in use by this function
15242 so that we can print its name in some tls_ld pattern. */
15244 static const char *
15245 rs6000_get_some_local_dynamic_name (void)
15249 if (cfun->machine->some_ld_name)
15250 return cfun->machine->some_ld_name;
15252 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15254 && for_each_rtx (&PATTERN (insn),
15255 rs6000_get_some_local_dynamic_name_1, 0))
15256 return cfun->machine->some_ld_name;
15258 gcc_unreachable ();
15261 /* Helper function for rs6000_get_some_local_dynamic_name. */
15264 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15268 if (GET_CODE (x) == SYMBOL_REF)
15270 const char *str = XSTR (x, 0);
15271 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15273 cfun->machine->some_ld_name = str;
15281 /* Write out a function code label. */
15284 rs6000_output_function_entry (FILE *file, const char *fname)
15286 if (fname[0] != '.')
15288 switch (DEFAULT_ABI)
15291 gcc_unreachable ();
15297 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15306 RS6000_OUTPUT_BASENAME (file, fname);
15309 /* Print an operand. Recognize special options, documented below. */
15312 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15313 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15315 #define SMALL_DATA_RELOC "sda21"
15316 #define SMALL_DATA_REG 0
15320 print_operand (FILE *file, rtx x, int code)
15324 unsigned HOST_WIDE_INT uval;
15329 /* Write out an instruction after the call which may be replaced
15330 with glue code by the loader. This depends on the AIX version. */
15331 asm_fprintf (file, RS6000_CALL_GLUE);
15334 /* %a is output_address. */
15337 /* If X is a constant integer whose low-order 5 bits are zero,
15338 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15339 in the AIX assembler where "sri" with a zero shift count
15340 writes a trash instruction. */
15341 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15348 /* If constant, low-order 16 bits of constant, unsigned.
15349 Otherwise, write normally. */
15351 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15353 print_operand (file, x, 0);
15357 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15358 for 64-bit mask direction. */
15359 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15362 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15366 /* X is a CR register. Print the number of the GT bit of the CR. */
15367 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15368 output_operand_lossage ("invalid %%c value");
15370 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15374 /* Like 'J' but get to the GT bit only. */
15375 gcc_assert (GET_CODE (x) == REG);
15377 /* Bit 1 is GT bit. */
15378 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15380 /* Add one for shift count in rlinm for scc. */
15381 fprintf (file, "%d", i + 1);
15385 /* X is a CR register. Print the number of the EQ bit of the CR */
15386 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15387 output_operand_lossage ("invalid %%E value");
15389 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15393 /* X is a CR register. Print the shift count needed to move it
15394 to the high-order four bits. */
15395 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15396 output_operand_lossage ("invalid %%f value");
15398 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15402 /* Similar, but print the count for the rotate in the opposite
15404 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15405 output_operand_lossage ("invalid %%F value");
15407 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15411 /* X is a constant integer. If it is negative, print "m",
15412 otherwise print "z". This is to make an aze or ame insn. */
15413 if (GET_CODE (x) != CONST_INT)
15414 output_operand_lossage ("invalid %%G value");
15415 else if (INTVAL (x) >= 0)
15422 /* If constant, output low-order five bits. Otherwise, write
15425 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15427 print_operand (file, x, 0);
15431 /* If constant, output low-order six bits. Otherwise, write
15434 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15436 print_operand (file, x, 0);
15440 /* Print `i' if this is a constant, else nothing. */
15446 /* Write the bit number in CCR for jump. */
15447 i = ccr_bit (x, 0);
15449 output_operand_lossage ("invalid %%j code");
15451 fprintf (file, "%d", i);
15455 /* Similar, but add one for shift count in rlinm for scc and pass
15456 scc flag to `ccr_bit'. */
15457 i = ccr_bit (x, 1);
15459 output_operand_lossage ("invalid %%J code");
15461 /* If we want bit 31, write a shift count of zero, not 32. */
15462 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15466 /* X must be a constant. Write the 1's complement of the
15469 output_operand_lossage ("invalid %%k value");
15471 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15475 /* X must be a symbolic constant on ELF. Write an
15476 expression suitable for an 'addi' that adds in the low 16
15477 bits of the MEM. */
15478 if (GET_CODE (x) == CONST)
15480 if (GET_CODE (XEXP (x, 0)) != PLUS
15481 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15482 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15483 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15484 output_operand_lossage ("invalid %%K value");
15486 print_operand_address (file, x);
15487 fputs ("@l", file);
15490 /* %l is output_asm_label. */
15493 /* Write second word of DImode or DFmode reference. Works on register
15494 or non-indexed memory only. */
15495 if (GET_CODE (x) == REG)
15496 fputs (reg_names[REGNO (x) + 1], file);
15497 else if (GET_CODE (x) == MEM)
15499 /* Handle possible auto-increment. Since it is pre-increment and
15500 we have already done it, we can just use an offset of word. */
15501 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15502 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15503 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15505 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15506 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15509 output_address (XEXP (adjust_address_nv (x, SImode,
15513 if (small_data_operand (x, GET_MODE (x)))
15514 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15515 reg_names[SMALL_DATA_REG]);
15520 /* MB value for a mask operand. */
15521 if (! mask_operand (x, SImode))
15522 output_operand_lossage ("invalid %%m value");
15524 fprintf (file, "%d", extract_MB (x));
15528 /* ME value for a mask operand. */
15529 if (! mask_operand (x, SImode))
15530 output_operand_lossage ("invalid %%M value");
15532 fprintf (file, "%d", extract_ME (x));
15535 /* %n outputs the negative of its operand. */
15538 /* Write the number of elements in the vector times 4. */
15539 if (GET_CODE (x) != PARALLEL)
15540 output_operand_lossage ("invalid %%N value");
15542 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15546 /* Similar, but subtract 1 first. */
15547 if (GET_CODE (x) != PARALLEL)
15548 output_operand_lossage ("invalid %%O value");
15550 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15554 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15556 || INT_LOWPART (x) < 0
15557 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15558 output_operand_lossage ("invalid %%p value");
15560 fprintf (file, "%d", i);
15564 /* The operand must be an indirect memory reference. The result
15565 is the register name. */
15566 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15567 || REGNO (XEXP (x, 0)) >= 32)
15568 output_operand_lossage ("invalid %%P value");
15570 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15574 /* This outputs the logical code corresponding to a boolean
15575 expression. The expression may have one or both operands
15576 negated (if one, only the first one). For condition register
15577 logical operations, it will also treat the negated
15578 CR codes as NOTs, but not handle NOTs of them. */
15580 const char *const *t = 0;
15582 enum rtx_code code = GET_CODE (x);
15583 static const char * const tbl[3][3] = {
15584 { "and", "andc", "nor" },
15585 { "or", "orc", "nand" },
15586 { "xor", "eqv", "xor" } };
15590 else if (code == IOR)
15592 else if (code == XOR)
15595 output_operand_lossage ("invalid %%q value");
15597 if (GET_CODE (XEXP (x, 0)) != NOT)
15601 if (GET_CODE (XEXP (x, 1)) == NOT)
15619 /* X is a CR register. Print the mask for `mtcrf'. */
15620 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15621 output_operand_lossage ("invalid %%R value");
15623 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15627 /* Low 5 bits of 32 - value */
15629 output_operand_lossage ("invalid %%s value");
15631 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15635 /* PowerPC64 mask position. All 0's is excluded.
15636 CONST_INT 32-bit mask is considered sign-extended so any
15637 transition must occur within the CONST_INT, not on the boundary. */
15638 if (! mask64_operand (x, DImode))
15639 output_operand_lossage ("invalid %%S value");
15641 uval = INT_LOWPART (x);
15643 if (uval & 1) /* Clear Left */
15645 #if HOST_BITS_PER_WIDE_INT > 64
15646 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15650 else /* Clear Right */
15653 #if HOST_BITS_PER_WIDE_INT > 64
15654 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15660 gcc_assert (i >= 0);
15661 fprintf (file, "%d", i);
15665 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15666 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15668 /* Bit 3 is OV bit. */
15669 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15671 /* If we want bit 31, write a shift count of zero, not 32. */
15672 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15676 /* Print the symbolic name of a branch target register. */
15677 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15678 && REGNO (x) != CTR_REGNO))
15679 output_operand_lossage ("invalid %%T value");
15680 else if (REGNO (x) == LR_REGNO)
15681 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15683 fputs ("ctr", file);
15687 /* High-order 16 bits of constant for use in unsigned operand. */
15689 output_operand_lossage ("invalid %%u value");
15691 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15692 (INT_LOWPART (x) >> 16) & 0xffff);
15696 /* High-order 16 bits of constant for use in signed operand. */
15698 output_operand_lossage ("invalid %%v value");
15700 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15701 (INT_LOWPART (x) >> 16) & 0xffff);
15705 /* Print `u' if this has an auto-increment or auto-decrement. */
15706 if (GET_CODE (x) == MEM
15707 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15708 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15709 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15714 /* Print the trap code for this operand. */
15715 switch (GET_CODE (x))
15718 fputs ("eq", file); /* 4 */
15721 fputs ("ne", file); /* 24 */
15724 fputs ("lt", file); /* 16 */
15727 fputs ("le", file); /* 20 */
15730 fputs ("gt", file); /* 8 */
15733 fputs ("ge", file); /* 12 */
15736 fputs ("llt", file); /* 2 */
15739 fputs ("lle", file); /* 6 */
15742 fputs ("lgt", file); /* 1 */
15745 fputs ("lge", file); /* 5 */
15748 gcc_unreachable ();
15753 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15756 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15757 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15759 print_operand (file, x, 0);
15763 /* MB value for a PowerPC64 rldic operand. */
15764 val = (GET_CODE (x) == CONST_INT
15765 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15770 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15771 if ((val <<= 1) < 0)
15774 #if HOST_BITS_PER_WIDE_INT == 32
15775 if (GET_CODE (x) == CONST_INT && i >= 0)
15776 i += 32; /* zero-extend high-part was all 0's */
15777 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15779 val = CONST_DOUBLE_LOW (x);
15785 for ( ; i < 64; i++)
15786 if ((val <<= 1) < 0)
15791 fprintf (file, "%d", i + 1);
15795 /* X is a FPR or Altivec register used in a VSX context. */
15796 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15797 output_operand_lossage ("invalid %%x value");
15800 int reg = REGNO (x);
15801 int vsx_reg = (FP_REGNO_P (reg)
15803 : reg - FIRST_ALTIVEC_REGNO + 32);
15805 #ifdef TARGET_REGNAMES
15806 if (TARGET_REGNAMES)
15807 fprintf (file, "%%vs%d", vsx_reg);
15810 fprintf (file, "%d", vsx_reg);
15815 if (GET_CODE (x) == MEM
15816 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15817 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15818 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15823 /* Like 'L', for third word of TImode */
15824 if (GET_CODE (x) == REG)
15825 fputs (reg_names[REGNO (x) + 2], file);
15826 else if (GET_CODE (x) == MEM)
15828 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15829 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15830 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15831 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15832 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15834 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15835 if (small_data_operand (x, GET_MODE (x)))
15836 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15837 reg_names[SMALL_DATA_REG]);
15842 /* X is a SYMBOL_REF. Write out the name preceded by a
15843 period and without any trailing data in brackets. Used for function
15844 names. If we are configured for System V (or the embedded ABI) on
15845 the PowerPC, do not emit the period, since those systems do not use
15846 TOCs and the like. */
15847 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15849 /* Mark the decl as referenced so that cgraph will output the
15851 if (SYMBOL_REF_DECL (x))
15852 mark_decl_referenced (SYMBOL_REF_DECL (x));
15854 /* For macho, check to see if we need a stub. */
15857 const char *name = XSTR (x, 0);
15859 if (darwin_emit_branch_islands
15860 && MACHOPIC_INDIRECT
15861 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15862 name = machopic_indirection_name (x, /*stub_p=*/true);
15864 assemble_name (file, name);
15866 else if (!DOT_SYMBOLS)
15867 assemble_name (file, XSTR (x, 0));
15869 rs6000_output_function_entry (file, XSTR (x, 0));
15873 /* Like 'L', for last word of TImode. */
15874 if (GET_CODE (x) == REG)
15875 fputs (reg_names[REGNO (x) + 3], file);
15876 else if (GET_CODE (x) == MEM)
15878 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15879 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15880 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15881 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15882 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15884 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15885 if (small_data_operand (x, GET_MODE (x)))
15886 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15887 reg_names[SMALL_DATA_REG]);
15891 /* Print AltiVec or SPE memory operand. */
15896 gcc_assert (GET_CODE (x) == MEM);
15900 /* Ugly hack because %y is overloaded. */
15901 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15902 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15903 || GET_MODE (x) == TFmode
15904 || GET_MODE (x) == TImode))
15906 /* Handle [reg]. */
15907 if (GET_CODE (tmp) == REG)
15909 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15912 /* Handle [reg+UIMM]. */
15913 else if (GET_CODE (tmp) == PLUS &&
15914 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15918 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15920 x = INTVAL (XEXP (tmp, 1));
15921 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15925 /* Fall through. Must be [reg+reg]. */
15927 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15928 && GET_CODE (tmp) == AND
15929 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15930 && INTVAL (XEXP (tmp, 1)) == -16)
15931 tmp = XEXP (tmp, 0);
15932 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15933 && GET_CODE (tmp) == PRE_MODIFY)
15934 tmp = XEXP (tmp, 1);
15935 if (GET_CODE (tmp) == REG)
15936 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15939 if (!GET_CODE (tmp) == PLUS
15940 || !REG_P (XEXP (tmp, 0))
15941 || !REG_P (XEXP (tmp, 1)))
15943 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15947 if (REGNO (XEXP (tmp, 0)) == 0)
15948 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15949 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15951 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15952 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15958 if (GET_CODE (x) == REG)
15959 fprintf (file, "%s", reg_names[REGNO (x)]);
15960 else if (GET_CODE (x) == MEM)
15962 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15963 know the width from the mode. */
15964 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15965 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15966 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15967 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15968 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15969 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15970 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15971 output_address (XEXP (XEXP (x, 0), 1));
15973 output_address (XEXP (x, 0));
15976 output_addr_const (file, x);
15980 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15984 output_operand_lossage ("invalid %%xn code");
15988 /* Print the address of an operand. */
15991 print_operand_address (FILE *file, rtx x)
15993 if (GET_CODE (x) == REG)
15994 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15995 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15996 || GET_CODE (x) == LABEL_REF)
15998 output_addr_const (file, x);
15999 if (small_data_operand (x, GET_MODE (x)))
16000 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16001 reg_names[SMALL_DATA_REG]);
16003 gcc_assert (!TARGET_TOC);
16005 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16007 gcc_assert (REG_P (XEXP (x, 0)));
16008 if (REGNO (XEXP (x, 0)) == 0)
16009 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16010 reg_names[ REGNO (XEXP (x, 0)) ]);
16012 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16013 reg_names[ REGNO (XEXP (x, 1)) ]);
16015 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16016 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16017 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16019 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16020 && CONSTANT_P (XEXP (x, 1)))
16022 fprintf (file, "lo16(");
16023 output_addr_const (file, XEXP (x, 1));
16024 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16027 else if (legitimate_constant_pool_address_p (x, true))
16029 /* This hack along with a corresponding hack in
16030 rs6000_output_addr_const_extra arranges to output addends
16031 where the assembler expects to find them. eg.
16033 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16034 without this hack would be output as "x@toc+8@l(9)". We
16035 want "x+8@toc@l(9)". */
16036 output_addr_const (file, tocrel_base);
16037 if (GET_CODE (x) == LO_SUM)
16038 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16040 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16043 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16044 && CONSTANT_P (XEXP (x, 1)))
16046 output_addr_const (file, XEXP (x, 1));
16047 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16051 gcc_unreachable ();
16054 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16057 rs6000_output_addr_const_extra (FILE *file, rtx x)
16059 if (GET_CODE (x) == UNSPEC)
16060 switch (XINT (x, 1))
16062 case UNSPEC_TOCREL:
16063 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16064 output_addr_const (file, XVECEXP (x, 0, 0));
16065 if (x == tocrel_base && tocrel_offset != const0_rtx)
16067 if (INTVAL (tocrel_offset) >= 0)
16068 fprintf (file, "+");
16069 output_addr_const (file, tocrel_offset);
16071 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16074 assemble_name (file, toc_label_name);
16076 else if (TARGET_ELF)
16077 fputs ("@toc", file);
16081 case UNSPEC_MACHOPIC_OFFSET:
16082 output_addr_const (file, XVECEXP (x, 0, 0));
16084 machopic_output_function_base_name (file);
16091 /* Target hook for assembling integer objects. The PowerPC version has
16092 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16093 is defined. It also needs to handle DI-mode objects on 64-bit
16097 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16099 #ifdef RELOCATABLE_NEEDS_FIXUP
16100 /* Special handling for SI values. */
16101 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16103 static int recurse = 0;
16105 /* For -mrelocatable, we mark all addresses that need to be fixed up
16106 in the .fixup section. */
16107 if (TARGET_RELOCATABLE
16108 && in_section != toc_section
16109 && in_section != text_section
16110 && !unlikely_text_section_p (in_section)
16112 && GET_CODE (x) != CONST_INT
16113 && GET_CODE (x) != CONST_DOUBLE
16119 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16121 ASM_OUTPUT_LABEL (asm_out_file, buf);
16122 fprintf (asm_out_file, "\t.long\t(");
16123 output_addr_const (asm_out_file, x);
16124 fprintf (asm_out_file, ")@fixup\n");
16125 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16126 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16127 fprintf (asm_out_file, "\t.long\t");
16128 assemble_name (asm_out_file, buf);
16129 fprintf (asm_out_file, "\n\t.previous\n");
16133 /* Remove initial .'s to turn a -mcall-aixdesc function
16134 address into the address of the descriptor, not the function
16136 else if (GET_CODE (x) == SYMBOL_REF
16137 && XSTR (x, 0)[0] == '.'
16138 && DEFAULT_ABI == ABI_AIX)
16140 const char *name = XSTR (x, 0);
16141 while (*name == '.')
16144 fprintf (asm_out_file, "\t.long\t%s\n", name);
16148 #endif /* RELOCATABLE_NEEDS_FIXUP */
16149 return default_assemble_integer (x, size, aligned_p);
16152 #ifdef HAVE_GAS_HIDDEN
16153 /* Emit an assembler directive to set symbol visibility for DECL to
16154 VISIBILITY_TYPE. */
16157 rs6000_assemble_visibility (tree decl, int vis)
16159 /* Functions need to have their entry point symbol visibility set as
16160 well as their descriptor symbol visibility. */
16161 if (DEFAULT_ABI == ABI_AIX
16163 && TREE_CODE (decl) == FUNCTION_DECL)
16165 static const char * const visibility_types[] = {
16166 NULL, "internal", "hidden", "protected"
16169 const char *name, *type;
16171 name = ((* targetm.strip_name_encoding)
16172 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16173 type = visibility_types[vis];
16175 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16176 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16179 default_assemble_visibility (decl, vis);
16184 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16186 /* Reversal of FP compares takes care -- an ordered compare
16187 becomes an unordered compare and vice versa. */
16188 if (mode == CCFPmode
16189 && (!flag_finite_math_only
16190 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16191 || code == UNEQ || code == LTGT))
16192 return reverse_condition_maybe_unordered (code);
16194 return reverse_condition (code);
16197 /* Generate a compare for CODE. Return a brand-new rtx that
16198 represents the result of the compare. */
16201 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16203 enum machine_mode comp_mode;
16204 rtx compare_result;
16205 enum rtx_code code = GET_CODE (cmp);
16206 rtx op0 = XEXP (cmp, 0);
16207 rtx op1 = XEXP (cmp, 1);
16209 if (FLOAT_MODE_P (mode))
16210 comp_mode = CCFPmode;
16211 else if (code == GTU || code == LTU
16212 || code == GEU || code == LEU)
16213 comp_mode = CCUNSmode;
16214 else if ((code == EQ || code == NE)
16215 && GET_CODE (op0) == SUBREG
16216 && GET_CODE (op1) == SUBREG
16217 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16218 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16219 /* These are unsigned values, perhaps there will be a later
16220 ordering compare that can be shared with this one.
16221 Unfortunately we cannot detect the signedness of the operands
16222 for non-subregs. */
16223 comp_mode = CCUNSmode;
16225 comp_mode = CCmode;
16227 /* First, the compare. */
16228 compare_result = gen_reg_rtx (comp_mode);
16230 /* E500 FP compare instructions on the GPRs. Yuck! */
16231 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16232 && FLOAT_MODE_P (mode))
16234 rtx cmp, or_result, compare_result2;
16235 enum machine_mode op_mode = GET_MODE (op0);
16237 if (op_mode == VOIDmode)
16238 op_mode = GET_MODE (op1);
16240 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16241 This explains the following mess. */
16245 case EQ: case UNEQ: case NE: case LTGT:
16249 cmp = (flag_finite_math_only && !flag_trapping_math)
16250 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16251 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16255 cmp = (flag_finite_math_only && !flag_trapping_math)
16256 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16257 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16261 cmp = (flag_finite_math_only && !flag_trapping_math)
16262 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16263 : gen_cmptfeq_gpr (compare_result, op0, op1);
16267 gcc_unreachable ();
16271 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16275 cmp = (flag_finite_math_only && !flag_trapping_math)
16276 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16277 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16281 cmp = (flag_finite_math_only && !flag_trapping_math)
16282 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16283 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16287 cmp = (flag_finite_math_only && !flag_trapping_math)
16288 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16289 : gen_cmptfgt_gpr (compare_result, op0, op1);
16293 gcc_unreachable ();
16297 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16301 cmp = (flag_finite_math_only && !flag_trapping_math)
16302 ? gen_tstsflt_gpr (compare_result, op0, op1)
16303 : gen_cmpsflt_gpr (compare_result, op0, op1);
16307 cmp = (flag_finite_math_only && !flag_trapping_math)
16308 ? gen_tstdflt_gpr (compare_result, op0, op1)
16309 : gen_cmpdflt_gpr (compare_result, op0, op1);
16313 cmp = (flag_finite_math_only && !flag_trapping_math)
16314 ? gen_tsttflt_gpr (compare_result, op0, op1)
16315 : gen_cmptflt_gpr (compare_result, op0, op1);
16319 gcc_unreachable ();
16323 gcc_unreachable ();
16326 /* Synthesize LE and GE from LT/GT || EQ. */
16327 if (code == LE || code == GE || code == LEU || code == GEU)
16333 case LE: code = LT; break;
16334 case GE: code = GT; break;
16335 case LEU: code = LT; break;
16336 case GEU: code = GT; break;
16337 default: gcc_unreachable ();
16340 compare_result2 = gen_reg_rtx (CCFPmode);
16346 cmp = (flag_finite_math_only && !flag_trapping_math)
16347 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16348 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16352 cmp = (flag_finite_math_only && !flag_trapping_math)
16353 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16354 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16358 cmp = (flag_finite_math_only && !flag_trapping_math)
16359 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16360 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16364 gcc_unreachable ();
16368 /* OR them together. */
16369 or_result = gen_reg_rtx (CCFPmode);
16370 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16372 compare_result = or_result;
16377 if (code == NE || code == LTGT)
16387 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16388 CLOBBERs to match cmptf_internal2 pattern. */
16389 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16390 && GET_MODE (op0) == TFmode
16391 && !TARGET_IEEEQUAD
16392 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16393 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16395 gen_rtx_SET (VOIDmode,
16397 gen_rtx_COMPARE (comp_mode, op0, op1)),
16398 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16399 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16400 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16401 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16402 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16403 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16404 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16405 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16406 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16407 else if (GET_CODE (op1) == UNSPEC
16408 && XINT (op1, 1) == UNSPEC_SP_TEST)
16410 rtx op1b = XVECEXP (op1, 0, 0);
16411 comp_mode = CCEQmode;
16412 compare_result = gen_reg_rtx (CCEQmode);
16414 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16416 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16419 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16420 gen_rtx_COMPARE (comp_mode, op0, op1)));
16423 /* Some kinds of FP comparisons need an OR operation;
16424 under flag_finite_math_only we don't bother. */
16425 if (FLOAT_MODE_P (mode)
16426 && !flag_finite_math_only
16427 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16428 && (code == LE || code == GE
16429 || code == UNEQ || code == LTGT
16430 || code == UNGT || code == UNLT))
16432 enum rtx_code or1, or2;
16433 rtx or1_rtx, or2_rtx, compare2_rtx;
16434 rtx or_result = gen_reg_rtx (CCEQmode);
16438 case LE: or1 = LT; or2 = EQ; break;
16439 case GE: or1 = GT; or2 = EQ; break;
16440 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16441 case LTGT: or1 = LT; or2 = GT; break;
16442 case UNGT: or1 = UNORDERED; or2 = GT; break;
16443 case UNLT: or1 = UNORDERED; or2 = LT; break;
16444 default: gcc_unreachable ();
16446 validate_condition_mode (or1, comp_mode);
16447 validate_condition_mode (or2, comp_mode);
16448 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16449 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16450 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16451 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16453 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16455 compare_result = or_result;
16459 validate_condition_mode (code, GET_MODE (compare_result));
16461 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16465 /* Emit the RTL for an sISEL pattern. */
16468 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16470 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16474 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16477 enum machine_mode op_mode;
16478 enum rtx_code cond_code;
16479 rtx result = operands[0];
16481 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16483 rs6000_emit_sISEL (mode, operands);
16487 condition_rtx = rs6000_generate_compare (operands[1], mode);
16488 cond_code = GET_CODE (condition_rtx);
16490 if (FLOAT_MODE_P (mode)
16491 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16495 PUT_MODE (condition_rtx, SImode);
16496 t = XEXP (condition_rtx, 0);
16498 gcc_assert (cond_code == NE || cond_code == EQ);
16500 if (cond_code == NE)
16501 emit_insn (gen_e500_flip_gt_bit (t, t));
16503 emit_insn (gen_move_from_CR_gt_bit (result, t));
16507 if (cond_code == NE
16508 || cond_code == GE || cond_code == LE
16509 || cond_code == GEU || cond_code == LEU
16510 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16512 rtx not_result = gen_reg_rtx (CCEQmode);
16513 rtx not_op, rev_cond_rtx;
16514 enum machine_mode cc_mode;
16516 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16518 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16519 SImode, XEXP (condition_rtx, 0), const0_rtx);
16520 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16521 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16522 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16525 op_mode = GET_MODE (XEXP (operands[1], 0));
16526 if (op_mode == VOIDmode)
16527 op_mode = GET_MODE (XEXP (operands[1], 1));
16529 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16531 PUT_MODE (condition_rtx, DImode);
16532 convert_move (result, condition_rtx, 0);
16536 PUT_MODE (condition_rtx, SImode);
16537 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16541 /* Emit a branch of kind CODE to location LOC. */
16544 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16546 rtx condition_rtx, loc_ref;
16548 condition_rtx = rs6000_generate_compare (operands[0], mode);
16549 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16550 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16551 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16552 loc_ref, pc_rtx)));
16555 /* Return the string to output a conditional branch to LABEL, which is
16556 the operand number of the label, or -1 if the branch is really a
16557 conditional return.
16559 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16560 condition code register and its mode specifies what kind of
16561 comparison we made.
16563 REVERSED is nonzero if we should reverse the sense of the comparison.
16565 INSN is the insn. */
16568 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16570 static char string[64];
16571 enum rtx_code code = GET_CODE (op);
16572 rtx cc_reg = XEXP (op, 0);
16573 enum machine_mode mode = GET_MODE (cc_reg);
16574 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16575 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16576 int really_reversed = reversed ^ need_longbranch;
16582 validate_condition_mode (code, mode);
16584 /* Work out which way this really branches. We could use
16585 reverse_condition_maybe_unordered here always but this
16586 makes the resulting assembler clearer. */
16587 if (really_reversed)
16589 /* Reversal of FP compares takes care -- an ordered compare
16590 becomes an unordered compare and vice versa. */
16591 if (mode == CCFPmode)
16592 code = reverse_condition_maybe_unordered (code);
16594 code = reverse_condition (code);
16597 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16599 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16604 /* Opposite of GT. */
16613 gcc_unreachable ();
16619 /* Not all of these are actually distinct opcodes, but
16620 we distinguish them for clarity of the resulting assembler. */
16621 case NE: case LTGT:
16622 ccode = "ne"; break;
16623 case EQ: case UNEQ:
16624 ccode = "eq"; break;
16626 ccode = "ge"; break;
16627 case GT: case GTU: case UNGT:
16628 ccode = "gt"; break;
16630 ccode = "le"; break;
16631 case LT: case LTU: case UNLT:
16632 ccode = "lt"; break;
16633 case UNORDERED: ccode = "un"; break;
16634 case ORDERED: ccode = "nu"; break;
16635 case UNGE: ccode = "nl"; break;
16636 case UNLE: ccode = "ng"; break;
16638 gcc_unreachable ();
16641 /* Maybe we have a guess as to how likely the branch is.
16642 The old mnemonics don't have a way to specify this information. */
16644 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16645 if (note != NULL_RTX)
16647 /* PROB is the difference from 50%. */
16648 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16650 /* Only hint for highly probable/improbable branches on newer
16651 cpus as static prediction overrides processor dynamic
16652 prediction. For older cpus we may as well always hint, but
16653 assume not taken for branches that are very close to 50% as a
16654 mispredicted taken branch is more expensive than a
16655 mispredicted not-taken branch. */
16656 if (rs6000_always_hint
16657 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16658 && br_prob_note_reliable_p (note)))
16660 if (abs (prob) > REG_BR_PROB_BASE / 20
16661 && ((prob > 0) ^ need_longbranch))
16669 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16671 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16673 /* We need to escape any '%' characters in the reg_names string.
16674 Assume they'd only be the first character.... */
16675 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16677 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16681 /* If the branch distance was too far, we may have to use an
16682 unconditional branch to go the distance. */
16683 if (need_longbranch)
16684 s += sprintf (s, ",$+8\n\tb %s", label);
16686 s += sprintf (s, ",%s", label);
16692 /* Return the string to flip the GT bit on a CR. */
16694 output_e500_flip_gt_bit (rtx dst, rtx src)
16696 static char string[64];
16699 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16700 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16703 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16704 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16706 sprintf (string, "crnot %d,%d", a, b);
16710 /* Return insn for VSX or Altivec comparisons. */
16713 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16716 enum machine_mode mode = GET_MODE (op0);
16724 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16730 mask = gen_reg_rtx (mode);
16731 emit_insn (gen_rtx_SET (VOIDmode,
16733 gen_rtx_fmt_ee (code, mode, op0, op1)));
16740 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16741 DMODE is expected destination mode. This is a recursive function. */
16744 rs6000_emit_vector_compare (enum rtx_code rcode,
16746 enum machine_mode dmode)
16749 bool swap_operands = false;
16750 bool try_again = false;
16752 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16753 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16755 /* See if the comparison works as is. */
16756 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16764 swap_operands = true;
16769 swap_operands = true;
16777 /* Invert condition and try again.
16778 e.g., A != B becomes ~(A==B). */
16780 enum rtx_code rev_code;
16781 enum insn_code nor_code;
16784 rev_code = reverse_condition_maybe_unordered (rcode);
16785 if (rev_code == UNKNOWN)
16788 nor_code = optab_handler (one_cmpl_optab, dmode);
16789 if (nor_code == CODE_FOR_nothing)
16792 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16796 mask = gen_reg_rtx (dmode);
16797 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16805 /* Try GT/GTU/LT/LTU OR EQ */
16808 enum insn_code ior_code;
16809 enum rtx_code new_code;
16830 gcc_unreachable ();
16833 ior_code = optab_handler (ior_optab, dmode);
16834 if (ior_code == CODE_FOR_nothing)
16837 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16841 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16845 mask = gen_reg_rtx (dmode);
16846 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16864 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16869 /* You only get two chances. */
16873 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16874 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16875 operands for the relation operation COND. */
16878 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16879 rtx cond, rtx cc_op0, rtx cc_op1)
16881 enum machine_mode dest_mode = GET_MODE (dest);
16882 enum rtx_code rcode = GET_CODE (cond);
16883 enum machine_mode cc_mode = CCmode;
16887 bool invert_move = false;
16889 if (VECTOR_UNIT_NONE_P (dest_mode))
16894 /* Swap operands if we can, and fall back to doing the operation as
16895 specified, and doing a NOR to invert the test. */
16901 /* Invert condition and try again.
16902 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16903 invert_move = true;
16904 rcode = reverse_condition_maybe_unordered (rcode);
16905 if (rcode == UNKNOWN)
16909 /* Mark unsigned tests with CCUNSmode. */
16914 cc_mode = CCUNSmode;
16921 /* Get the vector mask for the given relational operations. */
16922 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16930 op_true = op_false;
16934 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16935 emit_insn (gen_rtx_SET (VOIDmode,
16937 gen_rtx_IF_THEN_ELSE (dest_mode,
16944 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16945 operands of the last comparison is nonzero/true, FALSE_COND if it
16946 is zero/false. Return 0 if the hardware has no such operation. */
16949 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16951 enum rtx_code code = GET_CODE (op);
16952 rtx op0 = XEXP (op, 0);
16953 rtx op1 = XEXP (op, 1);
16954 REAL_VALUE_TYPE c1;
16955 enum machine_mode compare_mode = GET_MODE (op0);
16956 enum machine_mode result_mode = GET_MODE (dest);
16958 bool is_against_zero;
16960 /* These modes should always match. */
16961 if (GET_MODE (op1) != compare_mode
16962 /* In the isel case however, we can use a compare immediate, so
16963 op1 may be a small constant. */
16964 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16966 if (GET_MODE (true_cond) != result_mode)
16968 if (GET_MODE (false_cond) != result_mode)
16971 /* First, work out if the hardware can do this at all, or
16972 if it's too slow.... */
16973 if (!FLOAT_MODE_P (compare_mode))
16976 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16979 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16980 && SCALAR_FLOAT_MODE_P (compare_mode))
16983 is_against_zero = op1 == CONST0_RTX (compare_mode);
16985 /* A floating-point subtract might overflow, underflow, or produce
16986 an inexact result, thus changing the floating-point flags, so it
16987 can't be generated if we care about that. It's safe if one side
16988 of the construct is zero, since then no subtract will be
16990 if (SCALAR_FLOAT_MODE_P (compare_mode)
16991 && flag_trapping_math && ! is_against_zero)
16994 /* Eliminate half of the comparisons by switching operands, this
16995 makes the remaining code simpler. */
16996 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16997 || code == LTGT || code == LT || code == UNLE)
16999 code = reverse_condition_maybe_unordered (code);
17001 true_cond = false_cond;
17005 /* UNEQ and LTGT take four instructions for a comparison with zero,
17006 it'll probably be faster to use a branch here too. */
17007 if (code == UNEQ && HONOR_NANS (compare_mode))
17010 if (GET_CODE (op1) == CONST_DOUBLE)
17011 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17013 /* We're going to try to implement comparisons by performing
17014 a subtract, then comparing against zero. Unfortunately,
17015 Inf - Inf is NaN which is not zero, and so if we don't
17016 know that the operand is finite and the comparison
17017 would treat EQ different to UNORDERED, we can't do it. */
17018 if (HONOR_INFINITIES (compare_mode)
17019 && code != GT && code != UNGE
17020 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17021 /* Constructs of the form (a OP b ? a : b) are safe. */
17022 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17023 || (! rtx_equal_p (op0, true_cond)
17024 && ! rtx_equal_p (op1, true_cond))))
17027 /* At this point we know we can use fsel. */
17029 /* Reduce the comparison to a comparison against zero. */
17030 if (! is_against_zero)
17032 temp = gen_reg_rtx (compare_mode);
17033 emit_insn (gen_rtx_SET (VOIDmode, temp,
17034 gen_rtx_MINUS (compare_mode, op0, op1)));
17036 op1 = CONST0_RTX (compare_mode);
17039 /* If we don't care about NaNs we can reduce some of the comparisons
17040 down to faster ones. */
17041 if (! HONOR_NANS (compare_mode))
17047 true_cond = false_cond;
17060 /* Now, reduce everything down to a GE. */
17067 temp = gen_reg_rtx (compare_mode);
17068 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17073 temp = gen_reg_rtx (compare_mode);
17074 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17079 temp = gen_reg_rtx (compare_mode);
17080 emit_insn (gen_rtx_SET (VOIDmode, temp,
17081 gen_rtx_NEG (compare_mode,
17082 gen_rtx_ABS (compare_mode, op0))));
17087 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17088 temp = gen_reg_rtx (result_mode);
17089 emit_insn (gen_rtx_SET (VOIDmode, temp,
17090 gen_rtx_IF_THEN_ELSE (result_mode,
17091 gen_rtx_GE (VOIDmode,
17093 true_cond, false_cond)));
17094 false_cond = true_cond;
17097 temp = gen_reg_rtx (compare_mode);
17098 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17103 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17104 temp = gen_reg_rtx (result_mode);
17105 emit_insn (gen_rtx_SET (VOIDmode, temp,
17106 gen_rtx_IF_THEN_ELSE (result_mode,
17107 gen_rtx_GE (VOIDmode,
17109 true_cond, false_cond)));
17110 true_cond = false_cond;
17113 temp = gen_reg_rtx (compare_mode);
17114 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17119 gcc_unreachable ();
17122 emit_insn (gen_rtx_SET (VOIDmode, dest,
17123 gen_rtx_IF_THEN_ELSE (result_mode,
17124 gen_rtx_GE (VOIDmode,
17126 true_cond, false_cond)));
17130 /* Same as above, but for ints (isel). */
17133 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17135 rtx condition_rtx, cr;
17136 enum machine_mode mode = GET_MODE (dest);
17137 enum rtx_code cond_code;
17138 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17141 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17144 /* We still have to do the compare, because isel doesn't do a
17145 compare, it just looks at the CRx bits set by a previous compare
17147 condition_rtx = rs6000_generate_compare (op, mode);
17148 cond_code = GET_CODE (condition_rtx);
17149 cr = XEXP (condition_rtx, 0);
17150 signedp = GET_MODE (cr) == CCmode;
17152 isel_func = (mode == SImode
17153 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17154 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17158 case LT: case GT: case LTU: case GTU: case EQ:
17159 /* isel handles these directly. */
17163 /* We need to swap the sense of the comparison. */
17166 true_cond = false_cond;
17168 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17173 false_cond = force_reg (mode, false_cond);
17174 if (true_cond != const0_rtx)
17175 true_cond = force_reg (mode, true_cond);
17177 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17183 output_isel (rtx *operands)
17185 enum rtx_code code;
17187 code = GET_CODE (operands[1]);
17189 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17191 gcc_assert (GET_CODE (operands[2]) == REG
17192 && GET_CODE (operands[3]) == REG);
17193 PUT_CODE (operands[1], reverse_condition (code));
17194 return "isel %0,%3,%2,%j1";
17197 return "isel %0,%2,%3,%j1";
17201 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17203 enum machine_mode mode = GET_MODE (op0);
17207 /* VSX/altivec have direct min/max insns. */
17208 if ((code == SMAX || code == SMIN)
17209 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17210 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17212 emit_insn (gen_rtx_SET (VOIDmode,
17214 gen_rtx_fmt_ee (code, mode, op0, op1)));
17218 if (code == SMAX || code == SMIN)
17223 if (code == SMAX || code == UMAX)
17224 target = emit_conditional_move (dest, c, op0, op1, mode,
17225 op0, op1, mode, 0);
17227 target = emit_conditional_move (dest, c, op0, op1, mode,
17228 op1, op0, mode, 0);
17229 gcc_assert (target);
17230 if (target != dest)
17231 emit_move_insn (dest, target);
17234 /* Emit instructions to perform a load-reserved/store-conditional operation.
17235 The operation performed is an atomic
17236 (set M (CODE:MODE M OP))
17237 If not NULL, BEFORE is atomically set to M before the operation, and
17238 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17239 If SYNC_P then a memory barrier is emitted before the operation.
17240 Either OP or M may be wrapped in a NOT operation. */
17243 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17244 rtx m, rtx op, rtx before_param, rtx after_param,
17247 enum machine_mode used_mode;
17248 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17251 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17252 rtx shift = NULL_RTX;
17255 emit_insn (gen_lwsync ());
17259 /* If this is smaller than SImode, we'll have to use SImode with
17261 if (mode == QImode || mode == HImode)
17265 if (MEM_ALIGN (used_m) >= 32)
17268 if (BYTES_BIG_ENDIAN)
17269 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17271 shift = GEN_INT (ishift);
17272 used_m = change_address (used_m, SImode, 0);
17276 rtx addrSI, aligned_addr;
17277 int shift_mask = mode == QImode ? 0x18 : 0x10;
17279 addrSI = gen_lowpart_common (SImode,
17280 force_reg (Pmode, XEXP (used_m, 0)));
17281 addrSI = force_reg (SImode, addrSI);
17282 shift = gen_reg_rtx (SImode);
17284 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17285 GEN_INT (shift_mask)));
17286 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17288 aligned_addr = expand_binop (Pmode, and_optab,
17290 GEN_INT (-4), NULL_RTX,
17291 1, OPTAB_LIB_WIDEN);
17292 used_m = change_address (used_m, SImode, aligned_addr);
17293 set_mem_align (used_m, 32);
17295 /* It's safe to keep the old alias set of USED_M, because
17296 the operation is atomic and only affects the original
17300 if (GET_CODE (op) == NOT)
17302 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17303 oldop = gen_rtx_NOT (SImode, oldop);
17306 oldop = lowpart_subreg (SImode, op, mode);
17312 newop = expand_binop (SImode, and_optab,
17313 oldop, GEN_INT (imask), NULL_RTX,
17314 1, OPTAB_LIB_WIDEN);
17315 emit_insn (gen_ashlsi3 (newop, newop, shift));
17318 case NOT: /* NAND */
17319 newop = expand_binop (SImode, ior_optab,
17320 oldop, GEN_INT (~imask), NULL_RTX,
17321 1, OPTAB_LIB_WIDEN);
17322 emit_insn (gen_rotlsi3 (newop, newop, shift));
17326 newop = expand_binop (SImode, ior_optab,
17327 oldop, GEN_INT (~imask), NULL_RTX,
17328 1, OPTAB_LIB_WIDEN);
17329 emit_insn (gen_rotlsi3 (newop, newop, shift));
17337 newop = expand_binop (SImode, and_optab,
17338 oldop, GEN_INT (imask), NULL_RTX,
17339 1, OPTAB_LIB_WIDEN);
17340 emit_insn (gen_ashlsi3 (newop, newop, shift));
17342 mask = gen_reg_rtx (SImode);
17343 emit_move_insn (mask, GEN_INT (imask));
17344 emit_insn (gen_ashlsi3 (mask, mask, shift));
17347 newop = gen_rtx_PLUS (SImode, m, newop);
17349 newop = gen_rtx_MINUS (SImode, m, newop);
17350 newop = gen_rtx_AND (SImode, newop, mask);
17351 newop = gen_rtx_IOR (SImode, newop,
17352 gen_rtx_AND (SImode,
17353 gen_rtx_NOT (SImode, mask),
17359 gcc_unreachable ();
17363 used_mode = SImode;
17364 before = gen_reg_rtx (used_mode);
17365 after = gen_reg_rtx (used_mode);
17370 before = before_param;
17371 after = after_param;
17373 if (before == NULL_RTX)
17374 before = gen_reg_rtx (used_mode);
17375 if (after == NULL_RTX)
17376 after = gen_reg_rtx (used_mode);
17379 if ((code == PLUS || code == MINUS)
17380 && used_mode != mode)
17381 the_op = op; /* Computed above. */
17382 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17383 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17384 else if (code == NOT)
17385 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17386 gen_rtx_NOT (used_mode, m),
17387 gen_rtx_NOT (used_mode, op));
17389 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17391 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17392 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17393 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17394 gen_rtx_UNSPEC (used_mode,
17395 gen_rtvec (1, the_op),
17397 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17399 if ((code == PLUS || code == MINUS) && used_mode != mode)
17400 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17401 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17403 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17404 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17406 /* Shift and mask the return values properly. */
17407 if (used_mode != mode && before_param)
17409 emit_insn (gen_lshrsi3 (before, before, shift));
17410 convert_move (before_param, before, 1);
17413 if (used_mode != mode && after_param)
17415 emit_insn (gen_lshrsi3 (after, after, shift));
17416 convert_move (after_param, after, 1);
17419 /* The previous sequence will end with a branch that's dependent on
17420 the conditional store, so placing an isync will ensure that no
17421 other instructions (especially, no load or store instructions)
17422 can start before the atomic operation completes. */
17424 emit_insn (gen_isync ());
17427 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17428 COND is true. Mark the jump as unlikely to be taken. */
17431 emit_unlikely_jump (rtx cond, rtx label)
17433 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17436 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17437 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17438 add_reg_note (x, REG_BR_PROB, very_unlikely);
17441 /* A subroutine of the atomic operation splitters. Emit a load-locked
17442 instruction in MODE. */
17445 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17447 rtx (*fn) (rtx, rtx) = NULL;
17448 if (mode == SImode)
17449 fn = gen_load_locked_si;
17450 else if (mode == DImode)
17451 fn = gen_load_locked_di;
17452 emit_insn (fn (reg, mem));
17455 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17456 instruction in MODE. */
17459 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17461 rtx (*fn) (rtx, rtx, rtx) = NULL;
17462 if (mode == SImode)
17463 fn = gen_store_conditional_si;
17464 else if (mode == DImode)
17465 fn = gen_store_conditional_di;
17467 /* Emit sync before stwcx. to address PPC405 Erratum. */
17468 if (PPC405_ERRATUM77)
17469 emit_insn (gen_memory_barrier ());
17471 emit_insn (fn (res, mem, val));
17474 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17475 to perform. MEM is the memory on which to operate. VAL is the second
17476 operand of the binary operator. BEFORE and AFTER are optional locations to
17477 return the value of MEM either before of after the operation. SCRATCH is
17478 a scratch register. */
17481 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17482 rtx before, rtx after, rtx scratch)
17484 enum machine_mode mode = GET_MODE (mem);
17485 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17487 emit_insn (gen_lwsync ());
17489 label = gen_label_rtx ();
17490 emit_label (label);
17491 label = gen_rtx_LABEL_REF (VOIDmode, label);
17493 if (before == NULL_RTX)
17495 emit_load_locked (mode, before, mem);
17498 x = gen_rtx_IOR (mode,
17499 gen_rtx_NOT (mode, before),
17500 gen_rtx_NOT (mode, val));
17501 else if (code == AND)
17502 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17504 x = gen_rtx_fmt_ee (code, mode, before, val);
17506 if (after != NULL_RTX)
17507 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17508 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17510 emit_store_conditional (mode, cond, mem, scratch);
17512 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17513 emit_unlikely_jump (x, label);
17515 emit_insn (gen_isync ());
17518 /* Expand an atomic compare and swap operation. MEM is the memory on which
17519 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17520 value to be stored. SCRATCH is a scratch GPR. */
17523 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17526 enum machine_mode mode = GET_MODE (mem);
17527 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17529 emit_insn (gen_lwsync ());
17531 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17532 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17533 emit_label (XEXP (label1, 0));
17535 emit_load_locked (mode, retval, mem);
17537 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17538 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17540 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17541 emit_unlikely_jump (x, label2);
17543 emit_move_insn (scratch, newval);
17544 emit_store_conditional (mode, cond, mem, scratch);
17546 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17547 emit_unlikely_jump (x, label1);
17549 emit_insn (gen_isync ());
17550 emit_label (XEXP (label2, 0));
17553 /* Expand an atomic test and set operation. MEM is the memory on which
17554 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17557 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17559 enum machine_mode mode = GET_MODE (mem);
17560 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17562 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17563 emit_label (XEXP (label, 0));
17565 emit_load_locked (mode, retval, mem);
17566 emit_move_insn (scratch, val);
17567 emit_store_conditional (mode, cond, mem, scratch);
17569 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17570 emit_unlikely_jump (x, label);
17572 emit_insn (gen_isync ());
17576 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17578 enum machine_mode mode = GET_MODE (mem);
17579 rtx addrSI, align, wdst, shift, mask;
17580 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17581 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17583 /* Shift amount for subword relative to aligned word. */
17584 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17585 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17586 shift = gen_reg_rtx (SImode);
17587 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17588 GEN_INT (shift_mask)));
17589 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17591 /* Shift and mask old value into position within word. */
17592 oldval = convert_modes (SImode, mode, oldval, 1);
17593 oldval = expand_binop (SImode, and_optab,
17594 oldval, GEN_INT (imask), NULL_RTX,
17595 1, OPTAB_LIB_WIDEN);
17596 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17598 /* Shift and mask new value into position within word. */
17599 newval = convert_modes (SImode, mode, newval, 1);
17600 newval = expand_binop (SImode, and_optab,
17601 newval, GEN_INT (imask), NULL_RTX,
17602 1, OPTAB_LIB_WIDEN);
17603 emit_insn (gen_ashlsi3 (newval, newval, shift));
17605 /* Mask for insertion. */
17606 mask = gen_reg_rtx (SImode);
17607 emit_move_insn (mask, GEN_INT (imask));
17608 emit_insn (gen_ashlsi3 (mask, mask, shift));
17610 /* Address of aligned word containing subword. */
17611 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17612 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17613 mem = change_address (mem, SImode, align);
17614 set_mem_align (mem, 32);
17615 MEM_VOLATILE_P (mem) = 1;
17617 wdst = gen_reg_rtx (SImode);
17618 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17619 oldval, newval, mem));
17621 /* Shift the result back. */
17622 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17624 emit_move_insn (dst, gen_lowpart (mode, wdst));
17628 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17629 rtx oldval, rtx newval, rtx mem,
17632 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17634 emit_insn (gen_lwsync ());
17635 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17636 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17637 emit_label (XEXP (label1, 0));
17639 emit_load_locked (SImode, scratch, mem);
17641 /* Mask subword within loaded value for comparison with oldval.
17642 Use UNSPEC_AND to avoid clobber.*/
17643 emit_insn (gen_rtx_SET (SImode, dest,
17644 gen_rtx_UNSPEC (SImode,
17645 gen_rtvec (2, scratch, mask),
17648 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17649 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17651 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17652 emit_unlikely_jump (x, label2);
17654 /* Clear subword within loaded value for insertion of new value. */
17655 emit_insn (gen_rtx_SET (SImode, scratch,
17656 gen_rtx_AND (SImode,
17657 gen_rtx_NOT (SImode, mask), scratch)));
17658 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17659 emit_store_conditional (SImode, cond, mem, scratch);
17661 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17662 emit_unlikely_jump (x, label1);
17664 emit_insn (gen_isync ());
17665 emit_label (XEXP (label2, 0));
17669 /* Emit instructions to move SRC to DST. Called by splitters for
17670 multi-register moves. It will emit at most one instruction for
17671 each register that is accessed; that is, it won't emit li/lis pairs
17672 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17676 rs6000_split_multireg_move (rtx dst, rtx src)
17678 /* The register number of the first register being moved. */
17680 /* The mode that is to be moved. */
17681 enum machine_mode mode;
17682 /* The mode that the move is being done in, and its size. */
17683 enum machine_mode reg_mode;
17685 /* The number of registers that will be moved. */
17688 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17689 mode = GET_MODE (dst);
17690 nregs = hard_regno_nregs[reg][mode];
17691 if (FP_REGNO_P (reg))
17692 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17693 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17694 else if (ALTIVEC_REGNO_P (reg))
17695 reg_mode = V16QImode;
17696 else if (TARGET_E500_DOUBLE && mode == TFmode)
17699 reg_mode = word_mode;
17700 reg_mode_size = GET_MODE_SIZE (reg_mode);
17702 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17704 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17706 /* Move register range backwards, if we might have destructive
17709 for (i = nregs - 1; i >= 0; i--)
17710 emit_insn (gen_rtx_SET (VOIDmode,
17711 simplify_gen_subreg (reg_mode, dst, mode,
17712 i * reg_mode_size),
17713 simplify_gen_subreg (reg_mode, src, mode,
17714 i * reg_mode_size)));
17720 bool used_update = false;
17721 rtx restore_basereg = NULL_RTX;
17723 if (MEM_P (src) && INT_REGNO_P (reg))
17727 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17728 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17731 breg = XEXP (XEXP (src, 0), 0);
17732 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17733 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17734 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17735 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17736 src = replace_equiv_address (src, breg);
17738 else if (! rs6000_offsettable_memref_p (src))
17740 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17742 rtx basereg = XEXP (XEXP (src, 0), 0);
17745 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17746 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17747 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17748 used_update = true;
17751 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17752 XEXP (XEXP (src, 0), 1)));
17753 src = replace_equiv_address (src, basereg);
17757 rtx basereg = gen_rtx_REG (Pmode, reg);
17758 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17759 src = replace_equiv_address (src, basereg);
17763 breg = XEXP (src, 0);
17764 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17765 breg = XEXP (breg, 0);
17767 /* If the base register we are using to address memory is
17768 also a destination reg, then change that register last. */
17770 && REGNO (breg) >= REGNO (dst)
17771 && REGNO (breg) < REGNO (dst) + nregs)
17772 j = REGNO (breg) - REGNO (dst);
17774 else if (MEM_P (dst) && INT_REGNO_P (reg))
17778 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17779 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17782 breg = XEXP (XEXP (dst, 0), 0);
17783 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17784 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17785 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17787 /* We have to update the breg before doing the store.
17788 Use store with update, if available. */
17792 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17793 emit_insn (TARGET_32BIT
17794 ? (TARGET_POWERPC64
17795 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17796 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17797 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17798 used_update = true;
17801 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17802 dst = replace_equiv_address (dst, breg);
17804 else if (!rs6000_offsettable_memref_p (dst)
17805 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17807 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17809 rtx basereg = XEXP (XEXP (dst, 0), 0);
17812 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17813 emit_insn (gen_rtx_SET (VOIDmode,
17814 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17815 used_update = true;
17818 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17819 XEXP (XEXP (dst, 0), 1)));
17820 dst = replace_equiv_address (dst, basereg);
17824 rtx basereg = XEXP (XEXP (dst, 0), 0);
17825 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17826 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17828 && REG_P (offsetreg)
17829 && REGNO (basereg) != REGNO (offsetreg));
17830 if (REGNO (basereg) == 0)
17832 rtx tmp = offsetreg;
17833 offsetreg = basereg;
17836 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17837 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17838 dst = replace_equiv_address (dst, basereg);
17841 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17842 gcc_assert (rs6000_offsettable_memref_p (dst));
17845 for (i = 0; i < nregs; i++)
17847 /* Calculate index to next subword. */
17852 /* If compiler already emitted move of first word by
17853 store with update, no need to do anything. */
17854 if (j == 0 && used_update)
17857 emit_insn (gen_rtx_SET (VOIDmode,
17858 simplify_gen_subreg (reg_mode, dst, mode,
17859 j * reg_mode_size),
17860 simplify_gen_subreg (reg_mode, src, mode,
17861 j * reg_mode_size)));
17863 if (restore_basereg != NULL_RTX)
17864 emit_insn (restore_basereg);
17869 /* This page contains routines that are used to determine what the
17870 function prologue and epilogue code will do and write them out. */
17872 /* Return the first fixed-point register that is required to be
17873 saved. 32 if none. */
17876 first_reg_to_save (void)
17880 /* Find lowest numbered live register. */
17881 for (first_reg = 13; first_reg <= 31; first_reg++)
17882 if (df_regs_ever_live_p (first_reg)
17883 && (! call_used_regs[first_reg]
17884 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17885 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17886 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17887 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17892 && crtl->uses_pic_offset_table
17893 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17894 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17900 /* Similar, for FP regs. */
17903 first_fp_reg_to_save (void)
17907 /* Find lowest numbered live register. */
17908 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17909 if (df_regs_ever_live_p (first_reg))
17915 /* Similar, for AltiVec regs. */
17918 first_altivec_reg_to_save (void)
17922 /* Stack frame remains as is unless we are in AltiVec ABI. */
17923 if (! TARGET_ALTIVEC_ABI)
17924 return LAST_ALTIVEC_REGNO + 1;
17926 /* On Darwin, the unwind routines are compiled without
17927 TARGET_ALTIVEC, and use save_world to save/restore the
17928 altivec registers when necessary. */
17929 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17930 && ! TARGET_ALTIVEC)
17931 return FIRST_ALTIVEC_REGNO + 20;
17933 /* Find lowest numbered live register. */
17934 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17935 if (df_regs_ever_live_p (i))
17941 /* Return a 32-bit mask of the AltiVec registers we need to set in
17942 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17943 the 32-bit word is 0. */
17945 static unsigned int
17946 compute_vrsave_mask (void)
17948 unsigned int i, mask = 0;
17950 /* On Darwin, the unwind routines are compiled without
17951 TARGET_ALTIVEC, and use save_world to save/restore the
17952 call-saved altivec registers when necessary. */
17953 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17954 && ! TARGET_ALTIVEC)
17957 /* First, find out if we use _any_ altivec registers. */
17958 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17959 if (df_regs_ever_live_p (i))
17960 mask |= ALTIVEC_REG_BIT (i);
17965 /* Next, remove the argument registers from the set. These must
17966 be in the VRSAVE mask set by the caller, so we don't need to add
17967 them in again. More importantly, the mask we compute here is
17968 used to generate CLOBBERs in the set_vrsave insn, and we do not
17969 wish the argument registers to die. */
17970 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17971 mask &= ~ALTIVEC_REG_BIT (i);
17973 /* Similarly, remove the return value from the set. */
17976 diddle_return_value (is_altivec_return_reg, &yes);
17978 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17984 /* For a very restricted set of circumstances, we can cut down the
17985 size of prologues/epilogues by calling our own save/restore-the-world
17989 compute_save_world_info (rs6000_stack_t *info_ptr)
17991 info_ptr->world_save_p = 1;
17992 info_ptr->world_save_p
17993 = (WORLD_SAVE_P (info_ptr)
17994 && DEFAULT_ABI == ABI_DARWIN
17995 && ! (cfun->calls_setjmp && flag_exceptions)
17996 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17997 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17998 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17999 && info_ptr->cr_save_p);
18001 /* This will not work in conjunction with sibcalls. Make sure there
18002 are none. (This check is expensive, but seldom executed.) */
18003 if (WORLD_SAVE_P (info_ptr))
18006 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18007 if ( GET_CODE (insn) == CALL_INSN
18008 && SIBLING_CALL_P (insn))
18010 info_ptr->world_save_p = 0;
18015 if (WORLD_SAVE_P (info_ptr))
18017 /* Even if we're not touching VRsave, make sure there's room on the
18018 stack for it, if it looks like we're calling SAVE_WORLD, which
18019 will attempt to save it. */
18020 info_ptr->vrsave_size = 4;
18022 /* If we are going to save the world, we need to save the link register too. */
18023 info_ptr->lr_save_p = 1;
18025 /* "Save" the VRsave register too if we're saving the world. */
18026 if (info_ptr->vrsave_mask == 0)
18027 info_ptr->vrsave_mask = compute_vrsave_mask ();
18029 /* Because the Darwin register save/restore routines only handle
18030 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18032 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18033 && (info_ptr->first_altivec_reg_save
18034 >= FIRST_SAVED_ALTIVEC_REGNO));
18041 is_altivec_return_reg (rtx reg, void *xyes)
18043 bool *yes = (bool *) xyes;
18044 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18049 /* Determine the strategy for savings/restoring registers. */
18052 SAVRES_MULTIPLE = 0x1,
18053 SAVE_INLINE_FPRS = 0x2,
18054 SAVE_INLINE_GPRS = 0x4,
18055 REST_INLINE_FPRS = 0x8,
18056 REST_INLINE_GPRS = 0x10,
18057 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18058 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18059 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18063 rs6000_savres_strategy (rs6000_stack_t *info,
18064 bool using_static_chain_p)
18068 if (TARGET_MULTIPLE
18069 && !TARGET_POWERPC64
18070 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18071 && info->first_gp_reg_save < 31
18072 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18073 strategy |= SAVRES_MULTIPLE;
18075 if (crtl->calls_eh_return
18076 || cfun->machine->ra_need_lr
18077 || info->total_size > 32767)
18078 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18079 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18081 if (info->first_fp_reg_save == 64
18082 || FP_SAVE_INLINE (info->first_fp_reg_save)
18083 /* The out-of-line FP routines use double-precision stores;
18084 we can't use those routines if we don't have such stores. */
18085 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18086 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18087 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18089 if (info->first_gp_reg_save == 32
18090 || GP_SAVE_INLINE (info->first_gp_reg_save)
18091 || !((strategy & SAVRES_MULTIPLE)
18092 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18093 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18095 /* Don't bother to try to save things out-of-line if r11 is occupied
18096 by the static chain. It would require too much fiddling and the
18097 static chain is rarely used anyway. */
18098 if (using_static_chain_p)
18099 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18101 /* If we are going to use store multiple, then don't even bother
18102 with the out-of-line routines, since the store-multiple
18103 instruction will always be smaller. */
18104 if ((strategy & SAVRES_MULTIPLE))
18105 strategy |= SAVE_INLINE_GPRS;
18107 /* The situation is more complicated with load multiple. We'd
18108 prefer to use the out-of-line routines for restores, since the
18109 "exit" out-of-line routines can handle the restore of LR and the
18110 frame teardown. However if doesn't make sense to use the
18111 out-of-line routine if that is the only reason we'd need to save
18112 LR, and we can't use the "exit" out-of-line gpr restore if we
18113 have saved some fprs; In those cases it is advantageous to use
18114 load multiple when available. */
18115 if ((strategy & SAVRES_MULTIPLE)
18116 && (!info->lr_save_p
18117 || info->first_fp_reg_save != 64))
18118 strategy |= REST_INLINE_GPRS;
18120 /* We can only use load multiple or the out-of-line routines to
18121 restore if we've used store multiple or out-of-line routines
18122 in the prologue, i.e. if we've saved all the registers from
18123 first_gp_reg_save. Otherwise, we risk loading garbage. */
18124 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18125 strategy |= REST_INLINE_GPRS;
18127 /* Saving CR interferes with the exit routines used on the SPE, so
18130 && info->spe_64bit_regs_used
18131 && info->cr_save_p)
18132 strategy |= REST_INLINE_GPRS;
18134 #ifdef POWERPC_LINUX
18137 if (!(strategy & SAVE_INLINE_FPRS))
18138 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18139 else if (!(strategy & SAVE_INLINE_GPRS)
18140 && info->first_fp_reg_save == 64)
18141 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18144 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18145 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18150 /* Calculate the stack information for the current function. This is
18151 complicated by having two separate calling sequences, the AIX calling
18152 sequence and the V.4 calling sequence.
18154 AIX (and Darwin/Mac OS X) stack frames look like:
18156 SP----> +---------------------------------------+
18157 | back chain to caller | 0 0
18158 +---------------------------------------+
18159 | saved CR | 4 8 (8-11)
18160 +---------------------------------------+
18162 +---------------------------------------+
18163 | reserved for compilers | 12 24
18164 +---------------------------------------+
18165 | reserved for binders | 16 32
18166 +---------------------------------------+
18167 | saved TOC pointer | 20 40
18168 +---------------------------------------+
18169 | Parameter save area (P) | 24 48
18170 +---------------------------------------+
18171 | Alloca space (A) | 24+P etc.
18172 +---------------------------------------+
18173 | Local variable space (L) | 24+P+A
18174 +---------------------------------------+
18175 | Float/int conversion temporary (X) | 24+P+A+L
18176 +---------------------------------------+
18177 | Save area for AltiVec registers (W) | 24+P+A+L+X
18178 +---------------------------------------+
18179 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18180 +---------------------------------------+
18181 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18182 +---------------------------------------+
18183 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18184 +---------------------------------------+
18185 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18186 +---------------------------------------+
18187 old SP->| back chain to caller's caller |
18188 +---------------------------------------+
18190 The required alignment for AIX configurations is two words (i.e., 8
18194 V.4 stack frames look like:
18196 SP----> +---------------------------------------+
18197 | back chain to caller | 0
18198 +---------------------------------------+
18199 | caller's saved LR | 4
18200 +---------------------------------------+
18201 | Parameter save area (P) | 8
18202 +---------------------------------------+
18203 | Alloca space (A) | 8+P
18204 +---------------------------------------+
18205 | Varargs save area (V) | 8+P+A
18206 +---------------------------------------+
18207 | Local variable space (L) | 8+P+A+V
18208 +---------------------------------------+
18209 | Float/int conversion temporary (X) | 8+P+A+V+L
18210 +---------------------------------------+
18211 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18212 +---------------------------------------+
18213 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18214 +---------------------------------------+
18215 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18216 +---------------------------------------+
18217 | SPE: area for 64-bit GP registers |
18218 +---------------------------------------+
18219 | SPE alignment padding |
18220 +---------------------------------------+
18221 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18222 +---------------------------------------+
18223 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18224 +---------------------------------------+
18225 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18226 +---------------------------------------+
18227 old SP->| back chain to caller's caller |
18228 +---------------------------------------+
18230 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18231 given. (But note below and in sysv4.h that we require only 8 and
18232 may round up the size of our stack frame anyways. The historical
18233 reason is early versions of powerpc-linux which didn't properly
18234 align the stack at program startup. A happy side-effect is that
18235 -mno-eabi libraries can be used with -meabi programs.)
18237 The EABI configuration defaults to the V.4 layout. However,
18238 the stack alignment requirements may differ. If -mno-eabi is not
18239 given, the required stack alignment is 8 bytes; if -mno-eabi is
18240 given, the required alignment is 16 bytes. (But see V.4 comment
18243 #ifndef ABI_STACK_BOUNDARY
18244 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18247 static rs6000_stack_t *
18248 rs6000_stack_info (void)
18250 #ifdef ENABLE_CHECKING
18251 static rs6000_stack_t info_save;
18253 rs6000_stack_t *info_ptr = &stack_info;
18254 int reg_size = TARGET_32BIT ? 4 : 8;
18258 HOST_WIDE_INT non_fixed_size;
18259 bool using_static_chain_p;
18261 #ifdef ENABLE_CHECKING
18262 memcpy (&info_save, &stack_info, sizeof stack_info);
18264 if (reload_completed && info_ptr->reload_completed)
18268 memset (&stack_info, 0, sizeof (stack_info));
18269 info_ptr->reload_completed = reload_completed;
18273 /* Cache value so we don't rescan instruction chain over and over. */
18274 if (cfun->machine->insn_chain_scanned_p == 0)
18275 cfun->machine->insn_chain_scanned_p
18276 = spe_func_has_64bit_regs_p () + 1;
18277 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18280 /* Select which calling sequence. */
18281 info_ptr->abi = DEFAULT_ABI;
18283 /* Calculate which registers need to be saved & save area size. */
18284 info_ptr->first_gp_reg_save = first_reg_to_save ();
18285 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18286 even if it currently looks like we won't. Reload may need it to
18287 get at a constant; if so, it will have already created a constant
18288 pool entry for it. */
18289 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18290 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18291 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18292 && crtl->uses_const_pool
18293 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18294 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18296 first_gp = info_ptr->first_gp_reg_save;
18298 info_ptr->gp_size = reg_size * (32 - first_gp);
18300 /* For the SPE, we have an additional upper 32-bits on each GPR.
18301 Ideally we should save the entire 64-bits only when the upper
18302 half is used in SIMD instructions. Since we only record
18303 registers live (not the size they are used in), this proves
18304 difficult because we'd have to traverse the instruction chain at
18305 the right time, taking reload into account. This is a real pain,
18306 so we opt to save the GPRs in 64-bits always if but one register
18307 gets used in 64-bits. Otherwise, all the registers in the frame
18308 get saved in 32-bits.
18310 So... since when we save all GPRs (except the SP) in 64-bits, the
18311 traditional GP save area will be empty. */
18312 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18313 info_ptr->gp_size = 0;
18315 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18316 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18318 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18319 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18320 - info_ptr->first_altivec_reg_save);
18322 /* Does this function call anything? */
18323 info_ptr->calls_p = (! current_function_is_leaf
18324 || cfun->machine->ra_needs_full_frame);
18326 /* Determine if we need to save the condition code registers. */
18327 if (df_regs_ever_live_p (CR2_REGNO)
18328 || df_regs_ever_live_p (CR3_REGNO)
18329 || df_regs_ever_live_p (CR4_REGNO))
18331 info_ptr->cr_save_p = 1;
18332 if (DEFAULT_ABI == ABI_V4)
18333 info_ptr->cr_size = reg_size;
18336 /* If the current function calls __builtin_eh_return, then we need
18337 to allocate stack space for registers that will hold data for
18338 the exception handler. */
18339 if (crtl->calls_eh_return)
18342 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18345 /* SPE saves EH registers in 64-bits. */
18346 ehrd_size = i * (TARGET_SPE_ABI
18347 && info_ptr->spe_64bit_regs_used != 0
18348 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18353 /* Determine various sizes. */
18354 info_ptr->reg_size = reg_size;
18355 info_ptr->fixed_size = RS6000_SAVE_AREA;
18356 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18357 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18358 TARGET_ALTIVEC ? 16 : 8);
18359 if (FRAME_GROWS_DOWNWARD)
18360 info_ptr->vars_size
18361 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18362 + info_ptr->parm_size,
18363 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18364 - (info_ptr->fixed_size + info_ptr->vars_size
18365 + info_ptr->parm_size);
18367 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18368 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18370 info_ptr->spe_gp_size = 0;
18372 if (TARGET_ALTIVEC_ABI)
18373 info_ptr->vrsave_mask = compute_vrsave_mask ();
18375 info_ptr->vrsave_mask = 0;
18377 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18378 info_ptr->vrsave_size = 4;
18380 info_ptr->vrsave_size = 0;
18382 compute_save_world_info (info_ptr);
18384 /* Calculate the offsets. */
18385 switch (DEFAULT_ABI)
18389 gcc_unreachable ();
18393 info_ptr->fp_save_offset = - info_ptr->fp_size;
18394 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18396 if (TARGET_ALTIVEC_ABI)
18398 info_ptr->vrsave_save_offset
18399 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18401 /* Align stack so vector save area is on a quadword boundary.
18402 The padding goes above the vectors. */
18403 if (info_ptr->altivec_size != 0)
18404 info_ptr->altivec_padding_size
18405 = info_ptr->vrsave_save_offset & 0xF;
18407 info_ptr->altivec_padding_size = 0;
18409 info_ptr->altivec_save_offset
18410 = info_ptr->vrsave_save_offset
18411 - info_ptr->altivec_padding_size
18412 - info_ptr->altivec_size;
18413 gcc_assert (info_ptr->altivec_size == 0
18414 || info_ptr->altivec_save_offset % 16 == 0);
18416 /* Adjust for AltiVec case. */
18417 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18420 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18421 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18422 info_ptr->lr_save_offset = 2*reg_size;
18426 info_ptr->fp_save_offset = - info_ptr->fp_size;
18427 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18428 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18430 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18432 /* Align stack so SPE GPR save area is aligned on a
18433 double-word boundary. */
18434 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18435 info_ptr->spe_padding_size
18436 = 8 - (-info_ptr->cr_save_offset % 8);
18438 info_ptr->spe_padding_size = 0;
18440 info_ptr->spe_gp_save_offset
18441 = info_ptr->cr_save_offset
18442 - info_ptr->spe_padding_size
18443 - info_ptr->spe_gp_size;
18445 /* Adjust for SPE case. */
18446 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18448 else if (TARGET_ALTIVEC_ABI)
18450 info_ptr->vrsave_save_offset
18451 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18453 /* Align stack so vector save area is on a quadword boundary. */
18454 if (info_ptr->altivec_size != 0)
18455 info_ptr->altivec_padding_size
18456 = 16 - (-info_ptr->vrsave_save_offset % 16);
18458 info_ptr->altivec_padding_size = 0;
18460 info_ptr->altivec_save_offset
18461 = info_ptr->vrsave_save_offset
18462 - info_ptr->altivec_padding_size
18463 - info_ptr->altivec_size;
18465 /* Adjust for AltiVec case. */
18466 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18469 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18470 info_ptr->ehrd_offset -= ehrd_size;
18471 info_ptr->lr_save_offset = reg_size;
18475 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18476 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18477 + info_ptr->gp_size
18478 + info_ptr->altivec_size
18479 + info_ptr->altivec_padding_size
18480 + info_ptr->spe_gp_size
18481 + info_ptr->spe_padding_size
18483 + info_ptr->cr_size
18484 + info_ptr->vrsave_size,
18487 non_fixed_size = (info_ptr->vars_size
18488 + info_ptr->parm_size
18489 + info_ptr->save_size);
18491 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18492 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18494 /* Determine if we need to save the link register. */
18495 if (info_ptr->calls_p
18496 || (DEFAULT_ABI == ABI_AIX
18498 && !TARGET_PROFILE_KERNEL)
18499 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18500 #ifdef TARGET_RELOCATABLE
18501 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18503 || rs6000_ra_ever_killed ())
18504 info_ptr->lr_save_p = 1;
18506 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18507 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18508 && call_used_regs[STATIC_CHAIN_REGNUM]);
18509 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18510 using_static_chain_p);
18512 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18513 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18514 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18515 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18516 info_ptr->lr_save_p = 1;
18518 if (info_ptr->lr_save_p)
18519 df_set_regs_ever_live (LR_REGNO, true);
18521 /* Determine if we need to allocate any stack frame:
18523 For AIX we need to push the stack if a frame pointer is needed
18524 (because the stack might be dynamically adjusted), if we are
18525 debugging, if we make calls, or if the sum of fp_save, gp_save,
18526 and local variables are more than the space needed to save all
18527 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18528 + 18*8 = 288 (GPR13 reserved).
18530 For V.4 we don't have the stack cushion that AIX uses, but assume
18531 that the debugger can handle stackless frames. */
18533 if (info_ptr->calls_p)
18534 info_ptr->push_p = 1;
18536 else if (DEFAULT_ABI == ABI_V4)
18537 info_ptr->push_p = non_fixed_size != 0;
18539 else if (frame_pointer_needed)
18540 info_ptr->push_p = 1;
18542 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18543 info_ptr->push_p = 1;
18546 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18548 /* Zero offsets if we're not saving those registers. */
18549 if (info_ptr->fp_size == 0)
18550 info_ptr->fp_save_offset = 0;
18552 if (info_ptr->gp_size == 0)
18553 info_ptr->gp_save_offset = 0;
18555 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18556 info_ptr->altivec_save_offset = 0;
18558 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18559 info_ptr->vrsave_save_offset = 0;
18561 if (! TARGET_SPE_ABI
18562 || info_ptr->spe_64bit_regs_used == 0
18563 || info_ptr->spe_gp_size == 0)
18564 info_ptr->spe_gp_save_offset = 0;
18566 if (! info_ptr->lr_save_p)
18567 info_ptr->lr_save_offset = 0;
18569 if (! info_ptr->cr_save_p)
18570 info_ptr->cr_save_offset = 0;
18572 #ifdef ENABLE_CHECKING
18573 gcc_assert (!(reload_completed && info_save.reload_completed)
18574 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
18579 /* Return true if the current function uses any GPRs in 64-bit SIMD
18583 spe_func_has_64bit_regs_p (void)
18587 /* Functions that save and restore all the call-saved registers will
18588 need to save/restore the registers in 64-bits. */
18589 if (crtl->calls_eh_return
18590 || cfun->calls_setjmp
18591 || crtl->has_nonlocal_goto)
18594 insns = get_insns ();
18596 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18602 /* FIXME: This should be implemented with attributes...
18604 (set_attr "spe64" "true")....then,
18605 if (get_spe64(insn)) return true;
18607 It's the only reliable way to do the stuff below. */
18609 i = PATTERN (insn);
18610 if (GET_CODE (i) == SET)
18612 enum machine_mode mode = GET_MODE (SET_SRC (i));
18614 if (SPE_VECTOR_MODE (mode))
18616 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18626 debug_stack_info (rs6000_stack_t *info)
18628 const char *abi_string;
18631 info = rs6000_stack_info ();
18633 fprintf (stderr, "\nStack information for function %s:\n",
18634 ((current_function_decl && DECL_NAME (current_function_decl))
18635 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18640 default: abi_string = "Unknown"; break;
18641 case ABI_NONE: abi_string = "NONE"; break;
18642 case ABI_AIX: abi_string = "AIX"; break;
18643 case ABI_DARWIN: abi_string = "Darwin"; break;
18644 case ABI_V4: abi_string = "V.4"; break;
18647 fprintf (stderr, "\tABI = %5s\n", abi_string);
18649 if (TARGET_ALTIVEC_ABI)
18650 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18652 if (TARGET_SPE_ABI)
18653 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18655 if (info->first_gp_reg_save != 32)
18656 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18658 if (info->first_fp_reg_save != 64)
18659 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18661 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18662 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18663 info->first_altivec_reg_save);
18665 if (info->lr_save_p)
18666 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18668 if (info->cr_save_p)
18669 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18671 if (info->vrsave_mask)
18672 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18675 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18678 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18680 if (info->gp_save_offset)
18681 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18683 if (info->fp_save_offset)
18684 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18686 if (info->altivec_save_offset)
18687 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18688 info->altivec_save_offset);
18690 if (info->spe_gp_save_offset)
18691 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18692 info->spe_gp_save_offset);
18694 if (info->vrsave_save_offset)
18695 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18696 info->vrsave_save_offset);
18698 if (info->lr_save_offset)
18699 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18701 if (info->cr_save_offset)
18702 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18704 if (info->varargs_save_offset)
18705 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18707 if (info->total_size)
18708 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18711 if (info->vars_size)
18712 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18715 if (info->parm_size)
18716 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18718 if (info->fixed_size)
18719 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18722 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18724 if (info->spe_gp_size)
18725 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18728 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18730 if (info->altivec_size)
18731 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18733 if (info->vrsave_size)
18734 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18736 if (info->altivec_padding_size)
18737 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18738 info->altivec_padding_size);
18740 if (info->spe_padding_size)
18741 fprintf (stderr, "\tspe_padding_size = %5d\n",
18742 info->spe_padding_size);
18745 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18747 if (info->save_size)
18748 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18750 if (info->reg_size != 4)
18751 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18753 fprintf (stderr, "\n");
18757 rs6000_return_addr (int count, rtx frame)
18759 /* Currently we don't optimize very well between prolog and body
18760 code and for PIC code the code can be actually quite bad, so
18761 don't try to be too clever here. */
18762 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18764 cfun->machine->ra_needs_full_frame = 1;
18771 plus_constant (copy_to_reg
18772 (gen_rtx_MEM (Pmode,
18773 memory_address (Pmode, frame))),
18774 RETURN_ADDRESS_OFFSET)));
18777 cfun->machine->ra_need_lr = 1;
18778 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18781 /* Say whether a function is a candidate for sibcall handling or not.
18782 We do not allow indirect calls to be optimized into sibling calls.
18783 Also, we can't do it if there are any vector parameters; there's
18784 nowhere to put the VRsave code so it works; note that functions with
18785 vector parameters are required to have a prototype, so the argument
18786 type info must be available here. (The tail recursion case can work
18787 with vector parameters, but there's no way to distinguish here.) */
18789 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18794 if (TARGET_ALTIVEC_VRSAVE)
18796 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18797 type; type = TREE_CHAIN (type))
18799 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18803 if (DEFAULT_ABI == ABI_DARWIN
18804 || ((*targetm.binds_local_p) (decl)
18805 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18807 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18809 if (!lookup_attribute ("longcall", attr_list)
18810 || lookup_attribute ("shortcall", attr_list))
18817 /* NULL if INSN insn is valid within a low-overhead loop.
18818 Otherwise return why doloop cannot be applied.
18819 PowerPC uses the COUNT register for branch on table instructions. */
18821 static const char *
18822 rs6000_invalid_within_doloop (const_rtx insn)
18825 return "Function call in the loop.";
18828 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18829 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18830 return "Computed branch in the loop.";
18836 rs6000_ra_ever_killed (void)
18842 if (cfun->is_thunk)
18845 if (cfun->machine->lr_save_state)
18846 return cfun->machine->lr_save_state - 1;
18848 /* regs_ever_live has LR marked as used if any sibcalls are present,
18849 but this should not force saving and restoring in the
18850 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18851 clobbers LR, so that is inappropriate. */
18853 /* Also, the prologue can generate a store into LR that
18854 doesn't really count, like this:
18857 bcl to set PIC register
18861 When we're called from the epilogue, we need to avoid counting
18862 this as a store. */
18864 push_topmost_sequence ();
18865 top = get_insns ();
18866 pop_topmost_sequence ();
18867 reg = gen_rtx_REG (Pmode, LR_REGNO);
18869 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18875 if (!SIBLING_CALL_P (insn))
18878 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18880 else if (set_of (reg, insn) != NULL_RTX
18881 && !prologue_epilogue_contains (insn))
18888 /* Emit instructions needed to load the TOC register.
18889 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18890 a constant pool; or for SVR4 -fpic. */
18893 rs6000_emit_load_toc_table (int fromprolog)
18896 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18898 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18901 rtx lab, tmp1, tmp2, got;
18903 lab = gen_label_rtx ();
18904 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18905 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18907 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18909 got = rs6000_got_sym ();
18910 tmp1 = tmp2 = dest;
18913 tmp1 = gen_reg_rtx (Pmode);
18914 tmp2 = gen_reg_rtx (Pmode);
18916 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18917 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18918 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18919 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18921 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18923 emit_insn (gen_load_toc_v4_pic_si ());
18924 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18926 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18929 rtx temp0 = (fromprolog
18930 ? gen_rtx_REG (Pmode, 0)
18931 : gen_reg_rtx (Pmode));
18937 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18938 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18940 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18941 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18943 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18944 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18945 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18951 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18952 lab = gen_label_rtx ();
18953 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18954 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18955 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18957 emit_insn (gen_addsi3 (dest, temp0, dest));
18959 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18961 /* This is for AIX code running in non-PIC ELF32. */
18964 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18965 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18967 emit_insn (gen_elf_high (dest, realsym));
18968 emit_insn (gen_elf_low (dest, dest, realsym));
18972 gcc_assert (DEFAULT_ABI == ABI_AIX);
18975 emit_insn (gen_load_toc_aix_si (dest));
18977 emit_insn (gen_load_toc_aix_di (dest));
18981 /* Emit instructions to restore the link register after determining where
18982 its value has been stored. */
18985 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18987 rs6000_stack_t *info = rs6000_stack_info ();
18990 operands[0] = source;
18991 operands[1] = scratch;
18993 if (info->lr_save_p)
18995 rtx frame_rtx = stack_pointer_rtx;
18996 HOST_WIDE_INT sp_offset = 0;
18999 if (frame_pointer_needed
19000 || cfun->calls_alloca
19001 || info->total_size > 32767)
19003 tmp = gen_frame_mem (Pmode, frame_rtx);
19004 emit_move_insn (operands[1], tmp);
19005 frame_rtx = operands[1];
19007 else if (info->push_p)
19008 sp_offset = info->total_size;
19010 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19011 tmp = gen_frame_mem (Pmode, tmp);
19012 emit_move_insn (tmp, operands[0]);
19015 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19017 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19018 state of lr_save_p so any change from here on would be a bug. In
19019 particular, stop rs6000_ra_ever_killed from considering the SET
19020 of lr we may have added just above. */
19021 cfun->machine->lr_save_state = info->lr_save_p + 1;
19024 static GTY(()) alias_set_type set = -1;
19027 get_TOC_alias_set (void)
19030 set = new_alias_set ();
19034 /* This returns nonzero if the current function uses the TOC. This is
19035 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19036 is generated by the ABI_V4 load_toc_* patterns. */
19043 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19046 rtx pat = PATTERN (insn);
19049 if (GET_CODE (pat) == PARALLEL)
19050 for (i = 0; i < XVECLEN (pat, 0); i++)
19052 rtx sub = XVECEXP (pat, 0, i);
19053 if (GET_CODE (sub) == USE)
19055 sub = XEXP (sub, 0);
19056 if (GET_CODE (sub) == UNSPEC
19057 && XINT (sub, 1) == UNSPEC_TOC)
19067 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19069 rtx tocrel, tocreg;
19071 if (TARGET_DEBUG_ADDR)
19073 if (GET_CODE (symbol) == SYMBOL_REF)
19074 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19078 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19079 GET_RTX_NAME (GET_CODE (symbol)));
19080 debug_rtx (symbol);
19084 if (!can_create_pseudo_p ())
19085 df_set_regs_ever_live (TOC_REGISTER, true);
19087 tocrel = gen_rtx_CONST (Pmode,
19088 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19090 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19091 if (TARGET_CMODEL != CMODEL_SMALL)
19093 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19094 if (largetoc_reg != NULL)
19096 emit_move_insn (largetoc_reg, hi);
19099 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19102 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19105 /* Issue assembly directives that create a reference to the given DWARF
19106 FRAME_TABLE_LABEL from the current function section. */
19108 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19110 fprintf (asm_out_file, "\t.ref %s\n",
19111 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19114 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19115 and the change to the stack pointer. */
19118 rs6000_emit_stack_tie (void)
19120 rtx mem = gen_frame_mem (BLKmode,
19121 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19123 emit_insn (gen_stack_tie (mem));
19126 /* Emit the correct code for allocating stack space, as insns.
19127 If COPY_REG, make sure a copy of the old frame is left there.
19128 The generated code may use hard register 0 as a temporary. */
19131 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19134 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19135 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19136 rtx todec = gen_int_mode (-size, Pmode);
19139 if (INTVAL (todec) != -size)
19141 warning (0, "stack frame too large");
19142 emit_insn (gen_trap ());
19146 if (crtl->limit_stack)
19148 if (REG_P (stack_limit_rtx)
19149 && REGNO (stack_limit_rtx) > 1
19150 && REGNO (stack_limit_rtx) <= 31)
19152 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19153 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19156 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19158 && DEFAULT_ABI == ABI_V4)
19160 rtx toload = gen_rtx_CONST (VOIDmode,
19161 gen_rtx_PLUS (Pmode,
19165 emit_insn (gen_elf_high (tmp_reg, toload));
19166 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19167 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19171 warning (0, "stack limit expression is not supported");
19175 emit_move_insn (copy_reg, stack_reg);
19179 /* Need a note here so that try_split doesn't get confused. */
19180 if (get_last_insn () == NULL_RTX)
19181 emit_note (NOTE_INSN_DELETED);
19182 insn = emit_move_insn (tmp_reg, todec);
19183 try_split (PATTERN (insn), insn, 0);
19187 insn = emit_insn (TARGET_32BIT
19188 ? gen_movsi_update_stack (stack_reg, stack_reg,
19190 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19191 todec, stack_reg));
19192 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19193 it now and set the alias set/attributes. The above gen_*_update
19194 calls will generate a PARALLEL with the MEM set being the first
19196 par = PATTERN (insn);
19197 gcc_assert (GET_CODE (par) == PARALLEL);
19198 set = XVECEXP (par, 0, 0);
19199 gcc_assert (GET_CODE (set) == SET);
19200 mem = SET_DEST (set);
19201 gcc_assert (MEM_P (mem));
19202 MEM_NOTRAP_P (mem) = 1;
19203 set_mem_alias_set (mem, get_frame_alias_set ());
19205 RTX_FRAME_RELATED_P (insn) = 1;
19206 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19207 gen_rtx_SET (VOIDmode, stack_reg,
19208 gen_rtx_PLUS (Pmode, stack_reg,
19209 GEN_INT (-size))));
19212 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19214 #if PROBE_INTERVAL > 32768
19215 #error Cannot use indexed addressing mode for stack probing
19218 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19219 inclusive. These are offsets from the current stack pointer. */
19222 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19224 /* See if we have a constant small number of probes to generate. If so,
19225 that's the easy case. */
19226 if (first + size <= 32768)
19230 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19231 it exceeds SIZE. If only one probe is needed, this will not
19232 generate any code. Then probe at FIRST + SIZE. */
19233 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19234 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19236 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19239 /* Otherwise, do the same as above, but in a loop. Note that we must be
19240 extra careful with variables wrapping around because we might be at
19241 the very top (or the very bottom) of the address space and we have
19242 to be able to handle this case properly; in particular, we use an
19243 equality test for the loop condition. */
19246 HOST_WIDE_INT rounded_size;
19247 rtx r12 = gen_rtx_REG (Pmode, 12);
19248 rtx r0 = gen_rtx_REG (Pmode, 0);
19250 /* Sanity check for the addressing mode we're going to use. */
19251 gcc_assert (first <= 32768);
19253 /* Step 1: round SIZE to the previous multiple of the interval. */
19255 rounded_size = size & -PROBE_INTERVAL;
19258 /* Step 2: compute initial and final value of the loop counter. */
19260 /* TEST_ADDR = SP + FIRST. */
19261 emit_insn (gen_rtx_SET (VOIDmode, r12,
19262 plus_constant (stack_pointer_rtx, -first)));
19264 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19265 if (rounded_size > 32768)
19267 emit_move_insn (r0, GEN_INT (-rounded_size));
19268 emit_insn (gen_rtx_SET (VOIDmode, r0,
19269 gen_rtx_PLUS (Pmode, r12, r0)));
19272 emit_insn (gen_rtx_SET (VOIDmode, r0,
19273 plus_constant (r12, -rounded_size)));
19276 /* Step 3: the loop
19278 while (TEST_ADDR != LAST_ADDR)
19280 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19284 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19285 until it is equal to ROUNDED_SIZE. */
19288 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19290 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19293 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19294 that SIZE is equal to ROUNDED_SIZE. */
19296 if (size != rounded_size)
19297 emit_stack_probe (plus_constant (r12, rounded_size - size));
19301 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19302 absolute addresses. */
19305 output_probe_stack_range (rtx reg1, rtx reg2)
19307 static int labelno = 0;
19308 char loop_lab[32], end_lab[32];
19311 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19312 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19314 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19316 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19320 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19322 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19324 fputs ("\tbeq 0,", asm_out_file);
19325 assemble_name_raw (asm_out_file, end_lab);
19326 fputc ('\n', asm_out_file);
19328 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19329 xops[1] = GEN_INT (-PROBE_INTERVAL);
19330 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19332 /* Probe at TEST_ADDR and branch. */
19333 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19334 fprintf (asm_out_file, "\tb ");
19335 assemble_name_raw (asm_out_file, loop_lab);
19336 fputc ('\n', asm_out_file);
19338 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19343 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19344 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19345 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19346 deduce these equivalences by itself so it wasn't necessary to hold
19347 its hand so much. */
19350 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19351 rtx reg2, rtx rreg)
19355 /* copy_rtx will not make unique copies of registers, so we need to
19356 ensure we don't have unwanted sharing here. */
19358 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19361 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19363 real = copy_rtx (PATTERN (insn));
19365 if (reg2 != NULL_RTX)
19366 real = replace_rtx (real, reg2, rreg);
19368 real = replace_rtx (real, reg,
19369 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19370 STACK_POINTER_REGNUM),
19373 /* We expect that 'real' is either a SET or a PARALLEL containing
19374 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19375 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19377 if (GET_CODE (real) == SET)
19381 temp = simplify_rtx (SET_SRC (set));
19383 SET_SRC (set) = temp;
19384 temp = simplify_rtx (SET_DEST (set));
19386 SET_DEST (set) = temp;
19387 if (GET_CODE (SET_DEST (set)) == MEM)
19389 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19391 XEXP (SET_DEST (set), 0) = temp;
19398 gcc_assert (GET_CODE (real) == PARALLEL);
19399 for (i = 0; i < XVECLEN (real, 0); i++)
19400 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19402 rtx set = XVECEXP (real, 0, i);
19404 temp = simplify_rtx (SET_SRC (set));
19406 SET_SRC (set) = temp;
19407 temp = simplify_rtx (SET_DEST (set));
19409 SET_DEST (set) = temp;
19410 if (GET_CODE (SET_DEST (set)) == MEM)
19412 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19414 XEXP (SET_DEST (set), 0) = temp;
19416 RTX_FRAME_RELATED_P (set) = 1;
19420 RTX_FRAME_RELATED_P (insn) = 1;
19421 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19424 /* Returns an insn that has a vrsave set operation with the
19425 appropriate CLOBBERs. */
19428 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19431 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19432 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19435 = gen_rtx_SET (VOIDmode,
19437 gen_rtx_UNSPEC_VOLATILE (SImode,
19438 gen_rtvec (2, reg, vrsave),
19439 UNSPECV_SET_VRSAVE));
19443 /* We need to clobber the registers in the mask so the scheduler
19444 does not move sets to VRSAVE before sets of AltiVec registers.
19446 However, if the function receives nonlocal gotos, reload will set
19447 all call saved registers live. We will end up with:
19449 (set (reg 999) (mem))
19450 (parallel [ (set (reg vrsave) (unspec blah))
19451 (clobber (reg 999))])
19453 The clobber will cause the store into reg 999 to be dead, and
19454 flow will attempt to delete an epilogue insn. In this case, we
19455 need an unspec use/set of the register. */
19457 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19458 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19460 if (!epiloguep || call_used_regs [i])
19461 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19462 gen_rtx_REG (V4SImode, i));
19465 rtx reg = gen_rtx_REG (V4SImode, i);
19468 = gen_rtx_SET (VOIDmode,
19470 gen_rtx_UNSPEC (V4SImode,
19471 gen_rtvec (1, reg), 27));
19475 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19477 for (i = 0; i < nclobs; ++i)
19478 XVECEXP (insn, 0, i) = clobs[i];
19483 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19484 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19487 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19488 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19490 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19491 rtx replacea, replaceb;
19493 int_rtx = GEN_INT (offset);
19495 /* Some cases that need register indexed addressing. */
19496 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19497 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19498 || (TARGET_E500_DOUBLE && mode == DFmode)
19500 && SPE_VECTOR_MODE (mode)
19501 && !SPE_CONST_OFFSET_OK (offset)))
19503 /* Whomever calls us must make sure r11 is available in the
19504 flow path of instructions in the prologue. */
19505 offset_rtx = gen_rtx_REG (Pmode, 11);
19506 emit_move_insn (offset_rtx, int_rtx);
19508 replacea = offset_rtx;
19509 replaceb = int_rtx;
19513 offset_rtx = int_rtx;
19514 replacea = NULL_RTX;
19515 replaceb = NULL_RTX;
19518 reg = gen_rtx_REG (mode, regno);
19519 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19520 mem = gen_frame_mem (mode, addr);
19522 insn = emit_move_insn (mem, reg);
19524 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19527 /* Emit an offset memory reference suitable for a frame store, while
19528 converting to a valid addressing mode. */
19531 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19533 rtx int_rtx, offset_rtx;
19535 int_rtx = GEN_INT (offset);
19537 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19538 || (TARGET_E500_DOUBLE && mode == DFmode))
19540 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19541 emit_move_insn (offset_rtx, int_rtx);
19544 offset_rtx = int_rtx;
19546 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19549 /* Look for user-defined global regs. We should not save and restore these,
19550 and cannot use stmw/lmw if there are any in its range. */
19553 no_global_regs_above (int first, bool gpr)
19556 int last = gpr ? 32 : 64;
19557 for (i = first; i < last; i++)
19558 if (global_regs[i])
19563 #ifndef TARGET_FIX_AND_CONTINUE
19564 #define TARGET_FIX_AND_CONTINUE 0
19567 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19568 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19569 #define LAST_SAVRES_REGISTER 31
19570 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19572 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19574 /* Temporary holding space for an out-of-line register save/restore
19576 static char savres_routine_name[30];
19578 /* Return the name for an out-of-line register save/restore routine.
19579 We are saving/restoring GPRs if GPR is true. */
19582 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19583 bool savep, bool gpr, bool lr)
19585 const char *prefix = "";
19586 const char *suffix = "";
19588 /* Different targets are supposed to define
19589 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19590 routine name could be defined with:
19592 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19594 This is a nice idea in practice, but in reality, things are
19595 complicated in several ways:
19597 - ELF targets have save/restore routines for GPRs.
19599 - SPE targets use different prefixes for 32/64-bit registers, and
19600 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19602 - PPC64 ELF targets have routines for save/restore of GPRs that
19603 differ in what they do with the link register, so having a set
19604 prefix doesn't work. (We only use one of the save routines at
19605 the moment, though.)
19607 - PPC32 elf targets have "exit" versions of the restore routines
19608 that restore the link register and can save some extra space.
19609 These require an extra suffix. (There are also "tail" versions
19610 of the restore routines and "GOT" versions of the save routines,
19611 but we don't generate those at present. Same problems apply,
19614 We deal with all this by synthesizing our own prefix/suffix and
19615 using that for the simple sprintf call shown above. */
19618 /* No floating point saves on the SPE. */
19622 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19624 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19629 else if (DEFAULT_ABI == ABI_V4)
19635 prefix = savep ? "_savegpr_" : "_restgpr_";
19637 prefix = savep ? "_savefpr_" : "_restfpr_";
19642 else if (DEFAULT_ABI == ABI_AIX)
19644 #ifndef POWERPC_LINUX
19645 /* No out-of-line save/restore routines for GPRs on AIX. */
19646 gcc_assert (!TARGET_AIX || !gpr);
19652 ? (lr ? "_savegpr0_" : "_savegpr1_")
19653 : (lr ? "_restgpr0_" : "_restgpr1_"));
19654 #ifdef POWERPC_LINUX
19656 prefix = (savep ? "_savefpr_" : "_restfpr_");
19660 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19661 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19664 else if (DEFAULT_ABI == ABI_DARWIN)
19665 sorry ("Out-of-line save/restore routines not supported on Darwin");
19667 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19669 return savres_routine_name;
19672 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19673 We are saving/restoring GPRs if GPR is true. */
19676 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19679 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19681 int select = ((savep ? 1 : 0) << 2
19683 /* On the SPE, we never have any FPRs, but we do have
19684 32/64-bit versions of the routines. */
19685 ? (info->spe_64bit_regs_used ? 1 : 0)
19686 : (gpr ? 1 : 0)) << 1)
19689 /* Don't generate bogus routine names. */
19690 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19691 && regno <= LAST_SAVRES_REGISTER);
19693 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19699 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19701 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19702 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19703 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19709 /* Emit a sequence of insns, including a stack tie if needed, for
19710 resetting the stack pointer. If SAVRES is true, then don't reset the
19711 stack pointer, but move the base of the frame into r11 for use by
19712 out-of-line register restore routines. */
19715 rs6000_emit_stack_reset (rs6000_stack_t *info,
19716 rtx sp_reg_rtx, rtx frame_reg_rtx,
19717 int sp_offset, bool savres)
19719 /* This blockage is needed so that sched doesn't decide to move
19720 the sp change before the register restores. */
19721 if (frame_reg_rtx != sp_reg_rtx
19723 && info->spe_64bit_regs_used != 0
19724 && info->first_gp_reg_save != 32))
19725 rs6000_emit_stack_tie ();
19727 if (frame_reg_rtx != sp_reg_rtx)
19729 if (sp_offset != 0)
19731 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19732 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19733 GEN_INT (sp_offset)));
19736 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19738 else if (sp_offset != 0)
19740 /* If we are restoring registers out-of-line, we will be using the
19741 "exit" variants of the restore routines, which will reset the
19742 stack for us. But we do need to point r11 into the right place
19743 for those routines. */
19744 rtx dest_reg = (savres
19745 ? gen_rtx_REG (Pmode, 11)
19748 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19749 GEN_INT (sp_offset)));
19756 /* Construct a parallel rtx describing the effect of a call to an
19757 out-of-line register save/restore routine. */
19760 rs6000_make_savres_rtx (rs6000_stack_t *info,
19761 rtx frame_reg_rtx, int save_area_offset,
19762 enum machine_mode reg_mode,
19763 bool savep, bool gpr, bool lr)
19766 int offset, start_reg, end_reg, n_regs;
19767 int reg_size = GET_MODE_SIZE (reg_mode);
19773 ? info->first_gp_reg_save
19774 : info->first_fp_reg_save);
19775 end_reg = gpr ? 32 : 64;
19776 n_regs = end_reg - start_reg;
19777 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19780 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19782 RTVEC_ELT (p, offset++)
19783 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19785 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19786 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19787 RTVEC_ELT (p, offset++)
19788 = gen_rtx_USE (VOIDmode,
19789 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19793 for (i = 0; i < end_reg - start_reg; i++)
19795 rtx addr, reg, mem;
19796 reg = gen_rtx_REG (reg_mode, start_reg + i);
19797 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19798 GEN_INT (save_area_offset + reg_size*i));
19799 mem = gen_frame_mem (reg_mode, addr);
19801 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19803 savep ? reg : mem);
19808 rtx addr, reg, mem;
19809 reg = gen_rtx_REG (Pmode, 0);
19810 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19811 GEN_INT (info->lr_save_offset));
19812 mem = gen_frame_mem (Pmode, addr);
19813 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19816 return gen_rtx_PARALLEL (VOIDmode, p);
19819 /* Determine whether the gp REG is really used. */
19822 rs6000_reg_live_or_pic_offset_p (int reg)
19824 /* If the function calls eh_return, claim used all the registers that would
19825 be checked for liveness otherwise. This is required for the PIC offset
19826 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19827 register allocation purposes in this case. */
19829 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19830 && (!call_used_regs[reg]
19831 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19832 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19833 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19834 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19835 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19838 /* Emit function prologue as insns. */
19841 rs6000_emit_prologue (void)
19843 rs6000_stack_t *info = rs6000_stack_info ();
19844 enum machine_mode reg_mode = Pmode;
19845 int reg_size = TARGET_32BIT ? 4 : 8;
19846 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19847 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19848 rtx frame_reg_rtx = sp_reg_rtx;
19849 rtx cr_save_rtx = NULL_RTX;
19852 int saving_FPRs_inline;
19853 int saving_GPRs_inline;
19854 int using_store_multiple;
19855 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19856 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19857 && call_used_regs[STATIC_CHAIN_REGNUM]);
19858 HOST_WIDE_INT sp_offset = 0;
19860 if (flag_stack_usage)
19861 current_function_static_stack_size = info->total_size;
19863 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19864 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19866 if (TARGET_FIX_AND_CONTINUE)
19868 /* gdb on darwin arranges to forward a function from the old
19869 address by modifying the first 5 instructions of the function
19870 to branch to the overriding function. This is necessary to
19871 permit function pointers that point to the old function to
19872 actually forward to the new function. */
19873 emit_insn (gen_nop ());
19874 emit_insn (gen_nop ());
19875 emit_insn (gen_nop ());
19876 emit_insn (gen_nop ());
19877 emit_insn (gen_nop ());
19880 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19882 reg_mode = V2SImode;
19886 strategy = info->savres_strategy;
19887 using_store_multiple = strategy & SAVRES_MULTIPLE;
19888 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19889 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19891 /* For V.4, update stack before we do any saving and set back pointer. */
19892 if (! WORLD_SAVE_P (info)
19894 && (DEFAULT_ABI == ABI_V4
19895 || crtl->calls_eh_return))
19897 bool need_r11 = (TARGET_SPE
19898 ? (!saving_GPRs_inline
19899 && info->spe_64bit_regs_used == 0)
19900 : (!saving_FPRs_inline || !saving_GPRs_inline));
19901 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19903 if (info->total_size < 32767)
19904 sp_offset = info->total_size;
19906 frame_reg_rtx = copy_reg;
19907 else if (info->cr_save_p
19909 || info->first_fp_reg_save < 64
19910 || info->first_gp_reg_save < 32
19911 || info->altivec_size != 0
19912 || info->vrsave_mask != 0
19913 || crtl->calls_eh_return)
19915 copy_reg = frame_ptr_rtx;
19916 frame_reg_rtx = copy_reg;
19920 /* The prologue won't be saving any regs so there is no need
19921 to set up a frame register to access any frame save area.
19922 We also won't be using sp_offset anywhere below, but set
19923 the correct value anyway to protect against future
19924 changes to this function. */
19925 sp_offset = info->total_size;
19927 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19928 if (frame_reg_rtx != sp_reg_rtx)
19929 rs6000_emit_stack_tie ();
19932 /* Handle world saves specially here. */
19933 if (WORLD_SAVE_P (info))
19940 /* save_world expects lr in r0. */
19941 reg0 = gen_rtx_REG (Pmode, 0);
19942 if (info->lr_save_p)
19944 insn = emit_move_insn (reg0,
19945 gen_rtx_REG (Pmode, LR_REGNO));
19946 RTX_FRAME_RELATED_P (insn) = 1;
19949 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19950 assumptions about the offsets of various bits of the stack
19952 gcc_assert (info->gp_save_offset == -220
19953 && info->fp_save_offset == -144
19954 && info->lr_save_offset == 8
19955 && info->cr_save_offset == 4
19958 && (!crtl->calls_eh_return
19959 || info->ehrd_offset == -432)
19960 && info->vrsave_save_offset == -224
19961 && info->altivec_save_offset == -416);
19963 treg = gen_rtx_REG (SImode, 11);
19964 emit_move_insn (treg, GEN_INT (-info->total_size));
19966 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19967 in R11. It also clobbers R12, so beware! */
19969 /* Preserve CR2 for save_world prologues */
19971 sz += 32 - info->first_gp_reg_save;
19972 sz += 64 - info->first_fp_reg_save;
19973 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19974 p = rtvec_alloc (sz);
19976 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19977 gen_rtx_REG (SImode,
19979 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19980 gen_rtx_SYMBOL_REF (Pmode,
19982 /* We do floats first so that the instruction pattern matches
19984 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19986 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19987 ? DFmode : SFmode),
19988 info->first_fp_reg_save + i);
19989 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19990 GEN_INT (info->fp_save_offset
19991 + sp_offset + 8 * i));
19992 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19993 ? DFmode : SFmode), addr);
19995 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19997 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19999 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20000 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20001 GEN_INT (info->altivec_save_offset
20002 + sp_offset + 16 * i));
20003 rtx mem = gen_frame_mem (V4SImode, addr);
20005 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20007 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20009 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20010 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20011 GEN_INT (info->gp_save_offset
20012 + sp_offset + reg_size * i));
20013 rtx mem = gen_frame_mem (reg_mode, addr);
20015 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20019 /* CR register traditionally saved as CR2. */
20020 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20021 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20022 GEN_INT (info->cr_save_offset
20024 rtx mem = gen_frame_mem (reg_mode, addr);
20026 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20028 /* Explain about use of R0. */
20029 if (info->lr_save_p)
20031 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20032 GEN_INT (info->lr_save_offset
20034 rtx mem = gen_frame_mem (reg_mode, addr);
20036 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20038 /* Explain what happens to the stack pointer. */
20040 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20041 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20044 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20045 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20046 treg, GEN_INT (-info->total_size));
20047 sp_offset = info->total_size;
20050 /* If we use the link register, get it into r0. */
20051 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20053 rtx addr, reg, mem;
20055 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20056 gen_rtx_REG (Pmode, LR_REGNO));
20057 RTX_FRAME_RELATED_P (insn) = 1;
20059 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20060 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20062 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20063 GEN_INT (info->lr_save_offset + sp_offset));
20064 reg = gen_rtx_REG (Pmode, 0);
20065 mem = gen_rtx_MEM (Pmode, addr);
20066 /* This should not be of rs6000_sr_alias_set, because of
20067 __builtin_return_address. */
20069 insn = emit_move_insn (mem, reg);
20070 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20071 NULL_RTX, NULL_RTX);
20075 /* If we need to save CR, put it into r12 or r11. */
20076 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20081 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20083 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20084 RTX_FRAME_RELATED_P (insn) = 1;
20085 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20086 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20087 But that's OK. All we have to do is specify that _one_ condition
20088 code register is saved in this stack slot. The thrower's epilogue
20089 will then restore all the call-saved registers.
20090 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20091 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20092 gen_rtx_REG (SImode, CR2_REGNO));
20093 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20096 /* Do any required saving of fpr's. If only one or two to save, do
20097 it ourselves. Otherwise, call function. */
20098 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20101 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20102 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20103 && ! call_used_regs[info->first_fp_reg_save+i]))
20104 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20105 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20107 info->first_fp_reg_save + i,
20108 info->fp_save_offset + sp_offset + 8 * i,
20111 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20115 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20116 info->fp_save_offset + sp_offset,
20118 /*savep=*/true, /*gpr=*/false,
20120 & SAVE_NOINLINE_FPRS_SAVES_LR)
20122 insn = emit_insn (par);
20123 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20124 NULL_RTX, NULL_RTX);
20127 /* Save GPRs. This is done as a PARALLEL if we are using
20128 the store-multiple instructions. */
20129 if (!WORLD_SAVE_P (info)
20131 && info->spe_64bit_regs_used != 0
20132 && info->first_gp_reg_save != 32)
20135 rtx spe_save_area_ptr;
20137 /* Determine whether we can address all of the registers that need
20138 to be saved with an offset from the stack pointer that fits in
20139 the small const field for SPE memory instructions. */
20140 int spe_regs_addressable_via_sp
20141 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20142 + (32 - info->first_gp_reg_save - 1) * reg_size)
20143 && saving_GPRs_inline);
20146 if (spe_regs_addressable_via_sp)
20148 spe_save_area_ptr = frame_reg_rtx;
20149 spe_offset = info->spe_gp_save_offset + sp_offset;
20153 /* Make r11 point to the start of the SPE save area. We need
20154 to be careful here if r11 is holding the static chain. If
20155 it is, then temporarily save it in r0. We would use r0 as
20156 our base register here, but using r0 as a base register in
20157 loads and stores means something different from what we
20159 int ool_adjust = (saving_GPRs_inline
20161 : (info->first_gp_reg_save
20162 - (FIRST_SAVRES_REGISTER+1))*8);
20163 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20164 + sp_offset - ool_adjust);
20166 if (using_static_chain_p)
20168 rtx r0 = gen_rtx_REG (Pmode, 0);
20169 gcc_assert (info->first_gp_reg_save > 11);
20171 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20174 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20175 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20177 GEN_INT (offset)));
20178 /* We need to make sure the move to r11 gets noted for
20179 properly outputting unwind information. */
20180 if (!saving_GPRs_inline)
20181 rs6000_frame_related (insn, frame_reg_rtx, offset,
20182 NULL_RTX, NULL_RTX);
20186 if (saving_GPRs_inline)
20188 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20189 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20191 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20192 rtx offset, addr, mem;
20194 /* We're doing all this to ensure that the offset fits into
20195 the immediate offset of 'evstdd'. */
20196 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20198 offset = GEN_INT (reg_size * i + spe_offset);
20199 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20200 mem = gen_rtx_MEM (V2SImode, addr);
20202 insn = emit_move_insn (mem, reg);
20204 rs6000_frame_related (insn, spe_save_area_ptr,
20205 info->spe_gp_save_offset
20206 + sp_offset + reg_size * i,
20207 offset, const0_rtx);
20214 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20216 /*savep=*/true, /*gpr=*/true,
20218 insn = emit_insn (par);
20219 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20220 NULL_RTX, NULL_RTX);
20224 /* Move the static chain pointer back. */
20225 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20226 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20228 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20232 /* Need to adjust r11 (r12) if we saved any FPRs. */
20233 if (info->first_fp_reg_save != 64)
20235 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20237 rtx offset = GEN_INT (sp_offset
20238 + (-8 * (64-info->first_fp_reg_save)));
20239 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20242 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20243 info->gp_save_offset + sp_offset,
20245 /*savep=*/true, /*gpr=*/true,
20247 & SAVE_NOINLINE_GPRS_SAVES_LR)
20249 insn = emit_insn (par);
20250 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20251 NULL_RTX, NULL_RTX);
20253 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20257 p = rtvec_alloc (32 - info->first_gp_reg_save);
20258 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20260 rtx addr, reg, mem;
20261 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20262 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20263 GEN_INT (info->gp_save_offset
20266 mem = gen_frame_mem (reg_mode, addr);
20268 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20270 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20271 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20272 NULL_RTX, NULL_RTX);
20274 else if (!WORLD_SAVE_P (info))
20277 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20278 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20280 rtx addr, reg, mem;
20281 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20283 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20284 GEN_INT (info->gp_save_offset
20287 mem = gen_frame_mem (reg_mode, addr);
20289 insn = emit_move_insn (mem, reg);
20290 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20291 NULL_RTX, NULL_RTX);
20295 /* ??? There's no need to emit actual instructions here, but it's the
20296 easiest way to get the frame unwind information emitted. */
20297 if (crtl->calls_eh_return)
20299 unsigned int i, regno;
20303 regno = EH_RETURN_DATA_REGNO (i);
20304 if (regno == INVALID_REGNUM)
20307 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20308 info->ehrd_offset + sp_offset
20309 + reg_size * (int) i,
20314 /* In AIX ABI we need to make sure r2 is really saved. */
20315 if (TARGET_AIX && crtl->calls_eh_return)
20317 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20318 long toc_restore_insn;
20320 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20321 || frame_reg_rtx == sp_reg_rtx);
20322 tmp_reg = gen_rtx_REG (Pmode, 11);
20323 tmp_reg_si = gen_rtx_REG (SImode, 11);
20324 if (using_static_chain_p)
20325 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20326 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20327 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20328 /* Peek at instruction to which this function returns. If it's
20329 restoring r2, then we know we've already saved r2. We can't
20330 unconditionally save r2 because the value we have will already
20331 be updated if we arrived at this function via a plt call or
20332 toc adjusting stub. */
20333 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20334 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20335 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20336 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20337 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20338 validate_condition_mode (EQ, CCUNSmode);
20339 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20340 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20341 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20342 toc_save_done = gen_label_rtx ();
20343 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20344 gen_rtx_EQ (VOIDmode, compare_result,
20346 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20348 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20349 JUMP_LABEL (jump) = toc_save_done;
20350 LABEL_NUSES (toc_save_done) += 1;
20352 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20353 sp_offset + 5 * reg_size, info->total_size);
20354 emit_label (toc_save_done);
20355 if (using_static_chain_p)
20356 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20359 /* Save CR if we use any that must be preserved. */
20360 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20362 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20363 GEN_INT (info->cr_save_offset + sp_offset));
20364 rtx mem = gen_frame_mem (SImode, addr);
20365 /* See the large comment above about why CR2_REGNO is used. */
20366 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20368 /* If r12 was used to hold the original sp, copy cr into r0 now
20370 if (REGNO (frame_reg_rtx) == 12)
20374 cr_save_rtx = gen_rtx_REG (SImode, 0);
20375 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20376 RTX_FRAME_RELATED_P (insn) = 1;
20377 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20378 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20380 insn = emit_move_insn (mem, cr_save_rtx);
20382 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20383 NULL_RTX, NULL_RTX);
20386 /* Update stack and set back pointer unless this is V.4,
20387 for which it was done previously. */
20388 if (!WORLD_SAVE_P (info) && info->push_p
20389 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20391 rtx copy_reg = NULL;
20393 if (info->total_size < 32767)
20394 sp_offset = info->total_size;
20395 else if (info->altivec_size != 0
20396 || info->vrsave_mask != 0)
20398 copy_reg = frame_ptr_rtx;
20399 frame_reg_rtx = copy_reg;
20402 sp_offset = info->total_size;
20403 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20404 if (frame_reg_rtx != sp_reg_rtx)
20405 rs6000_emit_stack_tie ();
20408 /* Set frame pointer, if needed. */
20409 if (frame_pointer_needed)
20411 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20413 RTX_FRAME_RELATED_P (insn) = 1;
20416 /* Save AltiVec registers if needed. Save here because the red zone does
20417 not include AltiVec registers. */
20418 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20422 /* There should be a non inline version of this, for when we
20423 are saving lots of vector registers. */
20424 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20425 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20427 rtx areg, savereg, mem;
20430 offset = info->altivec_save_offset + sp_offset
20431 + 16 * (i - info->first_altivec_reg_save);
20433 savereg = gen_rtx_REG (V4SImode, i);
20435 areg = gen_rtx_REG (Pmode, 0);
20436 emit_move_insn (areg, GEN_INT (offset));
20438 /* AltiVec addressing mode is [reg+reg]. */
20439 mem = gen_frame_mem (V4SImode,
20440 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20442 insn = emit_move_insn (mem, savereg);
20444 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20445 areg, GEN_INT (offset));
20449 /* VRSAVE is a bit vector representing which AltiVec registers
20450 are used. The OS uses this to determine which vector
20451 registers to save on a context switch. We need to save
20452 VRSAVE on the stack frame, add whatever AltiVec registers we
20453 used in this function, and do the corresponding magic in the
20456 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20457 && info->vrsave_mask != 0)
20459 rtx reg, mem, vrsave;
20462 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20463 as frame_reg_rtx and r11 as the static chain pointer for
20464 nested functions. */
20465 reg = gen_rtx_REG (SImode, 0);
20466 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20468 emit_insn (gen_get_vrsave_internal (reg));
20470 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20472 if (!WORLD_SAVE_P (info))
20475 offset = info->vrsave_save_offset + sp_offset;
20476 mem = gen_frame_mem (SImode,
20477 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20478 GEN_INT (offset)));
20479 insn = emit_move_insn (mem, reg);
20482 /* Include the registers in the mask. */
20483 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20485 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20488 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20489 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20490 || (DEFAULT_ABI == ABI_V4
20491 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20492 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20494 /* If emit_load_toc_table will use the link register, we need to save
20495 it. We use R12 for this purpose because emit_load_toc_table
20496 can use register 0. This allows us to use a plain 'blr' to return
20497 from the procedure more often. */
20498 int save_LR_around_toc_setup = (TARGET_ELF
20499 && DEFAULT_ABI != ABI_AIX
20501 && ! info->lr_save_p
20502 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20503 if (save_LR_around_toc_setup)
20505 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20507 insn = emit_move_insn (frame_ptr_rtx, lr);
20508 RTX_FRAME_RELATED_P (insn) = 1;
20510 rs6000_emit_load_toc_table (TRUE);
20512 insn = emit_move_insn (lr, frame_ptr_rtx);
20513 RTX_FRAME_RELATED_P (insn) = 1;
20516 rs6000_emit_load_toc_table (TRUE);
20520 if (DEFAULT_ABI == ABI_DARWIN
20521 && flag_pic && crtl->uses_pic_offset_table)
20523 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20524 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20526 /* Save and restore LR locally around this call (in R0). */
20527 if (!info->lr_save_p)
20528 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20530 emit_insn (gen_load_macho_picbase (src));
20532 emit_move_insn (gen_rtx_REG (Pmode,
20533 RS6000_PIC_OFFSET_TABLE_REGNUM),
20536 if (!info->lr_save_p)
20537 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20542 /* Write function prologue. */
20545 rs6000_output_function_prologue (FILE *file,
20546 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20548 rs6000_stack_t *info = rs6000_stack_info ();
20550 if (TARGET_DEBUG_STACK)
20551 debug_stack_info (info);
20553 /* Write .extern for any function we will call to save and restore
20555 if (info->first_fp_reg_save < 64)
20558 int regno = info->first_fp_reg_save - 32;
20560 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20562 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20563 /*gpr=*/false, /*lr=*/false);
20564 fprintf (file, "\t.extern %s\n", name);
20566 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20568 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20569 /*gpr=*/false, /*lr=*/true);
20570 fprintf (file, "\t.extern %s\n", name);
20574 /* Write .extern for AIX common mode routines, if needed. */
20575 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20577 fputs ("\t.extern __mulh\n", file);
20578 fputs ("\t.extern __mull\n", file);
20579 fputs ("\t.extern __divss\n", file);
20580 fputs ("\t.extern __divus\n", file);
20581 fputs ("\t.extern __quoss\n", file);
20582 fputs ("\t.extern __quous\n", file);
20583 common_mode_defined = 1;
20586 if (! HAVE_prologue)
20592 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20593 the "toplevel" insn chain. */
20594 emit_note (NOTE_INSN_DELETED);
20595 rs6000_emit_prologue ();
20596 emit_note (NOTE_INSN_DELETED);
20598 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20602 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20604 INSN_ADDRESSES_NEW (insn, addr);
20609 prologue = get_insns ();
20612 if (TARGET_DEBUG_STACK)
20613 debug_rtx_list (prologue, 100);
20615 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20619 rs6000_pic_labelno++;
20622 /* Non-zero if vmx regs are restored before the frame pop, zero if
20623 we restore after the pop when possible. */
20624 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20626 /* Reload CR from REG. */
20629 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20634 if (using_mfcr_multiple)
20636 for (i = 0; i < 8; i++)
20637 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20639 gcc_assert (count);
20642 if (using_mfcr_multiple && count > 1)
20647 p = rtvec_alloc (count);
20650 for (i = 0; i < 8; i++)
20651 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20653 rtvec r = rtvec_alloc (2);
20654 RTVEC_ELT (r, 0) = reg;
20655 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20656 RTVEC_ELT (p, ndx) =
20657 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20658 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20661 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20662 gcc_assert (ndx == count);
20665 for (i = 0; i < 8; i++)
20666 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20668 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20674 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20675 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20676 below stack pointer not cloberred by signals. */
20679 offset_below_red_zone_p (HOST_WIDE_INT offset)
20681 return offset < (DEFAULT_ABI == ABI_V4
20683 : TARGET_32BIT ? -220 : -288);
20686 /* Emit function epilogue as insns. */
20689 rs6000_emit_epilogue (int sibcall)
20691 rs6000_stack_t *info;
20692 int restoring_GPRs_inline;
20693 int restoring_FPRs_inline;
20694 int using_load_multiple;
20695 int using_mtcr_multiple;
20696 int use_backchain_to_restore_sp;
20700 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20701 rtx frame_reg_rtx = sp_reg_rtx;
20702 rtx cfa_restores = NULL_RTX;
20704 rtx cr_save_reg = NULL_RTX;
20705 enum machine_mode reg_mode = Pmode;
20706 int reg_size = TARGET_32BIT ? 4 : 8;
20709 info = rs6000_stack_info ();
20711 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20713 reg_mode = V2SImode;
20717 strategy = info->savres_strategy;
20718 using_load_multiple = strategy & SAVRES_MULTIPLE;
20719 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20720 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20721 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20722 || rs6000_cpu == PROCESSOR_PPC603
20723 || rs6000_cpu == PROCESSOR_PPC750
20725 /* Restore via the backchain when we have a large frame, since this
20726 is more efficient than an addis, addi pair. The second condition
20727 here will not trigger at the moment; We don't actually need a
20728 frame pointer for alloca, but the generic parts of the compiler
20729 give us one anyway. */
20730 use_backchain_to_restore_sp = (info->total_size > 32767
20731 || info->total_size
20732 + (info->lr_save_p ? info->lr_save_offset : 0)
20734 || (cfun->calls_alloca
20735 && !frame_pointer_needed));
20736 restore_lr = (info->lr_save_p
20737 && (restoring_FPRs_inline
20738 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20739 && (restoring_GPRs_inline
20740 || info->first_fp_reg_save < 64));
20742 if (WORLD_SAVE_P (info))
20746 const char *alloc_rname;
20749 /* eh_rest_world_r10 will return to the location saved in the LR
20750 stack slot (which is not likely to be our caller.)
20751 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20752 rest_world is similar, except any R10 parameter is ignored.
20753 The exception-handling stuff that was here in 2.95 is no
20754 longer necessary. */
20758 + 32 - info->first_gp_reg_save
20759 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20760 + 63 + 1 - info->first_fp_reg_save);
20762 strcpy (rname, ((crtl->calls_eh_return) ?
20763 "*eh_rest_world_r10" : "*rest_world"));
20764 alloc_rname = ggc_strdup (rname);
20767 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20768 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20769 gen_rtx_REG (Pmode,
20772 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20773 /* The instruction pattern requires a clobber here;
20774 it is shared with the restVEC helper. */
20776 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20779 /* CR register traditionally saved as CR2. */
20780 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20781 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20782 GEN_INT (info->cr_save_offset));
20783 rtx mem = gen_frame_mem (reg_mode, addr);
20785 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20788 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20790 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20791 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20792 GEN_INT (info->gp_save_offset
20794 rtx mem = gen_frame_mem (reg_mode, addr);
20796 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20798 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20800 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20801 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20802 GEN_INT (info->altivec_save_offset
20804 rtx mem = gen_frame_mem (V4SImode, addr);
20806 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20808 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20810 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20811 ? DFmode : SFmode),
20812 info->first_fp_reg_save + i);
20813 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20814 GEN_INT (info->fp_save_offset
20816 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20817 ? DFmode : SFmode), addr);
20819 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20822 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20824 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20826 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20828 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20830 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20831 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20836 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20838 sp_offset = info->total_size;
20840 /* Restore AltiVec registers if we must do so before adjusting the
20842 if (TARGET_ALTIVEC_ABI
20843 && info->altivec_size != 0
20844 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20845 || (DEFAULT_ABI != ABI_V4
20846 && offset_below_red_zone_p (info->altivec_save_offset))))
20850 if (use_backchain_to_restore_sp)
20852 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20853 emit_move_insn (frame_reg_rtx,
20854 gen_rtx_MEM (Pmode, sp_reg_rtx));
20857 else if (frame_pointer_needed)
20858 frame_reg_rtx = hard_frame_pointer_rtx;
20860 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20861 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20863 rtx addr, areg, mem, reg;
20865 areg = gen_rtx_REG (Pmode, 0);
20867 (areg, GEN_INT (info->altivec_save_offset
20869 + 16 * (i - info->first_altivec_reg_save)));
20871 /* AltiVec addressing mode is [reg+reg]. */
20872 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20873 mem = gen_frame_mem (V4SImode, addr);
20875 reg = gen_rtx_REG (V4SImode, i);
20876 emit_move_insn (reg, mem);
20877 if (offset_below_red_zone_p (info->altivec_save_offset
20878 + (i - info->first_altivec_reg_save)
20880 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20885 /* Restore VRSAVE if we must do so before adjusting the stack. */
20887 && TARGET_ALTIVEC_VRSAVE
20888 && info->vrsave_mask != 0
20889 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20890 || (DEFAULT_ABI != ABI_V4
20891 && offset_below_red_zone_p (info->vrsave_save_offset))))
20893 rtx addr, mem, reg;
20895 if (frame_reg_rtx == sp_reg_rtx)
20897 if (use_backchain_to_restore_sp)
20899 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20900 emit_move_insn (frame_reg_rtx,
20901 gen_rtx_MEM (Pmode, sp_reg_rtx));
20904 else if (frame_pointer_needed)
20905 frame_reg_rtx = hard_frame_pointer_rtx;
20908 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20909 GEN_INT (info->vrsave_save_offset + sp_offset));
20910 mem = gen_frame_mem (SImode, addr);
20911 reg = gen_rtx_REG (SImode, 12);
20912 emit_move_insn (reg, mem);
20914 emit_insn (generate_set_vrsave (reg, info, 1));
20918 /* If we have a large stack frame, restore the old stack pointer
20919 using the backchain. */
20920 if (use_backchain_to_restore_sp)
20922 if (frame_reg_rtx == sp_reg_rtx)
20924 /* Under V.4, don't reset the stack pointer until after we're done
20925 loading the saved registers. */
20926 if (DEFAULT_ABI == ABI_V4)
20927 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20929 insn = emit_move_insn (frame_reg_rtx,
20930 gen_rtx_MEM (Pmode, sp_reg_rtx));
20933 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20934 && DEFAULT_ABI == ABI_V4)
20935 /* frame_reg_rtx has been set up by the altivec restore. */
20939 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20940 frame_reg_rtx = sp_reg_rtx;
20943 /* If we have a frame pointer, we can restore the old stack pointer
20945 else if (frame_pointer_needed)
20947 frame_reg_rtx = sp_reg_rtx;
20948 if (DEFAULT_ABI == ABI_V4)
20949 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20950 /* Prevent reordering memory accesses against stack pointer restore. */
20951 else if (cfun->calls_alloca
20952 || offset_below_red_zone_p (-info->total_size))
20954 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20955 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20956 MEM_NOTRAP_P (mem1) = 1;
20957 MEM_NOTRAP_P (mem2) = 1;
20958 emit_insn (gen_frame_tie (mem1, mem2));
20961 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20962 GEN_INT (info->total_size)));
20965 else if (info->push_p
20966 && DEFAULT_ABI != ABI_V4
20967 && !crtl->calls_eh_return)
20969 /* Prevent reordering memory accesses against stack pointer restore. */
20970 if (cfun->calls_alloca
20971 || offset_below_red_zone_p (-info->total_size))
20973 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20974 MEM_NOTRAP_P (mem) = 1;
20975 emit_insn (gen_stack_tie (mem));
20977 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20978 GEN_INT (info->total_size)));
20981 if (insn && frame_reg_rtx == sp_reg_rtx)
20985 REG_NOTES (insn) = cfa_restores;
20986 cfa_restores = NULL_RTX;
20988 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20989 RTX_FRAME_RELATED_P (insn) = 1;
20992 /* Restore AltiVec registers if we have not done so already. */
20993 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20994 && TARGET_ALTIVEC_ABI
20995 && info->altivec_size != 0
20996 && (DEFAULT_ABI == ABI_V4
20997 || !offset_below_red_zone_p (info->altivec_save_offset)))
21001 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21002 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21004 rtx addr, areg, mem, reg;
21006 areg = gen_rtx_REG (Pmode, 0);
21008 (areg, GEN_INT (info->altivec_save_offset
21010 + 16 * (i - info->first_altivec_reg_save)));
21012 /* AltiVec addressing mode is [reg+reg]. */
21013 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21014 mem = gen_frame_mem (V4SImode, addr);
21016 reg = gen_rtx_REG (V4SImode, i);
21017 emit_move_insn (reg, mem);
21018 if (DEFAULT_ABI == ABI_V4)
21019 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21024 /* Restore VRSAVE if we have not done so already. */
21025 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21027 && TARGET_ALTIVEC_VRSAVE
21028 && info->vrsave_mask != 0
21029 && (DEFAULT_ABI == ABI_V4
21030 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21032 rtx addr, mem, reg;
21034 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21035 GEN_INT (info->vrsave_save_offset + sp_offset));
21036 mem = gen_frame_mem (SImode, addr);
21037 reg = gen_rtx_REG (SImode, 12);
21038 emit_move_insn (reg, mem);
21040 emit_insn (generate_set_vrsave (reg, info, 1));
21043 /* Get the old lr if we saved it. If we are restoring registers
21044 out-of-line, then the out-of-line routines can do this for us. */
21045 if (restore_lr && restoring_GPRs_inline)
21047 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21048 info->lr_save_offset + sp_offset);
21050 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21053 /* Get the old cr if we saved it. */
21054 if (info->cr_save_p)
21056 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21057 GEN_INT (info->cr_save_offset + sp_offset));
21058 rtx mem = gen_frame_mem (SImode, addr);
21060 cr_save_reg = gen_rtx_REG (SImode,
21061 DEFAULT_ABI == ABI_AIX
21062 && !restoring_GPRs_inline
21063 && info->first_fp_reg_save < 64
21065 emit_move_insn (cr_save_reg, mem);
21068 /* Set LR here to try to overlap restores below. LR is always saved
21069 above incoming stack, so it never needs REG_CFA_RESTORE. */
21070 if (restore_lr && restoring_GPRs_inline)
21071 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21072 gen_rtx_REG (Pmode, 0));
21074 /* Load exception handler data registers, if needed. */
21075 if (crtl->calls_eh_return)
21077 unsigned int i, regno;
21081 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21082 GEN_INT (sp_offset + 5 * reg_size));
21083 rtx mem = gen_frame_mem (reg_mode, addr);
21085 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21092 regno = EH_RETURN_DATA_REGNO (i);
21093 if (regno == INVALID_REGNUM)
21096 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21097 info->ehrd_offset + sp_offset
21098 + reg_size * (int) i);
21100 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21104 /* Restore GPRs. This is done as a PARALLEL if we are using
21105 the load-multiple instructions. */
21107 && info->spe_64bit_regs_used != 0
21108 && info->first_gp_reg_save != 32)
21110 /* Determine whether we can address all of the registers that need
21111 to be saved with an offset from the stack pointer that fits in
21112 the small const field for SPE memory instructions. */
21113 int spe_regs_addressable_via_sp
21114 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21115 + (32 - info->first_gp_reg_save - 1) * reg_size)
21116 && restoring_GPRs_inline);
21119 if (spe_regs_addressable_via_sp)
21120 spe_offset = info->spe_gp_save_offset + sp_offset;
21123 rtx old_frame_reg_rtx = frame_reg_rtx;
21124 /* Make r11 point to the start of the SPE save area. We worried about
21125 not clobbering it when we were saving registers in the prologue.
21126 There's no need to worry here because the static chain is passed
21127 anew to every function. */
21128 int ool_adjust = (restoring_GPRs_inline
21130 : (info->first_gp_reg_save
21131 - (FIRST_SAVRES_REGISTER+1))*8);
21133 if (frame_reg_rtx == sp_reg_rtx)
21134 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21135 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21136 GEN_INT (info->spe_gp_save_offset
21139 /* Keep the invariant that frame_reg_rtx + sp_offset points
21140 at the top of the stack frame. */
21141 sp_offset = -info->spe_gp_save_offset;
21146 if (restoring_GPRs_inline)
21148 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21149 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21151 rtx offset, addr, mem, reg;
21153 /* We're doing all this to ensure that the immediate offset
21154 fits into the immediate field of 'evldd'. */
21155 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21157 offset = GEN_INT (spe_offset + reg_size * i);
21158 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21159 mem = gen_rtx_MEM (V2SImode, addr);
21160 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21162 insn = emit_move_insn (reg, mem);
21163 if (DEFAULT_ABI == ABI_V4)
21165 if (frame_pointer_needed
21166 && info->first_gp_reg_save + i
21167 == HARD_FRAME_POINTER_REGNUM)
21169 add_reg_note (insn, REG_CFA_DEF_CFA,
21170 plus_constant (frame_reg_rtx,
21172 RTX_FRAME_RELATED_P (insn) = 1;
21175 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21184 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21186 /*savep=*/false, /*gpr=*/true,
21188 emit_jump_insn (par);
21189 /* We don't want anybody else emitting things after we jumped
21194 else if (!restoring_GPRs_inline)
21196 /* We are jumping to an out-of-line function. */
21197 bool can_use_exit = info->first_fp_reg_save == 64;
21200 /* Emit stack reset code if we need it. */
21202 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21203 sp_offset, can_use_exit);
21206 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21209 GEN_INT (sp_offset - info->fp_size)));
21210 if (REGNO (frame_reg_rtx) == 11)
21211 sp_offset += info->fp_size;
21214 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21215 info->gp_save_offset, reg_mode,
21216 /*savep=*/false, /*gpr=*/true,
21217 /*lr=*/can_use_exit);
21221 if (info->cr_save_p)
21223 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21224 if (DEFAULT_ABI == ABI_V4)
21226 = alloc_reg_note (REG_CFA_RESTORE,
21227 gen_rtx_REG (SImode, CR2_REGNO),
21231 emit_jump_insn (par);
21233 /* We don't want anybody else emitting things after we jumped
21238 insn = emit_insn (par);
21239 if (DEFAULT_ABI == ABI_V4)
21241 if (frame_pointer_needed)
21243 add_reg_note (insn, REG_CFA_DEF_CFA,
21244 plus_constant (frame_reg_rtx, sp_offset));
21245 RTX_FRAME_RELATED_P (insn) = 1;
21248 for (i = info->first_gp_reg_save; i < 32; i++)
21250 = alloc_reg_note (REG_CFA_RESTORE,
21251 gen_rtx_REG (reg_mode, i), cfa_restores);
21254 else if (using_load_multiple)
21257 p = rtvec_alloc (32 - info->first_gp_reg_save);
21258 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21260 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21261 GEN_INT (info->gp_save_offset
21264 rtx mem = gen_frame_mem (reg_mode, addr);
21265 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21267 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21268 if (DEFAULT_ABI == ABI_V4)
21269 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21272 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21273 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21275 add_reg_note (insn, REG_CFA_DEF_CFA,
21276 plus_constant (frame_reg_rtx, sp_offset));
21277 RTX_FRAME_RELATED_P (insn) = 1;
21282 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21283 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21285 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21286 GEN_INT (info->gp_save_offset
21289 rtx mem = gen_frame_mem (reg_mode, addr);
21290 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21292 insn = emit_move_insn (reg, mem);
21293 if (DEFAULT_ABI == ABI_V4)
21295 if (frame_pointer_needed
21296 && info->first_gp_reg_save + i
21297 == HARD_FRAME_POINTER_REGNUM)
21299 add_reg_note (insn, REG_CFA_DEF_CFA,
21300 plus_constant (frame_reg_rtx, sp_offset));
21301 RTX_FRAME_RELATED_P (insn) = 1;
21304 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21310 if (restore_lr && !restoring_GPRs_inline)
21312 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21313 info->lr_save_offset + sp_offset);
21315 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21316 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21317 gen_rtx_REG (Pmode, 0));
21320 /* Restore fpr's if we need to do it without calling a function. */
21321 if (restoring_FPRs_inline)
21322 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21323 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21324 && ! call_used_regs[info->first_fp_reg_save+i]))
21326 rtx addr, mem, reg;
21327 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21328 GEN_INT (info->fp_save_offset
21331 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21332 ? DFmode : SFmode), addr);
21333 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21334 ? DFmode : SFmode),
21335 info->first_fp_reg_save + i);
21337 emit_move_insn (reg, mem);
21338 if (DEFAULT_ABI == ABI_V4)
21339 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21343 /* If we saved cr, restore it here. Just those that were used. */
21344 if (info->cr_save_p)
21346 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21347 if (DEFAULT_ABI == ABI_V4)
21349 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21353 /* If this is V.4, unwind the stack pointer after all of the loads
21355 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21356 sp_offset, !restoring_FPRs_inline);
21361 REG_NOTES (insn) = cfa_restores;
21362 cfa_restores = NULL_RTX;
21364 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21365 RTX_FRAME_RELATED_P (insn) = 1;
21368 if (crtl->calls_eh_return)
21370 rtx sa = EH_RETURN_STACKADJ_RTX;
21371 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21377 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21378 if (! restoring_FPRs_inline)
21379 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21381 p = rtvec_alloc (2);
21383 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21384 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21385 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21386 : gen_rtx_CLOBBER (VOIDmode,
21387 gen_rtx_REG (Pmode, 65)));
21389 /* If we have to restore more than two FP registers, branch to the
21390 restore function. It will return to our caller. */
21391 if (! restoring_FPRs_inline)
21396 sym = rs6000_savres_routine_sym (info,
21400 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21401 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21402 gen_rtx_REG (Pmode,
21403 DEFAULT_ABI == ABI_AIX
21405 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21408 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21409 GEN_INT (info->fp_save_offset + 8*i));
21410 mem = gen_frame_mem (DFmode, addr);
21412 RTVEC_ELT (p, i+4) =
21413 gen_rtx_SET (VOIDmode,
21414 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21419 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21423 /* Write function epilogue. */
21426 rs6000_output_function_epilogue (FILE *file,
21427 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21429 if (! HAVE_epilogue)
21431 rtx insn = get_last_insn ();
21432 /* If the last insn was a BARRIER, we don't have to write anything except
21433 the trace table. */
21434 if (GET_CODE (insn) == NOTE)
21435 insn = prev_nonnote_insn (insn);
21436 if (insn == 0 || GET_CODE (insn) != BARRIER)
21438 /* This is slightly ugly, but at least we don't have two
21439 copies of the epilogue-emitting code. */
21442 /* A NOTE_INSN_DELETED is supposed to be at the start
21443 and end of the "toplevel" insn chain. */
21444 emit_note (NOTE_INSN_DELETED);
21445 rs6000_emit_epilogue (FALSE);
21446 emit_note (NOTE_INSN_DELETED);
21448 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21452 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21454 INSN_ADDRESSES_NEW (insn, addr);
21459 if (TARGET_DEBUG_STACK)
21460 debug_rtx_list (get_insns (), 100);
21461 final (get_insns (), file, FALSE);
21467 macho_branch_islands ();
21468 /* Mach-O doesn't support labels at the end of objects, so if
21469 it looks like we might want one, insert a NOP. */
21471 rtx insn = get_last_insn ();
21474 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21475 insn = PREV_INSN (insn);
21479 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21480 fputs ("\tnop\n", file);
21484 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21487 We don't output a traceback table if -finhibit-size-directive was
21488 used. The documentation for -finhibit-size-directive reads
21489 ``don't output a @code{.size} assembler directive, or anything
21490 else that would cause trouble if the function is split in the
21491 middle, and the two halves are placed at locations far apart in
21492 memory.'' The traceback table has this property, since it
21493 includes the offset from the start of the function to the
21494 traceback table itself.
21496 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21497 different traceback table. */
21498 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21499 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21501 const char *fname = NULL;
21502 const char *language_string = lang_hooks.name;
21503 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21505 int optional_tbtab;
21506 rs6000_stack_t *info = rs6000_stack_info ();
21508 if (rs6000_traceback == traceback_full)
21509 optional_tbtab = 1;
21510 else if (rs6000_traceback == traceback_part)
21511 optional_tbtab = 0;
21513 optional_tbtab = !optimize_size && !TARGET_ELF;
21515 if (optional_tbtab)
21517 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21518 while (*fname == '.') /* V.4 encodes . in the name */
21521 /* Need label immediately before tbtab, so we can compute
21522 its offset from the function start. */
21523 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21524 ASM_OUTPUT_LABEL (file, fname);
21527 /* The .tbtab pseudo-op can only be used for the first eight
21528 expressions, since it can't handle the possibly variable
21529 length fields that follow. However, if you omit the optional
21530 fields, the assembler outputs zeros for all optional fields
21531 anyways, giving each variable length field is minimum length
21532 (as defined in sys/debug.h). Thus we can not use the .tbtab
21533 pseudo-op at all. */
21535 /* An all-zero word flags the start of the tbtab, for debuggers
21536 that have to find it by searching forward from the entry
21537 point or from the current pc. */
21538 fputs ("\t.long 0\n", file);
21540 /* Tbtab format type. Use format type 0. */
21541 fputs ("\t.byte 0,", file);
21543 /* Language type. Unfortunately, there does not seem to be any
21544 official way to discover the language being compiled, so we
21545 use language_string.
21546 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21547 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21548 a number, so for now use 9. LTO isn't assigned a number either,
21549 so for now use 0. */
21550 if (! strcmp (language_string, "GNU C")
21551 || ! strcmp (language_string, "GNU GIMPLE"))
21553 else if (! strcmp (language_string, "GNU F77")
21554 || ! strcmp (language_string, "GNU Fortran"))
21556 else if (! strcmp (language_string, "GNU Pascal"))
21558 else if (! strcmp (language_string, "GNU Ada"))
21560 else if (! strcmp (language_string, "GNU C++")
21561 || ! strcmp (language_string, "GNU Objective-C++"))
21563 else if (! strcmp (language_string, "GNU Java"))
21565 else if (! strcmp (language_string, "GNU Objective-C"))
21568 gcc_unreachable ();
21569 fprintf (file, "%d,", i);
21571 /* 8 single bit fields: global linkage (not set for C extern linkage,
21572 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21573 from start of procedure stored in tbtab, internal function, function
21574 has controlled storage, function has no toc, function uses fp,
21575 function logs/aborts fp operations. */
21576 /* Assume that fp operations are used if any fp reg must be saved. */
21577 fprintf (file, "%d,",
21578 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21580 /* 6 bitfields: function is interrupt handler, name present in
21581 proc table, function calls alloca, on condition directives
21582 (controls stack walks, 3 bits), saves condition reg, saves
21584 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21585 set up as a frame pointer, even when there is no alloca call. */
21586 fprintf (file, "%d,",
21587 ((optional_tbtab << 6)
21588 | ((optional_tbtab & frame_pointer_needed) << 5)
21589 | (info->cr_save_p << 1)
21590 | (info->lr_save_p)));
21592 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21594 fprintf (file, "%d,",
21595 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21597 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21598 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21600 if (optional_tbtab)
21602 /* Compute the parameter info from the function decl argument
21605 int next_parm_info_bit = 31;
21607 for (decl = DECL_ARGUMENTS (current_function_decl);
21608 decl; decl = DECL_CHAIN (decl))
21610 rtx parameter = DECL_INCOMING_RTL (decl);
21611 enum machine_mode mode = GET_MODE (parameter);
21613 if (GET_CODE (parameter) == REG)
21615 if (SCALAR_FLOAT_MODE_P (mode))
21636 gcc_unreachable ();
21639 /* If only one bit will fit, don't or in this entry. */
21640 if (next_parm_info_bit > 0)
21641 parm_info |= (bits << (next_parm_info_bit - 1));
21642 next_parm_info_bit -= 2;
21646 fixed_parms += ((GET_MODE_SIZE (mode)
21647 + (UNITS_PER_WORD - 1))
21649 next_parm_info_bit -= 1;
21655 /* Number of fixed point parameters. */
21656 /* This is actually the number of words of fixed point parameters; thus
21657 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21658 fprintf (file, "%d,", fixed_parms);
21660 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21662 /* This is actually the number of fp registers that hold parameters;
21663 and thus the maximum value is 13. */
21664 /* Set parameters on stack bit if parameters are not in their original
21665 registers, regardless of whether they are on the stack? Xlc
21666 seems to set the bit when not optimizing. */
21667 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21669 if (! optional_tbtab)
21672 /* Optional fields follow. Some are variable length. */
21674 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21675 11 double float. */
21676 /* There is an entry for each parameter in a register, in the order that
21677 they occur in the parameter list. Any intervening arguments on the
21678 stack are ignored. If the list overflows a long (max possible length
21679 34 bits) then completely leave off all elements that don't fit. */
21680 /* Only emit this long if there was at least one parameter. */
21681 if (fixed_parms || float_parms)
21682 fprintf (file, "\t.long %d\n", parm_info);
21684 /* Offset from start of code to tb table. */
21685 fputs ("\t.long ", file);
21686 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21687 RS6000_OUTPUT_BASENAME (file, fname);
21689 rs6000_output_function_entry (file, fname);
21692 /* Interrupt handler mask. */
21693 /* Omit this long, since we never set the interrupt handler bit
21696 /* Number of CTL (controlled storage) anchors. */
21697 /* Omit this long, since the has_ctl bit is never set above. */
21699 /* Displacement into stack of each CTL anchor. */
21700 /* Omit this list of longs, because there are no CTL anchors. */
21702 /* Length of function name. */
21705 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21707 /* Function name. */
21708 assemble_string (fname, strlen (fname));
21710 /* Register for alloca automatic storage; this is always reg 31.
21711 Only emit this if the alloca bit was set above. */
21712 if (frame_pointer_needed)
21713 fputs ("\t.byte 31\n", file);
21715 fputs ("\t.align 2\n", file);
21719 /* A C compound statement that outputs the assembler code for a thunk
21720 function, used to implement C++ virtual function calls with
21721 multiple inheritance. The thunk acts as a wrapper around a virtual
21722 function, adjusting the implicit object parameter before handing
21723 control off to the real function.
21725 First, emit code to add the integer DELTA to the location that
21726 contains the incoming first argument. Assume that this argument
21727 contains a pointer, and is the one used to pass the `this' pointer
21728 in C++. This is the incoming argument *before* the function
21729 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21730 values of all other incoming arguments.
21732 After the addition, emit code to jump to FUNCTION, which is a
21733 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21734 not touch the return address. Hence returning from FUNCTION will
21735 return to whoever called the current `thunk'.
21737 The effect must be as if FUNCTION had been called directly with the
21738 adjusted first argument. This macro is responsible for emitting
21739 all of the code for a thunk function; output_function_prologue()
21740 and output_function_epilogue() are not invoked.
21742 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21743 been extracted from it.) It might possibly be useful on some
21744 targets, but probably not.
21746 If you do not define this macro, the target-independent code in the
21747 C++ frontend will generate a less efficient heavyweight thunk that
21748 calls FUNCTION instead of jumping to it. The generic approach does
21749 not support varargs. */
21752 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21753 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21756 rtx this_rtx, insn, funexp;
21758 reload_completed = 1;
21759 epilogue_completed = 1;
21761 /* Mark the end of the (empty) prologue. */
21762 emit_note (NOTE_INSN_PROLOGUE_END);
21764 /* Find the "this" pointer. If the function returns a structure,
21765 the structure return pointer is in r3. */
21766 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21767 this_rtx = gen_rtx_REG (Pmode, 4);
21769 this_rtx = gen_rtx_REG (Pmode, 3);
21771 /* Apply the constant offset, if required. */
21773 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21775 /* Apply the offset from the vtable, if required. */
21778 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21779 rtx tmp = gen_rtx_REG (Pmode, 12);
21781 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21782 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21784 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21785 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21789 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21791 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21793 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21796 /* Generate a tail call to the target function. */
21797 if (!TREE_USED (function))
21799 assemble_external (function);
21800 TREE_USED (function) = 1;
21802 funexp = XEXP (DECL_RTL (function), 0);
21803 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21806 if (MACHOPIC_INDIRECT)
21807 funexp = machopic_indirect_call_target (funexp);
21810 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21811 generate sibcall RTL explicitly. */
21812 insn = emit_call_insn (
21813 gen_rtx_PARALLEL (VOIDmode,
21815 gen_rtx_CALL (VOIDmode,
21816 funexp, const0_rtx),
21817 gen_rtx_USE (VOIDmode, const0_rtx),
21818 gen_rtx_USE (VOIDmode,
21819 gen_rtx_REG (SImode,
21821 gen_rtx_RETURN (VOIDmode))));
21822 SIBLING_CALL_P (insn) = 1;
21825 /* Run just enough of rest_of_compilation to get the insns emitted.
21826 There's not really enough bulk here to make other passes such as
21827 instruction scheduling worth while. Note that use_thunk calls
21828 assemble_start_function and assemble_end_function. */
21829 insn = get_insns ();
21830 insn_locators_alloc ();
21831 shorten_branches (insn);
21832 final_start_function (insn, file, 1);
21833 final (insn, file, 1);
21834 final_end_function ();
21836 reload_completed = 0;
21837 epilogue_completed = 0;
21840 /* A quick summary of the various types of 'constant-pool tables'
21843 Target Flags Name One table per
21844 AIX (none) AIX TOC object file
21845 AIX -mfull-toc AIX TOC object file
21846 AIX -mminimal-toc AIX minimal TOC translation unit
21847 SVR4/EABI (none) SVR4 SDATA object file
21848 SVR4/EABI -fpic SVR4 pic object file
21849 SVR4/EABI -fPIC SVR4 PIC translation unit
21850 SVR4/EABI -mrelocatable EABI TOC function
21851 SVR4/EABI -maix AIX TOC object file
21852 SVR4/EABI -maix -mminimal-toc
21853 AIX minimal TOC translation unit
21855 Name Reg. Set by entries contains:
21856 made by addrs? fp? sum?
21858 AIX TOC 2 crt0 as Y option option
21859 AIX minimal TOC 30 prolog gcc Y Y option
21860 SVR4 SDATA 13 crt0 gcc N Y N
21861 SVR4 pic 30 prolog ld Y not yet N
21862 SVR4 PIC 30 prolog gcc Y option option
21863 EABI TOC 30 prolog gcc Y option option
21867 /* Hash functions for the hash table. */
21870 rs6000_hash_constant (rtx k)
21872 enum rtx_code code = GET_CODE (k);
21873 enum machine_mode mode = GET_MODE (k);
21874 unsigned result = (code << 3) ^ mode;
21875 const char *format;
21878 format = GET_RTX_FORMAT (code);
21879 flen = strlen (format);
21885 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21888 if (mode != VOIDmode)
21889 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21901 for (; fidx < flen; fidx++)
21902 switch (format[fidx])
21907 const char *str = XSTR (k, fidx);
21908 len = strlen (str);
21909 result = result * 613 + len;
21910 for (i = 0; i < len; i++)
21911 result = result * 613 + (unsigned) str[i];
21916 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21920 result = result * 613 + (unsigned) XINT (k, fidx);
21923 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21924 result = result * 613 + (unsigned) XWINT (k, fidx);
21928 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21929 result = result * 613 + (unsigned) (XWINT (k, fidx)
21936 gcc_unreachable ();
21943 toc_hash_function (const void *hash_entry)
21945 const struct toc_hash_struct *thc =
21946 (const struct toc_hash_struct *) hash_entry;
21947 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21950 /* Compare H1 and H2 for equivalence. */
21953 toc_hash_eq (const void *h1, const void *h2)
21955 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21956 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21958 if (((const struct toc_hash_struct *) h1)->key_mode
21959 != ((const struct toc_hash_struct *) h2)->key_mode)
21962 return rtx_equal_p (r1, r2);
21965 /* These are the names given by the C++ front-end to vtables, and
21966 vtable-like objects. Ideally, this logic should not be here;
21967 instead, there should be some programmatic way of inquiring as
21968 to whether or not an object is a vtable. */
21970 #define VTABLE_NAME_P(NAME) \
21971 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21972 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21973 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21974 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21975 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21977 #ifdef NO_DOLLAR_IN_LABEL
21978 /* Return a GGC-allocated character string translating dollar signs in
21979 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21982 rs6000_xcoff_strip_dollar (const char *name)
21987 p = strchr (name, '$');
21989 if (p == 0 || p == name)
21992 len = strlen (name);
21993 strip = (char *) alloca (len + 1);
21994 strcpy (strip, name);
21995 p = strchr (strip, '$');
21999 p = strchr (p + 1, '$');
22002 return ggc_alloc_string (strip, len);
22007 rs6000_output_symbol_ref (FILE *file, rtx x)
22009 /* Currently C++ toc references to vtables can be emitted before it
22010 is decided whether the vtable is public or private. If this is
22011 the case, then the linker will eventually complain that there is
22012 a reference to an unknown section. Thus, for vtables only,
22013 we emit the TOC reference to reference the symbol and not the
22015 const char *name = XSTR (x, 0);
22017 if (VTABLE_NAME_P (name))
22019 RS6000_OUTPUT_BASENAME (file, name);
22022 assemble_name (file, name);
22025 /* Output a TOC entry. We derive the entry name from what is being
22029 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22032 const char *name = buf;
22034 HOST_WIDE_INT offset = 0;
22036 gcc_assert (!TARGET_NO_TOC);
22038 /* When the linker won't eliminate them, don't output duplicate
22039 TOC entries (this happens on AIX if there is any kind of TOC,
22040 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22042 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22044 struct toc_hash_struct *h;
22047 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22048 time because GGC is not initialized at that point. */
22049 if (toc_hash_table == NULL)
22050 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22051 toc_hash_eq, NULL);
22053 h = ggc_alloc_toc_hash_struct ();
22055 h->key_mode = mode;
22056 h->labelno = labelno;
22058 found = htab_find_slot (toc_hash_table, h, INSERT);
22059 if (*found == NULL)
22061 else /* This is indeed a duplicate.
22062 Set this label equal to that label. */
22064 fputs ("\t.set ", file);
22065 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22066 fprintf (file, "%d,", labelno);
22067 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22068 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22074 /* If we're going to put a double constant in the TOC, make sure it's
22075 aligned properly when strict alignment is on. */
22076 if (GET_CODE (x) == CONST_DOUBLE
22077 && STRICT_ALIGNMENT
22078 && GET_MODE_BITSIZE (mode) >= 64
22079 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22080 ASM_OUTPUT_ALIGN (file, 3);
22083 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22085 /* Handle FP constants specially. Note that if we have a minimal
22086 TOC, things we put here aren't actually in the TOC, so we can allow
22088 if (GET_CODE (x) == CONST_DOUBLE &&
22089 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22091 REAL_VALUE_TYPE rv;
22094 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22095 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22096 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22098 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22102 if (TARGET_MINIMAL_TOC)
22103 fputs (DOUBLE_INT_ASM_OP, file);
22105 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22106 k[0] & 0xffffffff, k[1] & 0xffffffff,
22107 k[2] & 0xffffffff, k[3] & 0xffffffff);
22108 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22109 k[0] & 0xffffffff, k[1] & 0xffffffff,
22110 k[2] & 0xffffffff, k[3] & 0xffffffff);
22115 if (TARGET_MINIMAL_TOC)
22116 fputs ("\t.long ", file);
22118 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22119 k[0] & 0xffffffff, k[1] & 0xffffffff,
22120 k[2] & 0xffffffff, k[3] & 0xffffffff);
22121 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22122 k[0] & 0xffffffff, k[1] & 0xffffffff,
22123 k[2] & 0xffffffff, k[3] & 0xffffffff);
22127 else if (GET_CODE (x) == CONST_DOUBLE &&
22128 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22130 REAL_VALUE_TYPE rv;
22133 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22135 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22136 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22138 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22142 if (TARGET_MINIMAL_TOC)
22143 fputs (DOUBLE_INT_ASM_OP, file);
22145 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22146 k[0] & 0xffffffff, k[1] & 0xffffffff);
22147 fprintf (file, "0x%lx%08lx\n",
22148 k[0] & 0xffffffff, k[1] & 0xffffffff);
22153 if (TARGET_MINIMAL_TOC)
22154 fputs ("\t.long ", file);
22156 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22157 k[0] & 0xffffffff, k[1] & 0xffffffff);
22158 fprintf (file, "0x%lx,0x%lx\n",
22159 k[0] & 0xffffffff, k[1] & 0xffffffff);
22163 else if (GET_CODE (x) == CONST_DOUBLE &&
22164 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22166 REAL_VALUE_TYPE rv;
22169 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22170 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22171 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22173 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22177 if (TARGET_MINIMAL_TOC)
22178 fputs (DOUBLE_INT_ASM_OP, file);
22180 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22181 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22186 if (TARGET_MINIMAL_TOC)
22187 fputs ("\t.long ", file);
22189 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22190 fprintf (file, "0x%lx\n", l & 0xffffffff);
22194 else if (GET_MODE (x) == VOIDmode
22195 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22197 unsigned HOST_WIDE_INT low;
22198 HOST_WIDE_INT high;
22200 if (GET_CODE (x) == CONST_DOUBLE)
22202 low = CONST_DOUBLE_LOW (x);
22203 high = CONST_DOUBLE_HIGH (x);
22206 #if HOST_BITS_PER_WIDE_INT == 32
22209 high = (low & 0x80000000) ? ~0 : 0;
22213 low = INTVAL (x) & 0xffffffff;
22214 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22218 /* TOC entries are always Pmode-sized, but since this
22219 is a bigendian machine then if we're putting smaller
22220 integer constants in the TOC we have to pad them.
22221 (This is still a win over putting the constants in
22222 a separate constant pool, because then we'd have
22223 to have both a TOC entry _and_ the actual constant.)
22225 For a 32-bit target, CONST_INT values are loaded and shifted
22226 entirely within `low' and can be stored in one TOC entry. */
22228 /* It would be easy to make this work, but it doesn't now. */
22229 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22231 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22233 #if HOST_BITS_PER_WIDE_INT == 32
22234 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22235 POINTER_SIZE, &low, &high, 0);
22238 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22239 high = (HOST_WIDE_INT) low >> 32;
22246 if (TARGET_MINIMAL_TOC)
22247 fputs (DOUBLE_INT_ASM_OP, file);
22249 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22250 (long) high & 0xffffffff, (long) low & 0xffffffff);
22251 fprintf (file, "0x%lx%08lx\n",
22252 (long) high & 0xffffffff, (long) low & 0xffffffff);
22257 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22259 if (TARGET_MINIMAL_TOC)
22260 fputs ("\t.long ", file);
22262 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22263 (long) high & 0xffffffff, (long) low & 0xffffffff);
22264 fprintf (file, "0x%lx,0x%lx\n",
22265 (long) high & 0xffffffff, (long) low & 0xffffffff);
22269 if (TARGET_MINIMAL_TOC)
22270 fputs ("\t.long ", file);
22272 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22273 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22279 if (GET_CODE (x) == CONST)
22281 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22282 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22284 base = XEXP (XEXP (x, 0), 0);
22285 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22288 switch (GET_CODE (base))
22291 name = XSTR (base, 0);
22295 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22296 CODE_LABEL_NUMBER (XEXP (base, 0)));
22300 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22304 gcc_unreachable ();
22307 if (TARGET_MINIMAL_TOC)
22308 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22311 fputs ("\t.tc ", file);
22312 RS6000_OUTPUT_BASENAME (file, name);
22315 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22317 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22319 fputs ("[TC],", file);
22322 /* Currently C++ toc references to vtables can be emitted before it
22323 is decided whether the vtable is public or private. If this is
22324 the case, then the linker will eventually complain that there is
22325 a TOC reference to an unknown section. Thus, for vtables only,
22326 we emit the TOC reference to reference the symbol and not the
22328 if (VTABLE_NAME_P (name))
22330 RS6000_OUTPUT_BASENAME (file, name);
22332 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22333 else if (offset > 0)
22334 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22337 output_addr_const (file, x);
22341 /* Output an assembler pseudo-op to write an ASCII string of N characters
22342 starting at P to FILE.
22344 On the RS/6000, we have to do this using the .byte operation and
22345 write out special characters outside the quoted string.
22346 Also, the assembler is broken; very long strings are truncated,
22347 so we must artificially break them up early. */
22350 output_ascii (FILE *file, const char *p, int n)
22353 int i, count_string;
22354 const char *for_string = "\t.byte \"";
22355 const char *for_decimal = "\t.byte ";
22356 const char *to_close = NULL;
22359 for (i = 0; i < n; i++)
22362 if (c >= ' ' && c < 0177)
22365 fputs (for_string, file);
22368 /* Write two quotes to get one. */
22376 for_decimal = "\"\n\t.byte ";
22380 if (count_string >= 512)
22382 fputs (to_close, file);
22384 for_string = "\t.byte \"";
22385 for_decimal = "\t.byte ";
22393 fputs (for_decimal, file);
22394 fprintf (file, "%d", c);
22396 for_string = "\n\t.byte \"";
22397 for_decimal = ", ";
22403 /* Now close the string if we have written one. Then end the line. */
22405 fputs (to_close, file);
22408 /* Generate a unique section name for FILENAME for a section type
22409 represented by SECTION_DESC. Output goes into BUF.
22411 SECTION_DESC can be any string, as long as it is different for each
22412 possible section type.
22414 We name the section in the same manner as xlc. The name begins with an
22415 underscore followed by the filename (after stripping any leading directory
22416 names) with the last period replaced by the string SECTION_DESC. If
22417 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22421 rs6000_gen_section_name (char **buf, const char *filename,
22422 const char *section_desc)
22424 const char *q, *after_last_slash, *last_period = 0;
22428 after_last_slash = filename;
22429 for (q = filename; *q; q++)
22432 after_last_slash = q + 1;
22433 else if (*q == '.')
22437 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22438 *buf = (char *) xmalloc (len);
22443 for (q = after_last_slash; *q; q++)
22445 if (q == last_period)
22447 strcpy (p, section_desc);
22448 p += strlen (section_desc);
22452 else if (ISALNUM (*q))
22456 if (last_period == 0)
22457 strcpy (p, section_desc);
22462 /* Emit profile function. */
22465 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22467 /* Non-standard profiling for kernels, which just saves LR then calls
22468 _mcount without worrying about arg saves. The idea is to change
22469 the function prologue as little as possible as it isn't easy to
22470 account for arg save/restore code added just for _mcount. */
22471 if (TARGET_PROFILE_KERNEL)
22474 if (DEFAULT_ABI == ABI_AIX)
22476 #ifndef NO_PROFILE_COUNTERS
22477 # define NO_PROFILE_COUNTERS 0
22479 if (NO_PROFILE_COUNTERS)
22480 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22481 LCT_NORMAL, VOIDmode, 0);
22485 const char *label_name;
22488 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22489 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22490 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22492 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22493 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22496 else if (DEFAULT_ABI == ABI_DARWIN)
22498 const char *mcount_name = RS6000_MCOUNT;
22499 int caller_addr_regno = LR_REGNO;
22501 /* Be conservative and always set this, at least for now. */
22502 crtl->uses_pic_offset_table = 1;
22505 /* For PIC code, set up a stub and collect the caller's address
22506 from r0, which is where the prologue puts it. */
22507 if (MACHOPIC_INDIRECT
22508 && crtl->uses_pic_offset_table)
22509 caller_addr_regno = 0;
22511 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22512 LCT_NORMAL, VOIDmode, 1,
22513 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22517 /* Write function profiler code. */
22520 output_function_profiler (FILE *file, int labelno)
22524 switch (DEFAULT_ABI)
22527 gcc_unreachable ();
22532 warning (0, "no profiling of 64-bit code for this ABI");
22535 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22536 fprintf (file, "\tmflr %s\n", reg_names[0]);
22537 if (NO_PROFILE_COUNTERS)
22539 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22540 reg_names[0], reg_names[1]);
22542 else if (TARGET_SECURE_PLT && flag_pic)
22544 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22545 reg_names[0], reg_names[1]);
22546 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22547 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22548 reg_names[12], reg_names[12]);
22549 assemble_name (file, buf);
22550 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22551 assemble_name (file, buf);
22552 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22554 else if (flag_pic == 1)
22556 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22557 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22558 reg_names[0], reg_names[1]);
22559 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22560 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22561 assemble_name (file, buf);
22562 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22564 else if (flag_pic > 1)
22566 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22567 reg_names[0], reg_names[1]);
22568 /* Now, we need to get the address of the label. */
22569 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22570 assemble_name (file, buf);
22571 fputs ("-.\n1:", file);
22572 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22573 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22574 reg_names[0], reg_names[11]);
22575 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22576 reg_names[0], reg_names[0], reg_names[11]);
22580 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22581 assemble_name (file, buf);
22582 fputs ("@ha\n", file);
22583 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22584 reg_names[0], reg_names[1]);
22585 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22586 assemble_name (file, buf);
22587 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22590 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22591 fprintf (file, "\tbl %s%s\n",
22592 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22597 if (!TARGET_PROFILE_KERNEL)
22599 /* Don't do anything, done in output_profile_hook (). */
22603 gcc_assert (!TARGET_32BIT);
22605 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22606 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22608 if (cfun->static_chain_decl != NULL)
22610 asm_fprintf (file, "\tstd %s,24(%s)\n",
22611 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22612 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22613 asm_fprintf (file, "\tld %s,24(%s)\n",
22614 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22617 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22625 /* The following variable value is the last issued insn. */
22627 static rtx last_scheduled_insn;
22629 /* The following variable helps to balance issuing of load and
22630 store instructions */
22632 static int load_store_pendulum;
22634 /* Power4 load update and store update instructions are cracked into a
22635 load or store and an integer insn which are executed in the same cycle.
22636 Branches have their own dispatch slot which does not count against the
22637 GCC issue rate, but it changes the program flow so there are no other
22638 instructions to issue in this cycle. */
22641 rs6000_variable_issue_1 (rtx insn, int more)
22643 last_scheduled_insn = insn;
22644 if (GET_CODE (PATTERN (insn)) == USE
22645 || GET_CODE (PATTERN (insn)) == CLOBBER)
22647 cached_can_issue_more = more;
22648 return cached_can_issue_more;
22651 if (insn_terminates_group_p (insn, current_group))
22653 cached_can_issue_more = 0;
22654 return cached_can_issue_more;
22657 /* If no reservation, but reach here */
22658 if (recog_memoized (insn) < 0)
22661 if (rs6000_sched_groups)
22663 if (is_microcoded_insn (insn))
22664 cached_can_issue_more = 0;
22665 else if (is_cracked_insn (insn))
22666 cached_can_issue_more = more > 2 ? more - 2 : 0;
22668 cached_can_issue_more = more - 1;
22670 return cached_can_issue_more;
22673 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22676 cached_can_issue_more = more - 1;
22677 return cached_can_issue_more;
22681 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22683 int r = rs6000_variable_issue_1 (insn, more);
22685 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22689 /* Adjust the cost of a scheduling dependency. Return the new cost of
22690 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22693 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22695 enum attr_type attr_type;
22697 if (! recog_memoized (insn))
22700 switch (REG_NOTE_KIND (link))
22704 /* Data dependency; DEP_INSN writes a register that INSN reads
22705 some cycles later. */
22707 /* Separate a load from a narrower, dependent store. */
22708 if (rs6000_sched_groups
22709 && GET_CODE (PATTERN (insn)) == SET
22710 && GET_CODE (PATTERN (dep_insn)) == SET
22711 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22712 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22713 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22714 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22717 attr_type = get_attr_type (insn);
22722 /* Tell the first scheduling pass about the latency between
22723 a mtctr and bctr (and mtlr and br/blr). The first
22724 scheduling pass will not know about this latency since
22725 the mtctr instruction, which has the latency associated
22726 to it, will be generated by reload. */
22727 return TARGET_POWER ? 5 : 4;
22729 /* Leave some extra cycles between a compare and its
22730 dependent branch, to inhibit expensive mispredicts. */
22731 if ((rs6000_cpu_attr == CPU_PPC603
22732 || rs6000_cpu_attr == CPU_PPC604
22733 || rs6000_cpu_attr == CPU_PPC604E
22734 || rs6000_cpu_attr == CPU_PPC620
22735 || rs6000_cpu_attr == CPU_PPC630
22736 || rs6000_cpu_attr == CPU_PPC750
22737 || rs6000_cpu_attr == CPU_PPC7400
22738 || rs6000_cpu_attr == CPU_PPC7450
22739 || rs6000_cpu_attr == CPU_POWER4
22740 || rs6000_cpu_attr == CPU_POWER5
22741 || rs6000_cpu_attr == CPU_POWER7
22742 || rs6000_cpu_attr == CPU_CELL)
22743 && recog_memoized (dep_insn)
22744 && (INSN_CODE (dep_insn) >= 0))
22746 switch (get_attr_type (dep_insn))
22750 case TYPE_DELAYED_COMPARE:
22751 case TYPE_IMUL_COMPARE:
22752 case TYPE_LMUL_COMPARE:
22753 case TYPE_FPCOMPARE:
22754 case TYPE_CR_LOGICAL:
22755 case TYPE_DELAYED_CR:
22764 case TYPE_STORE_UX:
22766 case TYPE_FPSTORE_U:
22767 case TYPE_FPSTORE_UX:
22768 if ((rs6000_cpu == PROCESSOR_POWER6)
22769 && recog_memoized (dep_insn)
22770 && (INSN_CODE (dep_insn) >= 0))
22773 if (GET_CODE (PATTERN (insn)) != SET)
22774 /* If this happens, we have to extend this to schedule
22775 optimally. Return default for now. */
22778 /* Adjust the cost for the case where the value written
22779 by a fixed point operation is used as the address
22780 gen value on a store. */
22781 switch (get_attr_type (dep_insn))
22788 if (! store_data_bypass_p (dep_insn, insn))
22792 case TYPE_LOAD_EXT:
22793 case TYPE_LOAD_EXT_U:
22794 case TYPE_LOAD_EXT_UX:
22795 case TYPE_VAR_SHIFT_ROTATE:
22796 case TYPE_VAR_DELAYED_COMPARE:
22798 if (! store_data_bypass_p (dep_insn, insn))
22804 case TYPE_FAST_COMPARE:
22807 case TYPE_INSERT_WORD:
22808 case TYPE_INSERT_DWORD:
22809 case TYPE_FPLOAD_U:
22810 case TYPE_FPLOAD_UX:
22812 case TYPE_STORE_UX:
22813 case TYPE_FPSTORE_U:
22814 case TYPE_FPSTORE_UX:
22816 if (! store_data_bypass_p (dep_insn, insn))
22824 case TYPE_IMUL_COMPARE:
22825 case TYPE_LMUL_COMPARE:
22827 if (! store_data_bypass_p (dep_insn, insn))
22833 if (! store_data_bypass_p (dep_insn, insn))
22839 if (! store_data_bypass_p (dep_insn, insn))
22852 case TYPE_LOAD_EXT:
22853 case TYPE_LOAD_EXT_U:
22854 case TYPE_LOAD_EXT_UX:
22855 if ((rs6000_cpu == PROCESSOR_POWER6)
22856 && recog_memoized (dep_insn)
22857 && (INSN_CODE (dep_insn) >= 0))
22860 /* Adjust the cost for the case where the value written
22861 by a fixed point instruction is used within the address
22862 gen portion of a subsequent load(u)(x) */
22863 switch (get_attr_type (dep_insn))
22870 if (set_to_load_agen (dep_insn, insn))
22874 case TYPE_LOAD_EXT:
22875 case TYPE_LOAD_EXT_U:
22876 case TYPE_LOAD_EXT_UX:
22877 case TYPE_VAR_SHIFT_ROTATE:
22878 case TYPE_VAR_DELAYED_COMPARE:
22880 if (set_to_load_agen (dep_insn, insn))
22886 case TYPE_FAST_COMPARE:
22889 case TYPE_INSERT_WORD:
22890 case TYPE_INSERT_DWORD:
22891 case TYPE_FPLOAD_U:
22892 case TYPE_FPLOAD_UX:
22894 case TYPE_STORE_UX:
22895 case TYPE_FPSTORE_U:
22896 case TYPE_FPSTORE_UX:
22898 if (set_to_load_agen (dep_insn, insn))
22906 case TYPE_IMUL_COMPARE:
22907 case TYPE_LMUL_COMPARE:
22909 if (set_to_load_agen (dep_insn, insn))
22915 if (set_to_load_agen (dep_insn, insn))
22921 if (set_to_load_agen (dep_insn, insn))
22932 if ((rs6000_cpu == PROCESSOR_POWER6)
22933 && recog_memoized (dep_insn)
22934 && (INSN_CODE (dep_insn) >= 0)
22935 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22942 /* Fall out to return default cost. */
22946 case REG_DEP_OUTPUT:
22947 /* Output dependency; DEP_INSN writes a register that INSN writes some
22949 if ((rs6000_cpu == PROCESSOR_POWER6)
22950 && recog_memoized (dep_insn)
22951 && (INSN_CODE (dep_insn) >= 0))
22953 attr_type = get_attr_type (insn);
22958 if (get_attr_type (dep_insn) == TYPE_FP)
22962 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22970 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22975 gcc_unreachable ();
22981 /* Debug version of rs6000_adjust_cost. */
22984 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22986 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22992 switch (REG_NOTE_KIND (link))
22994 default: dep = "unknown depencency"; break;
22995 case REG_DEP_TRUE: dep = "data dependency"; break;
22996 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22997 case REG_DEP_ANTI: dep = "anti depencency"; break;
23001 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23002 "%s, insn:\n", ret, cost, dep);
23010 /* The function returns a true if INSN is microcoded.
23011 Return false otherwise. */
23014 is_microcoded_insn (rtx insn)
23016 if (!insn || !NONDEBUG_INSN_P (insn)
23017 || GET_CODE (PATTERN (insn)) == USE
23018 || GET_CODE (PATTERN (insn)) == CLOBBER)
23021 if (rs6000_cpu_attr == CPU_CELL)
23022 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23024 if (rs6000_sched_groups)
23026 enum attr_type type = get_attr_type (insn);
23027 if (type == TYPE_LOAD_EXT_U
23028 || type == TYPE_LOAD_EXT_UX
23029 || type == TYPE_LOAD_UX
23030 || type == TYPE_STORE_UX
23031 || type == TYPE_MFCR)
23038 /* The function returns true if INSN is cracked into 2 instructions
23039 by the processor (and therefore occupies 2 issue slots). */
23042 is_cracked_insn (rtx insn)
23044 if (!insn || !NONDEBUG_INSN_P (insn)
23045 || GET_CODE (PATTERN (insn)) == USE
23046 || GET_CODE (PATTERN (insn)) == CLOBBER)
23049 if (rs6000_sched_groups)
23051 enum attr_type type = get_attr_type (insn);
23052 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23053 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23054 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23055 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23056 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23057 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23058 || type == TYPE_IDIV || type == TYPE_LDIV
23059 || type == TYPE_INSERT_WORD)
23066 /* The function returns true if INSN can be issued only from
23067 the branch slot. */
23070 is_branch_slot_insn (rtx insn)
23072 if (!insn || !NONDEBUG_INSN_P (insn)
23073 || GET_CODE (PATTERN (insn)) == USE
23074 || GET_CODE (PATTERN (insn)) == CLOBBER)
23077 if (rs6000_sched_groups)
23079 enum attr_type type = get_attr_type (insn);
23080 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23088 /* The function returns true if out_inst sets a value that is
23089 used in the address generation computation of in_insn */
23091 set_to_load_agen (rtx out_insn, rtx in_insn)
23093 rtx out_set, in_set;
23095 /* For performance reasons, only handle the simple case where
23096 both loads are a single_set. */
23097 out_set = single_set (out_insn);
23100 in_set = single_set (in_insn);
23102 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23108 /* The function returns true if the target storage location of
23109 out_insn is adjacent to the target storage location of in_insn */
23110 /* Return 1 if memory locations are adjacent. */
23113 adjacent_mem_locations (rtx insn1, rtx insn2)
23116 rtx a = get_store_dest (PATTERN (insn1));
23117 rtx b = get_store_dest (PATTERN (insn2));
23119 if ((GET_CODE (XEXP (a, 0)) == REG
23120 || (GET_CODE (XEXP (a, 0)) == PLUS
23121 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23122 && (GET_CODE (XEXP (b, 0)) == REG
23123 || (GET_CODE (XEXP (b, 0)) == PLUS
23124 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23126 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23129 if (GET_CODE (XEXP (a, 0)) == PLUS)
23131 reg0 = XEXP (XEXP (a, 0), 0);
23132 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23135 reg0 = XEXP (a, 0);
23137 if (GET_CODE (XEXP (b, 0)) == PLUS)
23139 reg1 = XEXP (XEXP (b, 0), 0);
23140 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23143 reg1 = XEXP (b, 0);
23145 val_diff = val1 - val0;
23147 return ((REGNO (reg0) == REGNO (reg1))
23148 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23149 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23155 /* A C statement (sans semicolon) to update the integer scheduling
23156 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23157 INSN earlier, reduce the priority to execute INSN later. Do not
23158 define this macro if you do not need to adjust the scheduling
23159 priorities of insns. */
23162 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23164 /* On machines (like the 750) which have asymmetric integer units,
23165 where one integer unit can do multiply and divides and the other
23166 can't, reduce the priority of multiply/divide so it is scheduled
23167 before other integer operations. */
23170 if (! INSN_P (insn))
23173 if (GET_CODE (PATTERN (insn)) == USE)
23176 switch (rs6000_cpu_attr) {
23178 switch (get_attr_type (insn))
23185 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23186 priority, priority);
23187 if (priority >= 0 && priority < 0x01000000)
23194 if (insn_must_be_first_in_group (insn)
23195 && reload_completed
23196 && current_sched_info->sched_max_insns_priority
23197 && rs6000_sched_restricted_insns_priority)
23200 /* Prioritize insns that can be dispatched only in the first
23202 if (rs6000_sched_restricted_insns_priority == 1)
23203 /* Attach highest priority to insn. This means that in
23204 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23205 precede 'priority' (critical path) considerations. */
23206 return current_sched_info->sched_max_insns_priority;
23207 else if (rs6000_sched_restricted_insns_priority == 2)
23208 /* Increase priority of insn by a minimal amount. This means that in
23209 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23210 considerations precede dispatch-slot restriction considerations. */
23211 return (priority + 1);
23214 if (rs6000_cpu == PROCESSOR_POWER6
23215 && ((load_store_pendulum == -2 && is_load_insn (insn))
23216 || (load_store_pendulum == 2 && is_store_insn (insn))))
23217 /* Attach highest priority to insn if the scheduler has just issued two
23218 stores and this instruction is a load, or two loads and this instruction
23219 is a store. Power6 wants loads and stores scheduled alternately
23221 return current_sched_info->sched_max_insns_priority;
23226 /* Return true if the instruction is nonpipelined on the Cell. */
23228 is_nonpipeline_insn (rtx insn)
23230 enum attr_type type;
23231 if (!insn || !NONDEBUG_INSN_P (insn)
23232 || GET_CODE (PATTERN (insn)) == USE
23233 || GET_CODE (PATTERN (insn)) == CLOBBER)
23236 type = get_attr_type (insn);
23237 if (type == TYPE_IMUL
23238 || type == TYPE_IMUL2
23239 || type == TYPE_IMUL3
23240 || type == TYPE_LMUL
23241 || type == TYPE_IDIV
23242 || type == TYPE_LDIV
23243 || type == TYPE_SDIV
23244 || type == TYPE_DDIV
23245 || type == TYPE_SSQRT
23246 || type == TYPE_DSQRT
23247 || type == TYPE_MFCR
23248 || type == TYPE_MFCRF
23249 || type == TYPE_MFJMPR)
23257 /* Return how many instructions the machine can issue per cycle. */
23260 rs6000_issue_rate (void)
23262 /* Unless scheduling for register pressure, use issue rate of 1 for
23263 first scheduling pass to decrease degradation. */
23264 if (!reload_completed && !flag_sched_pressure)
23267 switch (rs6000_cpu_attr) {
23268 case CPU_RIOS1: /* ? */
23270 case CPU_PPC601: /* ? */
23279 case CPU_PPCE300C2:
23280 case CPU_PPCE300C3:
23281 case CPU_PPCE500MC:
23282 case CPU_PPCE500MC64:
23302 /* Return how many instructions to look ahead for better insn
23306 rs6000_use_sched_lookahead (void)
23308 if (rs6000_cpu_attr == CPU_PPC8540)
23310 if (rs6000_cpu_attr == CPU_CELL)
23311 return (reload_completed ? 8 : 0);
23315 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23317 rs6000_use_sched_lookahead_guard (rtx insn)
23319 if (rs6000_cpu_attr != CPU_CELL)
23322 if (insn == NULL_RTX || !INSN_P (insn))
23325 if (!reload_completed
23326 || is_nonpipeline_insn (insn)
23327 || is_microcoded_insn (insn))
23333 /* Determine is PAT refers to memory. */
23336 is_mem_ref (rtx pat)
23342 /* stack_tie does not produce any real memory traffic. */
23343 if (GET_CODE (pat) == UNSPEC
23344 && XINT (pat, 1) == UNSPEC_TIE)
23347 if (GET_CODE (pat) == MEM)
23350 /* Recursively process the pattern. */
23351 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23353 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23356 ret |= is_mem_ref (XEXP (pat, i));
23357 else if (fmt[i] == 'E')
23358 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23359 ret |= is_mem_ref (XVECEXP (pat, i, j));
23365 /* Determine if PAT is a PATTERN of a load insn. */
23368 is_load_insn1 (rtx pat)
23370 if (!pat || pat == NULL_RTX)
23373 if (GET_CODE (pat) == SET)
23374 return is_mem_ref (SET_SRC (pat));
23376 if (GET_CODE (pat) == PARALLEL)
23380 for (i = 0; i < XVECLEN (pat, 0); i++)
23381 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23388 /* Determine if INSN loads from memory. */
23391 is_load_insn (rtx insn)
23393 if (!insn || !INSN_P (insn))
23396 if (GET_CODE (insn) == CALL_INSN)
23399 return is_load_insn1 (PATTERN (insn));
23402 /* Determine if PAT is a PATTERN of a store insn. */
23405 is_store_insn1 (rtx pat)
23407 if (!pat || pat == NULL_RTX)
23410 if (GET_CODE (pat) == SET)
23411 return is_mem_ref (SET_DEST (pat));
23413 if (GET_CODE (pat) == PARALLEL)
23417 for (i = 0; i < XVECLEN (pat, 0); i++)
23418 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23425 /* Determine if INSN stores to memory. */
23428 is_store_insn (rtx insn)
23430 if (!insn || !INSN_P (insn))
23433 return is_store_insn1 (PATTERN (insn));
23436 /* Return the dest of a store insn. */
23439 get_store_dest (rtx pat)
23441 gcc_assert (is_store_insn1 (pat));
23443 if (GET_CODE (pat) == SET)
23444 return SET_DEST (pat);
23445 else if (GET_CODE (pat) == PARALLEL)
23449 for (i = 0; i < XVECLEN (pat, 0); i++)
23451 rtx inner_pat = XVECEXP (pat, 0, i);
23452 if (GET_CODE (inner_pat) == SET
23453 && is_mem_ref (SET_DEST (inner_pat)))
23457 /* We shouldn't get here, because we should have either a simple
23458 store insn or a store with update which are covered above. */
23462 /* Returns whether the dependence between INSN and NEXT is considered
23463 costly by the given target. */
23466 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23471 /* If the flag is not enabled - no dependence is considered costly;
23472 allow all dependent insns in the same group.
23473 This is the most aggressive option. */
23474 if (rs6000_sched_costly_dep == no_dep_costly)
23477 /* If the flag is set to 1 - a dependence is always considered costly;
23478 do not allow dependent instructions in the same group.
23479 This is the most conservative option. */
23480 if (rs6000_sched_costly_dep == all_deps_costly)
23483 insn = DEP_PRO (dep);
23484 next = DEP_CON (dep);
23486 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23487 && is_load_insn (next)
23488 && is_store_insn (insn))
23489 /* Prevent load after store in the same group. */
23492 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23493 && is_load_insn (next)
23494 && is_store_insn (insn)
23495 && DEP_TYPE (dep) == REG_DEP_TRUE)
23496 /* Prevent load after store in the same group if it is a true
23500 /* The flag is set to X; dependences with latency >= X are considered costly,
23501 and will not be scheduled in the same group. */
23502 if (rs6000_sched_costly_dep <= max_dep_latency
23503 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23509 /* Return the next insn after INSN that is found before TAIL is reached,
23510 skipping any "non-active" insns - insns that will not actually occupy
23511 an issue slot. Return NULL_RTX if such an insn is not found. */
23514 get_next_active_insn (rtx insn, rtx tail)
23516 if (insn == NULL_RTX || insn == tail)
23521 insn = NEXT_INSN (insn);
23522 if (insn == NULL_RTX || insn == tail)
23527 || (NONJUMP_INSN_P (insn)
23528 && GET_CODE (PATTERN (insn)) != USE
23529 && GET_CODE (PATTERN (insn)) != CLOBBER
23530 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23536 /* We are about to begin issuing insns for this clock cycle. */
23539 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23540 rtx *ready ATTRIBUTE_UNUSED,
23541 int *pn_ready ATTRIBUTE_UNUSED,
23542 int clock_var ATTRIBUTE_UNUSED)
23544 int n_ready = *pn_ready;
23547 fprintf (dump, "// rs6000_sched_reorder :\n");
23549 /* Reorder the ready list, if the second to last ready insn
23550 is a nonepipeline insn. */
23551 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23553 if (is_nonpipeline_insn (ready[n_ready - 1])
23554 && (recog_memoized (ready[n_ready - 2]) > 0))
23555 /* Simply swap first two insns. */
23557 rtx tmp = ready[n_ready - 1];
23558 ready[n_ready - 1] = ready[n_ready - 2];
23559 ready[n_ready - 2] = tmp;
23563 if (rs6000_cpu == PROCESSOR_POWER6)
23564 load_store_pendulum = 0;
23566 return rs6000_issue_rate ();
23569 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23572 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23573 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23576 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23578 /* For Power6, we need to handle some special cases to try and keep the
23579 store queue from overflowing and triggering expensive flushes.
23581 This code monitors how load and store instructions are being issued
23582 and skews the ready list one way or the other to increase the likelihood
23583 that a desired instruction is issued at the proper time.
23585 A couple of things are done. First, we maintain a "load_store_pendulum"
23586 to track the current state of load/store issue.
23588 - If the pendulum is at zero, then no loads or stores have been
23589 issued in the current cycle so we do nothing.
23591 - If the pendulum is 1, then a single load has been issued in this
23592 cycle and we attempt to locate another load in the ready list to
23595 - If the pendulum is -2, then two stores have already been
23596 issued in this cycle, so we increase the priority of the first load
23597 in the ready list to increase it's likelihood of being chosen first
23600 - If the pendulum is -1, then a single store has been issued in this
23601 cycle and we attempt to locate another store in the ready list to
23602 issue with it, preferring a store to an adjacent memory location to
23603 facilitate store pairing in the store queue.
23605 - If the pendulum is 2, then two loads have already been
23606 issued in this cycle, so we increase the priority of the first store
23607 in the ready list to increase it's likelihood of being chosen first
23610 - If the pendulum < -2 or > 2, then do nothing.
23612 Note: This code covers the most common scenarios. There exist non
23613 load/store instructions which make use of the LSU and which
23614 would need to be accounted for to strictly model the behavior
23615 of the machine. Those instructions are currently unaccounted
23616 for to help minimize compile time overhead of this code.
23618 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23624 if (is_store_insn (last_scheduled_insn))
23625 /* Issuing a store, swing the load_store_pendulum to the left */
23626 load_store_pendulum--;
23627 else if (is_load_insn (last_scheduled_insn))
23628 /* Issuing a load, swing the load_store_pendulum to the right */
23629 load_store_pendulum++;
23631 return cached_can_issue_more;
23633 /* If the pendulum is balanced, or there is only one instruction on
23634 the ready list, then all is well, so return. */
23635 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23636 return cached_can_issue_more;
23638 if (load_store_pendulum == 1)
23640 /* A load has been issued in this cycle. Scan the ready list
23641 for another load to issue with it */
23646 if (is_load_insn (ready[pos]))
23648 /* Found a load. Move it to the head of the ready list,
23649 and adjust it's priority so that it is more likely to
23652 for (i=pos; i<*pn_ready-1; i++)
23653 ready[i] = ready[i + 1];
23654 ready[*pn_ready-1] = tmp;
23656 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23657 INSN_PRIORITY (tmp)++;
23663 else if (load_store_pendulum == -2)
23665 /* Two stores have been issued in this cycle. Increase the
23666 priority of the first load in the ready list to favor it for
23667 issuing in the next cycle. */
23672 if (is_load_insn (ready[pos])
23674 && INSN_PRIORITY_KNOWN (ready[pos]))
23676 INSN_PRIORITY (ready[pos])++;
23678 /* Adjust the pendulum to account for the fact that a load
23679 was found and increased in priority. This is to prevent
23680 increasing the priority of multiple loads */
23681 load_store_pendulum--;
23688 else if (load_store_pendulum == -1)
23690 /* A store has been issued in this cycle. Scan the ready list for
23691 another store to issue with it, preferring a store to an adjacent
23693 int first_store_pos = -1;
23699 if (is_store_insn (ready[pos]))
23701 /* Maintain the index of the first store found on the
23703 if (first_store_pos == -1)
23704 first_store_pos = pos;
23706 if (is_store_insn (last_scheduled_insn)
23707 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23709 /* Found an adjacent store. Move it to the head of the
23710 ready list, and adjust it's priority so that it is
23711 more likely to stay there */
23713 for (i=pos; i<*pn_ready-1; i++)
23714 ready[i] = ready[i + 1];
23715 ready[*pn_ready-1] = tmp;
23717 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23718 INSN_PRIORITY (tmp)++;
23720 first_store_pos = -1;
23728 if (first_store_pos >= 0)
23730 /* An adjacent store wasn't found, but a non-adjacent store was,
23731 so move the non-adjacent store to the front of the ready
23732 list, and adjust its priority so that it is more likely to
23734 tmp = ready[first_store_pos];
23735 for (i=first_store_pos; i<*pn_ready-1; i++)
23736 ready[i] = ready[i + 1];
23737 ready[*pn_ready-1] = tmp;
23738 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23739 INSN_PRIORITY (tmp)++;
23742 else if (load_store_pendulum == 2)
23744 /* Two loads have been issued in this cycle. Increase the priority
23745 of the first store in the ready list to favor it for issuing in
23751 if (is_store_insn (ready[pos])
23753 && INSN_PRIORITY_KNOWN (ready[pos]))
23755 INSN_PRIORITY (ready[pos])++;
23757 /* Adjust the pendulum to account for the fact that a store
23758 was found and increased in priority. This is to prevent
23759 increasing the priority of multiple stores */
23760 load_store_pendulum++;
23769 return cached_can_issue_more;
23772 /* Return whether the presence of INSN causes a dispatch group termination
23773 of group WHICH_GROUP.
23775 If WHICH_GROUP == current_group, this function will return true if INSN
23776 causes the termination of the current group (i.e, the dispatch group to
23777 which INSN belongs). This means that INSN will be the last insn in the
23778 group it belongs to.
23780 If WHICH_GROUP == previous_group, this function will return true if INSN
23781 causes the termination of the previous group (i.e, the dispatch group that
23782 precedes the group to which INSN belongs). This means that INSN will be
23783 the first insn in the group it belongs to). */
23786 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23793 first = insn_must_be_first_in_group (insn);
23794 last = insn_must_be_last_in_group (insn);
23799 if (which_group == current_group)
23801 else if (which_group == previous_group)
23809 insn_must_be_first_in_group (rtx insn)
23811 enum attr_type type;
23814 || GET_CODE (insn) == NOTE
23815 || DEBUG_INSN_P (insn)
23816 || GET_CODE (PATTERN (insn)) == USE
23817 || GET_CODE (PATTERN (insn)) == CLOBBER)
23820 switch (rs6000_cpu)
23822 case PROCESSOR_POWER5:
23823 if (is_cracked_insn (insn))
23825 case PROCESSOR_POWER4:
23826 if (is_microcoded_insn (insn))
23829 if (!rs6000_sched_groups)
23832 type = get_attr_type (insn);
23839 case TYPE_DELAYED_CR:
23840 case TYPE_CR_LOGICAL:
23854 case PROCESSOR_POWER6:
23855 type = get_attr_type (insn);
23859 case TYPE_INSERT_DWORD:
23863 case TYPE_VAR_SHIFT_ROTATE:
23870 case TYPE_INSERT_WORD:
23871 case TYPE_DELAYED_COMPARE:
23872 case TYPE_IMUL_COMPARE:
23873 case TYPE_LMUL_COMPARE:
23874 case TYPE_FPCOMPARE:
23885 case TYPE_LOAD_EXT_UX:
23887 case TYPE_STORE_UX:
23888 case TYPE_FPLOAD_U:
23889 case TYPE_FPLOAD_UX:
23890 case TYPE_FPSTORE_U:
23891 case TYPE_FPSTORE_UX:
23897 case PROCESSOR_POWER7:
23898 type = get_attr_type (insn);
23902 case TYPE_CR_LOGICAL:
23909 case TYPE_DELAYED_COMPARE:
23910 case TYPE_VAR_DELAYED_COMPARE:
23916 case TYPE_LOAD_EXT:
23917 case TYPE_LOAD_EXT_U:
23918 case TYPE_LOAD_EXT_UX:
23920 case TYPE_STORE_UX:
23921 case TYPE_FPLOAD_U:
23922 case TYPE_FPLOAD_UX:
23923 case TYPE_FPSTORE_U:
23924 case TYPE_FPSTORE_UX:
23940 insn_must_be_last_in_group (rtx insn)
23942 enum attr_type type;
23945 || GET_CODE (insn) == NOTE
23946 || DEBUG_INSN_P (insn)
23947 || GET_CODE (PATTERN (insn)) == USE
23948 || GET_CODE (PATTERN (insn)) == CLOBBER)
23951 switch (rs6000_cpu) {
23952 case PROCESSOR_POWER4:
23953 case PROCESSOR_POWER5:
23954 if (is_microcoded_insn (insn))
23957 if (is_branch_slot_insn (insn))
23961 case PROCESSOR_POWER6:
23962 type = get_attr_type (insn);
23969 case TYPE_VAR_SHIFT_ROTATE:
23976 case TYPE_DELAYED_COMPARE:
23977 case TYPE_IMUL_COMPARE:
23978 case TYPE_LMUL_COMPARE:
23979 case TYPE_FPCOMPARE:
23993 case PROCESSOR_POWER7:
23994 type = get_attr_type (insn);
24002 case TYPE_LOAD_EXT_U:
24003 case TYPE_LOAD_EXT_UX:
24004 case TYPE_STORE_UX:
24017 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24018 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24021 is_costly_group (rtx *group_insns, rtx next_insn)
24024 int issue_rate = rs6000_issue_rate ();
24026 for (i = 0; i < issue_rate; i++)
24028 sd_iterator_def sd_it;
24030 rtx insn = group_insns[i];
24035 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24037 rtx next = DEP_CON (dep);
24039 if (next == next_insn
24040 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24048 /* Utility of the function redefine_groups.
24049 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24050 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24051 to keep it "far" (in a separate group) from GROUP_INSNS, following
24052 one of the following schemes, depending on the value of the flag
24053 -minsert_sched_nops = X:
24054 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24055 in order to force NEXT_INSN into a separate group.
24056 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24057 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24058 insertion (has a group just ended, how many vacant issue slots remain in the
24059 last group, and how many dispatch groups were encountered so far). */
24062 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24063 rtx next_insn, bool *group_end, int can_issue_more,
24068 int issue_rate = rs6000_issue_rate ();
24069 bool end = *group_end;
24072 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24073 return can_issue_more;
24075 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24076 return can_issue_more;
24078 force = is_costly_group (group_insns, next_insn);
24080 return can_issue_more;
24082 if (sched_verbose > 6)
24083 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24084 *group_count ,can_issue_more);
24086 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24089 can_issue_more = 0;
24091 /* Since only a branch can be issued in the last issue_slot, it is
24092 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24093 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24094 in this case the last nop will start a new group and the branch
24095 will be forced to the new group. */
24096 if (can_issue_more && !is_branch_slot_insn (next_insn))
24099 while (can_issue_more > 0)
24102 emit_insn_before (nop, next_insn);
24110 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24112 int n_nops = rs6000_sched_insert_nops;
24114 /* Nops can't be issued from the branch slot, so the effective
24115 issue_rate for nops is 'issue_rate - 1'. */
24116 if (can_issue_more == 0)
24117 can_issue_more = issue_rate;
24119 if (can_issue_more == 0)
24121 can_issue_more = issue_rate - 1;
24124 for (i = 0; i < issue_rate; i++)
24126 group_insns[i] = 0;
24133 emit_insn_before (nop, next_insn);
24134 if (can_issue_more == issue_rate - 1) /* new group begins */
24137 if (can_issue_more == 0)
24139 can_issue_more = issue_rate - 1;
24142 for (i = 0; i < issue_rate; i++)
24144 group_insns[i] = 0;
24150 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24153 /* Is next_insn going to start a new group? */
24156 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24157 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24158 || (can_issue_more < issue_rate &&
24159 insn_terminates_group_p (next_insn, previous_group)));
24160 if (*group_end && end)
24163 if (sched_verbose > 6)
24164 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24165 *group_count, can_issue_more);
24166 return can_issue_more;
24169 return can_issue_more;
24172 /* This function tries to synch the dispatch groups that the compiler "sees"
24173 with the dispatch groups that the processor dispatcher is expected to
24174 form in practice. It tries to achieve this synchronization by forcing the
24175 estimated processor grouping on the compiler (as opposed to the function
24176 'pad_goups' which tries to force the scheduler's grouping on the processor).
24178 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24179 examines the (estimated) dispatch groups that will be formed by the processor
24180 dispatcher. It marks these group boundaries to reflect the estimated
24181 processor grouping, overriding the grouping that the scheduler had marked.
24182 Depending on the value of the flag '-minsert-sched-nops' this function can
24183 force certain insns into separate groups or force a certain distance between
24184 them by inserting nops, for example, if there exists a "costly dependence"
24187 The function estimates the group boundaries that the processor will form as
24188 follows: It keeps track of how many vacant issue slots are available after
24189 each insn. A subsequent insn will start a new group if one of the following
24191 - no more vacant issue slots remain in the current dispatch group.
24192 - only the last issue slot, which is the branch slot, is vacant, but the next
24193 insn is not a branch.
24194 - only the last 2 or less issue slots, including the branch slot, are vacant,
24195 which means that a cracked insn (which occupies two issue slots) can't be
24196 issued in this group.
24197 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24198 start a new group. */
24201 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24203 rtx insn, next_insn;
24205 int can_issue_more;
24208 int group_count = 0;
24212 issue_rate = rs6000_issue_rate ();
24213 group_insns = XALLOCAVEC (rtx, issue_rate);
24214 for (i = 0; i < issue_rate; i++)
24216 group_insns[i] = 0;
24218 can_issue_more = issue_rate;
24220 insn = get_next_active_insn (prev_head_insn, tail);
24223 while (insn != NULL_RTX)
24225 slot = (issue_rate - can_issue_more);
24226 group_insns[slot] = insn;
24228 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24229 if (insn_terminates_group_p (insn, current_group))
24230 can_issue_more = 0;
24232 next_insn = get_next_active_insn (insn, tail);
24233 if (next_insn == NULL_RTX)
24234 return group_count + 1;
24236 /* Is next_insn going to start a new group? */
24238 = (can_issue_more == 0
24239 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24240 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24241 || (can_issue_more < issue_rate &&
24242 insn_terminates_group_p (next_insn, previous_group)));
24244 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24245 next_insn, &group_end, can_issue_more,
24251 can_issue_more = 0;
24252 for (i = 0; i < issue_rate; i++)
24254 group_insns[i] = 0;
24258 if (GET_MODE (next_insn) == TImode && can_issue_more)
24259 PUT_MODE (next_insn, VOIDmode);
24260 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24261 PUT_MODE (next_insn, TImode);
24264 if (can_issue_more == 0)
24265 can_issue_more = issue_rate;
24268 return group_count;
24271 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24272 dispatch group boundaries that the scheduler had marked. Pad with nops
24273 any dispatch groups which have vacant issue slots, in order to force the
24274 scheduler's grouping on the processor dispatcher. The function
24275 returns the number of dispatch groups found. */
24278 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24280 rtx insn, next_insn;
24283 int can_issue_more;
24285 int group_count = 0;
24287 /* Initialize issue_rate. */
24288 issue_rate = rs6000_issue_rate ();
24289 can_issue_more = issue_rate;
24291 insn = get_next_active_insn (prev_head_insn, tail);
24292 next_insn = get_next_active_insn (insn, tail);
24294 while (insn != NULL_RTX)
24297 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24299 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24301 if (next_insn == NULL_RTX)
24306 /* If the scheduler had marked group termination at this location
24307 (between insn and next_insn), and neither insn nor next_insn will
24308 force group termination, pad the group with nops to force group
24311 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24312 && !insn_terminates_group_p (insn, current_group)
24313 && !insn_terminates_group_p (next_insn, previous_group))
24315 if (!is_branch_slot_insn (next_insn))
24318 while (can_issue_more)
24321 emit_insn_before (nop, next_insn);
24326 can_issue_more = issue_rate;
24331 next_insn = get_next_active_insn (insn, tail);
24334 return group_count;
24337 /* We're beginning a new block. Initialize data structures as necessary. */
24340 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24341 int sched_verbose ATTRIBUTE_UNUSED,
24342 int max_ready ATTRIBUTE_UNUSED)
24344 last_scheduled_insn = NULL_RTX;
24345 load_store_pendulum = 0;
24348 /* The following function is called at the end of scheduling BB.
24349 After reload, it inserts nops at insn group bundling. */
24352 rs6000_sched_finish (FILE *dump, int sched_verbose)
24357 fprintf (dump, "=== Finishing schedule.\n");
24359 if (reload_completed && rs6000_sched_groups)
24361 /* Do not run sched_finish hook when selective scheduling enabled. */
24362 if (sel_sched_p ())
24365 if (rs6000_sched_insert_nops == sched_finish_none)
24368 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24369 n_groups = pad_groups (dump, sched_verbose,
24370 current_sched_info->prev_head,
24371 current_sched_info->next_tail);
24373 n_groups = redefine_groups (dump, sched_verbose,
24374 current_sched_info->prev_head,
24375 current_sched_info->next_tail);
24377 if (sched_verbose >= 6)
24379 fprintf (dump, "ngroups = %d\n", n_groups);
24380 print_rtl (dump, current_sched_info->prev_head);
24381 fprintf (dump, "Done finish_sched\n");
24386 struct _rs6000_sched_context
24388 short cached_can_issue_more;
24389 rtx last_scheduled_insn;
24390 int load_store_pendulum;
24393 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24394 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24396 /* Allocate store for new scheduling context. */
24398 rs6000_alloc_sched_context (void)
24400 return xmalloc (sizeof (rs6000_sched_context_def));
24403 /* If CLEAN_P is true then initializes _SC with clean data,
24404 and from the global context otherwise. */
24406 rs6000_init_sched_context (void *_sc, bool clean_p)
24408 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24412 sc->cached_can_issue_more = 0;
24413 sc->last_scheduled_insn = NULL_RTX;
24414 sc->load_store_pendulum = 0;
24418 sc->cached_can_issue_more = cached_can_issue_more;
24419 sc->last_scheduled_insn = last_scheduled_insn;
24420 sc->load_store_pendulum = load_store_pendulum;
24424 /* Sets the global scheduling context to the one pointed to by _SC. */
24426 rs6000_set_sched_context (void *_sc)
24428 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24430 gcc_assert (sc != NULL);
24432 cached_can_issue_more = sc->cached_can_issue_more;
24433 last_scheduled_insn = sc->last_scheduled_insn;
24434 load_store_pendulum = sc->load_store_pendulum;
24439 rs6000_free_sched_context (void *_sc)
24441 gcc_assert (_sc != NULL);
24447 /* Length in units of the trampoline for entering a nested function. */
24450 rs6000_trampoline_size (void)
24454 switch (DEFAULT_ABI)
24457 gcc_unreachable ();
24460 ret = (TARGET_32BIT) ? 12 : 24;
24465 ret = (TARGET_32BIT) ? 40 : 48;
24472 /* Emit RTL insns to initialize the variable parts of a trampoline.
24473 FNADDR is an RTX for the address of the function's pure code.
24474 CXT is an RTX for the static chain value for the function. */
24477 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24479 int regsize = (TARGET_32BIT) ? 4 : 8;
24480 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24481 rtx ctx_reg = force_reg (Pmode, cxt);
24482 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24484 switch (DEFAULT_ABI)
24487 gcc_unreachable ();
24489 /* Under AIX, just build the 3 word function descriptor */
24492 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24493 rtx fn_reg = gen_reg_rtx (Pmode);
24494 rtx toc_reg = gen_reg_rtx (Pmode);
24496 /* Macro to shorten the code expansions below. */
24497 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24499 m_tramp = replace_equiv_address (m_tramp, addr);
24501 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24502 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24503 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24504 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24505 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24511 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24514 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24515 LCT_NORMAL, VOIDmode, 4,
24517 GEN_INT (rs6000_trampoline_size ()), SImode,
24525 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24526 identifier as an argument, so the front end shouldn't look it up. */
24529 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24531 return is_attribute_p ("altivec", attr_id);
24534 /* Handle the "altivec" attribute. The attribute may have
24535 arguments as follows:
24537 __attribute__((altivec(vector__)))
24538 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24539 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24541 and may appear more than once (e.g., 'vector bool char') in a
24542 given declaration. */
24545 rs6000_handle_altivec_attribute (tree *node,
24546 tree name ATTRIBUTE_UNUSED,
24548 int flags ATTRIBUTE_UNUSED,
24549 bool *no_add_attrs)
24551 tree type = *node, result = NULL_TREE;
24552 enum machine_mode mode;
24555 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24556 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24557 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24560 while (POINTER_TYPE_P (type)
24561 || TREE_CODE (type) == FUNCTION_TYPE
24562 || TREE_CODE (type) == METHOD_TYPE
24563 || TREE_CODE (type) == ARRAY_TYPE)
24564 type = TREE_TYPE (type);
24566 mode = TYPE_MODE (type);
24568 /* Check for invalid AltiVec type qualifiers. */
24569 if (type == long_double_type_node)
24570 error ("use of %<long double%> in AltiVec types is invalid");
24571 else if (type == boolean_type_node)
24572 error ("use of boolean types in AltiVec types is invalid");
24573 else if (TREE_CODE (type) == COMPLEX_TYPE)
24574 error ("use of %<complex%> in AltiVec types is invalid");
24575 else if (DECIMAL_FLOAT_MODE_P (mode))
24576 error ("use of decimal floating point types in AltiVec types is invalid");
24577 else if (!TARGET_VSX)
24579 if (type == long_unsigned_type_node || type == long_integer_type_node)
24582 error ("use of %<long%> in AltiVec types is invalid for "
24583 "64-bit code without -mvsx");
24584 else if (rs6000_warn_altivec_long)
24585 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24588 else if (type == long_long_unsigned_type_node
24589 || type == long_long_integer_type_node)
24590 error ("use of %<long long%> in AltiVec types is invalid without "
24592 else if (type == double_type_node)
24593 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24596 switch (altivec_type)
24599 unsigned_p = TYPE_UNSIGNED (type);
24603 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24606 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24609 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24612 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24614 case SFmode: result = V4SF_type_node; break;
24615 case DFmode: result = V2DF_type_node; break;
24616 /* If the user says 'vector int bool', we may be handed the 'bool'
24617 attribute _before_ the 'vector' attribute, and so select the
24618 proper type in the 'b' case below. */
24619 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24620 case V2DImode: case V2DFmode:
24628 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24629 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24630 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24631 case QImode: case V16QImode: result = bool_V16QI_type_node;
24638 case V8HImode: result = pixel_V8HI_type_node;
24644 /* Propagate qualifiers attached to the element type
24645 onto the vector type. */
24646 if (result && result != type && TYPE_QUALS (type))
24647 result = build_qualified_type (result, TYPE_QUALS (type));
24649 *no_add_attrs = true; /* No need to hang on to the attribute. */
24652 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24657 /* AltiVec defines four built-in scalar types that serve as vector
24658 elements; we must teach the compiler how to mangle them. */
24660 static const char *
24661 rs6000_mangle_type (const_tree type)
24663 type = TYPE_MAIN_VARIANT (type);
24665 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24666 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24669 if (type == bool_char_type_node) return "U6__boolc";
24670 if (type == bool_short_type_node) return "U6__bools";
24671 if (type == pixel_type_node) return "u7__pixel";
24672 if (type == bool_int_type_node) return "U6__booli";
24673 if (type == bool_long_type_node) return "U6__booll";
24675 /* Mangle IBM extended float long double as `g' (__float128) on
24676 powerpc*-linux where long-double-64 previously was the default. */
24677 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24679 && TARGET_LONG_DOUBLE_128
24680 && !TARGET_IEEEQUAD)
24683 /* For all other types, use normal C++ mangling. */
24687 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24688 struct attribute_spec.handler. */
24691 rs6000_handle_longcall_attribute (tree *node, tree name,
24692 tree args ATTRIBUTE_UNUSED,
24693 int flags ATTRIBUTE_UNUSED,
24694 bool *no_add_attrs)
24696 if (TREE_CODE (*node) != FUNCTION_TYPE
24697 && TREE_CODE (*node) != FIELD_DECL
24698 && TREE_CODE (*node) != TYPE_DECL)
24700 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24702 *no_add_attrs = true;
24708 /* Set longcall attributes on all functions declared when
24709 rs6000_default_long_calls is true. */
24711 rs6000_set_default_type_attributes (tree type)
24713 if (rs6000_default_long_calls
24714 && (TREE_CODE (type) == FUNCTION_TYPE
24715 || TREE_CODE (type) == METHOD_TYPE))
24716 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24718 TYPE_ATTRIBUTES (type));
24721 darwin_set_default_type_attributes (type);
24725 /* Return a reference suitable for calling a function with the
24726 longcall attribute. */
24729 rs6000_longcall_ref (rtx call_ref)
24731 const char *call_name;
24734 if (GET_CODE (call_ref) != SYMBOL_REF)
24737 /* System V adds '.' to the internal name, so skip them. */
24738 call_name = XSTR (call_ref, 0);
24739 if (*call_name == '.')
24741 while (*call_name == '.')
24744 node = get_identifier (call_name);
24745 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24748 return force_reg (Pmode, call_ref);
24751 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24752 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24755 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24756 struct attribute_spec.handler. */
24758 rs6000_handle_struct_attribute (tree *node, tree name,
24759 tree args ATTRIBUTE_UNUSED,
24760 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24763 if (DECL_P (*node))
24765 if (TREE_CODE (*node) == TYPE_DECL)
24766 type = &TREE_TYPE (*node);
24771 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24772 || TREE_CODE (*type) == UNION_TYPE)))
24774 warning (OPT_Wattributes, "%qE attribute ignored", name);
24775 *no_add_attrs = true;
24778 else if ((is_attribute_p ("ms_struct", name)
24779 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24780 || ((is_attribute_p ("gcc_struct", name)
24781 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24783 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24785 *no_add_attrs = true;
24792 rs6000_ms_bitfield_layout_p (const_tree record_type)
24794 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24795 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24796 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24799 #ifdef USING_ELFOS_H
24801 /* A get_unnamed_section callback, used for switching to toc_section. */
24804 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24806 if (DEFAULT_ABI == ABI_AIX
24807 && TARGET_MINIMAL_TOC
24808 && !TARGET_RELOCATABLE)
24810 if (!toc_initialized)
24812 toc_initialized = 1;
24813 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24814 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24815 fprintf (asm_out_file, "\t.tc ");
24816 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24817 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24818 fprintf (asm_out_file, "\n");
24820 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24821 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24822 fprintf (asm_out_file, " = .+32768\n");
24825 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24827 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24828 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24831 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24832 if (!toc_initialized)
24834 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24835 fprintf (asm_out_file, " = .+32768\n");
24836 toc_initialized = 1;
24841 /* Implement TARGET_ASM_INIT_SECTIONS. */
24844 rs6000_elf_asm_init_sections (void)
24847 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24850 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24851 SDATA2_SECTION_ASM_OP);
24854 /* Implement TARGET_SELECT_RTX_SECTION. */
24857 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24858 unsigned HOST_WIDE_INT align)
24860 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24861 return toc_section;
24863 return default_elf_select_rtx_section (mode, x, align);
24866 /* For a SYMBOL_REF, set generic flags and then perform some
24867 target-specific processing.
24869 When the AIX ABI is requested on a non-AIX system, replace the
24870 function name with the real name (with a leading .) rather than the
24871 function descriptor name. This saves a lot of overriding code to
24872 read the prefixes. */
24875 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24877 default_encode_section_info (decl, rtl, first);
24880 && TREE_CODE (decl) == FUNCTION_DECL
24882 && DEFAULT_ABI == ABI_AIX)
24884 rtx sym_ref = XEXP (rtl, 0);
24885 size_t len = strlen (XSTR (sym_ref, 0));
24886 char *str = XALLOCAVEC (char, len + 2);
24888 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24889 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24894 compare_section_name (const char *section, const char *templ)
24898 len = strlen (templ);
24899 return (strncmp (section, templ, len) == 0
24900 && (section[len] == 0 || section[len] == '.'));
24904 rs6000_elf_in_small_data_p (const_tree decl)
24906 if (rs6000_sdata == SDATA_NONE)
24909 /* We want to merge strings, so we never consider them small data. */
24910 if (TREE_CODE (decl) == STRING_CST)
24913 /* Functions are never in the small data area. */
24914 if (TREE_CODE (decl) == FUNCTION_DECL)
24917 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24919 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24920 if (compare_section_name (section, ".sdata")
24921 || compare_section_name (section, ".sdata2")
24922 || compare_section_name (section, ".gnu.linkonce.s")
24923 || compare_section_name (section, ".sbss")
24924 || compare_section_name (section, ".sbss2")
24925 || compare_section_name (section, ".gnu.linkonce.sb")
24926 || strcmp (section, ".PPC.EMB.sdata0") == 0
24927 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24932 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24935 && size <= g_switch_value
24936 /* If it's not public, and we're not going to reference it there,
24937 there's no need to put it in the small data section. */
24938 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24945 #endif /* USING_ELFOS_H */
24947 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24950 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24952 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24955 /* Return a REG that occurs in ADDR with coefficient 1.
24956 ADDR can be effectively incremented by incrementing REG.
24958 r0 is special and we must not select it as an address
24959 register by this routine since our caller will try to
24960 increment the returned register via an "la" instruction. */
24963 find_addr_reg (rtx addr)
24965 while (GET_CODE (addr) == PLUS)
24967 if (GET_CODE (XEXP (addr, 0)) == REG
24968 && REGNO (XEXP (addr, 0)) != 0)
24969 addr = XEXP (addr, 0);
24970 else if (GET_CODE (XEXP (addr, 1)) == REG
24971 && REGNO (XEXP (addr, 1)) != 0)
24972 addr = XEXP (addr, 1);
24973 else if (CONSTANT_P (XEXP (addr, 0)))
24974 addr = XEXP (addr, 1);
24975 else if (CONSTANT_P (XEXP (addr, 1)))
24976 addr = XEXP (addr, 0);
24978 gcc_unreachable ();
24980 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24985 rs6000_fatal_bad_address (rtx op)
24987 fatal_insn ("bad address", op);
24992 typedef struct branch_island_d {
24993 tree function_name;
24998 DEF_VEC_O(branch_island);
24999 DEF_VEC_ALLOC_O(branch_island,gc);
25001 static VEC(branch_island,gc) *branch_islands;
25003 /* Remember to generate a branch island for far calls to the given
25007 add_compiler_branch_island (tree label_name, tree function_name,
25010 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25012 bi->function_name = function_name;
25013 bi->label_name = label_name;
25014 bi->line_number = line_number;
25017 /* Generate far-jump branch islands for everything recorded in
25018 branch_islands. Invoked immediately after the last instruction of
25019 the epilogue has been emitted; the branch islands must be appended
25020 to, and contiguous with, the function body. Mach-O stubs are
25021 generated in machopic_output_stub(). */
25024 macho_branch_islands (void)
25028 while (!VEC_empty (branch_island, branch_islands))
25030 branch_island *bi = VEC_last (branch_island, branch_islands);
25031 const char *label = IDENTIFIER_POINTER (bi->label_name);
25032 const char *name = IDENTIFIER_POINTER (bi->function_name);
25033 char name_buf[512];
25034 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25035 if (name[0] == '*' || name[0] == '&')
25036 strcpy (name_buf, name+1);
25040 strcpy (name_buf+1, name);
25042 strcpy (tmp_buf, "\n");
25043 strcat (tmp_buf, label);
25044 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25045 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25046 dbxout_stabd (N_SLINE, bi->line_number);
25047 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25050 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25051 strcat (tmp_buf, label);
25052 strcat (tmp_buf, "_pic\n");
25053 strcat (tmp_buf, label);
25054 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25056 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25057 strcat (tmp_buf, name_buf);
25058 strcat (tmp_buf, " - ");
25059 strcat (tmp_buf, label);
25060 strcat (tmp_buf, "_pic)\n");
25062 strcat (tmp_buf, "\tmtlr r0\n");
25064 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25065 strcat (tmp_buf, name_buf);
25066 strcat (tmp_buf, " - ");
25067 strcat (tmp_buf, label);
25068 strcat (tmp_buf, "_pic)\n");
25070 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25074 strcat (tmp_buf, ":\nlis r12,hi16(");
25075 strcat (tmp_buf, name_buf);
25076 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25077 strcat (tmp_buf, name_buf);
25078 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25080 output_asm_insn (tmp_buf, 0);
25081 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25082 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25083 dbxout_stabd (N_SLINE, bi->line_number);
25084 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25085 VEC_pop (branch_island, branch_islands);
25089 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25090 already there or not. */
25093 no_previous_def (tree function_name)
25098 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25099 if (function_name == bi->function_name)
25104 /* GET_PREV_LABEL gets the label name from the previous definition of
25108 get_prev_label (tree function_name)
25113 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25114 if (function_name == bi->function_name)
25115 return bi->label_name;
25119 /* INSN is either a function call or a millicode call. It may have an
25120 unconditional jump in its delay slot.
25122 CALL_DEST is the routine we are calling. */
25125 output_call (rtx insn, rtx *operands, int dest_operand_number,
25126 int cookie_operand_number)
25128 static char buf[256];
25129 if (darwin_emit_branch_islands
25130 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25131 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25134 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25136 if (no_previous_def (funname))
25138 rtx label_rtx = gen_label_rtx ();
25139 char *label_buf, temp_buf[256];
25140 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25141 CODE_LABEL_NUMBER (label_rtx));
25142 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25143 labelname = get_identifier (label_buf);
25144 add_compiler_branch_island (labelname, funname, insn_line (insn));
25147 labelname = get_prev_label (funname);
25149 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25150 instruction will reach 'foo', otherwise link as 'bl L42'".
25151 "L42" should be a 'branch island', that will do a far jump to
25152 'foo'. Branch islands are generated in
25153 macho_branch_islands(). */
25154 sprintf (buf, "jbsr %%z%d,%.246s",
25155 dest_operand_number, IDENTIFIER_POINTER (labelname));
25158 sprintf (buf, "bl %%z%d", dest_operand_number);
25162 /* Generate PIC and indirect symbol stubs. */
25165 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25167 unsigned int length;
25168 char *symbol_name, *lazy_ptr_name;
25169 char *local_label_0;
25170 static int label = 0;
25172 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25173 symb = (*targetm.strip_name_encoding) (symb);
25176 length = strlen (symb);
25177 symbol_name = XALLOCAVEC (char, length + 32);
25178 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25180 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25181 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25184 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25186 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25190 fprintf (file, "\t.align 5\n");
25192 fprintf (file, "%s:\n", stub);
25193 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25196 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25197 sprintf (local_label_0, "\"L%011d$spb\"", label);
25199 fprintf (file, "\tmflr r0\n");
25200 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25201 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25202 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25203 lazy_ptr_name, local_label_0);
25204 fprintf (file, "\tmtlr r0\n");
25205 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25206 (TARGET_64BIT ? "ldu" : "lwzu"),
25207 lazy_ptr_name, local_label_0);
25208 fprintf (file, "\tmtctr r12\n");
25209 fprintf (file, "\tbctr\n");
25213 fprintf (file, "\t.align 4\n");
25215 fprintf (file, "%s:\n", stub);
25216 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25218 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25219 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25220 (TARGET_64BIT ? "ldu" : "lwzu"),
25222 fprintf (file, "\tmtctr r12\n");
25223 fprintf (file, "\tbctr\n");
25226 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25227 fprintf (file, "%s:\n", lazy_ptr_name);
25228 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25229 fprintf (file, "%sdyld_stub_binding_helper\n",
25230 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25233 /* Legitimize PIC addresses. If the address is already
25234 position-independent, we return ORIG. Newly generated
25235 position-independent addresses go into a reg. This is REG if non
25236 zero, otherwise we allocate register(s) as necessary. */
25238 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25241 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25246 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25247 reg = gen_reg_rtx (Pmode);
25249 if (GET_CODE (orig) == CONST)
25253 if (GET_CODE (XEXP (orig, 0)) == PLUS
25254 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25257 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25259 /* Use a different reg for the intermediate value, as
25260 it will be marked UNCHANGING. */
25261 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25262 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25265 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25268 if (GET_CODE (offset) == CONST_INT)
25270 if (SMALL_INT (offset))
25271 return plus_constant (base, INTVAL (offset));
25272 else if (! reload_in_progress && ! reload_completed)
25273 offset = force_reg (Pmode, offset);
25276 rtx mem = force_const_mem (Pmode, orig);
25277 return machopic_legitimize_pic_address (mem, Pmode, reg);
25280 return gen_rtx_PLUS (Pmode, base, offset);
25283 /* Fall back on generic machopic code. */
25284 return machopic_legitimize_pic_address (orig, mode, reg);
25287 /* Output a .machine directive for the Darwin assembler, and call
25288 the generic start_file routine. */
25291 rs6000_darwin_file_start (void)
25293 static const struct
25299 { "ppc64", "ppc64", MASK_64BIT },
25300 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25301 { "power4", "ppc970", 0 },
25302 { "G5", "ppc970", 0 },
25303 { "7450", "ppc7450", 0 },
25304 { "7400", "ppc7400", MASK_ALTIVEC },
25305 { "G4", "ppc7400", 0 },
25306 { "750", "ppc750", 0 },
25307 { "740", "ppc750", 0 },
25308 { "G3", "ppc750", 0 },
25309 { "604e", "ppc604e", 0 },
25310 { "604", "ppc604", 0 },
25311 { "603e", "ppc603", 0 },
25312 { "603", "ppc603", 0 },
25313 { "601", "ppc601", 0 },
25314 { NULL, "ppc", 0 } };
25315 const char *cpu_id = "";
25318 rs6000_file_start ();
25319 darwin_file_start ();
25321 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25322 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25323 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25324 && rs6000_select[i].string[0] != '\0')
25325 cpu_id = rs6000_select[i].string;
25327 /* Look through the mapping array. Pick the first name that either
25328 matches the argument, has a bit set in IF_SET that is also set
25329 in the target flags, or has a NULL name. */
25332 while (mapping[i].arg != NULL
25333 && strcmp (mapping[i].arg, cpu_id) != 0
25334 && (mapping[i].if_set & target_flags) == 0)
25337 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25340 #endif /* TARGET_MACHO */
25344 rs6000_elf_reloc_rw_mask (void)
25348 else if (DEFAULT_ABI == ABI_AIX)
25354 /* Record an element in the table of global constructors. SYMBOL is
25355 a SYMBOL_REF of the function to be called; PRIORITY is a number
25356 between 0 and MAX_INIT_PRIORITY.
25358 This differs from default_named_section_asm_out_constructor in
25359 that we have special handling for -mrelocatable. */
25362 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25364 const char *section = ".ctors";
25367 if (priority != DEFAULT_INIT_PRIORITY)
25369 sprintf (buf, ".ctors.%.5u",
25370 /* Invert the numbering so the linker puts us in the proper
25371 order; constructors are run from right to left, and the
25372 linker sorts in increasing order. */
25373 MAX_INIT_PRIORITY - priority);
25377 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25378 assemble_align (POINTER_SIZE);
25380 if (TARGET_RELOCATABLE)
25382 fputs ("\t.long (", asm_out_file);
25383 output_addr_const (asm_out_file, symbol);
25384 fputs (")@fixup\n", asm_out_file);
25387 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25391 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25393 const char *section = ".dtors";
25396 if (priority != DEFAULT_INIT_PRIORITY)
25398 sprintf (buf, ".dtors.%.5u",
25399 /* Invert the numbering so the linker puts us in the proper
25400 order; constructors are run from right to left, and the
25401 linker sorts in increasing order. */
25402 MAX_INIT_PRIORITY - priority);
25406 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25407 assemble_align (POINTER_SIZE);
25409 if (TARGET_RELOCATABLE)
25411 fputs ("\t.long (", asm_out_file);
25412 output_addr_const (asm_out_file, symbol);
25413 fputs (")@fixup\n", asm_out_file);
25416 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25420 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25424 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25425 ASM_OUTPUT_LABEL (file, name);
25426 fputs (DOUBLE_INT_ASM_OP, file);
25427 rs6000_output_function_entry (file, name);
25428 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25431 fputs ("\t.size\t", file);
25432 assemble_name (file, name);
25433 fputs (",24\n\t.type\t.", file);
25434 assemble_name (file, name);
25435 fputs (",@function\n", file);
25436 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25438 fputs ("\t.globl\t.", file);
25439 assemble_name (file, name);
25444 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25445 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25446 rs6000_output_function_entry (file, name);
25447 fputs (":\n", file);
25451 if (TARGET_RELOCATABLE
25452 && !TARGET_SECURE_PLT
25453 && (get_pool_size () != 0 || crtl->profile)
25458 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25460 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25461 fprintf (file, "\t.long ");
25462 assemble_name (file, buf);
25464 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25465 assemble_name (file, buf);
25469 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25470 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25472 if (DEFAULT_ABI == ABI_AIX)
25474 const char *desc_name, *orig_name;
25476 orig_name = (*targetm.strip_name_encoding) (name);
25477 desc_name = orig_name;
25478 while (*desc_name == '.')
25481 if (TREE_PUBLIC (decl))
25482 fprintf (file, "\t.globl %s\n", desc_name);
25484 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25485 fprintf (file, "%s:\n", desc_name);
25486 fprintf (file, "\t.long %s\n", orig_name);
25487 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25488 if (DEFAULT_ABI == ABI_AIX)
25489 fputs ("\t.long 0\n", file);
25490 fprintf (file, "\t.previous\n");
25492 ASM_OUTPUT_LABEL (file, name);
25496 rs6000_elf_end_indicate_exec_stack (void)
25499 file_end_indicate_exec_stack ();
25505 rs6000_xcoff_asm_output_anchor (rtx symbol)
25509 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25510 SYMBOL_REF_BLOCK_OFFSET (symbol));
25511 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25515 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25517 fputs (GLOBAL_ASM_OP, stream);
25518 RS6000_OUTPUT_BASENAME (stream, name);
25519 putc ('\n', stream);
25522 /* A get_unnamed_decl callback, used for read-only sections. PTR
25523 points to the section string variable. */
25526 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25528 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25529 *(const char *const *) directive,
25530 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25533 /* Likewise for read-write sections. */
25536 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25538 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25539 *(const char *const *) directive,
25540 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25543 /* A get_unnamed_section callback, used for switching to toc_section. */
25546 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25548 if (TARGET_MINIMAL_TOC)
25550 /* toc_section is always selected at least once from
25551 rs6000_xcoff_file_start, so this is guaranteed to
25552 always be defined once and only once in each file. */
25553 if (!toc_initialized)
25555 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25556 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25557 toc_initialized = 1;
25559 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25560 (TARGET_32BIT ? "" : ",3"));
25563 fputs ("\t.toc\n", asm_out_file);
25566 /* Implement TARGET_ASM_INIT_SECTIONS. */
25569 rs6000_xcoff_asm_init_sections (void)
25571 read_only_data_section
25572 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25573 &xcoff_read_only_section_name);
25575 private_data_section
25576 = get_unnamed_section (SECTION_WRITE,
25577 rs6000_xcoff_output_readwrite_section_asm_op,
25578 &xcoff_private_data_section_name);
25580 read_only_private_data_section
25581 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25582 &xcoff_private_data_section_name);
25585 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25587 readonly_data_section = read_only_data_section;
25588 exception_section = data_section;
25592 rs6000_xcoff_reloc_rw_mask (void)
25598 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25599 tree decl ATTRIBUTE_UNUSED)
25602 static const char * const suffix[3] = { "PR", "RO", "RW" };
25604 if (flags & SECTION_CODE)
25606 else if (flags & SECTION_WRITE)
25611 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25612 (flags & SECTION_CODE) ? "." : "",
25613 name, suffix[smclass], flags & SECTION_ENTSIZE);
25617 rs6000_xcoff_select_section (tree decl, int reloc,
25618 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25620 if (decl_readonly_section (decl, reloc))
25622 if (TREE_PUBLIC (decl))
25623 return read_only_data_section;
25625 return read_only_private_data_section;
25629 if (TREE_PUBLIC (decl))
25630 return data_section;
25632 return private_data_section;
25637 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25641 /* Use select_section for private and uninitialized data. */
25642 if (!TREE_PUBLIC (decl)
25643 || DECL_COMMON (decl)
25644 || DECL_INITIAL (decl) == NULL_TREE
25645 || DECL_INITIAL (decl) == error_mark_node
25646 || (flag_zero_initialized_in_bss
25647 && initializer_zerop (DECL_INITIAL (decl))))
25650 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25651 name = (*targetm.strip_name_encoding) (name);
25652 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25655 /* Select section for constant in constant pool.
25657 On RS/6000, all constants are in the private read-only data area.
25658 However, if this is being placed in the TOC it must be output as a
25662 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25663 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25665 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25666 return toc_section;
25668 return read_only_private_data_section;
25671 /* Remove any trailing [DS] or the like from the symbol name. */
25673 static const char *
25674 rs6000_xcoff_strip_name_encoding (const char *name)
25679 len = strlen (name);
25680 if (name[len - 1] == ']')
25681 return ggc_alloc_string (name, len - 4);
25686 /* Section attributes. AIX is always PIC. */
25688 static unsigned int
25689 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25691 unsigned int align;
25692 unsigned int flags = default_section_type_flags (decl, name, reloc);
25694 /* Align to at least UNIT size. */
25695 if (flags & SECTION_CODE)
25696 align = MIN_UNITS_PER_WORD;
25698 /* Increase alignment of large objects if not already stricter. */
25699 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25700 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25701 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25703 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25706 /* Output at beginning of assembler file.
25708 Initialize the section names for the RS/6000 at this point.
25710 Specify filename, including full path, to assembler.
25712 We want to go into the TOC section so at least one .toc will be emitted.
25713 Also, in order to output proper .bs/.es pairs, we need at least one static
25714 [RW] section emitted.
25716 Finally, declare mcount when profiling to make the assembler happy. */
25719 rs6000_xcoff_file_start (void)
25721 rs6000_gen_section_name (&xcoff_bss_section_name,
25722 main_input_filename, ".bss_");
25723 rs6000_gen_section_name (&xcoff_private_data_section_name,
25724 main_input_filename, ".rw_");
25725 rs6000_gen_section_name (&xcoff_read_only_section_name,
25726 main_input_filename, ".ro_");
25728 fputs ("\t.file\t", asm_out_file);
25729 output_quoted_string (asm_out_file, main_input_filename);
25730 fputc ('\n', asm_out_file);
25731 if (write_symbols != NO_DEBUG)
25732 switch_to_section (private_data_section);
25733 switch_to_section (text_section);
25735 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25736 rs6000_file_start ();
25739 /* Output at end of assembler file.
25740 On the RS/6000, referencing data should automatically pull in text. */
25743 rs6000_xcoff_file_end (void)
25745 switch_to_section (text_section);
25746 fputs ("_section_.text:\n", asm_out_file);
25747 switch_to_section (data_section);
25748 fputs (TARGET_32BIT
25749 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25752 #endif /* TARGET_XCOFF */
25754 /* Compute a (partial) cost for rtx X. Return true if the complete
25755 cost has been computed, and false if subexpressions should be
25756 scanned. In either case, *TOTAL contains the cost result. */
25759 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25762 enum machine_mode mode = GET_MODE (x);
25766 /* On the RS/6000, if it is valid in the insn, it is free. */
25768 if (((outer_code == SET
25769 || outer_code == PLUS
25770 || outer_code == MINUS)
25771 && (satisfies_constraint_I (x)
25772 || satisfies_constraint_L (x)))
25773 || (outer_code == AND
25774 && (satisfies_constraint_K (x)
25776 ? satisfies_constraint_L (x)
25777 : satisfies_constraint_J (x))
25778 || mask_operand (x, mode)
25780 && mask64_operand (x, DImode))))
25781 || ((outer_code == IOR || outer_code == XOR)
25782 && (satisfies_constraint_K (x)
25784 ? satisfies_constraint_L (x)
25785 : satisfies_constraint_J (x))))
25786 || outer_code == ASHIFT
25787 || outer_code == ASHIFTRT
25788 || outer_code == LSHIFTRT
25789 || outer_code == ROTATE
25790 || outer_code == ROTATERT
25791 || outer_code == ZERO_EXTRACT
25792 || (outer_code == MULT
25793 && satisfies_constraint_I (x))
25794 || ((outer_code == DIV || outer_code == UDIV
25795 || outer_code == MOD || outer_code == UMOD)
25796 && exact_log2 (INTVAL (x)) >= 0)
25797 || (outer_code == COMPARE
25798 && (satisfies_constraint_I (x)
25799 || satisfies_constraint_K (x)))
25800 || ((outer_code == EQ || outer_code == NE)
25801 && (satisfies_constraint_I (x)
25802 || satisfies_constraint_K (x)
25804 ? satisfies_constraint_L (x)
25805 : satisfies_constraint_J (x))))
25806 || (outer_code == GTU
25807 && satisfies_constraint_I (x))
25808 || (outer_code == LTU
25809 && satisfies_constraint_P (x)))
25814 else if ((outer_code == PLUS
25815 && reg_or_add_cint_operand (x, VOIDmode))
25816 || (outer_code == MINUS
25817 && reg_or_sub_cint_operand (x, VOIDmode))
25818 || ((outer_code == SET
25819 || outer_code == IOR
25820 || outer_code == XOR)
25822 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25824 *total = COSTS_N_INSNS (1);
25830 if (mode == DImode && code == CONST_DOUBLE)
25832 if ((outer_code == IOR || outer_code == XOR)
25833 && CONST_DOUBLE_HIGH (x) == 0
25834 && (CONST_DOUBLE_LOW (x)
25835 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25840 else if ((outer_code == AND && and64_2_operand (x, DImode))
25841 || ((outer_code == SET
25842 || outer_code == IOR
25843 || outer_code == XOR)
25844 && CONST_DOUBLE_HIGH (x) == 0))
25846 *total = COSTS_N_INSNS (1);
25856 /* When optimizing for size, MEM should be slightly more expensive
25857 than generating address, e.g., (plus (reg) (const)).
25858 L1 cache latency is about two instructions. */
25859 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25867 if (mode == DFmode)
25869 if (GET_CODE (XEXP (x, 0)) == MULT)
25871 /* FNMA accounted in outer NEG. */
25872 if (outer_code == NEG)
25873 *total = rs6000_cost->dmul - rs6000_cost->fp;
25875 *total = rs6000_cost->dmul;
25878 *total = rs6000_cost->fp;
25880 else if (mode == SFmode)
25882 /* FNMA accounted in outer NEG. */
25883 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25886 *total = rs6000_cost->fp;
25889 *total = COSTS_N_INSNS (1);
25893 if (mode == DFmode)
25895 if (GET_CODE (XEXP (x, 0)) == MULT
25896 || GET_CODE (XEXP (x, 1)) == MULT)
25898 /* FNMA accounted in outer NEG. */
25899 if (outer_code == NEG)
25900 *total = rs6000_cost->dmul - rs6000_cost->fp;
25902 *total = rs6000_cost->dmul;
25905 *total = rs6000_cost->fp;
25907 else if (mode == SFmode)
25909 /* FNMA accounted in outer NEG. */
25910 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25913 *total = rs6000_cost->fp;
25916 *total = COSTS_N_INSNS (1);
25920 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25921 && satisfies_constraint_I (XEXP (x, 1)))
25923 if (INTVAL (XEXP (x, 1)) >= -256
25924 && INTVAL (XEXP (x, 1)) <= 255)
25925 *total = rs6000_cost->mulsi_const9;
25927 *total = rs6000_cost->mulsi_const;
25929 /* FMA accounted in outer PLUS/MINUS. */
25930 else if ((mode == DFmode || mode == SFmode)
25931 && (outer_code == PLUS || outer_code == MINUS))
25933 else if (mode == DFmode)
25934 *total = rs6000_cost->dmul;
25935 else if (mode == SFmode)
25936 *total = rs6000_cost->fp;
25937 else if (mode == DImode)
25938 *total = rs6000_cost->muldi;
25940 *total = rs6000_cost->mulsi;
25945 if (FLOAT_MODE_P (mode))
25947 *total = mode == DFmode ? rs6000_cost->ddiv
25948 : rs6000_cost->sdiv;
25955 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25956 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25958 if (code == DIV || code == MOD)
25960 *total = COSTS_N_INSNS (2);
25963 *total = COSTS_N_INSNS (1);
25967 if (GET_MODE (XEXP (x, 1)) == DImode)
25968 *total = rs6000_cost->divdi;
25970 *total = rs6000_cost->divsi;
25972 /* Add in shift and subtract for MOD. */
25973 if (code == MOD || code == UMOD)
25974 *total += COSTS_N_INSNS (2);
25979 *total = COSTS_N_INSNS (4);
25983 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
25987 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
25991 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26003 *total = COSTS_N_INSNS (1);
26011 /* Handle mul_highpart. */
26012 if (outer_code == TRUNCATE
26013 && GET_CODE (XEXP (x, 0)) == MULT)
26015 if (mode == DImode)
26016 *total = rs6000_cost->muldi;
26018 *total = rs6000_cost->mulsi;
26021 else if (outer_code == AND)
26024 *total = COSTS_N_INSNS (1);
26029 if (GET_CODE (XEXP (x, 0)) == MEM)
26032 *total = COSTS_N_INSNS (1);
26038 if (!FLOAT_MODE_P (mode))
26040 *total = COSTS_N_INSNS (1);
26046 case UNSIGNED_FLOAT:
26049 case FLOAT_TRUNCATE:
26050 *total = rs6000_cost->fp;
26054 if (mode == DFmode)
26057 *total = rs6000_cost->fp;
26061 switch (XINT (x, 1))
26064 *total = rs6000_cost->fp;
26076 *total = COSTS_N_INSNS (1);
26079 else if (FLOAT_MODE_P (mode)
26080 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26082 *total = rs6000_cost->fp;
26090 /* Carry bit requires mode == Pmode.
26091 NEG or PLUS already counted so only add one. */
26093 && (outer_code == NEG || outer_code == PLUS))
26095 *total = COSTS_N_INSNS (1);
26098 if (outer_code == SET)
26100 if (XEXP (x, 1) == const0_rtx)
26102 if (TARGET_ISEL && !TARGET_MFCRF)
26103 *total = COSTS_N_INSNS (8);
26105 *total = COSTS_N_INSNS (2);
26108 else if (mode == Pmode)
26110 *total = COSTS_N_INSNS (3);
26119 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26121 if (TARGET_ISEL && !TARGET_MFCRF)
26122 *total = COSTS_N_INSNS (8);
26124 *total = COSTS_N_INSNS (2);
26128 if (outer_code == COMPARE)
26142 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26145 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26148 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26151 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26152 "total = %d, speed = %s, x:\n",
26153 ret ? "complete" : "scan inner",
26154 GET_RTX_NAME (code),
26155 GET_RTX_NAME (outer_code),
26157 speed ? "true" : "false");
26164 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26167 rs6000_debug_address_cost (rtx x, bool speed)
26169 int ret = TARGET_ADDRESS_COST (x, speed);
26171 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26172 ret, speed ? "true" : "false");
26179 /* A C expression returning the cost of moving data from a register of class
26180 CLASS1 to one of CLASS2. */
26183 rs6000_register_move_cost (enum machine_mode mode,
26184 reg_class_t from, reg_class_t to)
26188 /* Moves from/to GENERAL_REGS. */
26189 if (reg_classes_intersect_p (to, GENERAL_REGS)
26190 || reg_classes_intersect_p (from, GENERAL_REGS))
26192 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26195 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26196 ret = (rs6000_memory_move_cost (mode, from, false)
26197 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26199 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26201 else if (from == CR_REGS)
26204 /* Power6 has slower LR/CTR moves so make them more expensive than
26205 memory in order to bias spills to memory .*/
26206 else if (rs6000_cpu == PROCESSOR_POWER6
26207 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26208 ret = 6 * hard_regno_nregs[0][mode];
26211 /* A move will cost one instruction per GPR moved. */
26212 ret = 2 * hard_regno_nregs[0][mode];
26215 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26216 else if (VECTOR_UNIT_VSX_P (mode)
26217 && reg_classes_intersect_p (to, VSX_REGS)
26218 && reg_classes_intersect_p (from, VSX_REGS))
26219 ret = 2 * hard_regno_nregs[32][mode];
26221 /* Moving between two similar registers is just one instruction. */
26222 else if (reg_classes_intersect_p (to, from))
26223 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26225 /* Everything else has to go through GENERAL_REGS. */
26227 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26228 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26230 if (TARGET_DEBUG_COST)
26232 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26233 ret, GET_MODE_NAME (mode), reg_class_names[from],
26234 reg_class_names[to]);
26239 /* A C expressions returning the cost of moving data of MODE from a register to
26243 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26244 bool in ATTRIBUTE_UNUSED)
26248 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26249 ret = 4 * hard_regno_nregs[0][mode];
26250 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26251 ret = 4 * hard_regno_nregs[32][mode];
26252 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26253 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26255 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26257 if (TARGET_DEBUG_COST)
26259 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26260 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26265 /* Returns a code for a target-specific builtin that implements
26266 reciprocal of the function, or NULL_TREE if not available. */
26269 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26270 bool sqrt ATTRIBUTE_UNUSED)
26272 if (optimize_insn_for_size_p ())
26278 case VSX_BUILTIN_XVSQRTDP:
26279 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26282 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26284 case VSX_BUILTIN_XVSQRTSP:
26285 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26288 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26297 case BUILT_IN_SQRT:
26298 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26301 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26303 case BUILT_IN_SQRTF:
26304 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26307 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26314 /* Load up a constant. If the mode is a vector mode, splat the value across
26315 all of the vector elements. */
26318 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26322 if (mode == SFmode || mode == DFmode)
26324 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26325 reg = force_reg (mode, d);
26327 else if (mode == V4SFmode)
26329 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26330 rtvec v = gen_rtvec (4, d, d, d, d);
26331 reg = gen_reg_rtx (mode);
26332 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26334 else if (mode == V2DFmode)
26336 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26337 rtvec v = gen_rtvec (2, d, d);
26338 reg = gen_reg_rtx (mode);
26339 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26342 gcc_unreachable ();
26347 /* Generate a FMADD instruction:
26348 dst = (m1 * m2) + a
26350 generating different RTL based on the fused multiply/add switch. */
26353 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26355 enum machine_mode mode = GET_MODE (dst);
26357 if (!TARGET_FUSED_MADD)
26359 /* For the simple ops, use the generator function, rather than assuming
26360 that the RTL is standard. */
26361 enum insn_code mcode = optab_handler (smul_optab, mode);
26362 enum insn_code acode = optab_handler (add_optab, mode);
26363 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26364 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26365 rtx mreg = gen_reg_rtx (mode);
26367 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26368 emit_insn (gen_mul (mreg, m1, m2));
26369 emit_insn (gen_add (dst, mreg, a));
26373 emit_insn (gen_rtx_SET (VOIDmode, dst,
26374 gen_rtx_PLUS (mode,
26375 gen_rtx_MULT (mode, m1, m2),
26379 /* Generate a FMSUB instruction:
26380 dst = (m1 * m2) - a
26382 generating different RTL based on the fused multiply/add switch. */
26385 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26387 enum machine_mode mode = GET_MODE (dst);
26389 if (!TARGET_FUSED_MADD
26390 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26392 /* For the simple ops, use the generator function, rather than assuming
26393 that the RTL is standard. */
26394 enum insn_code mcode = optab_handler (smul_optab, mode);
26395 enum insn_code scode = optab_handler (add_optab, mode);
26396 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26397 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26398 rtx mreg = gen_reg_rtx (mode);
26400 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26401 emit_insn (gen_mul (mreg, m1, m2));
26402 emit_insn (gen_sub (dst, mreg, a));
26406 emit_insn (gen_rtx_SET (VOIDmode, dst,
26407 gen_rtx_MINUS (mode,
26408 gen_rtx_MULT (mode, m1, m2),
26412 /* Generate a FNMSUB instruction:
26413 dst = - ((m1 * m2) - a)
26415 Which is equivalent to (except in the prescence of -0.0):
26416 dst = a - (m1 * m2)
26418 generating different RTL based on the fast-math and fused multiply/add
26422 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26424 enum machine_mode mode = GET_MODE (dst);
26426 if (!TARGET_FUSED_MADD)
26428 /* For the simple ops, use the generator function, rather than assuming
26429 that the RTL is standard. */
26430 enum insn_code mcode = optab_handler (smul_optab, mode);
26431 enum insn_code scode = optab_handler (sub_optab, mode);
26432 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26433 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26434 rtx mreg = gen_reg_rtx (mode);
26436 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26437 emit_insn (gen_mul (mreg, m1, m2));
26438 emit_insn (gen_sub (dst, a, mreg));
26443 rtx m = gen_rtx_MULT (mode, m1, m2);
26445 if (!HONOR_SIGNED_ZEROS (mode))
26446 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26449 emit_insn (gen_rtx_SET (VOIDmode, dst,
26451 gen_rtx_MINUS (mode, m, a))));
26455 /* Newton-Raphson approximation of floating point divide with just 2 passes
26456 (either single precision floating point, or newer machines with higher
26457 accuracy estimates). Support both scalar and vector divide. Assumes no
26458 trapping math and finite arguments. */
26461 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26463 enum machine_mode mode = GET_MODE (dst);
26464 rtx x0, e0, e1, y1, u0, v0;
26465 enum insn_code code = optab_handler (smul_optab, mode);
26466 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26467 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26469 gcc_assert (code != CODE_FOR_nothing);
26471 /* x0 = 1./d estimate */
26472 x0 = gen_reg_rtx (mode);
26473 emit_insn (gen_rtx_SET (VOIDmode, x0,
26474 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26477 e0 = gen_reg_rtx (mode);
26478 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26480 e1 = gen_reg_rtx (mode);
26481 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26483 y1 = gen_reg_rtx (mode);
26484 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26486 u0 = gen_reg_rtx (mode);
26487 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26489 v0 = gen_reg_rtx (mode);
26490 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26492 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26495 /* Newton-Raphson approximation of floating point divide that has a low
26496 precision estimate. Assumes no trapping math and finite arguments. */
26499 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26501 enum machine_mode mode = GET_MODE (dst);
26502 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26503 enum insn_code code = optab_handler (smul_optab, mode);
26504 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26506 gcc_assert (code != CODE_FOR_nothing);
26508 one = rs6000_load_constant_and_splat (mode, dconst1);
26510 /* x0 = 1./d estimate */
26511 x0 = gen_reg_rtx (mode);
26512 emit_insn (gen_rtx_SET (VOIDmode, x0,
26513 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26516 e0 = gen_reg_rtx (mode);
26517 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26519 y1 = gen_reg_rtx (mode);
26520 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26522 e1 = gen_reg_rtx (mode);
26523 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26525 y2 = gen_reg_rtx (mode);
26526 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26528 e2 = gen_reg_rtx (mode);
26529 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26531 y3 = gen_reg_rtx (mode);
26532 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26534 u0 = gen_reg_rtx (mode);
26535 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26537 v0 = gen_reg_rtx (mode);
26538 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26540 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26543 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26544 add a reg_note saying that this was a division. Support both scalar and
26545 vector divide. Assumes no trapping math and finite arguments. */
26548 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26550 enum machine_mode mode = GET_MODE (dst);
26552 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26553 rs6000_emit_swdiv_high_precision (dst, n, d);
26555 rs6000_emit_swdiv_low_precision (dst, n, d);
26558 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26561 /* Newton-Raphson approximation of single/double-precision floating point
26562 rsqrt. Assumes no trapping math and finite arguments. */
26565 rs6000_emit_swrsqrt (rtx dst, rtx src)
26567 enum machine_mode mode = GET_MODE (src);
26568 rtx x0 = gen_reg_rtx (mode);
26569 rtx y = gen_reg_rtx (mode);
26570 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26571 REAL_VALUE_TYPE dconst3_2;
26574 enum insn_code code = optab_handler (smul_optab, mode);
26575 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26577 gcc_assert (code != CODE_FOR_nothing);
26579 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26580 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26581 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26583 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26585 /* x0 = rsqrt estimate */
26586 emit_insn (gen_rtx_SET (VOIDmode, x0,
26587 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26590 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26591 rs6000_emit_msub (y, src, halfthree, src);
26593 for (i = 0; i < passes; i++)
26595 rtx x1 = gen_reg_rtx (mode);
26596 rtx u = gen_reg_rtx (mode);
26597 rtx v = gen_reg_rtx (mode);
26599 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26600 emit_insn (gen_mul (u, x0, x0));
26601 rs6000_emit_nmsub (v, y, u, halfthree);
26602 emit_insn (gen_mul (x1, x0, v));
26606 emit_move_insn (dst, x0);
26610 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26611 (Power7) targets. DST is the target, and SRC is the argument operand. */
26614 rs6000_emit_popcount (rtx dst, rtx src)
26616 enum machine_mode mode = GET_MODE (dst);
26619 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26620 if (TARGET_POPCNTD)
26622 if (mode == SImode)
26623 emit_insn (gen_popcntdsi2 (dst, src));
26625 emit_insn (gen_popcntddi2 (dst, src));
26629 tmp1 = gen_reg_rtx (mode);
26631 if (mode == SImode)
26633 emit_insn (gen_popcntbsi2 (tmp1, src));
26634 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26636 tmp2 = force_reg (SImode, tmp2);
26637 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26641 emit_insn (gen_popcntbdi2 (tmp1, src));
26642 tmp2 = expand_mult (DImode, tmp1,
26643 GEN_INT ((HOST_WIDE_INT)
26644 0x01010101 << 32 | 0x01010101),
26646 tmp2 = force_reg (DImode, tmp2);
26647 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26652 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26653 target, and SRC is the argument operand. */
26656 rs6000_emit_parity (rtx dst, rtx src)
26658 enum machine_mode mode = GET_MODE (dst);
26661 tmp = gen_reg_rtx (mode);
26663 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26666 if (mode == SImode)
26668 emit_insn (gen_popcntbsi2 (tmp, src));
26669 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26673 emit_insn (gen_popcntbdi2 (tmp, src));
26674 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26679 if (mode == SImode)
26681 /* Is mult+shift >= shift+xor+shift+xor? */
26682 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26684 rtx tmp1, tmp2, tmp3, tmp4;
26686 tmp1 = gen_reg_rtx (SImode);
26687 emit_insn (gen_popcntbsi2 (tmp1, src));
26689 tmp2 = gen_reg_rtx (SImode);
26690 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26691 tmp3 = gen_reg_rtx (SImode);
26692 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26694 tmp4 = gen_reg_rtx (SImode);
26695 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26696 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26699 rs6000_emit_popcount (tmp, src);
26700 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26704 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26705 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26707 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26709 tmp1 = gen_reg_rtx (DImode);
26710 emit_insn (gen_popcntbdi2 (tmp1, src));
26712 tmp2 = gen_reg_rtx (DImode);
26713 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26714 tmp3 = gen_reg_rtx (DImode);
26715 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26717 tmp4 = gen_reg_rtx (DImode);
26718 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26719 tmp5 = gen_reg_rtx (DImode);
26720 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26722 tmp6 = gen_reg_rtx (DImode);
26723 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26724 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26727 rs6000_emit_popcount (tmp, src);
26728 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26732 /* Return an RTX representing where to find the function value of a
26733 function returning MODE. */
26735 rs6000_complex_function_value (enum machine_mode mode)
26737 unsigned int regno;
26739 enum machine_mode inner = GET_MODE_INNER (mode);
26740 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26742 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26743 regno = FP_ARG_RETURN;
26746 regno = GP_ARG_RETURN;
26748 /* 32-bit is OK since it'll go in r3/r4. */
26749 if (TARGET_32BIT && inner_bytes >= 4)
26750 return gen_rtx_REG (mode, regno);
26753 if (inner_bytes >= 8)
26754 return gen_rtx_REG (mode, regno);
26756 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26758 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26759 GEN_INT (inner_bytes));
26760 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26763 /* Target hook for TARGET_FUNCTION_VALUE.
26765 On the SPE, both FPs and vectors are returned in r3.
26767 On RS/6000 an integer value is in r3 and a floating-point value is in
26768 fp1, unless -msoft-float. */
26771 rs6000_function_value (const_tree valtype,
26772 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26773 bool outgoing ATTRIBUTE_UNUSED)
26775 enum machine_mode mode;
26776 unsigned int regno;
26778 /* Special handling for structs in darwin64. */
26780 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26782 CUMULATIVE_ARGS valcum;
26786 valcum.fregno = FP_ARG_MIN_REG;
26787 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26788 /* Do a trial code generation as if this were going to be passed as
26789 an argument; if any part goes in memory, we return NULL. */
26790 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26793 /* Otherwise fall through to standard ABI rules. */
26796 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26798 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26799 return gen_rtx_PARALLEL (DImode,
26801 gen_rtx_EXPR_LIST (VOIDmode,
26802 gen_rtx_REG (SImode, GP_ARG_RETURN),
26804 gen_rtx_EXPR_LIST (VOIDmode,
26805 gen_rtx_REG (SImode,
26806 GP_ARG_RETURN + 1),
26809 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26811 return gen_rtx_PARALLEL (DCmode,
26813 gen_rtx_EXPR_LIST (VOIDmode,
26814 gen_rtx_REG (SImode, GP_ARG_RETURN),
26816 gen_rtx_EXPR_LIST (VOIDmode,
26817 gen_rtx_REG (SImode,
26818 GP_ARG_RETURN + 1),
26820 gen_rtx_EXPR_LIST (VOIDmode,
26821 gen_rtx_REG (SImode,
26822 GP_ARG_RETURN + 2),
26824 gen_rtx_EXPR_LIST (VOIDmode,
26825 gen_rtx_REG (SImode,
26826 GP_ARG_RETURN + 3),
26830 mode = TYPE_MODE (valtype);
26831 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26832 || POINTER_TYPE_P (valtype))
26833 mode = TARGET_32BIT ? SImode : DImode;
26835 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26836 /* _Decimal128 must use an even/odd register pair. */
26837 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26838 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26839 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26840 regno = FP_ARG_RETURN;
26841 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26842 && targetm.calls.split_complex_arg)
26843 return rs6000_complex_function_value (mode);
26844 else if (TREE_CODE (valtype) == VECTOR_TYPE
26845 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26846 && ALTIVEC_VECTOR_MODE (mode))
26847 regno = ALTIVEC_ARG_RETURN;
26848 else if (TREE_CODE (valtype) == VECTOR_TYPE
26849 && TARGET_VSX && TARGET_ALTIVEC_ABI
26850 && VSX_VECTOR_MODE (mode))
26851 regno = ALTIVEC_ARG_RETURN;
26852 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26853 && (mode == DFmode || mode == DCmode
26854 || mode == TFmode || mode == TCmode))
26855 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26857 regno = GP_ARG_RETURN;
26859 return gen_rtx_REG (mode, regno);
26862 /* Define how to find the value returned by a library function
26863 assuming the value has mode MODE. */
26865 rs6000_libcall_value (enum machine_mode mode)
26867 unsigned int regno;
26869 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26871 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26872 return gen_rtx_PARALLEL (DImode,
26874 gen_rtx_EXPR_LIST (VOIDmode,
26875 gen_rtx_REG (SImode, GP_ARG_RETURN),
26877 gen_rtx_EXPR_LIST (VOIDmode,
26878 gen_rtx_REG (SImode,
26879 GP_ARG_RETURN + 1),
26883 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26884 /* _Decimal128 must use an even/odd register pair. */
26885 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26886 else if (SCALAR_FLOAT_MODE_P (mode)
26887 && TARGET_HARD_FLOAT && TARGET_FPRS
26888 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26889 regno = FP_ARG_RETURN;
26890 else if (ALTIVEC_VECTOR_MODE (mode)
26891 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26892 regno = ALTIVEC_ARG_RETURN;
26893 else if (VSX_VECTOR_MODE (mode)
26894 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26895 regno = ALTIVEC_ARG_RETURN;
26896 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26897 return rs6000_complex_function_value (mode);
26898 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26899 && (mode == DFmode || mode == DCmode
26900 || mode == TFmode || mode == TCmode))
26901 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26903 regno = GP_ARG_RETURN;
26905 return gen_rtx_REG (mode, regno);
26909 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26910 Frame pointer elimination is automatically handled.
26912 For the RS/6000, if frame pointer elimination is being done, we would like
26913 to convert ap into fp, not sp.
26915 We need r30 if -mminimal-toc was specified, and there are constant pool
26919 rs6000_can_eliminate (const int from, const int to)
26921 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26922 ? ! frame_pointer_needed
26923 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26924 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26928 /* Define the offset between two registers, FROM to be eliminated and its
26929 replacement TO, at the start of a routine. */
26931 rs6000_initial_elimination_offset (int from, int to)
26933 rs6000_stack_t *info = rs6000_stack_info ();
26934 HOST_WIDE_INT offset;
26936 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26937 offset = info->push_p ? 0 : -info->total_size;
26938 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26940 offset = info->push_p ? 0 : -info->total_size;
26941 if (FRAME_GROWS_DOWNWARD)
26942 offset += info->fixed_size + info->vars_size + info->parm_size;
26944 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26945 offset = FRAME_GROWS_DOWNWARD
26946 ? info->fixed_size + info->vars_size + info->parm_size
26948 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26949 offset = info->total_size;
26950 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26951 offset = info->push_p ? info->total_size : 0;
26952 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26955 gcc_unreachable ();
26961 rs6000_dwarf_register_span (rtx reg)
26965 unsigned regno = REGNO (reg);
26966 enum machine_mode mode = GET_MODE (reg);
26970 && (SPE_VECTOR_MODE (GET_MODE (reg))
26971 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26972 && mode != SFmode && mode != SDmode && mode != SCmode)))
26977 regno = REGNO (reg);
26979 /* The duality of the SPE register size wreaks all kinds of havoc.
26980 This is a way of distinguishing r0 in 32-bits from r0 in
26982 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26983 gcc_assert (words <= 4);
26984 for (i = 0; i < words; i++, regno++)
26986 if (BYTES_BIG_ENDIAN)
26988 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26989 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26993 parts[2 * i] = gen_rtx_REG (SImode, regno);
26994 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26998 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27001 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27004 rs6000_init_dwarf_reg_sizes_extra (tree address)
27009 enum machine_mode mode = TYPE_MODE (char_type_node);
27010 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27011 rtx mem = gen_rtx_MEM (BLKmode, addr);
27012 rtx value = gen_int_mode (4, mode);
27014 for (i = 1201; i < 1232; i++)
27016 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27017 HOST_WIDE_INT offset
27018 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27020 emit_move_insn (adjust_address (mem, mode, offset), value);
27025 /* Map internal gcc register numbers to DWARF2 register numbers. */
27028 rs6000_dbx_register_number (unsigned int regno)
27030 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27032 if (regno == MQ_REGNO)
27034 if (regno == LR_REGNO)
27036 if (regno == CTR_REGNO)
27038 if (CR_REGNO_P (regno))
27039 return regno - CR0_REGNO + 86;
27040 if (regno == CA_REGNO)
27041 return 101; /* XER */
27042 if (ALTIVEC_REGNO_P (regno))
27043 return regno - FIRST_ALTIVEC_REGNO + 1124;
27044 if (regno == VRSAVE_REGNO)
27046 if (regno == VSCR_REGNO)
27048 if (regno == SPE_ACC_REGNO)
27050 if (regno == SPEFSCR_REGNO)
27052 /* SPE high reg number. We get these values of regno from
27053 rs6000_dwarf_register_span. */
27054 gcc_assert (regno >= 1200 && regno < 1232);
27058 /* target hook eh_return_filter_mode */
27059 static enum machine_mode
27060 rs6000_eh_return_filter_mode (void)
27062 return TARGET_32BIT ? SImode : word_mode;
27065 /* Target hook for scalar_mode_supported_p. */
27067 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27069 if (DECIMAL_FLOAT_MODE_P (mode))
27070 return default_decimal_float_supported_p ();
27072 return default_scalar_mode_supported_p (mode);
27075 /* Target hook for vector_mode_supported_p. */
27077 rs6000_vector_mode_supported_p (enum machine_mode mode)
27080 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27083 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27086 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27093 /* Target hook for invalid_arg_for_unprototyped_fn. */
27094 static const char *
27095 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27097 return (!rs6000_darwin64_abi
27099 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27100 && (funcdecl == NULL_TREE
27101 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27102 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27103 ? N_("AltiVec argument passed to unprototyped function")
27107 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27108 setup by using __stack_chk_fail_local hidden function instead of
27109 calling __stack_chk_fail directly. Otherwise it is better to call
27110 __stack_chk_fail directly. */
27113 rs6000_stack_protect_fail (void)
27115 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27116 ? default_hidden_stack_protect_fail ()
27117 : default_external_stack_protect_fail ();
27121 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27122 int num_operands ATTRIBUTE_UNUSED)
27124 if (rs6000_warn_cell_microcode)
27127 int insn_code_number = recog_memoized (insn);
27128 location_t location = locator_location (INSN_LOCATOR (insn));
27130 /* Punt on insns we cannot recognize. */
27131 if (insn_code_number < 0)
27134 temp = get_insn_template (insn_code_number, insn);
27136 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27137 warning_at (location, OPT_mwarn_cell_microcode,
27138 "emitting microcode insn %s\t[%s] #%d",
27139 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27140 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27141 warning_at (location, OPT_mwarn_cell_microcode,
27142 "emitting conditional microcode insn %s\t[%s] #%d",
27143 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27148 /* Allocate a stack temp and fixup the address so it meets the particular
27149 memory requirements (either offetable or REG+REG addressing). */
27152 rs6000_allocate_stack_temp (enum machine_mode mode,
27153 bool offsettable_p,
27156 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27157 rtx addr = XEXP (stack, 0);
27158 int strict_p = (reload_in_progress || reload_completed);
27160 if (!legitimate_indirect_address_p (addr, strict_p))
27163 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27164 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27166 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27167 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27173 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27174 to such a form to deal with memory reference instructions like STFIWX that
27175 only take reg+reg addressing. */
27178 rs6000_address_for_fpconvert (rtx x)
27180 int strict_p = (reload_in_progress || reload_completed);
27183 gcc_assert (MEM_P (x));
27184 addr = XEXP (x, 0);
27185 if (! legitimate_indirect_address_p (addr, strict_p)
27186 && ! legitimate_indexed_address_p (addr, strict_p))
27187 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27192 /* Expand 32-bit int -> floating point conversions. Return true if
27196 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27198 enum machine_mode dmode = GET_MODE (dest);
27199 rtx (*func_si) (rtx, rtx, rtx, rtx);
27200 rtx (*func_si_mem) (rtx, rtx);
27201 rtx (*func_di) (rtx, rtx);
27204 gcc_assert (GET_MODE (src) == SImode);
27206 if (dmode == SFmode)
27210 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27211 func_si = gen_floatunssisf2_lfiwzx;
27212 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27213 func_di = gen_floatunsdisf2;
27217 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27218 func_si = gen_floatsisf2_lfiwax;
27219 func_si_mem = gen_floatsisf2_lfiwax_mem;
27220 func_di = gen_floatdisf2;
27224 else if (dmode == DFmode)
27228 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27229 func_si = gen_floatunssidf2_lfiwzx;
27230 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27231 func_di = gen_floatunsdidf2;
27235 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27236 func_si = gen_floatsidf2_lfiwax;
27237 func_si_mem = gen_floatsidf2_lfiwax_mem;
27238 func_di = gen_floatdidf2;
27243 gcc_unreachable ();
27247 src = rs6000_address_for_fpconvert (src);
27248 emit_insn (func_si_mem (dest, src));
27250 else if (!TARGET_MFPGPR)
27252 reg = gen_reg_rtx (DImode);
27253 stack = rs6000_allocate_stack_temp (SImode, false, true);
27254 emit_insn (func_si (dest, src, stack, reg));
27259 src = force_reg (SImode, src);
27260 reg = convert_to_mode (DImode, src, unsigned_p);
27261 emit_insn (func_di (dest, reg));
27265 #include "gt-rs6000.h"