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"
49 #include "target-def.h"
50 #include "langhooks.h"
52 #include "cfglayout.h"
53 #include "sched-int.h"
55 #include "tree-flow.h"
58 #include "tm-constrs.h"
60 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
63 #include "gstab.h" /* for N_SLINE */
66 #ifndef TARGET_NO_PROTOTYPE
67 #define TARGET_NO_PROTOTYPE 0
70 #define min(A,B) ((A) < (B) ? (A) : (B))
71 #define max(A,B) ((A) > (B) ? (A) : (B))
73 /* Structure used to define the rs6000 stack */
74 typedef struct rs6000_stack {
75 int first_gp_reg_save; /* first callee saved GP register used */
76 int first_fp_reg_save; /* first callee saved FP register used */
77 int first_altivec_reg_save; /* first callee saved AltiVec register used */
78 int lr_save_p; /* true if the link reg needs to be saved */
79 int cr_save_p; /* true if the CR reg needs to be saved */
80 unsigned int vrsave_mask; /* mask of vec registers to save */
81 int push_p; /* true if we need to allocate stack space */
82 int calls_p; /* true if the function makes any calls */
83 int world_save_p; /* true if we're saving *everything*:
84 r13-r31, cr, f14-f31, vrsave, v20-v31 */
85 enum rs6000_abi abi; /* which ABI to use */
86 int gp_save_offset; /* offset to save GP regs from initial SP */
87 int fp_save_offset; /* offset to save FP regs from initial SP */
88 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
89 int lr_save_offset; /* offset to save LR from initial SP */
90 int cr_save_offset; /* offset to save CR from initial SP */
91 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
92 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
93 int varargs_save_offset; /* offset to save the varargs registers */
94 int ehrd_offset; /* offset to EH return data */
95 int reg_size; /* register size (4 or 8) */
96 HOST_WIDE_INT vars_size; /* variable save area size */
97 int parm_size; /* outgoing parameter size */
98 int save_size; /* save area size */
99 int fixed_size; /* fixed size of stack frame */
100 int gp_size; /* size of saved GP registers */
101 int fp_size; /* size of saved FP registers */
102 int altivec_size; /* size of saved AltiVec registers */
103 int cr_size; /* size to hold CR if not in save_size */
104 int vrsave_size; /* size to hold VRSAVE if not in save_size */
105 int altivec_padding_size; /* size of altivec alignment padding if
107 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
108 int spe_padding_size;
109 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
110 int spe_64bit_regs_used;
113 /* A C structure for machine-specific, per-function data.
114 This is added to the cfun structure. */
115 typedef struct GTY(()) machine_function
117 /* Some local-dynamic symbol. */
118 const char *some_ld_name;
119 /* Whether the instruction chain has been scanned already. */
120 int insn_chain_scanned_p;
121 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
122 int ra_needs_full_frame;
123 /* Flags if __builtin_return_address (0) was used. */
125 /* Cache lr_save_p after expansion of builtin_eh_return. */
127 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
128 varargs save area. */
129 HOST_WIDE_INT varargs_save_offset;
130 /* Temporary stack slot to use for SDmode copies. This slot is
131 64-bits wide and is allocated early enough so that the offset
132 does not overflow the 16-bit load/store offset field. */
133 rtx sdmode_stack_slot;
136 /* Target cpu type */
138 enum processor_type rs6000_cpu;
139 struct rs6000_cpu_select rs6000_select[3] =
141 /* switch name, tune arch */
142 { (const char *)0, "--with-cpu=", 1, 1 },
143 { (const char *)0, "-mcpu=", 1, 1 },
144 { (const char *)0, "-mtune=", 1, 0 },
147 /* Always emit branch hint bits. */
148 static GTY(()) bool rs6000_always_hint;
150 /* Schedule instructions for group formation. */
151 static GTY(()) bool rs6000_sched_groups;
153 /* Align branch targets. */
154 static GTY(()) bool rs6000_align_branch_targets;
156 /* Support for -msched-costly-dep option. */
157 const char *rs6000_sched_costly_dep_str;
158 enum rs6000_dependence_cost rs6000_sched_costly_dep;
160 /* Support for -minsert-sched-nops option. */
161 const char *rs6000_sched_insert_nops_str;
162 enum rs6000_nop_insertion rs6000_sched_insert_nops;
164 /* Support targetm.vectorize.builtin_mask_for_load. */
165 static GTY(()) tree altivec_builtin_mask_for_load;
167 /* Size of long double. */
168 int rs6000_long_double_type_size;
170 /* IEEE quad extended precision long double. */
173 /* Nonzero to use AltiVec ABI. */
174 int rs6000_altivec_abi;
176 /* Nonzero if we want SPE SIMD instructions. */
179 /* Nonzero if we want SPE ABI extensions. */
182 /* Nonzero if floating point operations are done in the GPRs. */
183 int rs6000_float_gprs = 0;
185 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
186 int rs6000_darwin64_abi;
188 /* Set to nonzero once AIX common-mode calls have been defined. */
189 static GTY(()) int common_mode_defined;
191 /* Label number of label created for -mrelocatable, to call to so we can
192 get the address of the GOT section */
193 int rs6000_pic_labelno;
196 /* Which abi to adhere to */
197 const char *rs6000_abi_name;
199 /* Semantics of the small data area */
200 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
202 /* Which small data model to use */
203 const char *rs6000_sdata_name = (char *)0;
205 /* Counter for labels which are to be placed in .fixup. */
206 int fixuplabelno = 0;
209 /* Bit size of immediate TLS offsets and string from which it is decoded. */
210 int rs6000_tls_size = 32;
211 const char *rs6000_tls_size_string;
213 /* ABI enumeration available for subtarget to use. */
214 enum rs6000_abi rs6000_current_abi;
216 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
220 const char *rs6000_debug_name;
221 int rs6000_debug_stack; /* debug stack applications */
222 int rs6000_debug_arg; /* debug argument handling */
223 int rs6000_debug_reg; /* debug register classes */
224 int rs6000_debug_addr; /* debug memory addressing */
225 int rs6000_debug_cost; /* debug rtx_costs */
227 /* Specify the machine mode that pointers have. After generation of rtl, the
228 compiler makes no further distinction between pointers and any other objects
229 of this machine mode. The type is unsigned since not all things that
230 include rs6000.h also include machmode.h. */
231 unsigned rs6000_pmode;
233 /* Width in bits of a pointer. */
234 unsigned rs6000_pointer_size;
237 /* Value is TRUE if register/mode pair is acceptable. */
238 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
240 /* Maximum number of registers needed for a given register class and mode. */
241 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
243 /* How many registers are needed for a given register and mode. */
244 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
246 /* Map register number to register class. */
247 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
249 /* Reload functions based on the type and the vector unit. */
250 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
252 /* Built in types. */
253 tree rs6000_builtin_types[RS6000_BTI_MAX];
254 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
256 const char *rs6000_traceback_name;
258 traceback_default = 0,
264 /* Flag to say the TOC is initialized */
266 char toc_label_name[10];
268 /* Cached value of rs6000_variable_issue. This is cached in
269 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
270 static short cached_can_issue_more;
272 static GTY(()) section *read_only_data_section;
273 static GTY(()) section *private_data_section;
274 static GTY(()) section *read_only_private_data_section;
275 static GTY(()) section *sdata2_section;
276 static GTY(()) section *toc_section;
278 /* Control alignment for fields within structures. */
279 /* String from -malign-XXXXX. */
280 int rs6000_alignment_flags;
282 /* True for any options that were explicitly set. */
284 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
285 bool alignment; /* True if -malign- was used. */
286 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
287 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
288 bool spe; /* True if -mspe= was used. */
289 bool float_gprs; /* True if -mfloat-gprs= was used. */
290 bool long_double; /* True if -mlong-double- was used. */
291 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
292 bool vrsave; /* True if -mvrsave was used. */
293 } rs6000_explicit_options;
295 struct builtin_description
297 /* mask is not const because we're going to alter it below. This
298 nonsense will go away when we rewrite the -march infrastructure
299 to give us more target flag bits. */
301 const enum insn_code icode;
302 const char *const name;
303 const enum rs6000_builtins code;
306 /* Describe the vector unit used for modes. */
307 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
308 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
310 /* Register classes for various constraints that are based on the target
312 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
314 /* Describe the alignment of a vector. */
315 int rs6000_vector_align[NUM_MACHINE_MODES];
317 /* Map selected modes to types for builtins. */
318 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
320 /* What modes to automatically generate reciprocal divide estimate (fre) and
321 reciprocal sqrt (frsqrte) for. */
322 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
324 /* Masks to determine which reciprocal esitmate instructions to generate
326 enum rs6000_recip_mask {
327 RECIP_SF_DIV = 0x001, /* Use divide estimate */
328 RECIP_DF_DIV = 0x002,
329 RECIP_V4SF_DIV = 0x004,
330 RECIP_V2DF_DIV = 0x008,
332 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
333 RECIP_DF_RSQRT = 0x020,
334 RECIP_V4SF_RSQRT = 0x040,
335 RECIP_V2DF_RSQRT = 0x080,
337 /* Various combination of flags for -mrecip=xxx. */
339 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
340 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
341 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
343 RECIP_HIGH_PRECISION = RECIP_ALL,
345 /* On low precision machines like the power5, don't enable double precision
346 reciprocal square root estimate, since it isn't accurate enough. */
347 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
350 static unsigned int rs6000_recip_control;
351 static const char *rs6000_recip_name;
353 /* -mrecip options. */
356 const char *string; /* option name */
357 unsigned int mask; /* mask bits to set */
358 } recip_options[] = {
359 { "all", RECIP_ALL },
360 { "none", RECIP_NONE },
361 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
363 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
364 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
365 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
366 | RECIP_V2DF_RSQRT) },
367 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
368 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
371 /* 2 argument gen function typedef. */
372 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
375 /* Target cpu costs. */
377 struct processor_costs {
378 const int mulsi; /* cost of SImode multiplication. */
379 const int mulsi_const; /* cost of SImode multiplication by constant. */
380 const int mulsi_const9; /* cost of SImode mult by short constant. */
381 const int muldi; /* cost of DImode multiplication. */
382 const int divsi; /* cost of SImode division. */
383 const int divdi; /* cost of DImode division. */
384 const int fp; /* cost of simple SFmode and DFmode insns. */
385 const int dmul; /* cost of DFmode multiplication (and fmadd). */
386 const int sdiv; /* cost of SFmode division (fdivs). */
387 const int ddiv; /* cost of DFmode division (fdiv). */
388 const int cache_line_size; /* cache line size in bytes. */
389 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
390 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
391 const int simultaneous_prefetches; /* number of parallel prefetch
395 const struct processor_costs *rs6000_cost;
397 /* Processor costs (relative to an add) */
399 /* Instruction size costs on 32bit processors. */
401 struct processor_costs size32_cost = {
402 COSTS_N_INSNS (1), /* mulsi */
403 COSTS_N_INSNS (1), /* mulsi_const */
404 COSTS_N_INSNS (1), /* mulsi_const9 */
405 COSTS_N_INSNS (1), /* muldi */
406 COSTS_N_INSNS (1), /* divsi */
407 COSTS_N_INSNS (1), /* divdi */
408 COSTS_N_INSNS (1), /* fp */
409 COSTS_N_INSNS (1), /* dmul */
410 COSTS_N_INSNS (1), /* sdiv */
411 COSTS_N_INSNS (1), /* ddiv */
418 /* Instruction size costs on 64bit processors. */
420 struct processor_costs size64_cost = {
421 COSTS_N_INSNS (1), /* mulsi */
422 COSTS_N_INSNS (1), /* mulsi_const */
423 COSTS_N_INSNS (1), /* mulsi_const9 */
424 COSTS_N_INSNS (1), /* muldi */
425 COSTS_N_INSNS (1), /* divsi */
426 COSTS_N_INSNS (1), /* divdi */
427 COSTS_N_INSNS (1), /* fp */
428 COSTS_N_INSNS (1), /* dmul */
429 COSTS_N_INSNS (1), /* sdiv */
430 COSTS_N_INSNS (1), /* ddiv */
437 /* Instruction costs on RIOS1 processors. */
439 struct processor_costs rios1_cost = {
440 COSTS_N_INSNS (5), /* mulsi */
441 COSTS_N_INSNS (4), /* mulsi_const */
442 COSTS_N_INSNS (3), /* mulsi_const9 */
443 COSTS_N_INSNS (5), /* muldi */
444 COSTS_N_INSNS (19), /* divsi */
445 COSTS_N_INSNS (19), /* divdi */
446 COSTS_N_INSNS (2), /* fp */
447 COSTS_N_INSNS (2), /* dmul */
448 COSTS_N_INSNS (19), /* sdiv */
449 COSTS_N_INSNS (19), /* ddiv */
450 128, /* cache line size */
456 /* Instruction costs on RIOS2 processors. */
458 struct processor_costs rios2_cost = {
459 COSTS_N_INSNS (2), /* mulsi */
460 COSTS_N_INSNS (2), /* mulsi_const */
461 COSTS_N_INSNS (2), /* mulsi_const9 */
462 COSTS_N_INSNS (2), /* muldi */
463 COSTS_N_INSNS (13), /* divsi */
464 COSTS_N_INSNS (13), /* divdi */
465 COSTS_N_INSNS (2), /* fp */
466 COSTS_N_INSNS (2), /* dmul */
467 COSTS_N_INSNS (17), /* sdiv */
468 COSTS_N_INSNS (17), /* ddiv */
469 256, /* cache line size */
475 /* Instruction costs on RS64A processors. */
477 struct processor_costs rs64a_cost = {
478 COSTS_N_INSNS (20), /* mulsi */
479 COSTS_N_INSNS (12), /* mulsi_const */
480 COSTS_N_INSNS (8), /* mulsi_const9 */
481 COSTS_N_INSNS (34), /* muldi */
482 COSTS_N_INSNS (65), /* divsi */
483 COSTS_N_INSNS (67), /* divdi */
484 COSTS_N_INSNS (4), /* fp */
485 COSTS_N_INSNS (4), /* dmul */
486 COSTS_N_INSNS (31), /* sdiv */
487 COSTS_N_INSNS (31), /* ddiv */
488 128, /* cache line size */
494 /* Instruction costs on MPCCORE processors. */
496 struct processor_costs mpccore_cost = {
497 COSTS_N_INSNS (2), /* mulsi */
498 COSTS_N_INSNS (2), /* mulsi_const */
499 COSTS_N_INSNS (2), /* mulsi_const9 */
500 COSTS_N_INSNS (2), /* muldi */
501 COSTS_N_INSNS (6), /* divsi */
502 COSTS_N_INSNS (6), /* divdi */
503 COSTS_N_INSNS (4), /* fp */
504 COSTS_N_INSNS (5), /* dmul */
505 COSTS_N_INSNS (10), /* sdiv */
506 COSTS_N_INSNS (17), /* ddiv */
507 32, /* cache line size */
513 /* Instruction costs on PPC403 processors. */
515 struct processor_costs ppc403_cost = {
516 COSTS_N_INSNS (4), /* mulsi */
517 COSTS_N_INSNS (4), /* mulsi_const */
518 COSTS_N_INSNS (4), /* mulsi_const9 */
519 COSTS_N_INSNS (4), /* muldi */
520 COSTS_N_INSNS (33), /* divsi */
521 COSTS_N_INSNS (33), /* divdi */
522 COSTS_N_INSNS (11), /* fp */
523 COSTS_N_INSNS (11), /* dmul */
524 COSTS_N_INSNS (11), /* sdiv */
525 COSTS_N_INSNS (11), /* ddiv */
526 32, /* cache line size */
532 /* Instruction costs on PPC405 processors. */
534 struct processor_costs ppc405_cost = {
535 COSTS_N_INSNS (5), /* mulsi */
536 COSTS_N_INSNS (4), /* mulsi_const */
537 COSTS_N_INSNS (3), /* mulsi_const9 */
538 COSTS_N_INSNS (5), /* muldi */
539 COSTS_N_INSNS (35), /* divsi */
540 COSTS_N_INSNS (35), /* divdi */
541 COSTS_N_INSNS (11), /* fp */
542 COSTS_N_INSNS (11), /* dmul */
543 COSTS_N_INSNS (11), /* sdiv */
544 COSTS_N_INSNS (11), /* ddiv */
545 32, /* cache line size */
551 /* Instruction costs on PPC440 processors. */
553 struct processor_costs ppc440_cost = {
554 COSTS_N_INSNS (3), /* mulsi */
555 COSTS_N_INSNS (2), /* mulsi_const */
556 COSTS_N_INSNS (2), /* mulsi_const9 */
557 COSTS_N_INSNS (3), /* muldi */
558 COSTS_N_INSNS (34), /* divsi */
559 COSTS_N_INSNS (34), /* divdi */
560 COSTS_N_INSNS (5), /* fp */
561 COSTS_N_INSNS (5), /* dmul */
562 COSTS_N_INSNS (19), /* sdiv */
563 COSTS_N_INSNS (33), /* ddiv */
564 32, /* cache line size */
570 /* Instruction costs on PPC476 processors. */
572 struct processor_costs ppc476_cost = {
573 COSTS_N_INSNS (4), /* mulsi */
574 COSTS_N_INSNS (4), /* mulsi_const */
575 COSTS_N_INSNS (4), /* mulsi_const9 */
576 COSTS_N_INSNS (4), /* muldi */
577 COSTS_N_INSNS (11), /* divsi */
578 COSTS_N_INSNS (11), /* divdi */
579 COSTS_N_INSNS (6), /* fp */
580 COSTS_N_INSNS (6), /* dmul */
581 COSTS_N_INSNS (19), /* sdiv */
582 COSTS_N_INSNS (33), /* ddiv */
583 32, /* l1 cache line size */
589 /* Instruction costs on PPC601 processors. */
591 struct processor_costs ppc601_cost = {
592 COSTS_N_INSNS (5), /* mulsi */
593 COSTS_N_INSNS (5), /* mulsi_const */
594 COSTS_N_INSNS (5), /* mulsi_const9 */
595 COSTS_N_INSNS (5), /* muldi */
596 COSTS_N_INSNS (36), /* divsi */
597 COSTS_N_INSNS (36), /* divdi */
598 COSTS_N_INSNS (4), /* fp */
599 COSTS_N_INSNS (5), /* dmul */
600 COSTS_N_INSNS (17), /* sdiv */
601 COSTS_N_INSNS (31), /* ddiv */
602 32, /* cache line size */
608 /* Instruction costs on PPC603 processors. */
610 struct processor_costs ppc603_cost = {
611 COSTS_N_INSNS (5), /* mulsi */
612 COSTS_N_INSNS (3), /* mulsi_const */
613 COSTS_N_INSNS (2), /* mulsi_const9 */
614 COSTS_N_INSNS (5), /* muldi */
615 COSTS_N_INSNS (37), /* divsi */
616 COSTS_N_INSNS (37), /* divdi */
617 COSTS_N_INSNS (3), /* fp */
618 COSTS_N_INSNS (4), /* dmul */
619 COSTS_N_INSNS (18), /* sdiv */
620 COSTS_N_INSNS (33), /* ddiv */
621 32, /* cache line size */
627 /* Instruction costs on PPC604 processors. */
629 struct processor_costs ppc604_cost = {
630 COSTS_N_INSNS (4), /* mulsi */
631 COSTS_N_INSNS (4), /* mulsi_const */
632 COSTS_N_INSNS (4), /* mulsi_const9 */
633 COSTS_N_INSNS (4), /* muldi */
634 COSTS_N_INSNS (20), /* divsi */
635 COSTS_N_INSNS (20), /* divdi */
636 COSTS_N_INSNS (3), /* fp */
637 COSTS_N_INSNS (3), /* dmul */
638 COSTS_N_INSNS (18), /* sdiv */
639 COSTS_N_INSNS (32), /* ddiv */
640 32, /* cache line size */
646 /* Instruction costs on PPC604e processors. */
648 struct processor_costs ppc604e_cost = {
649 COSTS_N_INSNS (2), /* mulsi */
650 COSTS_N_INSNS (2), /* mulsi_const */
651 COSTS_N_INSNS (2), /* mulsi_const9 */
652 COSTS_N_INSNS (2), /* muldi */
653 COSTS_N_INSNS (20), /* divsi */
654 COSTS_N_INSNS (20), /* divdi */
655 COSTS_N_INSNS (3), /* fp */
656 COSTS_N_INSNS (3), /* dmul */
657 COSTS_N_INSNS (18), /* sdiv */
658 COSTS_N_INSNS (32), /* ddiv */
659 32, /* cache line size */
665 /* Instruction costs on PPC620 processors. */
667 struct processor_costs ppc620_cost = {
668 COSTS_N_INSNS (5), /* mulsi */
669 COSTS_N_INSNS (4), /* mulsi_const */
670 COSTS_N_INSNS (3), /* mulsi_const9 */
671 COSTS_N_INSNS (7), /* muldi */
672 COSTS_N_INSNS (21), /* divsi */
673 COSTS_N_INSNS (37), /* divdi */
674 COSTS_N_INSNS (3), /* fp */
675 COSTS_N_INSNS (3), /* dmul */
676 COSTS_N_INSNS (18), /* sdiv */
677 COSTS_N_INSNS (32), /* ddiv */
678 128, /* cache line size */
684 /* Instruction costs on PPC630 processors. */
686 struct processor_costs ppc630_cost = {
687 COSTS_N_INSNS (5), /* mulsi */
688 COSTS_N_INSNS (4), /* mulsi_const */
689 COSTS_N_INSNS (3), /* mulsi_const9 */
690 COSTS_N_INSNS (7), /* muldi */
691 COSTS_N_INSNS (21), /* divsi */
692 COSTS_N_INSNS (37), /* divdi */
693 COSTS_N_INSNS (3), /* fp */
694 COSTS_N_INSNS (3), /* dmul */
695 COSTS_N_INSNS (17), /* sdiv */
696 COSTS_N_INSNS (21), /* ddiv */
697 128, /* cache line size */
703 /* Instruction costs on Cell processor. */
704 /* COSTS_N_INSNS (1) ~ one add. */
706 struct processor_costs ppccell_cost = {
707 COSTS_N_INSNS (9/2)+2, /* mulsi */
708 COSTS_N_INSNS (6/2), /* mulsi_const */
709 COSTS_N_INSNS (6/2), /* mulsi_const9 */
710 COSTS_N_INSNS (15/2)+2, /* muldi */
711 COSTS_N_INSNS (38/2), /* divsi */
712 COSTS_N_INSNS (70/2), /* divdi */
713 COSTS_N_INSNS (10/2), /* fp */
714 COSTS_N_INSNS (10/2), /* dmul */
715 COSTS_N_INSNS (74/2), /* sdiv */
716 COSTS_N_INSNS (74/2), /* ddiv */
717 128, /* cache line size */
723 /* Instruction costs on PPC750 and PPC7400 processors. */
725 struct processor_costs ppc750_cost = {
726 COSTS_N_INSNS (5), /* mulsi */
727 COSTS_N_INSNS (3), /* mulsi_const */
728 COSTS_N_INSNS (2), /* mulsi_const9 */
729 COSTS_N_INSNS (5), /* muldi */
730 COSTS_N_INSNS (17), /* divsi */
731 COSTS_N_INSNS (17), /* divdi */
732 COSTS_N_INSNS (3), /* fp */
733 COSTS_N_INSNS (3), /* dmul */
734 COSTS_N_INSNS (17), /* sdiv */
735 COSTS_N_INSNS (31), /* ddiv */
736 32, /* cache line size */
742 /* Instruction costs on PPC7450 processors. */
744 struct processor_costs ppc7450_cost = {
745 COSTS_N_INSNS (4), /* mulsi */
746 COSTS_N_INSNS (3), /* mulsi_const */
747 COSTS_N_INSNS (3), /* mulsi_const9 */
748 COSTS_N_INSNS (4), /* muldi */
749 COSTS_N_INSNS (23), /* divsi */
750 COSTS_N_INSNS (23), /* divdi */
751 COSTS_N_INSNS (5), /* fp */
752 COSTS_N_INSNS (5), /* dmul */
753 COSTS_N_INSNS (21), /* sdiv */
754 COSTS_N_INSNS (35), /* ddiv */
755 32, /* cache line size */
761 /* Instruction costs on PPC8540 processors. */
763 struct processor_costs ppc8540_cost = {
764 COSTS_N_INSNS (4), /* mulsi */
765 COSTS_N_INSNS (4), /* mulsi_const */
766 COSTS_N_INSNS (4), /* mulsi_const9 */
767 COSTS_N_INSNS (4), /* muldi */
768 COSTS_N_INSNS (19), /* divsi */
769 COSTS_N_INSNS (19), /* divdi */
770 COSTS_N_INSNS (4), /* fp */
771 COSTS_N_INSNS (4), /* dmul */
772 COSTS_N_INSNS (29), /* sdiv */
773 COSTS_N_INSNS (29), /* ddiv */
774 32, /* cache line size */
777 1, /* prefetch streams /*/
780 /* Instruction costs on E300C2 and E300C3 cores. */
782 struct processor_costs ppce300c2c3_cost = {
783 COSTS_N_INSNS (4), /* mulsi */
784 COSTS_N_INSNS (4), /* mulsi_const */
785 COSTS_N_INSNS (4), /* mulsi_const9 */
786 COSTS_N_INSNS (4), /* muldi */
787 COSTS_N_INSNS (19), /* divsi */
788 COSTS_N_INSNS (19), /* divdi */
789 COSTS_N_INSNS (3), /* fp */
790 COSTS_N_INSNS (4), /* dmul */
791 COSTS_N_INSNS (18), /* sdiv */
792 COSTS_N_INSNS (33), /* ddiv */
796 1, /* prefetch streams /*/
799 /* Instruction costs on PPCE500MC processors. */
801 struct processor_costs ppce500mc_cost = {
802 COSTS_N_INSNS (4), /* mulsi */
803 COSTS_N_INSNS (4), /* mulsi_const */
804 COSTS_N_INSNS (4), /* mulsi_const9 */
805 COSTS_N_INSNS (4), /* muldi */
806 COSTS_N_INSNS (14), /* divsi */
807 COSTS_N_INSNS (14), /* divdi */
808 COSTS_N_INSNS (8), /* fp */
809 COSTS_N_INSNS (10), /* dmul */
810 COSTS_N_INSNS (36), /* sdiv */
811 COSTS_N_INSNS (66), /* ddiv */
812 64, /* cache line size */
815 1, /* prefetch streams /*/
818 /* Instruction costs on PPCE500MC64 processors. */
820 struct processor_costs ppce500mc64_cost = {
821 COSTS_N_INSNS (4), /* mulsi */
822 COSTS_N_INSNS (4), /* mulsi_const */
823 COSTS_N_INSNS (4), /* mulsi_const9 */
824 COSTS_N_INSNS (4), /* muldi */
825 COSTS_N_INSNS (14), /* divsi */
826 COSTS_N_INSNS (14), /* divdi */
827 COSTS_N_INSNS (4), /* fp */
828 COSTS_N_INSNS (10), /* dmul */
829 COSTS_N_INSNS (36), /* sdiv */
830 COSTS_N_INSNS (66), /* ddiv */
831 64, /* cache line size */
834 1, /* prefetch streams /*/
837 /* Instruction costs on POWER4 and POWER5 processors. */
839 struct processor_costs power4_cost = {
840 COSTS_N_INSNS (3), /* mulsi */
841 COSTS_N_INSNS (2), /* mulsi_const */
842 COSTS_N_INSNS (2), /* mulsi_const9 */
843 COSTS_N_INSNS (4), /* muldi */
844 COSTS_N_INSNS (18), /* divsi */
845 COSTS_N_INSNS (34), /* divdi */
846 COSTS_N_INSNS (3), /* fp */
847 COSTS_N_INSNS (3), /* dmul */
848 COSTS_N_INSNS (17), /* sdiv */
849 COSTS_N_INSNS (17), /* ddiv */
850 128, /* cache line size */
853 8, /* prefetch streams /*/
856 /* Instruction costs on POWER6 processors. */
858 struct processor_costs power6_cost = {
859 COSTS_N_INSNS (8), /* mulsi */
860 COSTS_N_INSNS (8), /* mulsi_const */
861 COSTS_N_INSNS (8), /* mulsi_const9 */
862 COSTS_N_INSNS (8), /* muldi */
863 COSTS_N_INSNS (22), /* divsi */
864 COSTS_N_INSNS (28), /* divdi */
865 COSTS_N_INSNS (3), /* fp */
866 COSTS_N_INSNS (3), /* dmul */
867 COSTS_N_INSNS (13), /* sdiv */
868 COSTS_N_INSNS (16), /* ddiv */
869 128, /* cache line size */
872 16, /* prefetch streams */
875 /* Instruction costs on POWER7 processors. */
877 struct processor_costs power7_cost = {
878 COSTS_N_INSNS (2), /* mulsi */
879 COSTS_N_INSNS (2), /* mulsi_const */
880 COSTS_N_INSNS (2), /* mulsi_const9 */
881 COSTS_N_INSNS (2), /* muldi */
882 COSTS_N_INSNS (18), /* divsi */
883 COSTS_N_INSNS (34), /* divdi */
884 COSTS_N_INSNS (3), /* fp */
885 COSTS_N_INSNS (3), /* dmul */
886 COSTS_N_INSNS (13), /* sdiv */
887 COSTS_N_INSNS (16), /* ddiv */
888 128, /* cache line size */
891 12, /* prefetch streams */
894 /* Instruction costs on POWER A2 processors. */
896 struct processor_costs ppca2_cost = {
897 COSTS_N_INSNS (16), /* mulsi */
898 COSTS_N_INSNS (16), /* mulsi_const */
899 COSTS_N_INSNS (16), /* mulsi_const9 */
900 COSTS_N_INSNS (16), /* muldi */
901 COSTS_N_INSNS (22), /* divsi */
902 COSTS_N_INSNS (28), /* divdi */
903 COSTS_N_INSNS (3), /* fp */
904 COSTS_N_INSNS (3), /* dmul */
905 COSTS_N_INSNS (59), /* sdiv */
906 COSTS_N_INSNS (72), /* ddiv */
910 16, /* prefetch streams */
914 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
915 #undef RS6000_BUILTIN
916 #undef RS6000_BUILTIN_EQUATE
917 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
918 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
920 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
922 #include "rs6000-builtin.def"
925 #undef RS6000_BUILTIN
926 #undef RS6000_BUILTIN_EQUATE
929 static bool rs6000_function_ok_for_sibcall (tree, tree);
930 static const char *rs6000_invalid_within_doloop (const_rtx);
931 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
932 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
933 static rtx rs6000_generate_compare (rtx, enum machine_mode);
934 static void rs6000_emit_stack_tie (void);
935 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
936 static bool spe_func_has_64bit_regs_p (void);
937 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
939 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
940 static unsigned rs6000_hash_constant (rtx);
941 static unsigned toc_hash_function (const void *);
942 static int toc_hash_eq (const void *, const void *);
943 static bool reg_offset_addressing_ok_p (enum machine_mode);
944 static bool virtual_stack_registers_memory_p (rtx);
945 static bool constant_pool_expr_p (rtx);
946 static bool legitimate_small_data_p (enum machine_mode, rtx);
947 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
948 static struct machine_function * rs6000_init_machine_status (void);
949 static bool rs6000_assemble_integer (rtx, unsigned int, int);
950 static bool no_global_regs_above (int, bool);
951 #ifdef HAVE_GAS_HIDDEN
952 static void rs6000_assemble_visibility (tree, int);
954 static int rs6000_ra_ever_killed (void);
955 static bool rs6000_attribute_takes_identifier_p (const_tree);
956 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
957 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
958 static bool rs6000_ms_bitfield_layout_p (const_tree);
959 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
960 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
961 static const char *rs6000_mangle_type (const_tree);
962 static void rs6000_set_default_type_attributes (tree);
963 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
964 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
965 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
966 enum machine_mode, bool, bool, bool);
967 static bool rs6000_reg_live_or_pic_offset_p (int);
968 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
969 static int rs6000_savres_strategy (rs6000_stack_t *, bool, int, int);
970 static void rs6000_restore_saved_cr (rtx, int);
971 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
972 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
973 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
975 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
976 static bool rs6000_return_in_memory (const_tree, const_tree);
977 static rtx rs6000_function_value (const_tree, const_tree, bool);
978 static void rs6000_file_start (void);
980 static int rs6000_elf_reloc_rw_mask (void);
981 static void rs6000_elf_asm_out_constructor (rtx, int);
982 static void rs6000_elf_asm_out_destructor (rtx, int);
983 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
984 static void rs6000_elf_asm_init_sections (void);
985 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
986 unsigned HOST_WIDE_INT);
987 static void rs6000_elf_encode_section_info (tree, rtx, int)
990 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
991 static void rs6000_alloc_sdmode_stack_slot (void);
992 static void rs6000_instantiate_decls (void);
994 static void rs6000_xcoff_asm_output_anchor (rtx);
995 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
996 static void rs6000_xcoff_asm_init_sections (void);
997 static int rs6000_xcoff_reloc_rw_mask (void);
998 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
999 static section *rs6000_xcoff_select_section (tree, int,
1000 unsigned HOST_WIDE_INT);
1001 static void rs6000_xcoff_unique_section (tree, int);
1002 static section *rs6000_xcoff_select_rtx_section
1003 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1004 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1005 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1006 static void rs6000_xcoff_file_start (void);
1007 static void rs6000_xcoff_file_end (void);
1009 static int rs6000_variable_issue (FILE *, int, rtx, int);
1010 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1011 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1012 static int rs6000_debug_address_cost (rtx, bool);
1013 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1014 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1015 static void rs6000_sched_init (FILE *, int, int);
1016 static bool is_microcoded_insn (rtx);
1017 static bool is_nonpipeline_insn (rtx);
1018 static bool is_cracked_insn (rtx);
1019 static bool is_branch_slot_insn (rtx);
1020 static bool is_load_insn (rtx);
1021 static rtx get_store_dest (rtx pat);
1022 static bool is_store_insn (rtx);
1023 static bool set_to_load_agen (rtx,rtx);
1024 static bool adjacent_mem_locations (rtx,rtx);
1025 static int rs6000_adjust_priority (rtx, int);
1026 static int rs6000_issue_rate (void);
1027 static bool rs6000_is_costly_dependence (dep_t, int, int);
1028 static rtx get_next_active_insn (rtx, rtx);
1029 static bool insn_terminates_group_p (rtx , enum group_termination);
1030 static bool insn_must_be_first_in_group (rtx);
1031 static bool insn_must_be_last_in_group (rtx);
1032 static bool is_costly_group (rtx *, rtx);
1033 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1034 static int redefine_groups (FILE *, int, rtx, rtx);
1035 static int pad_groups (FILE *, int, rtx, rtx);
1036 static void rs6000_sched_finish (FILE *, int);
1037 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1038 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1039 static int rs6000_use_sched_lookahead (void);
1040 static int rs6000_use_sched_lookahead_guard (rtx);
1041 static void * rs6000_alloc_sched_context (void);
1042 static void rs6000_init_sched_context (void *, bool);
1043 static void rs6000_set_sched_context (void *);
1044 static void rs6000_free_sched_context (void *);
1045 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1046 static tree rs6000_builtin_mask_for_load (void);
1047 static tree rs6000_builtin_mul_widen_even (tree);
1048 static tree rs6000_builtin_mul_widen_odd (tree);
1049 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1050 static tree rs6000_builtin_vec_perm (tree, tree *);
1051 static bool rs6000_builtin_support_vector_misalignment (enum
1056 static void def_builtin (int, const char *, tree, int);
1057 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1058 static void rs6000_init_builtins (void);
1059 static tree rs6000_builtin_decl (unsigned, bool);
1061 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1062 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1063 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1064 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1065 static void altivec_init_builtins (void);
1066 static unsigned builtin_hash_function (const void *);
1067 static int builtin_hash_eq (const void *, const void *);
1068 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1069 enum machine_mode, enum machine_mode,
1070 enum rs6000_builtins, const char *name);
1071 static void rs6000_common_init_builtins (void);
1072 static void rs6000_init_libfuncs (void);
1074 static void paired_init_builtins (void);
1075 static rtx paired_expand_builtin (tree, rtx, bool *);
1076 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1077 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1078 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1080 static void enable_mask_for_builtins (struct builtin_description *, int,
1081 enum rs6000_builtins,
1082 enum rs6000_builtins);
1083 static void spe_init_builtins (void);
1084 static rtx spe_expand_builtin (tree, rtx, bool *);
1085 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1086 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1087 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1088 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1089 static rs6000_stack_t *rs6000_stack_info (void);
1090 static void debug_stack_info (rs6000_stack_t *);
1092 static rtx altivec_expand_builtin (tree, rtx, bool *);
1093 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1094 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1095 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1096 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1097 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1098 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1099 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1100 static rtx altivec_expand_vec_set_builtin (tree);
1101 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1102 static int get_element_number (tree, tree);
1103 static bool rs6000_handle_option (size_t, const char *, int);
1104 static void rs6000_parse_tls_size_option (void);
1105 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1106 static int first_altivec_reg_to_save (void);
1107 static unsigned int compute_vrsave_mask (void);
1108 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1109 static void is_altivec_return_reg (rtx, void *);
1110 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1111 int easy_vector_constant (rtx, enum machine_mode);
1112 static rtx rs6000_dwarf_register_span (rtx);
1113 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1114 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1115 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1116 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1117 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1118 static rtx rs6000_delegitimize_address (rtx);
1119 static rtx rs6000_tls_get_addr (void);
1120 static rtx rs6000_got_sym (void);
1121 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1122 static const char *rs6000_get_some_local_dynamic_name (void);
1123 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1124 static rtx rs6000_complex_function_value (enum machine_mode);
1125 static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
1126 enum machine_mode, tree);
1127 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1129 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1130 tree, HOST_WIDE_INT);
1131 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1134 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1135 const_tree, HOST_WIDE_INT,
1137 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
1138 static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
1139 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1140 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1141 enum machine_mode, tree,
1143 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1145 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1147 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1149 static void macho_branch_islands (void);
1150 static int no_previous_def (tree function_name);
1151 static tree get_prev_label (tree function_name);
1152 static void rs6000_darwin_file_start (void);
1155 static tree rs6000_build_builtin_va_list (void);
1156 static void rs6000_va_start (tree, rtx);
1157 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1158 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1159 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1160 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1161 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1162 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1164 static tree rs6000_stack_protect_fail (void);
1166 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1169 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1172 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1174 = rs6000_legitimize_reload_address;
1176 static bool rs6000_mode_dependent_address_p (const_rtx);
1177 static bool rs6000_mode_dependent_address (const_rtx);
1178 static bool rs6000_debug_mode_dependent_address (const_rtx);
1179 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1180 = rs6000_mode_dependent_address;
1182 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1183 enum machine_mode, rtx);
1184 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1187 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1188 enum machine_mode, rtx)
1189 = rs6000_secondary_reload_class;
1191 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1192 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1194 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1195 = rs6000_preferred_reload_class;
1197 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1200 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1204 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1206 = rs6000_secondary_memory_needed;
1208 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1211 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1215 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1218 = rs6000_cannot_change_mode_class;
1220 static enum reg_class rs6000_secondary_reload (bool, rtx, enum reg_class,
1222 struct secondary_reload_info *);
1224 static const enum reg_class *rs6000_ira_cover_classes (void);
1226 const int INSN_NOT_AVAILABLE = -1;
1227 static enum machine_mode rs6000_eh_return_filter_mode (void);
1228 static bool rs6000_can_eliminate (const int, const int);
1229 static void rs6000_trampoline_init (rtx, tree, rtx);
1231 /* Hash table stuff for keeping track of TOC entries. */
1233 struct GTY(()) toc_hash_struct
1235 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1236 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1238 enum machine_mode key_mode;
1242 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1244 /* Hash table to keep track of the argument types for builtin functions. */
1246 struct GTY(()) builtin_hash_struct
1249 enum machine_mode mode[4]; /* return value + 3 arguments. */
1250 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1253 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1255 /* Default register names. */
1256 char rs6000_reg_names[][8] =
1258 "0", "1", "2", "3", "4", "5", "6", "7",
1259 "8", "9", "10", "11", "12", "13", "14", "15",
1260 "16", "17", "18", "19", "20", "21", "22", "23",
1261 "24", "25", "26", "27", "28", "29", "30", "31",
1262 "0", "1", "2", "3", "4", "5", "6", "7",
1263 "8", "9", "10", "11", "12", "13", "14", "15",
1264 "16", "17", "18", "19", "20", "21", "22", "23",
1265 "24", "25", "26", "27", "28", "29", "30", "31",
1266 "mq", "lr", "ctr","ap",
1267 "0", "1", "2", "3", "4", "5", "6", "7",
1269 /* AltiVec registers. */
1270 "0", "1", "2", "3", "4", "5", "6", "7",
1271 "8", "9", "10", "11", "12", "13", "14", "15",
1272 "16", "17", "18", "19", "20", "21", "22", "23",
1273 "24", "25", "26", "27", "28", "29", "30", "31",
1275 /* SPE registers. */
1276 "spe_acc", "spefscr",
1277 /* Soft frame pointer. */
1281 #ifdef TARGET_REGNAMES
1282 static const char alt_reg_names[][8] =
1284 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1285 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1286 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1287 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1288 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1289 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1290 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1291 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1292 "mq", "lr", "ctr", "ap",
1293 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1295 /* AltiVec registers. */
1296 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1297 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1298 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1299 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1301 /* SPE registers. */
1302 "spe_acc", "spefscr",
1303 /* Soft frame pointer. */
1308 /* Table of valid machine attributes. */
1310 static const struct attribute_spec rs6000_attribute_table[] =
1312 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1313 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1314 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1315 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1316 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1317 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1318 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1319 SUBTARGET_ATTRIBUTE_TABLE,
1321 { NULL, 0, 0, false, false, false, NULL }
1324 #ifndef MASK_STRICT_ALIGN
1325 #define MASK_STRICT_ALIGN 0
1327 #ifndef TARGET_PROFILE_KERNEL
1328 #define TARGET_PROFILE_KERNEL 0
1331 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1332 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1334 /* Initialize the GCC target structure. */
1335 #undef TARGET_ATTRIBUTE_TABLE
1336 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1337 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1338 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1339 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1340 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1342 #undef TARGET_ASM_ALIGNED_DI_OP
1343 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1345 /* Default unaligned ops are only provided for ELF. Find the ops needed
1346 for non-ELF systems. */
1347 #ifndef OBJECT_FORMAT_ELF
1349 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1351 #undef TARGET_ASM_UNALIGNED_HI_OP
1352 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1353 #undef TARGET_ASM_UNALIGNED_SI_OP
1354 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1355 #undef TARGET_ASM_UNALIGNED_DI_OP
1356 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1359 #undef TARGET_ASM_UNALIGNED_HI_OP
1360 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1361 #undef TARGET_ASM_UNALIGNED_SI_OP
1362 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1363 #undef TARGET_ASM_UNALIGNED_DI_OP
1364 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1365 #undef TARGET_ASM_ALIGNED_DI_OP
1366 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1370 /* This hook deals with fixups for relocatable code and DI-mode objects
1372 #undef TARGET_ASM_INTEGER
1373 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1375 #ifdef HAVE_GAS_HIDDEN
1376 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1377 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1380 #undef TARGET_HAVE_TLS
1381 #define TARGET_HAVE_TLS HAVE_AS_TLS
1383 #undef TARGET_CANNOT_FORCE_CONST_MEM
1384 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1386 #undef TARGET_DELEGITIMIZE_ADDRESS
1387 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1389 #undef TARGET_ASM_FUNCTION_PROLOGUE
1390 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1391 #undef TARGET_ASM_FUNCTION_EPILOGUE
1392 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1394 #undef TARGET_LEGITIMIZE_ADDRESS
1395 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1397 #undef TARGET_SCHED_VARIABLE_ISSUE
1398 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1400 #undef TARGET_SCHED_ISSUE_RATE
1401 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1402 #undef TARGET_SCHED_ADJUST_COST
1403 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1404 #undef TARGET_SCHED_ADJUST_PRIORITY
1405 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1406 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1407 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1408 #undef TARGET_SCHED_INIT
1409 #define TARGET_SCHED_INIT rs6000_sched_init
1410 #undef TARGET_SCHED_FINISH
1411 #define TARGET_SCHED_FINISH rs6000_sched_finish
1412 #undef TARGET_SCHED_REORDER
1413 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1414 #undef TARGET_SCHED_REORDER2
1415 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1417 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1418 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1420 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1421 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1423 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1424 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1425 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1426 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1427 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1428 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1429 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1430 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1432 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1433 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1434 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1435 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1436 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1437 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1438 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1439 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1440 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1441 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1442 #undef TARGET_SUPPORT_VECTOR_MISALIGNMENT
1443 #define TARGET_SUPPORT_VECTOR_MISALIGNMENT \
1444 rs6000_builtin_support_vector_misalignment
1445 #undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1446 #define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1448 #undef TARGET_INIT_BUILTINS
1449 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1450 #undef TARGET_BUILTIN_DECL
1451 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1453 #undef TARGET_EXPAND_BUILTIN
1454 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1456 #undef TARGET_MANGLE_TYPE
1457 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1459 #undef TARGET_INIT_LIBFUNCS
1460 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1463 #undef TARGET_BINDS_LOCAL_P
1464 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1467 #undef TARGET_MS_BITFIELD_LAYOUT_P
1468 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1470 #undef TARGET_ASM_OUTPUT_MI_THUNK
1471 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1473 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1474 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1476 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1477 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1479 #undef TARGET_INVALID_WITHIN_DOLOOP
1480 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1482 #undef TARGET_RTX_COSTS
1483 #define TARGET_RTX_COSTS rs6000_rtx_costs
1484 #undef TARGET_ADDRESS_COST
1485 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1487 #undef TARGET_DWARF_REGISTER_SPAN
1488 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1490 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1491 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1493 /* On rs6000, function arguments are promoted, as are function return
1495 #undef TARGET_PROMOTE_FUNCTION_MODE
1496 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1498 #undef TARGET_RETURN_IN_MEMORY
1499 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1501 #undef TARGET_SETUP_INCOMING_VARARGS
1502 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1504 /* Always strict argument naming on rs6000. */
1505 #undef TARGET_STRICT_ARGUMENT_NAMING
1506 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1507 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1508 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1509 #undef TARGET_SPLIT_COMPLEX_ARG
1510 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1511 #undef TARGET_MUST_PASS_IN_STACK
1512 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1513 #undef TARGET_PASS_BY_REFERENCE
1514 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1515 #undef TARGET_ARG_PARTIAL_BYTES
1516 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1518 #undef TARGET_BUILD_BUILTIN_VA_LIST
1519 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1521 #undef TARGET_EXPAND_BUILTIN_VA_START
1522 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1524 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1525 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1527 #undef TARGET_EH_RETURN_FILTER_MODE
1528 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1530 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1531 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1533 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1534 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1536 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1537 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1539 #undef TARGET_HANDLE_OPTION
1540 #define TARGET_HANDLE_OPTION rs6000_handle_option
1542 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1543 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1544 rs6000_builtin_vectorized_function
1546 #undef TARGET_DEFAULT_TARGET_FLAGS
1547 #define TARGET_DEFAULT_TARGET_FLAGS \
1550 #undef TARGET_STACK_PROTECT_FAIL
1551 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1553 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1554 The PowerPC architecture requires only weak consistency among
1555 processors--that is, memory accesses between processors need not be
1556 sequentially consistent and memory accesses among processors can occur
1557 in any order. The ability to order memory accesses weakly provides
1558 opportunities for more efficient use of the system bus. Unless a
1559 dependency exists, the 604e allows read operations to precede store
1561 #undef TARGET_RELAXED_ORDERING
1562 #define TARGET_RELAXED_ORDERING true
1565 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1566 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1569 /* Use a 32-bit anchor range. This leads to sequences like:
1571 addis tmp,anchor,high
1574 where tmp itself acts as an anchor, and can be shared between
1575 accesses to the same 64k page. */
1576 #undef TARGET_MIN_ANCHOR_OFFSET
1577 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1578 #undef TARGET_MAX_ANCHOR_OFFSET
1579 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1580 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1581 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1583 #undef TARGET_BUILTIN_RECIPROCAL
1584 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1586 #undef TARGET_EXPAND_TO_RTL_HOOK
1587 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1589 #undef TARGET_INSTANTIATE_DECLS
1590 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1592 #undef TARGET_SECONDARY_RELOAD
1593 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1595 #undef TARGET_IRA_COVER_CLASSES
1596 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1598 #undef TARGET_LEGITIMATE_ADDRESS_P
1599 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1601 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1602 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1604 #undef TARGET_CAN_ELIMINATE
1605 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1607 #undef TARGET_TRAMPOLINE_INIT
1608 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1610 #undef TARGET_FUNCTION_VALUE
1611 #define TARGET_FUNCTION_VALUE rs6000_function_value
1613 struct gcc_target targetm = TARGET_INITIALIZER;
1615 /* Return number of consecutive hard regs needed starting at reg REGNO
1616 to hold something of mode MODE.
1617 This is ordinarily the length in words of a value of mode MODE
1618 but can be less for certain modes in special long registers.
1620 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1621 scalar instructions. The upper 32 bits are only available to the
1624 POWER and PowerPC GPRs hold 32 bits worth;
1625 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1628 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1630 unsigned HOST_WIDE_INT reg_size;
1632 if (FP_REGNO_P (regno))
1633 reg_size = (VECTOR_MEM_VSX_P (mode)
1634 ? UNITS_PER_VSX_WORD
1635 : UNITS_PER_FP_WORD);
1637 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1638 reg_size = UNITS_PER_SPE_WORD;
1640 else if (ALTIVEC_REGNO_P (regno))
1641 reg_size = UNITS_PER_ALTIVEC_WORD;
1643 /* The value returned for SCmode in the E500 double case is 2 for
1644 ABI compatibility; storing an SCmode value in a single register
1645 would require function_arg and rs6000_spe_function_arg to handle
1646 SCmode so as to pass the value correctly in a pair of
1648 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1649 && !DECIMAL_FLOAT_MODE_P (mode))
1650 reg_size = UNITS_PER_FP_WORD;
1653 reg_size = UNITS_PER_WORD;
1655 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1658 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1661 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1663 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1665 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1666 implementations. Don't allow an item to be split between a FP register
1667 and an Altivec register. */
1668 if (VECTOR_MEM_VSX_P (mode))
1670 if (FP_REGNO_P (regno))
1671 return FP_REGNO_P (last_regno);
1673 if (ALTIVEC_REGNO_P (regno))
1674 return ALTIVEC_REGNO_P (last_regno);
1677 /* The GPRs can hold any mode, but values bigger than one register
1678 cannot go past R31. */
1679 if (INT_REGNO_P (regno))
1680 return INT_REGNO_P (last_regno);
1682 /* The float registers (except for VSX vector modes) can only hold floating
1683 modes and DImode. This excludes the 32-bit decimal float mode for
1685 if (FP_REGNO_P (regno))
1687 if (SCALAR_FLOAT_MODE_P (mode)
1688 && (mode != TDmode || (regno % 2) == 0)
1689 && FP_REGNO_P (last_regno))
1692 if (GET_MODE_CLASS (mode) == MODE_INT
1693 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1696 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1697 && PAIRED_VECTOR_MODE (mode))
1703 /* The CR register can only hold CC modes. */
1704 if (CR_REGNO_P (regno))
1705 return GET_MODE_CLASS (mode) == MODE_CC;
1707 if (CA_REGNO_P (regno))
1708 return mode == BImode;
1710 /* AltiVec only in AldyVec registers. */
1711 if (ALTIVEC_REGNO_P (regno))
1712 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1714 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1715 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1718 /* We cannot put TImode anywhere except general register and it must be able
1719 to fit within the register set. In the future, allow TImode in the
1720 Altivec or VSX registers. */
1722 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1725 /* Print interesting facts about registers. */
1727 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1731 for (r = first_regno; r <= last_regno; ++r)
1733 const char *comma = "";
1736 if (first_regno == last_regno)
1737 fprintf (stderr, "%s:\t", reg_name);
1739 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1742 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1743 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1747 fprintf (stderr, ",\n\t");
1752 if (rs6000_hard_regno_nregs[m][r] > 1)
1753 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1754 rs6000_hard_regno_nregs[m][r]);
1756 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1761 if (call_used_regs[r])
1765 fprintf (stderr, ",\n\t");
1770 len += fprintf (stderr, "%s%s", comma, "call-used");
1778 fprintf (stderr, ",\n\t");
1783 len += fprintf (stderr, "%s%s", comma, "fixed");
1789 fprintf (stderr, ",\n\t");
1793 fprintf (stderr, "%sregno = %d\n", comma, r);
1797 /* Print various interesting information with -mdebug=reg. */
1799 rs6000_debug_reg_global (void)
1801 const char *nl = (const char *)0;
1803 char costly_num[20];
1805 const char *costly_str;
1806 const char *nop_str;
1808 /* Map enum rs6000_vector to string. */
1809 static const char *rs6000_debug_vector_unit[] = {
1818 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1819 LAST_VIRTUAL_REGISTER);
1820 rs6000_debug_reg_print (0, 31, "gr");
1821 rs6000_debug_reg_print (32, 63, "fp");
1822 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1825 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1826 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1827 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1828 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1829 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1830 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1831 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1832 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1833 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1837 "d reg_class = %s\n"
1838 "f reg_class = %s\n"
1839 "v reg_class = %s\n"
1840 "wa reg_class = %s\n"
1841 "wd reg_class = %s\n"
1842 "wf reg_class = %s\n"
1843 "ws reg_class = %s\n\n",
1844 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1845 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1846 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1847 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1848 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1849 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1850 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1852 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1853 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1856 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1858 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1859 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1865 if (rs6000_recip_control)
1867 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1869 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1870 if (rs6000_recip_bits[m])
1873 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1875 (RS6000_RECIP_AUTO_RE_P (m)
1877 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1878 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1880 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1883 fputs ("\n", stderr);
1886 switch (rs6000_sched_costly_dep)
1888 case max_dep_latency:
1889 costly_str = "max_dep_latency";
1893 costly_str = "no_dep_costly";
1896 case all_deps_costly:
1897 costly_str = "all_deps_costly";
1900 case true_store_to_load_dep_costly:
1901 costly_str = "true_store_to_load_dep_costly";
1904 case store_to_load_dep_costly:
1905 costly_str = "store_to_load_dep_costly";
1909 costly_str = costly_num;
1910 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
1914 switch (rs6000_sched_insert_nops)
1916 case sched_finish_regroup_exact:
1917 nop_str = "sched_finish_regroup_exact";
1920 case sched_finish_pad_groups:
1921 nop_str = "sched_finish_pad_groups";
1924 case sched_finish_none:
1925 nop_str = "sched_finish_none";
1930 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
1935 "always_hint = %s\n"
1936 "align_branch_targets = %s\n"
1937 "sched_restricted_insns_priority = %d\n"
1938 "sched_costly_dep = %s\n"
1939 "sched_insert_nops = %s\n\n",
1940 rs6000_always_hint ? "true" : "false",
1941 rs6000_align_branch_targets ? "true" : "false",
1942 (int)rs6000_sched_restricted_insns_priority,
1943 costly_str, nop_str);
1946 /* Initialize the various global tables that are based on register size. */
1948 rs6000_init_hard_regno_mode_ok (void)
1954 /* Precalculate REGNO_REG_CLASS. */
1955 rs6000_regno_regclass[0] = GENERAL_REGS;
1956 for (r = 1; r < 32; ++r)
1957 rs6000_regno_regclass[r] = BASE_REGS;
1959 for (r = 32; r < 64; ++r)
1960 rs6000_regno_regclass[r] = FLOAT_REGS;
1962 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
1963 rs6000_regno_regclass[r] = NO_REGS;
1965 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
1966 rs6000_regno_regclass[r] = ALTIVEC_REGS;
1968 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
1969 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
1970 rs6000_regno_regclass[r] = CR_REGS;
1972 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
1973 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
1974 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
1975 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
1976 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
1977 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
1978 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
1979 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
1980 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
1981 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
1983 /* Precalculate vector information, this must be set up before the
1984 rs6000_hard_regno_nregs_internal below. */
1985 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1987 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
1988 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
1989 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
1992 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
1993 rs6000_constraints[c] = NO_REGS;
1995 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
1996 believes it can use native alignment or still uses 128-bit alignment. */
1997 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2008 /* V2DF mode, VSX only. */
2011 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2012 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2013 rs6000_vector_align[V2DFmode] = align64;
2016 /* V4SF mode, either VSX or Altivec. */
2019 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2020 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2021 rs6000_vector_align[V4SFmode] = align32;
2023 else if (TARGET_ALTIVEC)
2025 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2026 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2027 rs6000_vector_align[V4SFmode] = align32;
2030 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2034 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2035 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2036 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2037 rs6000_vector_align[V4SImode] = align32;
2038 rs6000_vector_align[V8HImode] = align32;
2039 rs6000_vector_align[V16QImode] = align32;
2043 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2044 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2045 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2049 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2050 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2051 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2055 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2056 Altivec doesn't have 64-bit support. */
2059 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2060 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2061 rs6000_vector_align[V2DImode] = align64;
2064 /* DFmode, see if we want to use the VSX unit. */
2065 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2067 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2068 rs6000_vector_mem[DFmode]
2069 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2070 rs6000_vector_align[DFmode] = align64;
2073 /* TODO add SPE and paired floating point vector support. */
2075 /* Register class constaints for the constraints that depend on compile
2077 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2078 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2080 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2081 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2085 /* At present, we just use VSX_REGS, but we have different constraints
2086 based on the use, in case we want to fine tune the default register
2087 class used. wa = any VSX register, wf = register class to use for
2088 V4SF, wd = register class to use for V2DF, and ws = register classs to
2089 use for DF scalars. */
2090 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2091 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2092 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2093 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2099 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2101 /* Set up the reload helper functions. */
2102 if (TARGET_VSX || TARGET_ALTIVEC)
2106 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2107 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2108 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2109 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2110 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2111 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2112 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2113 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2114 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2115 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2116 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2117 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2121 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2122 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2123 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2124 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2125 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2126 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2127 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2128 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2129 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2130 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2131 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2132 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2136 /* Precalculate HARD_REGNO_NREGS. */
2137 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2138 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2139 rs6000_hard_regno_nregs[m][r]
2140 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2142 /* Precalculate HARD_REGNO_MODE_OK. */
2143 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2144 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2145 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2146 rs6000_hard_regno_mode_ok_p[m][r] = true;
2148 /* Precalculate CLASS_MAX_NREGS sizes. */
2149 for (c = 0; c < LIM_REG_CLASSES; ++c)
2153 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2154 reg_size = UNITS_PER_VSX_WORD;
2156 else if (c == ALTIVEC_REGS)
2157 reg_size = UNITS_PER_ALTIVEC_WORD;
2159 else if (c == FLOAT_REGS)
2160 reg_size = UNITS_PER_FP_WORD;
2163 reg_size = UNITS_PER_WORD;
2165 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2166 rs6000_class_max_nregs[m][c]
2167 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2170 if (TARGET_E500_DOUBLE)
2171 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2173 /* Calculate which modes to automatically generate code to use a the
2174 reciprocal divide and square root instructions. In the future, possibly
2175 automatically generate the instructions even if the user did not specify
2176 -mrecip. The older machines double precision reciprocal sqrt estimate is
2177 not accurate enough. */
2178 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2180 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2182 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2183 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2184 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2185 if (VECTOR_UNIT_VSX_P (V2DFmode))
2186 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2188 if (TARGET_FRSQRTES)
2189 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2191 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2192 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2193 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2194 if (VECTOR_UNIT_VSX_P (V2DFmode))
2195 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2197 if (rs6000_recip_control)
2199 if (!TARGET_FUSED_MADD)
2200 warning (0, "-mrecip requires -mfused-madd");
2201 if (!flag_finite_math_only)
2202 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2203 if (flag_trapping_math)
2204 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2205 if (!flag_reciprocal_math)
2206 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2207 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2208 && flag_reciprocal_math)
2210 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2211 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2212 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2214 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2215 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2216 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2218 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2219 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2220 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2222 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2223 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2224 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2226 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2227 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2228 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2230 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2231 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2232 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2234 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2235 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2236 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2238 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2239 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2240 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2244 if (TARGET_DEBUG_REG)
2245 rs6000_debug_reg_global ();
2247 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2249 "SImode variable mult cost = %d\n"
2250 "SImode constant mult cost = %d\n"
2251 "SImode short constant mult cost = %d\n"
2252 "DImode multipliciation cost = %d\n"
2253 "SImode division cost = %d\n"
2254 "DImode division cost = %d\n"
2255 "Simple fp operation cost = %d\n"
2256 "DFmode multiplication cost = %d\n"
2257 "SFmode division cost = %d\n"
2258 "DFmode division cost = %d\n"
2259 "cache line size = %d\n"
2260 "l1 cache size = %d\n"
2261 "l2 cache size = %d\n"
2262 "simultaneous prefetches = %d\n"
2265 rs6000_cost->mulsi_const,
2266 rs6000_cost->mulsi_const9,
2274 rs6000_cost->cache_line_size,
2275 rs6000_cost->l1_cache_size,
2276 rs6000_cost->l2_cache_size,
2277 rs6000_cost->simultaneous_prefetches);
2281 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2284 darwin_rs6000_override_options (void)
2286 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2288 rs6000_altivec_abi = 1;
2289 TARGET_ALTIVEC_VRSAVE = 1;
2290 if (DEFAULT_ABI == ABI_DARWIN)
2292 if (MACHO_DYNAMIC_NO_PIC_P)
2295 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
2298 else if (flag_pic == 1)
2303 if (TARGET_64BIT && ! TARGET_POWERPC64)
2305 target_flags |= MASK_POWERPC64;
2306 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2310 rs6000_default_long_calls = 1;
2311 target_flags |= MASK_SOFT_FLOAT;
2314 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2316 if (!flag_mkernel && !flag_apple_kext
2318 && ! (target_flags_explicit & MASK_ALTIVEC))
2319 target_flags |= MASK_ALTIVEC;
2321 /* Unless the user (not the configurer) has explicitly overridden
2322 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2323 G4 unless targetting the kernel. */
2326 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2327 && ! (target_flags_explicit & MASK_ALTIVEC)
2328 && ! rs6000_select[1].string)
2330 target_flags |= MASK_ALTIVEC;
2335 /* If not otherwise specified by a target, make 'long double' equivalent to
2338 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2339 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2342 /* Override command line options. Mostly we process the processor
2343 type and sometimes adjust other TARGET_ options. */
2346 rs6000_override_options (const char *default_cpu)
2349 struct rs6000_cpu_select *ptr;
2352 /* Simplifications for entries below. */
2355 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2356 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2359 /* This table occasionally claims that a processor does not support
2360 a particular feature even though it does, but the feature is slower
2361 than the alternative. Thus, it shouldn't be relied on as a
2362 complete description of the processor's support.
2364 Please keep this list in order, and don't forget to update the
2365 documentation in invoke.texi when adding a new processor or
2369 const char *const name; /* Canonical processor name. */
2370 const enum processor_type processor; /* Processor type enum value. */
2371 const int target_enable; /* Target flags to enable. */
2372 } const processor_target_table[]
2373 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2374 {"403", PROCESSOR_PPC403,
2375 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2376 {"405", PROCESSOR_PPC405,
2377 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2378 {"405fp", PROCESSOR_PPC405,
2379 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2380 {"440", PROCESSOR_PPC440,
2381 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2382 {"440fp", PROCESSOR_PPC440,
2383 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2384 {"464", PROCESSOR_PPC440,
2385 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2386 {"464fp", PROCESSOR_PPC440,
2387 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2388 {"476", PROCESSOR_PPC476,
2389 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2390 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2391 {"476fp", PROCESSOR_PPC476,
2392 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2393 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2394 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2395 {"601", PROCESSOR_PPC601,
2396 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2397 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2398 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2399 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2400 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2401 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2402 {"620", PROCESSOR_PPC620,
2403 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2404 {"630", PROCESSOR_PPC630,
2405 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2406 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2407 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2408 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2409 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2410 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2411 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2412 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2413 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2415 /* 8548 has a dummy entry for now. */
2416 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2418 {"a2", PROCESSOR_PPCA2,
2419 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2420 | MASK_CMPB | MASK_NO_UPDATE },
2421 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2422 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2423 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2425 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2426 | MASK_PPC_GFXOPT | MASK_ISEL},
2427 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2428 {"970", PROCESSOR_POWER4,
2429 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2430 {"cell", PROCESSOR_CELL,
2431 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2432 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2433 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2434 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2435 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2436 {"G5", PROCESSOR_POWER4,
2437 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2438 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2439 {"power2", PROCESSOR_POWER,
2440 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2441 {"power3", PROCESSOR_PPC630,
2442 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2443 {"power4", PROCESSOR_POWER4,
2444 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2446 {"power5", PROCESSOR_POWER5,
2447 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2448 | MASK_MFCRF | MASK_POPCNTB},
2449 {"power5+", PROCESSOR_POWER5,
2450 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2451 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2452 {"power6", PROCESSOR_POWER6,
2453 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2454 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2455 | MASK_RECIP_PRECISION},
2456 {"power6x", PROCESSOR_POWER6,
2457 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2458 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2459 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2460 {"power7", PROCESSOR_POWER7,
2461 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2462 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2463 | MASK_VSX| MASK_RECIP_PRECISION}, /* Don't add MASK_ISEL by default */
2464 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2465 {"powerpc64", PROCESSOR_POWERPC64,
2466 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2467 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2468 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2469 {"rios2", PROCESSOR_RIOS2,
2470 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2471 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2472 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2473 {"rs64", PROCESSOR_RS64A,
2474 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2477 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2479 /* Some OSs don't support saving the high part of 64-bit registers on
2480 context switch. Other OSs don't support saving Altivec registers.
2481 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2482 settings; if the user wants either, the user must explicitly specify
2483 them and we won't interfere with the user's specification. */
2486 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2487 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2488 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2489 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2490 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2491 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2492 | MASK_RECIP_PRECISION)
2495 /* Masks for instructions set at various powerpc ISAs. */
2497 ISA_2_1_MASKS = MASK_MFCRF,
2498 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2500 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and
2501 don't add ALTIVEC, since in general it isn't a win on power6. */
2502 ISA_2_5_MASKS = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2505 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2506 altivec is a win so enable it. */
2507 ISA_2_6_MASKS = (ISA_2_5_MASKS | MASK_ALTIVEC | MASK_POPCNTD
2508 | MASK_VSX | MASK_RECIP_PRECISION)
2511 /* Numerous experiment shows that IRA based loop pressure
2512 calculation works better for RTL loop invariant motion on targets
2513 with enough (>= 32) registers. It is an expensive optimization.
2514 So it is on only for peak performance. */
2516 flag_ira_loop_pressure = 1;
2518 /* Set the pointer size. */
2521 rs6000_pmode = (int)DImode;
2522 rs6000_pointer_size = 64;
2526 rs6000_pmode = (int)SImode;
2527 rs6000_pointer_size = 32;
2530 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2531 #ifdef OS_MISSING_POWERPC64
2532 if (OS_MISSING_POWERPC64)
2533 set_masks &= ~MASK_POWERPC64;
2535 #ifdef OS_MISSING_ALTIVEC
2536 if (OS_MISSING_ALTIVEC)
2537 set_masks &= ~MASK_ALTIVEC;
2540 /* Don't override by the processor default if given explicitly. */
2541 set_masks &= ~target_flags_explicit;
2543 /* Identify the processor type. */
2544 rs6000_select[0].string = default_cpu;
2545 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2547 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2549 ptr = &rs6000_select[i];
2550 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2552 for (j = 0; j < ptt_size; j++)
2553 if (! strcmp (ptr->string, processor_target_table[j].name))
2555 if (ptr->set_tune_p)
2556 rs6000_cpu = processor_target_table[j].processor;
2558 if (ptr->set_arch_p)
2560 target_flags &= ~set_masks;
2561 target_flags |= (processor_target_table[j].target_enable
2568 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2572 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2573 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2576 error ("AltiVec not supported in this target");
2578 error ("Spe not supported in this target");
2581 /* Disable Cell microcode if we are optimizing for the Cell
2582 and not optimizing for size. */
2583 if (rs6000_gen_cell_microcode == -1)
2584 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2587 /* If we are optimizing big endian systems for space and it's OK to
2588 use instructions that would be microcoded on the Cell, use the
2589 load/store multiple and string instructions. */
2590 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2591 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2593 /* Don't allow -mmultiple or -mstring on little endian systems
2594 unless the cpu is a 750, because the hardware doesn't support the
2595 instructions used in little endian mode, and causes an alignment
2596 trap. The 750 does not cause an alignment trap (except when the
2597 target is unaligned). */
2599 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2601 if (TARGET_MULTIPLE)
2603 target_flags &= ~MASK_MULTIPLE;
2604 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2605 warning (0, "-mmultiple is not supported on little endian systems");
2610 target_flags &= ~MASK_STRING;
2611 if ((target_flags_explicit & MASK_STRING) != 0)
2612 warning (0, "-mstring is not supported on little endian systems");
2616 /* Add some warnings for VSX. */
2619 const char *msg = NULL;
2620 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2621 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2623 if (target_flags_explicit & MASK_VSX)
2624 msg = N_("-mvsx requires hardware floating point");
2626 target_flags &= ~ MASK_VSX;
2628 else if (TARGET_PAIRED_FLOAT)
2629 msg = N_("-mvsx and -mpaired are incompatible");
2630 /* The hardware will allow VSX and little endian, but until we make sure
2631 things like vector select, etc. work don't allow VSX on little endian
2632 systems at this point. */
2633 else if (!BYTES_BIG_ENDIAN)
2634 msg = N_("-mvsx used with little endian code");
2635 else if (TARGET_AVOID_XFORM > 0)
2636 msg = N_("-mvsx needs indexed addressing");
2637 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2639 if (target_flags_explicit & MASK_VSX)
2640 msg = N_("-mvsx and -mno-altivec are incompatible");
2642 msg = N_("-mno-altivec disables vsx");
2648 target_flags &= ~ MASK_VSX;
2652 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2653 unless the user explicitly used the -mno-<option> to disable the code. */
2655 target_flags |= (ISA_2_6_MASKS & (target_flags_explicit & ~ISA_2_6_MASKS));
2656 else if (TARGET_DFP)
2657 target_flags |= (ISA_2_5_MASKS & (target_flags_explicit & ~ISA_2_5_MASKS));
2658 else if (TARGET_ALTIVEC)
2659 target_flags |= (MASK_PPC_GFXOPT & (target_flags_explicit & ~MASK_PPC_GFXOPT));
2661 /* Set debug flags */
2662 if (rs6000_debug_name)
2664 if (! strcmp (rs6000_debug_name, "all"))
2665 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2666 = rs6000_debug_addr = rs6000_debug_cost = 1;
2667 else if (! strcmp (rs6000_debug_name, "stack"))
2668 rs6000_debug_stack = 1;
2669 else if (! strcmp (rs6000_debug_name, "arg"))
2670 rs6000_debug_arg = 1;
2671 else if (! strcmp (rs6000_debug_name, "reg"))
2672 rs6000_debug_reg = 1;
2673 else if (! strcmp (rs6000_debug_name, "addr"))
2674 rs6000_debug_addr = 1;
2675 else if (! strcmp (rs6000_debug_name, "cost"))
2676 rs6000_debug_cost = 1;
2678 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2680 /* If the appropriate debug option is enabled, replace the target hooks
2681 with debug versions that call the real version and then prints
2682 debugging information. */
2683 if (TARGET_DEBUG_COST)
2685 targetm.rtx_costs = rs6000_debug_rtx_costs;
2686 targetm.address_cost = rs6000_debug_address_cost;
2687 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2690 if (TARGET_DEBUG_ADDR)
2692 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2693 targetm.legitimize_address = rs6000_debug_legitimize_address;
2694 rs6000_secondary_reload_class_ptr
2695 = rs6000_debug_secondary_reload_class;
2696 rs6000_secondary_memory_needed_ptr
2697 = rs6000_debug_secondary_memory_needed;
2698 rs6000_cannot_change_mode_class_ptr
2699 = rs6000_debug_cannot_change_mode_class;
2700 rs6000_preferred_reload_class_ptr
2701 = rs6000_debug_preferred_reload_class;
2702 rs6000_legitimize_reload_address_ptr
2703 = rs6000_debug_legitimize_reload_address;
2704 rs6000_mode_dependent_address_ptr
2705 = rs6000_debug_mode_dependent_address;
2709 if (rs6000_traceback_name)
2711 if (! strncmp (rs6000_traceback_name, "full", 4))
2712 rs6000_traceback = traceback_full;
2713 else if (! strncmp (rs6000_traceback_name, "part", 4))
2714 rs6000_traceback = traceback_part;
2715 else if (! strncmp (rs6000_traceback_name, "no", 2))
2716 rs6000_traceback = traceback_none;
2718 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2719 rs6000_traceback_name);
2722 if (!rs6000_explicit_options.long_double)
2723 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2725 #ifndef POWERPC_LINUX
2726 if (!rs6000_explicit_options.ieee)
2727 rs6000_ieeequad = 1;
2730 /* Enable Altivec ABI for AIX -maltivec. */
2731 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2732 rs6000_altivec_abi = 1;
2734 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2735 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2736 be explicitly overridden in either case. */
2739 if (!rs6000_explicit_options.altivec_abi
2740 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2741 rs6000_altivec_abi = 1;
2743 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2744 if (!rs6000_explicit_options.vrsave)
2745 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2748 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
2749 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2751 rs6000_darwin64_abi = 1;
2753 darwin_one_byte_bool = 1;
2755 /* Default to natural alignment, for better performance. */
2756 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2759 /* Place FP constants in the constant pool instead of TOC
2760 if section anchors enabled. */
2761 if (flag_section_anchors)
2762 TARGET_NO_FP_IN_TOC = 1;
2764 /* Handle -mtls-size option. */
2765 rs6000_parse_tls_size_option ();
2767 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2768 SUBTARGET_OVERRIDE_OPTIONS;
2770 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2771 SUBSUBTARGET_OVERRIDE_OPTIONS;
2773 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2774 SUB3TARGET_OVERRIDE_OPTIONS;
2777 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2778 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2780 /* The e500 and e500mc do not have string instructions, and we set
2781 MASK_STRING above when optimizing for size. */
2782 if ((target_flags & MASK_STRING) != 0)
2783 target_flags = target_flags & ~MASK_STRING;
2785 else if (rs6000_select[1].string != NULL)
2787 /* For the powerpc-eabispe configuration, we set all these by
2788 default, so let's unset them if we manually set another
2789 CPU that is not the E500. */
2790 if (!rs6000_explicit_options.spe_abi)
2792 if (!rs6000_explicit_options.spe)
2794 if (!rs6000_explicit_options.float_gprs)
2795 rs6000_float_gprs = 0;
2796 if (!(target_flags_explicit & MASK_ISEL))
2797 target_flags &= ~MASK_ISEL;
2800 /* Detect invalid option combinations with E500. */
2803 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2804 && rs6000_cpu != PROCESSOR_POWER5
2805 && rs6000_cpu != PROCESSOR_POWER6
2806 && rs6000_cpu != PROCESSOR_POWER7
2807 && rs6000_cpu != PROCESSOR_PPCA2
2808 && rs6000_cpu != PROCESSOR_CELL);
2809 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2810 || rs6000_cpu == PROCESSOR_POWER5
2811 || rs6000_cpu == PROCESSOR_POWER7);
2812 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2813 || rs6000_cpu == PROCESSOR_POWER5
2814 || rs6000_cpu == PROCESSOR_POWER6
2815 || rs6000_cpu == PROCESSOR_POWER7
2816 || rs6000_cpu == PROCESSOR_PPCE500MC
2817 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2819 /* Allow debug switches to override the above settings. */
2820 if (TARGET_ALWAYS_HINT > 0)
2821 rs6000_always_hint = TARGET_ALWAYS_HINT;
2823 if (TARGET_SCHED_GROUPS > 0)
2824 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2826 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2827 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2829 rs6000_sched_restricted_insns_priority
2830 = (rs6000_sched_groups ? 1 : 0);
2832 /* Handle -msched-costly-dep option. */
2833 rs6000_sched_costly_dep
2834 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2836 if (rs6000_sched_costly_dep_str)
2838 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2839 rs6000_sched_costly_dep = no_dep_costly;
2840 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2841 rs6000_sched_costly_dep = all_deps_costly;
2842 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2843 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2844 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2845 rs6000_sched_costly_dep = store_to_load_dep_costly;
2847 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2848 atoi (rs6000_sched_costly_dep_str));
2851 /* Handle -minsert-sched-nops option. */
2852 rs6000_sched_insert_nops
2853 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2855 if (rs6000_sched_insert_nops_str)
2857 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2858 rs6000_sched_insert_nops = sched_finish_none;
2859 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2860 rs6000_sched_insert_nops = sched_finish_pad_groups;
2861 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2862 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2864 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2865 atoi (rs6000_sched_insert_nops_str));
2868 #ifdef TARGET_REGNAMES
2869 /* If the user desires alternate register names, copy in the
2870 alternate names now. */
2871 if (TARGET_REGNAMES)
2872 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2875 /* Set aix_struct_return last, after the ABI is determined.
2876 If -maix-struct-return or -msvr4-struct-return was explicitly
2877 used, don't override with the ABI default. */
2878 if (!rs6000_explicit_options.aix_struct_ret)
2879 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2881 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
2882 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
2885 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
2887 /* We can only guarantee the availability of DI pseudo-ops when
2888 assembling for 64-bit targets. */
2891 targetm.asm_out.aligned_op.di = NULL;
2892 targetm.asm_out.unaligned_op.di = NULL;
2895 /* Set branch target alignment, if not optimizing for size. */
2898 /* Cell wants to be aligned 8byte for dual issue. */
2899 if (rs6000_cpu == PROCESSOR_CELL)
2901 if (align_functions <= 0)
2902 align_functions = 8;
2903 if (align_jumps <= 0)
2905 if (align_loops <= 0)
2908 if (rs6000_align_branch_targets)
2910 if (align_functions <= 0)
2911 align_functions = 16;
2912 if (align_jumps <= 0)
2914 if (align_loops <= 0)
2917 if (align_jumps_max_skip <= 0)
2918 align_jumps_max_skip = 15;
2919 if (align_loops_max_skip <= 0)
2920 align_loops_max_skip = 15;
2923 /* Arrange to save and restore machine status around nested functions. */
2924 init_machine_status = rs6000_init_machine_status;
2926 /* We should always be splitting complex arguments, but we can't break
2927 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
2928 if (DEFAULT_ABI != ABI_AIX)
2929 targetm.calls.split_complex_arg = NULL;
2931 /* Initialize rs6000_cost with the appropriate target costs. */
2933 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
2937 case PROCESSOR_RIOS1:
2938 rs6000_cost = &rios1_cost;
2941 case PROCESSOR_RIOS2:
2942 rs6000_cost = &rios2_cost;
2945 case PROCESSOR_RS64A:
2946 rs6000_cost = &rs64a_cost;
2949 case PROCESSOR_MPCCORE:
2950 rs6000_cost = &mpccore_cost;
2953 case PROCESSOR_PPC403:
2954 rs6000_cost = &ppc403_cost;
2957 case PROCESSOR_PPC405:
2958 rs6000_cost = &ppc405_cost;
2961 case PROCESSOR_PPC440:
2962 rs6000_cost = &ppc440_cost;
2965 case PROCESSOR_PPC476:
2966 rs6000_cost = &ppc476_cost;
2969 case PROCESSOR_PPC601:
2970 rs6000_cost = &ppc601_cost;
2973 case PROCESSOR_PPC603:
2974 rs6000_cost = &ppc603_cost;
2977 case PROCESSOR_PPC604:
2978 rs6000_cost = &ppc604_cost;
2981 case PROCESSOR_PPC604e:
2982 rs6000_cost = &ppc604e_cost;
2985 case PROCESSOR_PPC620:
2986 rs6000_cost = &ppc620_cost;
2989 case PROCESSOR_PPC630:
2990 rs6000_cost = &ppc630_cost;
2993 case PROCESSOR_CELL:
2994 rs6000_cost = &ppccell_cost;
2997 case PROCESSOR_PPC750:
2998 case PROCESSOR_PPC7400:
2999 rs6000_cost = &ppc750_cost;
3002 case PROCESSOR_PPC7450:
3003 rs6000_cost = &ppc7450_cost;
3006 case PROCESSOR_PPC8540:
3007 rs6000_cost = &ppc8540_cost;
3010 case PROCESSOR_PPCE300C2:
3011 case PROCESSOR_PPCE300C3:
3012 rs6000_cost = &ppce300c2c3_cost;
3015 case PROCESSOR_PPCE500MC:
3016 rs6000_cost = &ppce500mc_cost;
3019 case PROCESSOR_PPCE500MC64:
3020 rs6000_cost = &ppce500mc64_cost;
3023 case PROCESSOR_POWER4:
3024 case PROCESSOR_POWER5:
3025 rs6000_cost = &power4_cost;
3028 case PROCESSOR_POWER6:
3029 rs6000_cost = &power6_cost;
3032 case PROCESSOR_POWER7:
3033 rs6000_cost = &power7_cost;
3036 case PROCESSOR_PPCA2:
3037 rs6000_cost = &ppca2_cost;
3044 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
3045 set_param_value ("simultaneous-prefetches",
3046 rs6000_cost->simultaneous_prefetches);
3047 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
3048 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
3049 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
3050 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
3051 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
3052 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
3054 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3055 can be optimized to ap = __builtin_next_arg (0). */
3056 if (DEFAULT_ABI != ABI_V4)
3057 targetm.expand_builtin_va_start = NULL;
3059 /* Set up single/double float flags.
3060 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3061 then set both flags. */
3062 if (TARGET_HARD_FLOAT && TARGET_FPRS
3063 && rs6000_single_float == 0 && rs6000_double_float == 0)
3064 rs6000_single_float = rs6000_double_float = 1;
3066 /* Reset single and double FP flags if target is E500. */
3069 rs6000_single_float = rs6000_double_float = 0;
3070 if (TARGET_E500_SINGLE)
3071 rs6000_single_float = 1;
3072 if (TARGET_E500_DOUBLE)
3073 rs6000_single_float = rs6000_double_float = 1;
3076 /* If not explicitly specified via option, decide whether to generate indexed
3077 load/store instructions. */
3078 if (TARGET_AVOID_XFORM == -1)
3079 /* Avoid indexed addressing when targeting Power6 in order to avoid
3080 the DERAT mispredict penalty. */
3081 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3083 /* Set the -mrecip options. */
3084 if (rs6000_recip_name)
3086 char *p = ASTRDUP (rs6000_recip_name);
3088 unsigned int mask, i;
3091 while ((q = strtok (p, ",")) != NULL)
3102 if (!strcmp (q, "default"))
3103 mask = ((TARGET_RECIP_PRECISION)
3104 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3107 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3108 if (!strcmp (q, recip_options[i].string))
3110 mask = recip_options[i].mask;
3114 if (i == ARRAY_SIZE (recip_options))
3116 error ("Unknown option for -mrecip=%s", q);
3123 rs6000_recip_control &= ~mask;
3125 rs6000_recip_control |= mask;
3129 rs6000_init_hard_regno_mode_ok ();
3132 /* Implement targetm.vectorize.builtin_mask_for_load. */
3134 rs6000_builtin_mask_for_load (void)
3136 if (TARGET_ALTIVEC || TARGET_VSX)
3137 return altivec_builtin_mask_for_load;
3142 /* Implement targetm.vectorize.builtin_conversion.
3143 Returns a decl of a function that implements conversion of an integer vector
3144 into a floating-point vector, or vice-versa. DEST_TYPE is the
3145 destination type and SRC_TYPE the source type of the conversion.
3146 Return NULL_TREE if it is not available. */
3148 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3150 enum tree_code code = (enum tree_code) tcode;
3154 case FIX_TRUNC_EXPR:
3155 switch (TYPE_MODE (dest_type))
3158 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3161 return TYPE_UNSIGNED (dest_type)
3162 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3163 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3166 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3169 return TYPE_UNSIGNED (dest_type)
3170 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3171 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3178 switch (TYPE_MODE (src_type))
3181 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3184 return TYPE_UNSIGNED (src_type)
3185 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3186 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3189 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3192 return TYPE_UNSIGNED (src_type)
3193 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3194 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3205 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3207 rs6000_builtin_mul_widen_even (tree type)
3209 if (!TARGET_ALTIVEC)
3212 switch (TYPE_MODE (type))
3215 return TYPE_UNSIGNED (type)
3216 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3217 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3220 return TYPE_UNSIGNED (type)
3221 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3222 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3228 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3230 rs6000_builtin_mul_widen_odd (tree type)
3232 if (!TARGET_ALTIVEC)
3235 switch (TYPE_MODE (type))
3238 return TYPE_UNSIGNED (type)
3239 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3240 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3243 return TYPE_UNSIGNED (type)
3244 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3245 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3252 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3253 after applying N number of iterations. This routine does not determine
3254 how may iterations are required to reach desired alignment. */
3257 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3264 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3267 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3277 /* Assuming that all other types are naturally aligned. CHECKME! */
3282 /* Return true if the vector misalignment factor is supported by the
3285 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3292 /* Return if movmisalign pattern is not supported for this mode. */
3293 if (optab_handler (movmisalign_optab, mode)->insn_code ==
3297 if (misalignment == -1)
3299 /* misalignment factor is unknown at compile time but we know
3300 it's word aligned. */
3301 if (rs6000_vector_alignment_reachable (type, is_packed))
3305 /* VSX supports word-aligned vector. */
3306 if (misalignment % 4 == 0)
3312 /* Implement targetm.vectorize.builtin_vec_perm. */
3314 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3316 tree inner_type = TREE_TYPE (type);
3317 bool uns_p = TYPE_UNSIGNED (inner_type);
3320 *mask_element_type = unsigned_char_type_node;
3322 switch (TYPE_MODE (type))
3326 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3327 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3332 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3333 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3338 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3339 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3343 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3347 if (!TARGET_ALLOW_DF_PERMUTE)
3350 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3354 if (!TARGET_ALLOW_DF_PERMUTE)
3358 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3359 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3370 /* Handle generic options of the form -mfoo=yes/no.
3371 NAME is the option name.
3372 VALUE is the option value.
3373 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3374 whether the option value is 'yes' or 'no' respectively. */
3376 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3380 else if (!strcmp (value, "yes"))
3382 else if (!strcmp (value, "no"))
3385 error ("unknown -m%s= option specified: '%s'", name, value);
3388 /* Validate and record the size specified with the -mtls-size option. */
3391 rs6000_parse_tls_size_option (void)
3393 if (rs6000_tls_size_string == 0)
3395 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3396 rs6000_tls_size = 16;
3397 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3398 rs6000_tls_size = 32;
3399 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3400 rs6000_tls_size = 64;
3402 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3406 optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
3408 if (DEFAULT_ABI == ABI_DARWIN)
3409 /* The Darwin libraries never set errno, so we might as well
3410 avoid calling them when that's the only reason we would. */
3411 flag_errno_math = 0;
3413 /* Double growth factor to counter reduced min jump length. */
3414 set_param_value ("max-grow-copy-bb-insns", 16);
3416 /* Enable section anchors by default.
3417 Skip section anchors for Objective C and Objective C++
3418 until front-ends fixed. */
3419 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
3420 flag_section_anchors = 2;
3423 static enum fpu_type_t
3424 rs6000_parse_fpu_option (const char *option)
3426 if (!strcmp("none", option)) return FPU_NONE;
3427 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3428 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3429 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3430 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3431 error("unknown value %s for -mfpu", option);
3435 /* Returns a function decl for a vectorized version of the builtin function
3436 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3437 if it is not available. */
3440 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3443 enum machine_mode in_mode, out_mode;
3446 if (TREE_CODE (type_out) != VECTOR_TYPE
3447 || TREE_CODE (type_in) != VECTOR_TYPE
3448 || !TARGET_VECTORIZE_BUILTINS)
3451 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3452 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3453 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3454 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3456 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3458 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3461 case BUILT_IN_COPYSIGN:
3462 if (VECTOR_UNIT_VSX_P (V2DFmode)
3463 && out_mode == DFmode && out_n == 2
3464 && in_mode == DFmode && in_n == 2)
3465 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3467 case BUILT_IN_COPYSIGNF:
3468 if (out_mode != SFmode || out_n != 4
3469 || in_mode != SFmode || in_n != 4)
3471 if (VECTOR_UNIT_VSX_P (V4SFmode))
3472 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3473 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3474 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3477 if (VECTOR_UNIT_VSX_P (V2DFmode)
3478 && out_mode == DFmode && out_n == 2
3479 && in_mode == DFmode && in_n == 2)
3480 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3482 case BUILT_IN_SQRTF:
3483 if (VECTOR_UNIT_VSX_P (V4SFmode)
3484 && out_mode == SFmode && out_n == 4
3485 && in_mode == SFmode && in_n == 4)
3486 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3489 if (VECTOR_UNIT_VSX_P (V2DFmode)
3490 && out_mode == DFmode && out_n == 2
3491 && in_mode == DFmode && in_n == 2)
3492 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3494 case BUILT_IN_CEILF:
3495 if (out_mode != SFmode || out_n != 4
3496 || in_mode != SFmode || in_n != 4)
3498 if (VECTOR_UNIT_VSX_P (V4SFmode))
3499 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3500 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3501 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3503 case BUILT_IN_FLOOR:
3504 if (VECTOR_UNIT_VSX_P (V2DFmode)
3505 && out_mode == DFmode && out_n == 2
3506 && in_mode == DFmode && in_n == 2)
3507 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3509 case BUILT_IN_FLOORF:
3510 if (out_mode != SFmode || out_n != 4
3511 || in_mode != SFmode || in_n != 4)
3513 if (VECTOR_UNIT_VSX_P (V4SFmode))
3514 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3515 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3516 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3518 case BUILT_IN_TRUNC:
3519 if (VECTOR_UNIT_VSX_P (V2DFmode)
3520 && out_mode == DFmode && out_n == 2
3521 && in_mode == DFmode && in_n == 2)
3522 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
3524 case BUILT_IN_TRUNCF:
3525 if (out_mode != SFmode || out_n != 4
3526 || in_mode != SFmode || in_n != 4)
3528 if (VECTOR_UNIT_VSX_P (V4SFmode))
3529 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
3530 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3531 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
3533 case BUILT_IN_NEARBYINT:
3534 if (VECTOR_UNIT_VSX_P (V2DFmode)
3535 && flag_unsafe_math_optimizations
3536 && out_mode == DFmode && out_n == 2
3537 && in_mode == DFmode && in_n == 2)
3538 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
3540 case BUILT_IN_NEARBYINTF:
3541 if (VECTOR_UNIT_VSX_P (V4SFmode)
3542 && flag_unsafe_math_optimizations
3543 && out_mode == SFmode && out_n == 4
3544 && in_mode == SFmode && in_n == 4)
3545 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
3548 if (VECTOR_UNIT_VSX_P (V2DFmode)
3549 && !flag_trapping_math
3550 && out_mode == DFmode && out_n == 2
3551 && in_mode == DFmode && in_n == 2)
3552 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
3554 case BUILT_IN_RINTF:
3555 if (VECTOR_UNIT_VSX_P (V4SFmode)
3556 && !flag_trapping_math
3557 && out_mode == SFmode && out_n == 4
3558 && in_mode == SFmode && in_n == 4)
3559 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
3566 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
3568 enum rs6000_builtins fn
3569 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
3572 case RS6000_BUILTIN_RSQRTF:
3573 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3574 && out_mode == SFmode && out_n == 4
3575 && in_mode == SFmode && in_n == 4)
3576 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
3578 case RS6000_BUILTIN_RSQRT:
3579 if (VECTOR_UNIT_VSX_P (V2DFmode)
3580 && out_mode == DFmode && out_n == 2
3581 && in_mode == DFmode && in_n == 2)
3582 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
3584 case RS6000_BUILTIN_RECIPF:
3585 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
3586 && out_mode == SFmode && out_n == 4
3587 && in_mode == SFmode && in_n == 4)
3588 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
3590 case RS6000_BUILTIN_RECIP:
3591 if (VECTOR_UNIT_VSX_P (V2DFmode)
3592 && out_mode == DFmode && out_n == 2
3593 && in_mode == DFmode && in_n == 2)
3594 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
3605 /* Implement TARGET_HANDLE_OPTION. */
3608 rs6000_handle_option (size_t code, const char *arg, int value)
3610 enum fpu_type_t fpu_type = FPU_NONE;
3616 target_flags &= ~(MASK_POWER | MASK_POWER2
3617 | MASK_MULTIPLE | MASK_STRING);
3618 target_flags_explicit |= (MASK_POWER | MASK_POWER2
3619 | MASK_MULTIPLE | MASK_STRING);
3621 case OPT_mno_powerpc:
3622 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
3623 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3624 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
3625 | MASK_PPC_GFXOPT | MASK_POWERPC64);
3628 target_flags &= ~MASK_MINIMAL_TOC;
3629 TARGET_NO_FP_IN_TOC = 0;
3630 TARGET_NO_SUM_IN_TOC = 0;
3631 target_flags_explicit |= MASK_MINIMAL_TOC;
3632 #ifdef TARGET_USES_SYSV4_OPT
3633 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
3634 just the same as -mminimal-toc. */
3635 target_flags |= MASK_MINIMAL_TOC;
3636 target_flags_explicit |= MASK_MINIMAL_TOC;
3640 #ifdef TARGET_USES_SYSV4_OPT
3642 /* Make -mtoc behave like -mminimal-toc. */
3643 target_flags |= MASK_MINIMAL_TOC;
3644 target_flags_explicit |= MASK_MINIMAL_TOC;
3648 #ifdef TARGET_USES_AIX64_OPT
3653 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
3654 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
3655 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
3658 #ifdef TARGET_USES_AIX64_OPT
3663 target_flags &= ~MASK_POWERPC64;
3664 target_flags_explicit |= MASK_POWERPC64;
3667 case OPT_minsert_sched_nops_:
3668 rs6000_sched_insert_nops_str = arg;
3671 case OPT_mminimal_toc:
3674 TARGET_NO_FP_IN_TOC = 0;
3675 TARGET_NO_SUM_IN_TOC = 0;
3682 target_flags |= (MASK_MULTIPLE | MASK_STRING);
3683 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
3690 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3691 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
3695 case OPT_mpowerpc_gpopt:
3696 case OPT_mpowerpc_gfxopt:
3699 target_flags |= MASK_POWERPC;
3700 target_flags_explicit |= MASK_POWERPC;
3704 case OPT_maix_struct_return:
3705 case OPT_msvr4_struct_return:
3706 rs6000_explicit_options.aix_struct_ret = true;
3710 rs6000_explicit_options.vrsave = true;
3711 TARGET_ALTIVEC_VRSAVE = value;
3715 rs6000_explicit_options.vrsave = true;
3716 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
3720 target_flags_explicit |= MASK_ISEL;
3722 rs6000_parse_yes_no_option ("isel", arg, &isel);
3724 target_flags |= MASK_ISEL;
3726 target_flags &= ~MASK_ISEL;
3730 rs6000_explicit_options.spe = true;
3735 rs6000_explicit_options.spe = true;
3736 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
3740 rs6000_debug_name = arg;
3743 #ifdef TARGET_USES_SYSV4_OPT
3745 rs6000_abi_name = arg;
3749 rs6000_sdata_name = arg;
3752 case OPT_mtls_size_:
3753 rs6000_tls_size_string = arg;
3756 case OPT_mrelocatable:
3759 target_flags |= MASK_MINIMAL_TOC;
3760 target_flags_explicit |= MASK_MINIMAL_TOC;
3761 TARGET_NO_FP_IN_TOC = 1;
3765 case OPT_mrelocatable_lib:
3768 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3769 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
3770 TARGET_NO_FP_IN_TOC = 1;
3774 target_flags &= ~MASK_RELOCATABLE;
3775 target_flags_explicit |= MASK_RELOCATABLE;
3781 if (!strcmp (arg, "altivec"))
3783 rs6000_explicit_options.altivec_abi = true;
3784 rs6000_altivec_abi = 1;
3786 /* Enabling the AltiVec ABI turns off the SPE ABI. */
3789 else if (! strcmp (arg, "no-altivec"))
3791 rs6000_explicit_options.altivec_abi = true;
3792 rs6000_altivec_abi = 0;
3794 else if (! strcmp (arg, "spe"))
3796 rs6000_explicit_options.spe_abi = true;
3798 rs6000_altivec_abi = 0;
3799 if (!TARGET_SPE_ABI)
3800 error ("not configured for ABI: '%s'", arg);
3802 else if (! strcmp (arg, "no-spe"))
3804 rs6000_explicit_options.spe_abi = true;
3808 /* These are here for testing during development only, do not
3809 document in the manual please. */
3810 else if (! strcmp (arg, "d64"))
3812 rs6000_darwin64_abi = 1;
3813 warning (0, "Using darwin64 ABI");
3815 else if (! strcmp (arg, "d32"))
3817 rs6000_darwin64_abi = 0;
3818 warning (0, "Using old darwin ABI");
3821 else if (! strcmp (arg, "ibmlongdouble"))
3823 rs6000_explicit_options.ieee = true;
3824 rs6000_ieeequad = 0;
3825 warning (0, "Using IBM extended precision long double");
3827 else if (! strcmp (arg, "ieeelongdouble"))
3829 rs6000_explicit_options.ieee = true;
3830 rs6000_ieeequad = 1;
3831 warning (0, "Using IEEE extended precision long double");
3836 error ("unknown ABI specified: '%s'", arg);
3842 rs6000_select[1].string = arg;
3846 rs6000_select[2].string = arg;
3849 case OPT_mtraceback_:
3850 rs6000_traceback_name = arg;
3853 case OPT_mfloat_gprs_:
3854 rs6000_explicit_options.float_gprs = true;
3855 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
3856 rs6000_float_gprs = 1;
3857 else if (! strcmp (arg, "double"))
3858 rs6000_float_gprs = 2;
3859 else if (! strcmp (arg, "no"))
3860 rs6000_float_gprs = 0;
3863 error ("invalid option for -mfloat-gprs: '%s'", arg);
3868 case OPT_mlong_double_:
3869 rs6000_explicit_options.long_double = true;
3870 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3871 if (value != 64 && value != 128)
3873 error ("Unknown switch -mlong-double-%s", arg);
3874 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
3878 rs6000_long_double_type_size = value;
3881 case OPT_msched_costly_dep_:
3882 rs6000_sched_costly_dep_str = arg;
3886 rs6000_explicit_options.alignment = true;
3887 if (! strcmp (arg, "power"))
3889 /* On 64-bit Darwin, power alignment is ABI-incompatible with
3890 some C library functions, so warn about it. The flag may be
3891 useful for performance studies from time to time though, so
3892 don't disable it entirely. */
3893 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
3894 warning (0, "-malign-power is not supported for 64-bit Darwin;"
3895 " it is incompatible with the installed C and C++ libraries");
3896 rs6000_alignment_flags = MASK_ALIGN_POWER;
3898 else if (! strcmp (arg, "natural"))
3899 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
3902 error ("unknown -malign-XXXXX option specified: '%s'", arg);
3907 case OPT_msingle_float:
3908 if (!TARGET_SINGLE_FPU)
3909 warning (0, "-msingle-float option equivalent to -mhard-float");
3910 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
3911 rs6000_double_float = 0;
3912 target_flags &= ~MASK_SOFT_FLOAT;
3913 target_flags_explicit |= MASK_SOFT_FLOAT;
3916 case OPT_mdouble_float:
3917 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
3918 rs6000_single_float = 1;
3919 target_flags &= ~MASK_SOFT_FLOAT;
3920 target_flags_explicit |= MASK_SOFT_FLOAT;
3923 case OPT_msimple_fpu:
3924 if (!TARGET_SINGLE_FPU)
3925 warning (0, "-msimple-fpu option ignored");
3928 case OPT_mhard_float:
3929 /* -mhard_float implies -msingle-float and -mdouble-float. */
3930 rs6000_single_float = rs6000_double_float = 1;
3933 case OPT_msoft_float:
3934 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
3935 rs6000_single_float = rs6000_double_float = 0;
3939 fpu_type = rs6000_parse_fpu_option(arg);
3940 if (fpu_type != FPU_NONE)
3941 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
3943 target_flags &= ~MASK_SOFT_FLOAT;
3944 target_flags_explicit |= MASK_SOFT_FLOAT;
3945 rs6000_xilinx_fpu = 1;
3946 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
3947 rs6000_single_float = 1;
3948 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
3949 rs6000_single_float = rs6000_double_float = 1;
3950 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
3951 rs6000_simple_fpu = 1;
3955 /* -mfpu=none is equivalent to -msoft-float */
3956 target_flags |= MASK_SOFT_FLOAT;
3957 target_flags_explicit |= MASK_SOFT_FLOAT;
3958 rs6000_single_float = rs6000_double_float = 0;
3962 rs6000_recip_name = (value) ? "default" : "none";
3966 rs6000_recip_name = arg;
3972 /* Do anything needed at the start of the asm file. */
3975 rs6000_file_start (void)
3979 const char *start = buffer;
3980 struct rs6000_cpu_select *ptr;
3981 const char *default_cpu = TARGET_CPU_DEFAULT;
3982 FILE *file = asm_out_file;
3984 default_file_start ();
3986 #ifdef TARGET_BI_ARCH
3987 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
3991 if (flag_verbose_asm)
3993 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
3994 rs6000_select[0].string = default_cpu;
3996 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3998 ptr = &rs6000_select[i];
3999 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4001 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4006 if (PPC405_ERRATUM77)
4008 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4012 #ifdef USING_ELFOS_H
4013 switch (rs6000_sdata)
4015 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4016 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4017 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4018 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4021 if (rs6000_sdata && g_switch_value)
4023 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
4033 #ifdef HAVE_AS_GNU_ATTRIBUTE
4034 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4036 fprintf (file, "\t.gnu_attribute 4, %d\n",
4037 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4038 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4040 fprintf (file, "\t.gnu_attribute 8, %d\n",
4041 (TARGET_ALTIVEC_ABI ? 2
4042 : TARGET_SPE_ABI ? 3
4044 fprintf (file, "\t.gnu_attribute 12, %d\n",
4045 aix_struct_return ? 2 : 1);
4050 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4052 switch_to_section (toc_section);
4053 switch_to_section (text_section);
4058 /* Return nonzero if this function is known to have a null epilogue. */
4061 direct_return (void)
4063 if (reload_completed)
4065 rs6000_stack_t *info = rs6000_stack_info ();
4067 if (info->first_gp_reg_save == 32
4068 && info->first_fp_reg_save == 64
4069 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4070 && ! info->lr_save_p
4071 && ! info->cr_save_p
4072 && info->vrsave_mask == 0
4080 /* Return the number of instructions it takes to form a constant in an
4081 integer register. */
4084 num_insns_constant_wide (HOST_WIDE_INT value)
4086 /* signed constant loadable with {cal|addi} */
4087 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4090 /* constant loadable with {cau|addis} */
4091 else if ((value & 0xffff) == 0
4092 && (value >> 31 == -1 || value >> 31 == 0))
4095 #if HOST_BITS_PER_WIDE_INT == 64
4096 else if (TARGET_POWERPC64)
4098 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4099 HOST_WIDE_INT high = value >> 31;
4101 if (high == 0 || high == -1)
4107 return num_insns_constant_wide (high) + 1;
4109 return num_insns_constant_wide (low) + 1;
4111 return (num_insns_constant_wide (high)
4112 + num_insns_constant_wide (low) + 1);
4121 num_insns_constant (rtx op, enum machine_mode mode)
4123 HOST_WIDE_INT low, high;
4125 switch (GET_CODE (op))
4128 #if HOST_BITS_PER_WIDE_INT == 64
4129 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4130 && mask64_operand (op, mode))
4134 return num_insns_constant_wide (INTVAL (op));
4137 if (mode == SFmode || mode == SDmode)
4142 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4143 if (DECIMAL_FLOAT_MODE_P (mode))
4144 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4146 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4147 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4150 if (mode == VOIDmode || mode == DImode)
4152 high = CONST_DOUBLE_HIGH (op);
4153 low = CONST_DOUBLE_LOW (op);
4160 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4161 if (DECIMAL_FLOAT_MODE_P (mode))
4162 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4164 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4165 high = l[WORDS_BIG_ENDIAN == 0];
4166 low = l[WORDS_BIG_ENDIAN != 0];
4170 return (num_insns_constant_wide (low)
4171 + num_insns_constant_wide (high));
4174 if ((high == 0 && low >= 0)
4175 || (high == -1 && low < 0))
4176 return num_insns_constant_wide (low);
4178 else if (mask64_operand (op, mode))
4182 return num_insns_constant_wide (high) + 1;
4185 return (num_insns_constant_wide (high)
4186 + num_insns_constant_wide (low) + 1);
4194 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4195 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4196 corresponding element of the vector, but for V4SFmode and V2SFmode,
4197 the corresponding "float" is interpreted as an SImode integer. */
4200 const_vector_elt_as_int (rtx op, unsigned int elt)
4202 rtx tmp = CONST_VECTOR_ELT (op, elt);
4203 if (GET_MODE (op) == V4SFmode
4204 || GET_MODE (op) == V2SFmode)
4205 tmp = gen_lowpart (SImode, tmp);
4206 return INTVAL (tmp);
4209 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4210 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4211 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4212 all items are set to the same value and contain COPIES replicas of the
4213 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4214 operand and the others are set to the value of the operand's msb. */
4217 vspltis_constant (rtx op, unsigned step, unsigned copies)
4219 enum machine_mode mode = GET_MODE (op);
4220 enum machine_mode inner = GET_MODE_INNER (mode);
4223 unsigned nunits = GET_MODE_NUNITS (mode);
4224 unsigned bitsize = GET_MODE_BITSIZE (inner);
4225 unsigned mask = GET_MODE_MASK (inner);
4227 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4228 HOST_WIDE_INT splat_val = val;
4229 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4231 /* Construct the value to be splatted, if possible. If not, return 0. */
4232 for (i = 2; i <= copies; i *= 2)
4234 HOST_WIDE_INT small_val;
4236 small_val = splat_val >> bitsize;
4238 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4240 splat_val = small_val;
4243 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4244 if (EASY_VECTOR_15 (splat_val))
4247 /* Also check if we can splat, and then add the result to itself. Do so if
4248 the value is positive, of if the splat instruction is using OP's mode;
4249 for splat_val < 0, the splat and the add should use the same mode. */
4250 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4251 && (splat_val >= 0 || (step == 1 && copies == 1)))
4254 /* Also check if are loading up the most significant bit which can be done by
4255 loading up -1 and shifting the value left by -1. */
4256 else if (EASY_VECTOR_MSB (splat_val, inner))
4262 /* Check if VAL is present in every STEP-th element, and the
4263 other elements are filled with its most significant bit. */
4264 for (i = 0; i < nunits - 1; ++i)
4266 HOST_WIDE_INT desired_val;
4267 if (((i + 1) & (step - 1)) == 0)
4270 desired_val = msb_val;
4272 if (desired_val != const_vector_elt_as_int (op, i))
4280 /* Return true if OP is of the given MODE and can be synthesized
4281 with a vspltisb, vspltish or vspltisw. */
4284 easy_altivec_constant (rtx op, enum machine_mode mode)
4286 unsigned step, copies;
4288 if (mode == VOIDmode)
4289 mode = GET_MODE (op);
4290 else if (mode != GET_MODE (op))
4293 /* Start with a vspltisw. */
4294 step = GET_MODE_NUNITS (mode) / 4;
4297 if (vspltis_constant (op, step, copies))
4300 /* Then try with a vspltish. */
4306 if (vspltis_constant (op, step, copies))
4309 /* And finally a vspltisb. */
4315 if (vspltis_constant (op, step, copies))
4321 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4322 result is OP. Abort if it is not possible. */
4325 gen_easy_altivec_constant (rtx op)
4327 enum machine_mode mode = GET_MODE (op);
4328 int nunits = GET_MODE_NUNITS (mode);
4329 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4330 unsigned step = nunits / 4;
4331 unsigned copies = 1;
4333 /* Start with a vspltisw. */
4334 if (vspltis_constant (op, step, copies))
4335 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4337 /* Then try with a vspltish. */
4343 if (vspltis_constant (op, step, copies))
4344 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4346 /* And finally a vspltisb. */
4352 if (vspltis_constant (op, step, copies))
4353 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4359 output_vec_const_move (rtx *operands)
4362 enum machine_mode mode;
4367 mode = GET_MODE (dest);
4369 if (TARGET_VSX && zero_constant (vec, mode))
4370 return "xxlxor %x0,%x0,%x0";
4375 if (zero_constant (vec, mode))
4376 return "vxor %0,%0,%0";
4378 splat_vec = gen_easy_altivec_constant (vec);
4379 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4380 operands[1] = XEXP (splat_vec, 0);
4381 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4384 switch (GET_MODE (splat_vec))
4387 return "vspltisw %0,%1";
4390 return "vspltish %0,%1";
4393 return "vspltisb %0,%1";
4400 gcc_assert (TARGET_SPE);
4402 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4403 pattern of V1DI, V4HI, and V2SF.
4405 FIXME: We should probably return # and add post reload
4406 splitters for these, but this way is so easy ;-). */
4407 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4408 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4409 operands[1] = CONST_VECTOR_ELT (vec, 0);
4410 operands[2] = CONST_VECTOR_ELT (vec, 1);
4412 return "li %0,%1\n\tevmergelo %0,%0,%0";
4414 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4417 /* Initialize TARGET of vector PAIRED to VALS. */
4420 paired_expand_vector_init (rtx target, rtx vals)
4422 enum machine_mode mode = GET_MODE (target);
4423 int n_elts = GET_MODE_NUNITS (mode);
4425 rtx x, new_rtx, tmp, constant_op, op1, op2;
4428 for (i = 0; i < n_elts; ++i)
4430 x = XVECEXP (vals, 0, i);
4431 if (!CONSTANT_P (x))
4436 /* Load from constant pool. */
4437 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4443 /* The vector is initialized only with non-constants. */
4444 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4445 XVECEXP (vals, 0, 1));
4447 emit_move_insn (target, new_rtx);
4451 /* One field is non-constant and the other one is a constant. Load the
4452 constant from the constant pool and use ps_merge instruction to
4453 construct the whole vector. */
4454 op1 = XVECEXP (vals, 0, 0);
4455 op2 = XVECEXP (vals, 0, 1);
4457 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4459 tmp = gen_reg_rtx (GET_MODE (constant_op));
4460 emit_move_insn (tmp, constant_op);
4462 if (CONSTANT_P (op1))
4463 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4465 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4467 emit_move_insn (target, new_rtx);
4471 paired_expand_vector_move (rtx operands[])
4473 rtx op0 = operands[0], op1 = operands[1];
4475 emit_move_insn (op0, op1);
4478 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4479 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4480 operands for the relation operation COND. This is a recursive
4484 paired_emit_vector_compare (enum rtx_code rcode,
4485 rtx dest, rtx op0, rtx op1,
4486 rtx cc_op0, rtx cc_op1)
4488 rtx tmp = gen_reg_rtx (V2SFmode);
4491 gcc_assert (TARGET_PAIRED_FLOAT);
4492 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
4498 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4502 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4503 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
4507 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
4510 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4513 tmp1 = gen_reg_rtx (V2SFmode);
4514 max = gen_reg_rtx (V2SFmode);
4515 min = gen_reg_rtx (V2SFmode);
4516 gen_reg_rtx (V2SFmode);
4518 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
4519 emit_insn (gen_selv2sf4
4520 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4521 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
4522 emit_insn (gen_selv2sf4
4523 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
4524 emit_insn (gen_subv2sf3 (tmp1, min, max));
4525 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
4528 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
4531 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
4534 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
4537 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
4540 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
4549 /* Emit vector conditional expression.
4550 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
4551 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
4554 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
4555 rtx cond, rtx cc_op0, rtx cc_op1)
4557 enum rtx_code rcode = GET_CODE (cond);
4559 if (!TARGET_PAIRED_FLOAT)
4562 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
4567 /* Initialize vector TARGET to VALS. */
4570 rs6000_expand_vector_init (rtx target, rtx vals)
4572 enum machine_mode mode = GET_MODE (target);
4573 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4574 int n_elts = GET_MODE_NUNITS (mode);
4575 int n_var = 0, one_var = -1;
4576 bool all_same = true, all_const_zero = true;
4580 for (i = 0; i < n_elts; ++i)
4582 x = XVECEXP (vals, 0, i);
4583 if (!CONSTANT_P (x))
4584 ++n_var, one_var = i;
4585 else if (x != CONST0_RTX (inner_mode))
4586 all_const_zero = false;
4588 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
4594 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
4595 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
4596 if ((int_vector_p || TARGET_VSX) && all_const_zero)
4598 /* Zero register. */
4599 emit_insn (gen_rtx_SET (VOIDmode, target,
4600 gen_rtx_XOR (mode, target, target)));
4603 else if (int_vector_p && easy_vector_constant (const_vec, mode))
4605 /* Splat immediate. */
4606 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
4611 /* Load from constant pool. */
4612 emit_move_insn (target, const_vec);
4617 /* Double word values on VSX can use xxpermdi or lxvdsx. */
4618 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4622 rtx element = XVECEXP (vals, 0, 0);
4623 if (mode == V2DFmode)
4624 emit_insn (gen_vsx_splat_v2df (target, element));
4626 emit_insn (gen_vsx_splat_v2di (target, element));
4630 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
4631 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
4632 if (mode == V2DFmode)
4633 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
4635 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
4640 /* With single precision floating point on VSX, know that internally single
4641 precision is actually represented as a double, and either make 2 V2DF
4642 vectors, and convert these vectors to single precision, or do one
4643 conversion, and splat the result to the other elements. */
4644 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
4648 rtx freg = gen_reg_rtx (V4SFmode);
4649 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
4651 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
4652 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
4656 rtx dbl_even = gen_reg_rtx (V2DFmode);
4657 rtx dbl_odd = gen_reg_rtx (V2DFmode);
4658 rtx flt_even = gen_reg_rtx (V4SFmode);
4659 rtx flt_odd = gen_reg_rtx (V4SFmode);
4661 emit_insn (gen_vsx_concat_v2sf (dbl_even,
4662 copy_to_reg (XVECEXP (vals, 0, 0)),
4663 copy_to_reg (XVECEXP (vals, 0, 1))));
4664 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
4665 copy_to_reg (XVECEXP (vals, 0, 2)),
4666 copy_to_reg (XVECEXP (vals, 0, 3))));
4667 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
4668 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
4669 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
4674 /* Store value to stack temp. Load vector element. Splat. However, splat
4675 of 64-bit items is not supported on Altivec. */
4676 if (all_same && GET_MODE_SIZE (mode) <= 4)
4678 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4679 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
4680 XVECEXP (vals, 0, 0));
4681 x = gen_rtx_UNSPEC (VOIDmode,
4682 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4683 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4685 gen_rtx_SET (VOIDmode,
4688 x = gen_rtx_VEC_SELECT (inner_mode, target,
4689 gen_rtx_PARALLEL (VOIDmode,
4690 gen_rtvec (1, const0_rtx)));
4691 emit_insn (gen_rtx_SET (VOIDmode, target,
4692 gen_rtx_VEC_DUPLICATE (mode, x)));
4696 /* One field is non-constant. Load constant then overwrite
4700 rtx copy = copy_rtx (vals);
4702 /* Load constant part of vector, substitute neighboring value for
4704 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
4705 rs6000_expand_vector_init (target, copy);
4707 /* Insert variable. */
4708 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
4712 /* Construct the vector in memory one field at a time
4713 and load the whole vector. */
4714 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4715 for (i = 0; i < n_elts; i++)
4716 emit_move_insn (adjust_address_nv (mem, inner_mode,
4717 i * GET_MODE_SIZE (inner_mode)),
4718 XVECEXP (vals, 0, i));
4719 emit_move_insn (target, mem);
4722 /* Set field ELT of TARGET to VAL. */
4725 rs6000_expand_vector_set (rtx target, rtx val, int elt)
4727 enum machine_mode mode = GET_MODE (target);
4728 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4729 rtx reg = gen_reg_rtx (mode);
4731 int width = GET_MODE_SIZE (inner_mode);
4734 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4736 rtx (*set_func) (rtx, rtx, rtx, rtx)
4737 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
4738 emit_insn (set_func (target, target, val, GEN_INT (elt)));
4742 /* Load single variable value. */
4743 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
4744 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
4745 x = gen_rtx_UNSPEC (VOIDmode,
4746 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
4747 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4749 gen_rtx_SET (VOIDmode,
4753 /* Linear sequence. */
4754 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
4755 for (i = 0; i < 16; ++i)
4756 XVECEXP (mask, 0, i) = GEN_INT (i);
4758 /* Set permute mask to insert element into target. */
4759 for (i = 0; i < width; ++i)
4760 XVECEXP (mask, 0, elt*width + i)
4761 = GEN_INT (i + 0x10);
4762 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
4763 x = gen_rtx_UNSPEC (mode,
4764 gen_rtvec (3, target, reg,
4765 force_reg (V16QImode, x)),
4767 emit_insn (gen_rtx_SET (VOIDmode, target, x));
4770 /* Extract field ELT from VEC into TARGET. */
4773 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
4775 enum machine_mode mode = GET_MODE (vec);
4776 enum machine_mode inner_mode = GET_MODE_INNER (mode);
4779 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
4781 rtx (*extract_func) (rtx, rtx, rtx)
4782 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
4783 emit_insn (extract_func (target, vec, GEN_INT (elt)));
4787 /* Allocate mode-sized buffer. */
4788 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
4790 /* Add offset to field within buffer matching vector element. */
4791 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
4793 /* Store single field into mode-sized buffer. */
4794 x = gen_rtx_UNSPEC (VOIDmode,
4795 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
4796 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4798 gen_rtx_SET (VOIDmode,
4801 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
4804 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
4805 implement ANDing by the mask IN. */
4807 build_mask64_2_operands (rtx in, rtx *out)
4809 #if HOST_BITS_PER_WIDE_INT >= 64
4810 unsigned HOST_WIDE_INT c, lsb, m1, m2;
4813 gcc_assert (GET_CODE (in) == CONST_INT);
4818 /* Assume c initially something like 0x00fff000000fffff. The idea
4819 is to rotate the word so that the middle ^^^^^^ group of zeros
4820 is at the MS end and can be cleared with an rldicl mask. We then
4821 rotate back and clear off the MS ^^ group of zeros with a
4823 c = ~c; /* c == 0xff000ffffff00000 */
4824 lsb = c & -c; /* lsb == 0x0000000000100000 */
4825 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
4826 c = ~c; /* c == 0x00fff000000fffff */
4827 c &= -lsb; /* c == 0x00fff00000000000 */
4828 lsb = c & -c; /* lsb == 0x0000100000000000 */
4829 c = ~c; /* c == 0xff000fffffffffff */
4830 c &= -lsb; /* c == 0xff00000000000000 */
4832 while ((lsb >>= 1) != 0)
4833 shift++; /* shift == 44 on exit from loop */
4834 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
4835 m1 = ~m1; /* m1 == 0x000000ffffffffff */
4836 m2 = ~c; /* m2 == 0x00ffffffffffffff */
4840 /* Assume c initially something like 0xff000f0000000000. The idea
4841 is to rotate the word so that the ^^^ middle group of zeros
4842 is at the LS end and can be cleared with an rldicr mask. We then
4843 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
4845 lsb = c & -c; /* lsb == 0x0000010000000000 */
4846 m2 = -lsb; /* m2 == 0xffffff0000000000 */
4847 c = ~c; /* c == 0x00fff0ffffffffff */
4848 c &= -lsb; /* c == 0x00fff00000000000 */
4849 lsb = c & -c; /* lsb == 0x0000100000000000 */
4850 c = ~c; /* c == 0xff000fffffffffff */
4851 c &= -lsb; /* c == 0xff00000000000000 */
4853 while ((lsb >>= 1) != 0)
4854 shift++; /* shift == 44 on exit from loop */
4855 m1 = ~c; /* m1 == 0x00ffffffffffffff */
4856 m1 >>= shift; /* m1 == 0x0000000000000fff */
4857 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
4860 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
4861 masks will be all 1's. We are guaranteed more than one transition. */
4862 out[0] = GEN_INT (64 - shift);
4863 out[1] = GEN_INT (m1);
4864 out[2] = GEN_INT (shift);
4865 out[3] = GEN_INT (m2);
4873 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
4876 invalid_e500_subreg (rtx op, enum machine_mode mode)
4878 if (TARGET_E500_DOUBLE)
4880 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
4881 subreg:TI and reg:TF. Decimal float modes are like integer
4882 modes (only low part of each register used) for this
4884 if (GET_CODE (op) == SUBREG
4885 && (mode == SImode || mode == DImode || mode == TImode
4886 || mode == DDmode || mode == TDmode)
4887 && REG_P (SUBREG_REG (op))
4888 && (GET_MODE (SUBREG_REG (op)) == DFmode
4889 || GET_MODE (SUBREG_REG (op)) == TFmode))
4892 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
4894 if (GET_CODE (op) == SUBREG
4895 && (mode == DFmode || mode == TFmode)
4896 && REG_P (SUBREG_REG (op))
4897 && (GET_MODE (SUBREG_REG (op)) == DImode
4898 || GET_MODE (SUBREG_REG (op)) == TImode
4899 || GET_MODE (SUBREG_REG (op)) == DDmode
4900 || GET_MODE (SUBREG_REG (op)) == TDmode))
4905 && GET_CODE (op) == SUBREG
4907 && REG_P (SUBREG_REG (op))
4908 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
4914 /* AIX increases natural record alignment to doubleword if the first
4915 field is an FP double while the FP fields remain word aligned. */
4918 rs6000_special_round_type_align (tree type, unsigned int computed,
4919 unsigned int specified)
4921 unsigned int align = MAX (computed, specified);
4922 tree field = TYPE_FIELDS (type);
4924 /* Skip all non field decls */
4925 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4926 field = TREE_CHAIN (field);
4928 if (field != NULL && field != type)
4930 type = TREE_TYPE (field);
4931 while (TREE_CODE (type) == ARRAY_TYPE)
4932 type = TREE_TYPE (type);
4934 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
4935 align = MAX (align, 64);
4941 /* Darwin increases record alignment to the natural alignment of
4945 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
4946 unsigned int specified)
4948 unsigned int align = MAX (computed, specified);
4950 if (TYPE_PACKED (type))
4953 /* Find the first field, looking down into aggregates. */
4955 tree field = TYPE_FIELDS (type);
4956 /* Skip all non field decls */
4957 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
4958 field = TREE_CHAIN (field);
4961 /* A packed field does not contribute any extra alignment. */
4962 if (DECL_PACKED (field))
4964 type = TREE_TYPE (field);
4965 while (TREE_CODE (type) == ARRAY_TYPE)
4966 type = TREE_TYPE (type);
4967 } while (AGGREGATE_TYPE_P (type));
4969 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
4970 align = MAX (align, TYPE_ALIGN (type));
4975 /* Return 1 for an operand in small memory on V.4/eabi. */
4978 small_data_operand (rtx op ATTRIBUTE_UNUSED,
4979 enum machine_mode mode ATTRIBUTE_UNUSED)
4984 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
4987 if (DEFAULT_ABI != ABI_V4)
4990 /* Vector and float memory instructions have a limited offset on the
4991 SPE, so using a vector or float variable directly as an operand is
4994 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
4997 if (GET_CODE (op) == SYMBOL_REF)
5000 else if (GET_CODE (op) != CONST
5001 || GET_CODE (XEXP (op, 0)) != PLUS
5002 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5003 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5008 rtx sum = XEXP (op, 0);
5009 HOST_WIDE_INT summand;
5011 /* We have to be careful here, because it is the referenced address
5012 that must be 32k from _SDA_BASE_, not just the symbol. */
5013 summand = INTVAL (XEXP (sum, 1));
5014 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
5017 sym_ref = XEXP (sum, 0);
5020 return SYMBOL_REF_SMALL_P (sym_ref);
5026 /* Return true if either operand is a general purpose register. */
5029 gpr_or_gpr_p (rtx op0, rtx op1)
5031 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5032 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5036 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5039 reg_offset_addressing_ok_p (enum machine_mode mode)
5049 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5050 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5058 /* Paired vector modes. Only reg+reg addressing is valid. */
5059 if (TARGET_PAIRED_FLOAT)
5071 virtual_stack_registers_memory_p (rtx op)
5075 if (GET_CODE (op) == REG)
5076 regnum = REGNO (op);
5078 else if (GET_CODE (op) == PLUS
5079 && GET_CODE (XEXP (op, 0)) == REG
5080 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5081 regnum = REGNO (XEXP (op, 0));
5086 return (regnum >= FIRST_VIRTUAL_REGISTER
5087 && regnum <= LAST_VIRTUAL_REGISTER);
5091 constant_pool_expr_p (rtx op)
5095 split_const (op, &base, &offset);
5096 return (GET_CODE (base) == SYMBOL_REF
5097 && CONSTANT_POOL_ADDRESS_P (base)
5098 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5102 toc_relative_expr_p (rtx op)
5106 if (GET_CODE (op) != CONST)
5109 split_const (op, &base, &offset);
5110 return (GET_CODE (base) == UNSPEC
5111 && XINT (base, 1) == UNSPEC_TOCREL);
5115 legitimate_constant_pool_address_p (rtx x)
5118 && GET_CODE (x) == PLUS
5119 && GET_CODE (XEXP (x, 0)) == REG
5120 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
5121 && toc_relative_expr_p (XEXP (x, 1)));
5125 legitimate_small_data_p (enum machine_mode mode, rtx x)
5127 return (DEFAULT_ABI == ABI_V4
5128 && !flag_pic && !TARGET_TOC
5129 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5130 && small_data_operand (x, mode));
5133 /* SPE offset addressing is limited to 5-bits worth of double words. */
5134 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5137 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5139 unsigned HOST_WIDE_INT offset, extra;
5141 if (GET_CODE (x) != PLUS)
5143 if (GET_CODE (XEXP (x, 0)) != REG)
5145 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5147 if (!reg_offset_addressing_ok_p (mode))
5148 return virtual_stack_registers_memory_p (x);
5149 if (legitimate_constant_pool_address_p (x))
5151 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5154 offset = INTVAL (XEXP (x, 1));
5162 /* SPE vector modes. */
5163 return SPE_CONST_OFFSET_OK (offset);
5166 if (TARGET_E500_DOUBLE)
5167 return SPE_CONST_OFFSET_OK (offset);
5169 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5171 if (VECTOR_MEM_VSX_P (DFmode))
5176 /* On e500v2, we may have:
5178 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5180 Which gets addressed with evldd instructions. */
5181 if (TARGET_E500_DOUBLE)
5182 return SPE_CONST_OFFSET_OK (offset);
5184 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5186 else if (offset & 3)
5191 if (TARGET_E500_DOUBLE)
5192 return (SPE_CONST_OFFSET_OK (offset)
5193 && SPE_CONST_OFFSET_OK (offset + 8));
5197 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5199 else if (offset & 3)
5210 return (offset < 0x10000) && (offset + extra < 0x10000);
5214 legitimate_indexed_address_p (rtx x, int strict)
5218 if (GET_CODE (x) != PLUS)
5224 /* Recognize the rtl generated by reload which we know will later be
5225 replaced with proper base and index regs. */
5227 && reload_in_progress
5228 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5232 return (REG_P (op0) && REG_P (op1)
5233 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5234 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5235 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5236 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5240 avoiding_indexed_address_p (enum machine_mode mode)
5242 /* Avoid indexed addressing for modes that have non-indexed
5243 load/store instruction forms. */
5244 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5248 legitimate_indirect_address_p (rtx x, int strict)
5250 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5254 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5256 if (!TARGET_MACHO || !flag_pic
5257 || mode != SImode || GET_CODE (x) != MEM)
5261 if (GET_CODE (x) != LO_SUM)
5263 if (GET_CODE (XEXP (x, 0)) != REG)
5265 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5269 return CONSTANT_P (x);
5273 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5275 if (GET_CODE (x) != LO_SUM)
5277 if (GET_CODE (XEXP (x, 0)) != REG)
5279 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5281 /* Restrict addressing for DI because of our SUBREG hackery. */
5282 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5283 || mode == DDmode || mode == TDmode
5288 if (TARGET_ELF || TARGET_MACHO)
5290 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5294 if (GET_MODE_NUNITS (mode) != 1)
5296 if (GET_MODE_BITSIZE (mode) > 64
5297 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5298 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5299 && (mode == DFmode || mode == DDmode))))
5302 return CONSTANT_P (x);
5309 /* Try machine-dependent ways of modifying an illegitimate address
5310 to be legitimate. If we find one, return the new, valid address.
5311 This is used from only one place: `memory_address' in explow.c.
5313 OLDX is the address as it was before break_out_memory_refs was
5314 called. In some cases it is useful to look at this to decide what
5317 It is always safe for this function to do nothing. It exists to
5318 recognize opportunities to optimize the output.
5320 On RS/6000, first check for the sum of a register with a constant
5321 integer that is out of range. If so, generate code to add the
5322 constant with the low-order 16 bits masked to the register and force
5323 this result into another register (this can be done with `cau').
5324 Then generate an address of REG+(CONST&0xffff), allowing for the
5325 possibility of bit 16 being a one.
5327 Then check for the sum of a register and something not constant, try to
5328 load the other things into a register and return the sum. */
5331 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5332 enum machine_mode mode)
5334 unsigned int extra = 0;
5336 if (!reg_offset_addressing_ok_p (mode))
5338 if (virtual_stack_registers_memory_p (x))
5341 /* In theory we should not be seeing addresses of the form reg+0,
5342 but just in case it is generated, optimize it away. */
5343 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5344 return force_reg (Pmode, XEXP (x, 0));
5346 /* Make sure both operands are registers. */
5347 else if (GET_CODE (x) == PLUS)
5348 return gen_rtx_PLUS (Pmode,
5349 force_reg (Pmode, XEXP (x, 0)),
5350 force_reg (Pmode, XEXP (x, 1)));
5352 return force_reg (Pmode, x);
5354 if (GET_CODE (x) == SYMBOL_REF)
5356 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5358 return rs6000_legitimize_tls_address (x, model);
5368 if (!TARGET_POWERPC64)
5376 extra = TARGET_POWERPC64 ? 8 : 12;
5382 if (GET_CODE (x) == PLUS
5383 && GET_CODE (XEXP (x, 0)) == REG
5384 && GET_CODE (XEXP (x, 1)) == CONST_INT
5385 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5387 && !((TARGET_POWERPC64
5388 && (mode == DImode || mode == TImode)
5389 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5390 || SPE_VECTOR_MODE (mode)
5391 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5392 || mode == DImode || mode == DDmode
5393 || mode == TDmode))))
5395 HOST_WIDE_INT high_int, low_int;
5397 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5398 if (low_int >= 0x8000 - extra)
5400 high_int = INTVAL (XEXP (x, 1)) - low_int;
5401 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5402 GEN_INT (high_int)), 0);
5403 return plus_constant (sum, low_int);
5405 else if (GET_CODE (x) == PLUS
5406 && GET_CODE (XEXP (x, 0)) == REG
5407 && GET_CODE (XEXP (x, 1)) != CONST_INT
5408 && GET_MODE_NUNITS (mode) == 1
5409 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5411 || ((mode != DImode && mode != DFmode && mode != DDmode)
5412 || (TARGET_E500_DOUBLE && mode != DDmode)))
5413 && (TARGET_POWERPC64 || mode != DImode)
5414 && !avoiding_indexed_address_p (mode)
5419 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5420 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5422 else if (SPE_VECTOR_MODE (mode)
5423 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5424 || mode == DDmode || mode == TDmode
5425 || mode == DImode)))
5429 /* We accept [reg + reg] and [reg + OFFSET]. */
5431 if (GET_CODE (x) == PLUS)
5433 rtx op1 = XEXP (x, 0);
5434 rtx op2 = XEXP (x, 1);
5437 op1 = force_reg (Pmode, op1);
5439 if (GET_CODE (op2) != REG
5440 && (GET_CODE (op2) != CONST_INT
5441 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5442 || (GET_MODE_SIZE (mode) > 8
5443 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5444 op2 = force_reg (Pmode, op2);
5446 /* We can't always do [reg + reg] for these, because [reg +
5447 reg + offset] is not a legitimate addressing mode. */
5448 y = gen_rtx_PLUS (Pmode, op1, op2);
5450 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5451 return force_reg (Pmode, y);
5456 return force_reg (Pmode, x);
5462 && GET_CODE (x) != CONST_INT
5463 && GET_CODE (x) != CONST_DOUBLE
5465 && GET_MODE_NUNITS (mode) == 1
5466 && (GET_MODE_BITSIZE (mode) <= 32
5467 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5468 && (mode == DFmode || mode == DDmode))))
5470 rtx reg = gen_reg_rtx (Pmode);
5471 emit_insn (gen_elf_high (reg, x));
5472 return gen_rtx_LO_SUM (Pmode, reg, x);
5474 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5477 && ! MACHO_DYNAMIC_NO_PIC_P
5479 && GET_CODE (x) != CONST_INT
5480 && GET_CODE (x) != CONST_DOUBLE
5482 && GET_MODE_NUNITS (mode) == 1
5483 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5484 || (mode != DFmode && mode != DDmode))
5488 rtx reg = gen_reg_rtx (Pmode);
5489 emit_insn (gen_macho_high (reg, x));
5490 return gen_rtx_LO_SUM (Pmode, reg, x);
5493 && GET_CODE (x) == SYMBOL_REF
5494 && constant_pool_expr_p (x)
5495 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
5497 return create_TOC_reference (x);
5503 /* Debug version of rs6000_legitimize_address. */
5505 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
5511 ret = rs6000_legitimize_address (x, oldx, mode);
5512 insns = get_insns ();
5518 "\nrs6000_legitimize_address: mode %s, old code %s, "
5519 "new code %s, modified\n",
5520 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
5521 GET_RTX_NAME (GET_CODE (ret)));
5523 fprintf (stderr, "Original address:\n");
5526 fprintf (stderr, "oldx:\n");
5529 fprintf (stderr, "New address:\n");
5534 fprintf (stderr, "Insns added:\n");
5535 debug_rtx_list (insns, 20);
5541 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
5542 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
5553 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
5554 We need to emit DTP-relative relocations. */
5557 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
5562 fputs ("\t.long\t", file);
5565 fputs (DOUBLE_INT_ASM_OP, file);
5570 output_addr_const (file, x);
5571 fputs ("@dtprel+0x8000", file);
5574 /* In the name of slightly smaller debug output, and to cater to
5575 general assembler lossage, recognize various UNSPEC sequences
5576 and turn them back into a direct symbol reference. */
5579 rs6000_delegitimize_address (rtx orig_x)
5583 orig_x = delegitimize_mem_from_attrs (orig_x);
5588 if (GET_CODE (x) == PLUS
5589 && GET_CODE (XEXP (x, 1)) == CONST
5590 && GET_CODE (XEXP (x, 0)) == REG
5591 && REGNO (XEXP (x, 0)) == TOC_REGISTER)
5593 y = XEXP (XEXP (x, 1), 0);
5594 if (GET_CODE (y) == UNSPEC
5595 && XINT (y, 1) == UNSPEC_TOCREL)
5597 y = XVECEXP (y, 0, 0);
5598 if (!MEM_P (orig_x))
5601 return replace_equiv_address_nv (orig_x, y);
5607 && GET_CODE (orig_x) == LO_SUM
5608 && GET_CODE (XEXP (x, 1)) == CONST)
5610 y = XEXP (XEXP (x, 1), 0);
5611 if (GET_CODE (y) == UNSPEC
5612 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
5613 return XVECEXP (y, 0, 0);
5619 /* Construct the SYMBOL_REF for the tls_get_addr function. */
5621 static GTY(()) rtx rs6000_tls_symbol;
5623 rs6000_tls_get_addr (void)
5625 if (!rs6000_tls_symbol)
5626 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
5628 return rs6000_tls_symbol;
5631 /* Construct the SYMBOL_REF for TLS GOT references. */
5633 static GTY(()) rtx rs6000_got_symbol;
5635 rs6000_got_sym (void)
5637 if (!rs6000_got_symbol)
5639 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
5640 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
5641 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
5644 return rs6000_got_symbol;
5647 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
5648 this (thread-local) address. */
5651 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
5655 dest = gen_reg_rtx (Pmode);
5656 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
5662 tlsreg = gen_rtx_REG (Pmode, 13);
5663 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
5667 tlsreg = gen_rtx_REG (Pmode, 2);
5668 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
5672 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
5676 tmp = gen_reg_rtx (Pmode);
5679 tlsreg = gen_rtx_REG (Pmode, 13);
5680 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
5684 tlsreg = gen_rtx_REG (Pmode, 2);
5685 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
5689 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
5691 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
5696 rtx r3, got, tga, tmp1, tmp2, call_insn;
5698 /* We currently use relocations like @got@tlsgd for tls, which
5699 means the linker will handle allocation of tls entries, placing
5700 them in the .got section. So use a pointer to the .got section,
5701 not one to secondary TOC sections used by 64-bit -mminimal-toc,
5702 or to secondary GOT sections used by 32-bit -fPIC. */
5704 got = gen_rtx_REG (Pmode, 2);
5708 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
5711 rtx gsym = rs6000_got_sym ();
5712 got = gen_reg_rtx (Pmode);
5714 rs6000_emit_move (got, gsym, Pmode);
5719 tmp1 = gen_reg_rtx (Pmode);
5720 tmp2 = gen_reg_rtx (Pmode);
5721 mem = gen_const_mem (Pmode, tmp1);
5722 lab = gen_label_rtx ();
5723 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
5724 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
5725 emit_move_insn (tmp2, mem);
5726 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
5727 set_unique_reg_note (last, REG_EQUAL, gsym);
5732 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
5734 r3 = gen_rtx_REG (Pmode, 3);
5735 tga = rs6000_tls_get_addr ();
5736 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
5738 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5739 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
5740 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5741 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
5742 else if (DEFAULT_ABI == ABI_V4)
5743 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
5746 call_insn = last_call_insn ();
5747 PATTERN (call_insn) = insn;
5748 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5749 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5750 pic_offset_table_rtx);
5752 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
5754 r3 = gen_rtx_REG (Pmode, 3);
5755 tga = rs6000_tls_get_addr ();
5756 tmp1 = gen_reg_rtx (Pmode);
5757 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
5759 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5760 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
5761 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
5762 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
5763 else if (DEFAULT_ABI == ABI_V4)
5764 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
5767 call_insn = last_call_insn ();
5768 PATTERN (call_insn) = insn;
5769 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
5770 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
5771 pic_offset_table_rtx);
5773 if (rs6000_tls_size == 16)
5776 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
5778 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
5780 else if (rs6000_tls_size == 32)
5782 tmp2 = gen_reg_rtx (Pmode);
5784 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
5786 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
5789 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
5791 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
5795 tmp2 = gen_reg_rtx (Pmode);
5797 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
5799 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
5801 insn = gen_rtx_SET (Pmode, dest,
5802 gen_rtx_PLUS (Pmode, tmp2, tmp1));
5808 /* IE, or 64-bit offset LE. */
5809 tmp2 = gen_reg_rtx (Pmode);
5811 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
5813 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
5816 insn = gen_tls_tls_64 (dest, tmp2, addr);
5818 insn = gen_tls_tls_32 (dest, tmp2, addr);
5826 /* Return 1 if X contains a thread-local symbol. */
5829 rs6000_tls_referenced_p (rtx x)
5831 if (! TARGET_HAVE_TLS)
5834 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
5837 /* Return 1 if *X is a thread-local symbol. This is the same as
5838 rs6000_tls_symbol_ref except for the type of the unused argument. */
5841 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
5843 return RS6000_SYMBOL_REF_TLS_P (*x);
5846 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
5847 replace the input X, or the original X if no replacement is called for.
5848 The output parameter *WIN is 1 if the calling macro should goto WIN,
5851 For RS/6000, we wish to handle large displacements off a base
5852 register by splitting the addend across an addiu/addis and the mem insn.
5853 This cuts number of extra insns needed from 3 to 1.
5855 On Darwin, we use this to generate code for floating point constants.
5856 A movsf_low is generated so we wind up with 2 instructions rather than 3.
5857 The Darwin code is inside #if TARGET_MACHO because only then are the
5858 machopic_* functions defined. */
5860 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
5861 int opnum, int type,
5862 int ind_levels ATTRIBUTE_UNUSED, int *win)
5864 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
5866 /* We must recognize output that we have already generated ourselves. */
5867 if (GET_CODE (x) == PLUS
5868 && GET_CODE (XEXP (x, 0)) == PLUS
5869 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
5870 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
5871 && GET_CODE (XEXP (x, 1)) == CONST_INT)
5873 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5874 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5875 opnum, (enum reload_type)type);
5881 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
5882 && GET_CODE (x) == LO_SUM
5883 && GET_CODE (XEXP (x, 0)) == PLUS
5884 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
5885 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
5886 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
5887 && machopic_operand_p (XEXP (x, 1)))
5889 /* Result of previous invocation of this function on Darwin
5890 floating point constant. */
5891 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5892 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5893 opnum, (enum reload_type)type);
5899 /* Force ld/std non-word aligned offset into base register by wrapping
5901 if (GET_CODE (x) == PLUS
5902 && GET_CODE (XEXP (x, 0)) == REG
5903 && REGNO (XEXP (x, 0)) < 32
5904 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5905 && GET_CODE (XEXP (x, 1)) == CONST_INT
5907 && (INTVAL (XEXP (x, 1)) & 3) != 0
5908 && VECTOR_MEM_NONE_P (mode)
5909 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
5910 && TARGET_POWERPC64)
5912 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
5913 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5914 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5915 opnum, (enum reload_type) type);
5920 if (GET_CODE (x) == PLUS
5921 && GET_CODE (XEXP (x, 0)) == REG
5922 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
5923 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
5924 && GET_CODE (XEXP (x, 1)) == CONST_INT
5926 && !SPE_VECTOR_MODE (mode)
5927 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5928 || mode == DDmode || mode == TDmode
5930 && VECTOR_MEM_NONE_P (mode))
5932 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
5933 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
5935 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
5937 /* Check for 32-bit overflow. */
5938 if (high + low != val)
5944 /* Reload the high part into a base reg; leave the low part
5945 in the mem directly. */
5947 x = gen_rtx_PLUS (GET_MODE (x),
5948 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
5952 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5953 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
5954 opnum, (enum reload_type)type);
5959 if (GET_CODE (x) == SYMBOL_REF
5961 && VECTOR_MEM_NONE_P (mode)
5962 && !SPE_VECTOR_MODE (mode)
5964 && DEFAULT_ABI == ABI_DARWIN
5965 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
5967 && DEFAULT_ABI == ABI_V4
5970 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
5971 The same goes for DImode without 64-bit gprs and DFmode and DDmode
5975 && (mode != DImode || TARGET_POWERPC64)
5976 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
5977 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
5982 rtx offset = machopic_gen_offset (x);
5983 x = gen_rtx_LO_SUM (GET_MODE (x),
5984 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
5985 gen_rtx_HIGH (Pmode, offset)), offset);
5989 x = gen_rtx_LO_SUM (GET_MODE (x),
5990 gen_rtx_HIGH (Pmode, x), x);
5992 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
5993 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
5994 opnum, (enum reload_type)type);
5999 /* Reload an offset address wrapped by an AND that represents the
6000 masking of the lower bits. Strip the outer AND and let reload
6001 convert the offset address into an indirect address. For VSX,
6002 force reload to create the address with an AND in a separate
6003 register, because we can't guarantee an altivec register will
6005 if (VECTOR_MEM_ALTIVEC_P (mode)
6006 && GET_CODE (x) == AND
6007 && GET_CODE (XEXP (x, 0)) == PLUS
6008 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6009 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6010 && GET_CODE (XEXP (x, 1)) == CONST_INT
6011 && INTVAL (XEXP (x, 1)) == -16)
6020 && GET_CODE (x) == SYMBOL_REF
6021 && constant_pool_expr_p (x)
6022 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6024 x = create_TOC_reference (x);
6032 /* Debug version of rs6000_legitimize_reload_address. */
6034 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6035 int opnum, int type,
6036 int ind_levels, int *win)
6038 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6041 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6042 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6043 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6047 fprintf (stderr, "Same address returned\n");
6049 fprintf (stderr, "NULL returned\n");
6052 fprintf (stderr, "New address:\n");
6059 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6060 that is a valid memory address for an instruction.
6061 The MODE argument is the machine mode for the MEM expression
6062 that wants to use this address.
6064 On the RS/6000, there are four valid address: a SYMBOL_REF that
6065 refers to a constant pool entry of an address (or the sum of it
6066 plus a constant), a short (16-bit signed) constant plus a register,
6067 the sum of two registers, or a register indirect, possibly with an
6068 auto-increment. For DFmode, DDmode and DImode with a constant plus
6069 register, we must ensure that both words are addressable or PowerPC64
6070 with offset word aligned.
6072 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6073 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6074 because adjacent memory cells are accessed by adding word-sized offsets
6075 during assembly output. */
6077 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6079 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6081 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6082 if (VECTOR_MEM_ALTIVEC_P (mode)
6083 && GET_CODE (x) == AND
6084 && GET_CODE (XEXP (x, 1)) == CONST_INT
6085 && INTVAL (XEXP (x, 1)) == -16)
6088 if (RS6000_SYMBOL_REF_TLS_P (x))
6090 if (legitimate_indirect_address_p (x, reg_ok_strict))
6092 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6093 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6094 && !SPE_VECTOR_MODE (mode)
6097 /* Restrict addressing for DI because of our SUBREG hackery. */
6098 && !(TARGET_E500_DOUBLE
6099 && (mode == DFmode || mode == DDmode || mode == DImode))
6101 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6103 if (virtual_stack_registers_memory_p (x))
6105 if (reg_offset_p && legitimate_small_data_p (mode, x))
6107 if (reg_offset_p && legitimate_constant_pool_address_p (x))
6109 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6112 && GET_CODE (x) == PLUS
6113 && GET_CODE (XEXP (x, 0)) == REG
6114 && (XEXP (x, 0) == virtual_stack_vars_rtx
6115 || XEXP (x, 0) == arg_pointer_rtx)
6116 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6118 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6123 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6125 || (mode != DFmode && mode != DDmode)
6126 || (TARGET_E500_DOUBLE && mode != DDmode))
6127 && (TARGET_POWERPC64 || mode != DImode)
6128 && !avoiding_indexed_address_p (mode)
6129 && legitimate_indexed_address_p (x, reg_ok_strict))
6131 if (GET_CODE (x) == PRE_MODIFY
6135 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6137 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6138 && (TARGET_POWERPC64 || mode != DImode)
6139 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6140 && !SPE_VECTOR_MODE (mode)
6141 /* Restrict addressing for DI because of our SUBREG hackery. */
6142 && !(TARGET_E500_DOUBLE
6143 && (mode == DFmode || mode == DDmode || mode == DImode))
6145 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6146 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6147 || (!avoiding_indexed_address_p (mode)
6148 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6149 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6151 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6156 /* Debug version of rs6000_legitimate_address_p. */
6158 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6161 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6163 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6164 "strict = %d, code = %s\n",
6165 ret ? "true" : "false",
6166 GET_MODE_NAME (mode),
6168 GET_RTX_NAME (GET_CODE (x)));
6174 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6177 rs6000_mode_dependent_address_p (const_rtx addr)
6179 return rs6000_mode_dependent_address_ptr (addr);
6182 /* Go to LABEL if ADDR (a legitimate address expression)
6183 has an effect that depends on the machine mode it is used for.
6185 On the RS/6000 this is true of all integral offsets (since AltiVec
6186 and VSX modes don't allow them) or is a pre-increment or decrement.
6188 ??? Except that due to conceptual problems in offsettable_address_p
6189 we can't really report the problems of integral offsets. So leave
6190 this assuming that the adjustable offset must be valid for the
6191 sub-words of a TFmode operand, which is what we had before. */
6194 rs6000_mode_dependent_address (const_rtx addr)
6196 switch (GET_CODE (addr))
6199 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6200 is considered a legitimate address before reload, so there
6201 are no offset restrictions in that case. Note that this
6202 condition is safe in strict mode because any address involving
6203 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6204 been rejected as illegitimate. */
6205 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6206 && XEXP (addr, 0) != arg_pointer_rtx
6207 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6209 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6210 return val + 12 + 0x8000 >= 0x10000;
6217 /* Auto-increment cases are now treated generically in recog.c. */
6219 return TARGET_UPDATE;
6221 /* AND is only allowed in Altivec loads. */
6232 /* Debug version of rs6000_mode_dependent_address. */
6234 rs6000_debug_mode_dependent_address (const_rtx addr)
6236 bool ret = rs6000_mode_dependent_address (addr);
6238 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6239 ret ? "true" : "false");
6245 /* Implement FIND_BASE_TERM. */
6248 rs6000_find_base_term (rtx op)
6252 split_const (op, &base, &offset);
6253 if (GET_CODE (base) == UNSPEC)
6254 switch (XINT (base, 1))
6257 case UNSPEC_MACHOPIC_OFFSET:
6258 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6259 for aliasing purposes. */
6260 return XVECEXP (base, 0, 0);
6266 /* More elaborate version of recog's offsettable_memref_p predicate
6267 that works around the ??? note of rs6000_mode_dependent_address.
6268 In particular it accepts
6270 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6272 in 32-bit mode, that the recog predicate rejects. */
6275 rs6000_offsettable_memref_p (rtx op)
6280 /* First mimic offsettable_memref_p. */
6281 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6284 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6285 the latter predicate knows nothing about the mode of the memory
6286 reference and, therefore, assumes that it is the largest supported
6287 mode (TFmode). As a consequence, legitimate offsettable memory
6288 references are rejected. rs6000_legitimate_offset_address_p contains
6289 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6290 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6293 /* Change register usage conditional on target flags. */
6295 rs6000_conditional_register_usage (void)
6299 /* Set MQ register fixed (already call_used) if not POWER
6300 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6305 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6307 fixed_regs[13] = call_used_regs[13]
6308 = call_really_used_regs[13] = 1;
6310 /* Conditionally disable FPRs. */
6311 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6312 for (i = 32; i < 64; i++)
6313 fixed_regs[i] = call_used_regs[i]
6314 = call_really_used_regs[i] = 1;
6316 /* The TOC register is not killed across calls in a way that is
6317 visible to the compiler. */
6318 if (DEFAULT_ABI == ABI_AIX)
6319 call_really_used_regs[2] = 0;
6321 if (DEFAULT_ABI == ABI_V4
6322 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6324 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6326 if (DEFAULT_ABI == ABI_V4
6327 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6329 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6330 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6331 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6333 if (DEFAULT_ABI == ABI_DARWIN
6334 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6335 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6336 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6337 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6339 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6340 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6341 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6345 global_regs[SPEFSCR_REGNO] = 1;
6346 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6347 registers in prologues and epilogues. We no longer use r14
6348 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6349 pool for link-compatibility with older versions of GCC. Once
6350 "old" code has died out, we can return r14 to the allocation
6353 = call_used_regs[14]
6354 = call_really_used_regs[14] = 1;
6357 if (!TARGET_ALTIVEC && !TARGET_VSX)
6359 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6360 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6361 call_really_used_regs[VRSAVE_REGNO] = 1;
6364 if (TARGET_ALTIVEC || TARGET_VSX)
6365 global_regs[VSCR_REGNO] = 1;
6367 if (TARGET_ALTIVEC_ABI)
6369 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6370 call_used_regs[i] = call_really_used_regs[i] = 1;
6372 /* AIX reserves VR20:31 in non-extended ABI mode. */
6374 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6375 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6379 /* Try to output insns to set TARGET equal to the constant C if it can
6380 be done in less than N insns. Do all computations in MODE.
6381 Returns the place where the output has been placed if it can be
6382 done and the insns have been emitted. If it would take more than N
6383 insns, zero is returned and no insns and emitted. */
6386 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6387 rtx source, int n ATTRIBUTE_UNUSED)
6389 rtx result, insn, set;
6390 HOST_WIDE_INT c0, c1;
6397 dest = gen_reg_rtx (mode);
6398 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6402 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6404 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6405 GEN_INT (INTVAL (source)
6406 & (~ (HOST_WIDE_INT) 0xffff))));
6407 emit_insn (gen_rtx_SET (VOIDmode, dest,
6408 gen_rtx_IOR (SImode, copy_rtx (result),
6409 GEN_INT (INTVAL (source) & 0xffff))));
6414 switch (GET_CODE (source))
6417 c0 = INTVAL (source);
6422 #if HOST_BITS_PER_WIDE_INT >= 64
6423 c0 = CONST_DOUBLE_LOW (source);
6426 c0 = CONST_DOUBLE_LOW (source);
6427 c1 = CONST_DOUBLE_HIGH (source);
6435 result = rs6000_emit_set_long_const (dest, c0, c1);
6442 insn = get_last_insn ();
6443 set = single_set (insn);
6444 if (! CONSTANT_P (SET_SRC (set)))
6445 set_unique_reg_note (insn, REG_EQUAL, source);
6450 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6451 fall back to a straight forward decomposition. We do this to avoid
6452 exponential run times encountered when looking for longer sequences
6453 with rs6000_emit_set_const. */
6455 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
6457 if (!TARGET_POWERPC64)
6459 rtx operand1, operand2;
6461 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
6463 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
6465 emit_move_insn (operand1, GEN_INT (c1));
6466 emit_move_insn (operand2, GEN_INT (c2));
6470 HOST_WIDE_INT ud1, ud2, ud3, ud4;
6473 ud2 = (c1 & 0xffff0000) >> 16;
6474 #if HOST_BITS_PER_WIDE_INT >= 64
6478 ud4 = (c2 & 0xffff0000) >> 16;
6480 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
6481 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
6484 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
6486 emit_move_insn (dest, GEN_INT (ud1));
6489 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
6490 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
6493 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6496 emit_move_insn (dest, GEN_INT (ud2 << 16));
6498 emit_move_insn (copy_rtx (dest),
6499 gen_rtx_IOR (DImode, copy_rtx (dest),
6502 else if (ud3 == 0 && ud4 == 0)
6504 gcc_assert (ud2 & 0x8000);
6505 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
6508 emit_move_insn (copy_rtx (dest),
6509 gen_rtx_IOR (DImode, copy_rtx (dest),
6511 emit_move_insn (copy_rtx (dest),
6512 gen_rtx_ZERO_EXTEND (DImode,
6513 gen_lowpart (SImode,
6516 else if ((ud4 == 0xffff && (ud3 & 0x8000))
6517 || (ud4 == 0 && ! (ud3 & 0x8000)))
6520 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
6523 emit_move_insn (dest, GEN_INT (ud3 << 16));
6526 emit_move_insn (copy_rtx (dest),
6527 gen_rtx_IOR (DImode, copy_rtx (dest),
6529 emit_move_insn (copy_rtx (dest),
6530 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6533 emit_move_insn (copy_rtx (dest),
6534 gen_rtx_IOR (DImode, copy_rtx (dest),
6540 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
6543 emit_move_insn (dest, GEN_INT (ud4 << 16));
6546 emit_move_insn (copy_rtx (dest),
6547 gen_rtx_IOR (DImode, copy_rtx (dest),
6550 emit_move_insn (copy_rtx (dest),
6551 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
6554 emit_move_insn (copy_rtx (dest),
6555 gen_rtx_IOR (DImode, copy_rtx (dest),
6556 GEN_INT (ud2 << 16)));
6558 emit_move_insn (copy_rtx (dest),
6559 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
6565 /* Helper for the following. Get rid of [r+r] memory refs
6566 in cases where it won't work (TImode, TFmode, TDmode). */
6569 rs6000_eliminate_indexed_memrefs (rtx operands[2])
6571 if (GET_CODE (operands[0]) == MEM
6572 && GET_CODE (XEXP (operands[0], 0)) != REG
6573 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
6574 && ! reload_in_progress)
6576 = replace_equiv_address (operands[0],
6577 copy_addr_to_reg (XEXP (operands[0], 0)));
6579 if (GET_CODE (operands[1]) == MEM
6580 && GET_CODE (XEXP (operands[1], 0)) != REG
6581 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
6582 && ! reload_in_progress)
6584 = replace_equiv_address (operands[1],
6585 copy_addr_to_reg (XEXP (operands[1], 0)));
6588 /* Emit a move from SOURCE to DEST in mode MODE. */
6590 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
6594 operands[1] = source;
6596 if (TARGET_DEBUG_ADDR)
6599 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
6600 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
6601 GET_MODE_NAME (mode),
6604 can_create_pseudo_p ());
6606 fprintf (stderr, "source:\n");
6610 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
6611 if (GET_CODE (operands[1]) == CONST_DOUBLE
6612 && ! FLOAT_MODE_P (mode)
6613 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
6615 /* FIXME. This should never happen. */
6616 /* Since it seems that it does, do the safe thing and convert
6618 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
6620 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
6621 || FLOAT_MODE_P (mode)
6622 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
6623 || CONST_DOUBLE_LOW (operands[1]) < 0)
6624 && (CONST_DOUBLE_HIGH (operands[1]) != -1
6625 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
6627 /* Check if GCC is setting up a block move that will end up using FP
6628 registers as temporaries. We must make sure this is acceptable. */
6629 if (GET_CODE (operands[0]) == MEM
6630 && GET_CODE (operands[1]) == MEM
6632 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
6633 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
6634 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
6635 ? 32 : MEM_ALIGN (operands[0])))
6636 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
6638 : MEM_ALIGN (operands[1]))))
6639 && ! MEM_VOLATILE_P (operands [0])
6640 && ! MEM_VOLATILE_P (operands [1]))
6642 emit_move_insn (adjust_address (operands[0], SImode, 0),
6643 adjust_address (operands[1], SImode, 0));
6644 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
6645 adjust_address (copy_rtx (operands[1]), SImode, 4));
6649 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
6650 && !gpc_reg_operand (operands[1], mode))
6651 operands[1] = force_reg (mode, operands[1]);
6653 if (mode == SFmode && ! TARGET_POWERPC
6654 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6655 && GET_CODE (operands[0]) == MEM)
6659 if (reload_in_progress || reload_completed)
6660 regnum = true_regnum (operands[1]);
6661 else if (GET_CODE (operands[1]) == REG)
6662 regnum = REGNO (operands[1]);
6666 /* If operands[1] is a register, on POWER it may have
6667 double-precision data in it, so truncate it to single
6669 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
6672 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
6673 : gen_reg_rtx (mode));
6674 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
6675 operands[1] = newreg;
6679 /* Recognize the case where operand[1] is a reference to thread-local
6680 data and load its address to a register. */
6681 if (rs6000_tls_referenced_p (operands[1]))
6683 enum tls_model model;
6684 rtx tmp = operands[1];
6687 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
6689 addend = XEXP (XEXP (tmp, 0), 1);
6690 tmp = XEXP (XEXP (tmp, 0), 0);
6693 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
6694 model = SYMBOL_REF_TLS_MODEL (tmp);
6695 gcc_assert (model != 0);
6697 tmp = rs6000_legitimize_tls_address (tmp, model);
6700 tmp = gen_rtx_PLUS (mode, tmp, addend);
6701 tmp = force_operand (tmp, operands[0]);
6706 /* Handle the case where reload calls us with an invalid address. */
6707 if (reload_in_progress && mode == Pmode
6708 && (! general_operand (operands[1], mode)
6709 || ! nonimmediate_operand (operands[0], mode)))
6712 /* 128-bit constant floating-point values on Darwin should really be
6713 loaded as two parts. */
6714 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
6715 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
6717 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
6718 know how to get a DFmode SUBREG of a TFmode. */
6719 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
6720 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
6721 simplify_gen_subreg (imode, operands[1], mode, 0),
6723 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
6724 GET_MODE_SIZE (imode)),
6725 simplify_gen_subreg (imode, operands[1], mode,
6726 GET_MODE_SIZE (imode)),
6731 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
6732 cfun->machine->sdmode_stack_slot =
6733 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
6735 if (reload_in_progress
6737 && MEM_P (operands[0])
6738 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
6739 && REG_P (operands[1]))
6741 if (FP_REGNO_P (REGNO (operands[1])))
6743 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
6744 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6745 emit_insn (gen_movsd_store (mem, operands[1]));
6747 else if (INT_REGNO_P (REGNO (operands[1])))
6749 rtx mem = adjust_address_nv (operands[0], mode, 4);
6750 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6751 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
6757 if (reload_in_progress
6759 && REG_P (operands[0])
6760 && MEM_P (operands[1])
6761 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
6763 if (FP_REGNO_P (REGNO (operands[0])))
6765 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
6766 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6767 emit_insn (gen_movsd_load (operands[0], mem));
6769 else if (INT_REGNO_P (REGNO (operands[0])))
6771 rtx mem = adjust_address_nv (operands[1], mode, 4);
6772 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
6773 emit_insn (gen_movsd_hardfloat (operands[0], mem));
6780 /* FIXME: In the long term, this switch statement should go away
6781 and be replaced by a sequence of tests based on things like
6787 if (CONSTANT_P (operands[1])
6788 && GET_CODE (operands[1]) != CONST_INT)
6789 operands[1] = force_const_mem (mode, operands[1]);
6794 rs6000_eliminate_indexed_memrefs (operands);
6801 if (CONSTANT_P (operands[1])
6802 && ! easy_fp_constant (operands[1], mode))
6803 operands[1] = force_const_mem (mode, operands[1]);
6816 if (CONSTANT_P (operands[1])
6817 && !easy_vector_constant (operands[1], mode))
6818 operands[1] = force_const_mem (mode, operands[1]);
6823 /* Use default pattern for address of ELF small data */
6826 && DEFAULT_ABI == ABI_V4
6827 && (GET_CODE (operands[1]) == SYMBOL_REF
6828 || GET_CODE (operands[1]) == CONST)
6829 && small_data_operand (operands[1], mode))
6831 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6835 if (DEFAULT_ABI == ABI_V4
6836 && mode == Pmode && mode == SImode
6837 && flag_pic == 1 && got_operand (operands[1], mode))
6839 emit_insn (gen_movsi_got (operands[0], operands[1]));
6843 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
6847 && CONSTANT_P (operands[1])
6848 && GET_CODE (operands[1]) != HIGH
6849 && GET_CODE (operands[1]) != CONST_INT)
6851 rtx target = (!can_create_pseudo_p ()
6853 : gen_reg_rtx (mode));
6855 /* If this is a function address on -mcall-aixdesc,
6856 convert it to the address of the descriptor. */
6857 if (DEFAULT_ABI == ABI_AIX
6858 && GET_CODE (operands[1]) == SYMBOL_REF
6859 && XSTR (operands[1], 0)[0] == '.')
6861 const char *name = XSTR (operands[1], 0);
6863 while (*name == '.')
6865 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
6866 CONSTANT_POOL_ADDRESS_P (new_ref)
6867 = CONSTANT_POOL_ADDRESS_P (operands[1]);
6868 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
6869 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
6870 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
6871 operands[1] = new_ref;
6874 if (DEFAULT_ABI == ABI_DARWIN)
6877 if (MACHO_DYNAMIC_NO_PIC_P)
6879 /* Take care of any required data indirection. */
6880 operands[1] = rs6000_machopic_legitimize_pic_address (
6881 operands[1], mode, operands[0]);
6882 if (operands[0] != operands[1])
6883 emit_insn (gen_rtx_SET (VOIDmode,
6884 operands[0], operands[1]));
6888 emit_insn (gen_macho_high (target, operands[1]));
6889 emit_insn (gen_macho_low (operands[0], target, operands[1]));
6893 emit_insn (gen_elf_high (target, operands[1]));
6894 emit_insn (gen_elf_low (operands[0], target, operands[1]));
6898 /* If this is a SYMBOL_REF that refers to a constant pool entry,
6899 and we have put it in the TOC, we just need to make a TOC-relative
6902 && GET_CODE (operands[1]) == SYMBOL_REF
6903 && constant_pool_expr_p (operands[1])
6904 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
6905 get_pool_mode (operands[1])))
6907 operands[1] = create_TOC_reference (operands[1]);
6909 else if (mode == Pmode
6910 && CONSTANT_P (operands[1])
6911 && ((GET_CODE (operands[1]) != CONST_INT
6912 && ! easy_fp_constant (operands[1], mode))
6913 || (GET_CODE (operands[1]) == CONST_INT
6914 && num_insns_constant (operands[1], mode) > 2)
6915 || (GET_CODE (operands[0]) == REG
6916 && FP_REGNO_P (REGNO (operands[0]))))
6917 && GET_CODE (operands[1]) != HIGH
6918 && ! legitimate_constant_pool_address_p (operands[1])
6919 && ! toc_relative_expr_p (operands[1]))
6923 /* Darwin uses a special PIC legitimizer. */
6924 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
6927 rs6000_machopic_legitimize_pic_address (operands[1], mode,
6929 if (operands[0] != operands[1])
6930 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
6935 /* If we are to limit the number of things we put in the TOC and
6936 this is a symbol plus a constant we can add in one insn,
6937 just put the symbol in the TOC and add the constant. Don't do
6938 this if reload is in progress. */
6939 if (GET_CODE (operands[1]) == CONST
6940 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
6941 && GET_CODE (XEXP (operands[1], 0)) == PLUS
6942 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
6943 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
6944 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
6945 && ! side_effects_p (operands[0]))
6948 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
6949 rtx other = XEXP (XEXP (operands[1], 0), 1);
6951 sym = force_reg (mode, sym);
6952 emit_insn (gen_add3_insn (operands[0], sym, other));
6956 operands[1] = force_const_mem (mode, operands[1]);
6959 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6960 && constant_pool_expr_p (XEXP (operands[1], 0))
6961 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
6962 get_pool_constant (XEXP (operands[1], 0)),
6963 get_pool_mode (XEXP (operands[1], 0))))
6966 = gen_const_mem (mode,
6967 create_TOC_reference (XEXP (operands[1], 0)));
6968 set_mem_alias_set (operands[1], get_TOC_alias_set ());
6974 rs6000_eliminate_indexed_memrefs (operands);
6978 emit_insn (gen_rtx_PARALLEL (VOIDmode,
6980 gen_rtx_SET (VOIDmode,
6981 operands[0], operands[1]),
6982 gen_rtx_CLOBBER (VOIDmode,
6983 gen_rtx_SCRATCH (SImode)))));
6989 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
6992 /* Above, we may have called force_const_mem which may have returned
6993 an invalid address. If we can, fix this up; otherwise, reload will
6994 have to deal with it. */
6995 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
6996 operands[1] = validize_mem (operands[1]);
6999 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7002 /* Nonzero if we can use a floating-point register to pass this arg. */
7003 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7004 (SCALAR_FLOAT_MODE_P (MODE) \
7005 && (CUM)->fregno <= FP_ARG_MAX_REG \
7006 && TARGET_HARD_FLOAT && TARGET_FPRS)
7008 /* Nonzero if we can use an AltiVec register to pass this arg. */
7009 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7010 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7011 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7012 && TARGET_ALTIVEC_ABI \
7015 /* Return a nonzero value to say to return the function value in
7016 memory, just as large structures are always returned. TYPE will be
7017 the data type of the value, and FNTYPE will be the type of the
7018 function doing the returning, or @code{NULL} for libcalls.
7020 The AIX ABI for the RS/6000 specifies that all structures are
7021 returned in memory. The Darwin ABI does the same. The SVR4 ABI
7022 specifies that structures <= 8 bytes are returned in r3/r4, but a
7023 draft put them in memory, and GCC used to implement the draft
7024 instead of the final standard. Therefore, aix_struct_return
7025 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7026 compatibility can change DRAFT_V4_STRUCT_RET to override the
7027 default, and -m switches get the final word. See
7028 rs6000_override_options for more details.
7030 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7031 long double support is enabled. These values are returned in memory.
7033 int_size_in_bytes returns -1 for variable size objects, which go in
7034 memory always. The cast to unsigned makes -1 > 8. */
7037 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7039 /* In the darwin64 abi, try to use registers for larger structs
7041 if (rs6000_darwin64_abi
7042 && TREE_CODE (type) == RECORD_TYPE
7043 && int_size_in_bytes (type) > 0)
7045 CUMULATIVE_ARGS valcum;
7049 valcum.fregno = FP_ARG_MIN_REG;
7050 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7051 /* Do a trial code generation as if this were going to be passed
7052 as an argument; if any part goes in memory, we return NULL. */
7053 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
7056 /* Otherwise fall through to more conventional ABI rules. */
7059 if (AGGREGATE_TYPE_P (type)
7060 && (aix_struct_return
7061 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7064 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7065 modes only exist for GCC vector types if -maltivec. */
7066 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7067 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7070 /* Return synthetic vectors in memory. */
7071 if (TREE_CODE (type) == VECTOR_TYPE
7072 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7074 static bool warned_for_return_big_vectors = false;
7075 if (!warned_for_return_big_vectors)
7077 warning (0, "GCC vector returned by reference: "
7078 "non-standard ABI extension with no compatibility guarantee");
7079 warned_for_return_big_vectors = true;
7084 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7090 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7091 for a call to a function whose data type is FNTYPE.
7092 For a library call, FNTYPE is 0.
7094 For incoming args we set the number of arguments in the prototype large
7095 so we never return a PARALLEL. */
7098 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7099 rtx libname ATTRIBUTE_UNUSED, int incoming,
7100 int libcall, int n_named_args)
7102 static CUMULATIVE_ARGS zero_cumulative;
7104 *cum = zero_cumulative;
7106 cum->fregno = FP_ARG_MIN_REG;
7107 cum->vregno = ALTIVEC_ARG_MIN_REG;
7108 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7109 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7110 ? CALL_LIBCALL : CALL_NORMAL);
7111 cum->sysv_gregno = GP_ARG_MIN_REG;
7112 cum->stdarg = fntype
7113 && (TYPE_ARG_TYPES (fntype) != 0
7114 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
7115 != void_type_node));
7117 cum->nargs_prototype = 0;
7118 if (incoming || cum->prototype)
7119 cum->nargs_prototype = n_named_args;
7121 /* Check for a longcall attribute. */
7122 if ((!fntype && rs6000_default_long_calls)
7124 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7125 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7126 cum->call_cookie |= CALL_LONG;
7128 if (TARGET_DEBUG_ARG)
7130 fprintf (stderr, "\ninit_cumulative_args:");
7133 tree ret_type = TREE_TYPE (fntype);
7134 fprintf (stderr, " ret code = %s,",
7135 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7138 if (cum->call_cookie & CALL_LONG)
7139 fprintf (stderr, " longcall,");
7141 fprintf (stderr, " proto = %d, nargs = %d\n",
7142 cum->prototype, cum->nargs_prototype);
7147 && TARGET_ALTIVEC_ABI
7148 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7150 error ("cannot return value in vector register because"
7151 " altivec instructions are disabled, use -maltivec"
7156 /* Return true if TYPE must be passed on the stack and not in registers. */
7159 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7161 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7162 return must_pass_in_stack_var_size (mode, type);
7164 return must_pass_in_stack_var_size_or_pad (mode, type);
7167 /* If defined, a C expression which determines whether, and in which
7168 direction, to pad out an argument with extra space. The value
7169 should be of type `enum direction': either `upward' to pad above
7170 the argument, `downward' to pad below, or `none' to inhibit
7173 For the AIX ABI structs are always stored left shifted in their
7177 function_arg_padding (enum machine_mode mode, const_tree type)
7179 #ifndef AGGREGATE_PADDING_FIXED
7180 #define AGGREGATE_PADDING_FIXED 0
7182 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7183 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7186 if (!AGGREGATE_PADDING_FIXED)
7188 /* GCC used to pass structures of the same size as integer types as
7189 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7190 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7191 passed padded downward, except that -mstrict-align further
7192 muddied the water in that multi-component structures of 2 and 4
7193 bytes in size were passed padded upward.
7195 The following arranges for best compatibility with previous
7196 versions of gcc, but removes the -mstrict-align dependency. */
7197 if (BYTES_BIG_ENDIAN)
7199 HOST_WIDE_INT size = 0;
7201 if (mode == BLKmode)
7203 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7204 size = int_size_in_bytes (type);
7207 size = GET_MODE_SIZE (mode);
7209 if (size == 1 || size == 2 || size == 4)
7215 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7217 if (type != 0 && AGGREGATE_TYPE_P (type))
7221 /* Fall back to the default. */
7222 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7225 /* If defined, a C expression that gives the alignment boundary, in bits,
7226 of an argument with the specified mode and type. If it is not defined,
7227 PARM_BOUNDARY is used for all arguments.
7229 V.4 wants long longs and doubles to be double word aligned. Just
7230 testing the mode size is a boneheaded way to do this as it means
7231 that other types such as complex int are also double word aligned.
7232 However, we're stuck with this because changing the ABI might break
7233 existing library interfaces.
7235 Doubleword align SPE vectors.
7236 Quadword align Altivec vectors.
7237 Quadword align large synthetic vector types. */
7240 function_arg_boundary (enum machine_mode mode, tree type)
7242 if (DEFAULT_ABI == ABI_V4
7243 && (GET_MODE_SIZE (mode) == 8
7244 || (TARGET_HARD_FLOAT
7246 && (mode == TFmode || mode == TDmode))))
7248 else if (SPE_VECTOR_MODE (mode)
7249 || (type && TREE_CODE (type) == VECTOR_TYPE
7250 && int_size_in_bytes (type) >= 8
7251 && int_size_in_bytes (type) < 16))
7253 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7254 || (type && TREE_CODE (type) == VECTOR_TYPE
7255 && int_size_in_bytes (type) >= 16))
7257 else if (rs6000_darwin64_abi && mode == BLKmode
7258 && type && TYPE_ALIGN (type) > 64)
7261 return PARM_BOUNDARY;
7264 /* For a function parm of MODE and TYPE, return the starting word in
7265 the parameter area. NWORDS of the parameter area are already used. */
7268 rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
7271 unsigned int parm_offset;
7273 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7274 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7275 return nwords + (-(parm_offset + nwords) & align);
7278 /* Compute the size (in words) of a function argument. */
7280 static unsigned long
7281 rs6000_arg_size (enum machine_mode mode, tree type)
7285 if (mode != BLKmode)
7286 size = GET_MODE_SIZE (mode);
7288 size = int_size_in_bytes (type);
7291 return (size + 3) >> 2;
7293 return (size + 7) >> 3;
7296 /* Use this to flush pending int fields. */
7299 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7300 HOST_WIDE_INT bitpos)
7302 unsigned int startbit, endbit;
7303 int intregs, intoffset;
7304 enum machine_mode mode;
7306 if (cum->intoffset == -1)
7309 intoffset = cum->intoffset;
7310 cum->intoffset = -1;
7312 if (intoffset % BITS_PER_WORD != 0)
7314 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7316 if (mode == BLKmode)
7318 /* We couldn't find an appropriate mode, which happens,
7319 e.g., in packed structs when there are 3 bytes to load.
7320 Back intoffset back to the beginning of the word in this
7322 intoffset = intoffset & -BITS_PER_WORD;
7326 startbit = intoffset & -BITS_PER_WORD;
7327 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7328 intregs = (endbit - startbit) / BITS_PER_WORD;
7329 cum->words += intregs;
7332 /* The darwin64 ABI calls for us to recurse down through structs,
7333 looking for elements passed in registers. Unfortunately, we have
7334 to track int register count here also because of misalignments
7335 in powerpc alignment mode. */
7338 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7340 HOST_WIDE_INT startbitpos)
7344 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7345 if (TREE_CODE (f) == FIELD_DECL)
7347 HOST_WIDE_INT bitpos = startbitpos;
7348 tree ftype = TREE_TYPE (f);
7349 enum machine_mode mode;
7350 if (ftype == error_mark_node)
7352 mode = TYPE_MODE (ftype);
7354 if (DECL_SIZE (f) != 0
7355 && host_integerp (bit_position (f), 1))
7356 bitpos += int_bit_position (f);
7358 /* ??? FIXME: else assume zero offset. */
7360 if (TREE_CODE (ftype) == RECORD_TYPE)
7361 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7362 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7364 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7365 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7366 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
7368 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
7370 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
7374 else if (cum->intoffset == -1)
7375 cum->intoffset = bitpos;
7379 /* Update the data in CUM to advance over an argument
7380 of mode MODE and data type TYPE.
7381 (TYPE is null for libcalls where that information may not be available.)
7383 Note that for args passed by reference, function_arg will be called
7384 with MODE and TYPE set to that of the pointer to the arg, not the arg
7388 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7389 tree type, int named, int depth)
7393 /* Only tick off an argument if we're not recursing. */
7395 cum->nargs_prototype--;
7397 if (TARGET_ALTIVEC_ABI
7398 && (ALTIVEC_VECTOR_MODE (mode)
7399 || VSX_VECTOR_MODE (mode)
7400 || (type && TREE_CODE (type) == VECTOR_TYPE
7401 && int_size_in_bytes (type) == 16)))
7405 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7408 if (!TARGET_ALTIVEC)
7409 error ("cannot pass argument in vector register because"
7410 " altivec instructions are disabled, use -maltivec"
7413 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
7414 even if it is going to be passed in a vector register.
7415 Darwin does the same for variable-argument functions. */
7416 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
7417 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
7427 /* Vector parameters must be 16-byte aligned. This places
7428 them at 2 mod 4 in terms of words in 32-bit mode, since
7429 the parameter save area starts at offset 24 from the
7430 stack. In 64-bit mode, they just have to start on an
7431 even word, since the parameter save area is 16-byte
7432 aligned. Space for GPRs is reserved even if the argument
7433 will be passed in memory. */
7435 align = (2 - cum->words) & 3;
7437 align = cum->words & 1;
7438 cum->words += align + rs6000_arg_size (mode, type);
7440 if (TARGET_DEBUG_ARG)
7442 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
7444 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
7445 cum->nargs_prototype, cum->prototype,
7446 GET_MODE_NAME (mode));
7450 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
7452 && cum->sysv_gregno <= GP_ARG_MAX_REG)
7455 else if (rs6000_darwin64_abi
7457 && TREE_CODE (type) == RECORD_TYPE
7458 && (size = int_size_in_bytes (type)) > 0)
7460 /* Variable sized types have size == -1 and are
7461 treated as if consisting entirely of ints.
7462 Pad to 16 byte boundary if needed. */
7463 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7464 && (cum->words % 2) != 0)
7466 /* For varargs, we can just go up by the size of the struct. */
7468 cum->words += (size + 7) / 8;
7471 /* It is tempting to say int register count just goes up by
7472 sizeof(type)/8, but this is wrong in a case such as
7473 { int; double; int; } [powerpc alignment]. We have to
7474 grovel through the fields for these too. */
7476 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
7477 rs6000_darwin64_record_arg_advance_flush (cum,
7478 size * BITS_PER_UNIT);
7481 else if (DEFAULT_ABI == ABI_V4)
7483 if (TARGET_HARD_FLOAT && TARGET_FPRS
7484 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
7485 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
7486 || (mode == TFmode && !TARGET_IEEEQUAD)
7487 || mode == SDmode || mode == DDmode || mode == TDmode))
7489 /* _Decimal128 must use an even/odd register pair. This assumes
7490 that the register number is odd when fregno is odd. */
7491 if (mode == TDmode && (cum->fregno % 2) == 1)
7494 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
7495 <= FP_ARG_V4_MAX_REG)
7496 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7499 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7500 if (mode == DFmode || mode == TFmode
7501 || mode == DDmode || mode == TDmode)
7502 cum->words += cum->words & 1;
7503 cum->words += rs6000_arg_size (mode, type);
7508 int n_words = rs6000_arg_size (mode, type);
7509 int gregno = cum->sysv_gregno;
7511 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
7512 (r7,r8) or (r9,r10). As does any other 2 word item such
7513 as complex int due to a historical mistake. */
7515 gregno += (1 - gregno) & 1;
7517 /* Multi-reg args are not split between registers and stack. */
7518 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7520 /* Long long and SPE vectors are aligned on the stack.
7521 So are other 2 word items such as complex int due to
7522 a historical mistake. */
7524 cum->words += cum->words & 1;
7525 cum->words += n_words;
7528 /* Note: continuing to accumulate gregno past when we've started
7529 spilling to the stack indicates the fact that we've started
7530 spilling to the stack to expand_builtin_saveregs. */
7531 cum->sysv_gregno = gregno + n_words;
7534 if (TARGET_DEBUG_ARG)
7536 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7537 cum->words, cum->fregno);
7538 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
7539 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
7540 fprintf (stderr, "mode = %4s, named = %d\n",
7541 GET_MODE_NAME (mode), named);
7546 int n_words = rs6000_arg_size (mode, type);
7547 int start_words = cum->words;
7548 int align_words = rs6000_parm_start (mode, type, start_words);
7550 cum->words = align_words + n_words;
7552 if (SCALAR_FLOAT_MODE_P (mode)
7553 && TARGET_HARD_FLOAT && TARGET_FPRS)
7555 /* _Decimal128 must be passed in an even/odd float register pair.
7556 This assumes that the register number is odd when fregno is
7558 if (mode == TDmode && (cum->fregno % 2) == 1)
7560 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
7563 if (TARGET_DEBUG_ARG)
7565 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
7566 cum->words, cum->fregno);
7567 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
7568 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
7569 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
7570 named, align_words - start_words, depth);
7576 spe_build_register_parallel (enum machine_mode mode, int gregno)
7583 r1 = gen_rtx_REG (DImode, gregno);
7584 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7585 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
7589 r1 = gen_rtx_REG (DImode, gregno);
7590 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7591 r3 = gen_rtx_REG (DImode, gregno + 2);
7592 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7593 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
7596 r1 = gen_rtx_REG (DImode, gregno);
7597 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
7598 r3 = gen_rtx_REG (DImode, gregno + 2);
7599 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
7600 r5 = gen_rtx_REG (DImode, gregno + 4);
7601 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
7602 r7 = gen_rtx_REG (DImode, gregno + 6);
7603 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
7604 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
7611 /* Determine where to put a SIMD argument on the SPE. */
7613 rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7616 int gregno = cum->sysv_gregno;
7618 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
7619 are passed and returned in a pair of GPRs for ABI compatibility. */
7620 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7621 || mode == DCmode || mode == TCmode))
7623 int n_words = rs6000_arg_size (mode, type);
7625 /* Doubles go in an odd/even register pair (r5/r6, etc). */
7627 gregno += (1 - gregno) & 1;
7629 /* Multi-reg args are not split between registers and stack. */
7630 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
7633 return spe_build_register_parallel (mode, gregno);
7637 int n_words = rs6000_arg_size (mode, type);
7639 /* SPE vectors are put in odd registers. */
7640 if (n_words == 2 && (gregno & 1) == 0)
7643 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
7646 enum machine_mode m = SImode;
7648 r1 = gen_rtx_REG (m, gregno);
7649 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
7650 r2 = gen_rtx_REG (m, gregno + 1);
7651 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
7652 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
7659 if (gregno <= GP_ARG_MAX_REG)
7660 return gen_rtx_REG (mode, gregno);
7666 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
7667 structure between cum->intoffset and bitpos to integer registers. */
7670 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
7671 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
7673 enum machine_mode mode;
7675 unsigned int startbit, endbit;
7676 int this_regno, intregs, intoffset;
7679 if (cum->intoffset == -1)
7682 intoffset = cum->intoffset;
7683 cum->intoffset = -1;
7685 /* If this is the trailing part of a word, try to only load that
7686 much into the register. Otherwise load the whole register. Note
7687 that in the latter case we may pick up unwanted bits. It's not a
7688 problem at the moment but may wish to revisit. */
7690 if (intoffset % BITS_PER_WORD != 0)
7692 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7694 if (mode == BLKmode)
7696 /* We couldn't find an appropriate mode, which happens,
7697 e.g., in packed structs when there are 3 bytes to load.
7698 Back intoffset back to the beginning of the word in this
7700 intoffset = intoffset & -BITS_PER_WORD;
7707 startbit = intoffset & -BITS_PER_WORD;
7708 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7709 intregs = (endbit - startbit) / BITS_PER_WORD;
7710 this_regno = cum->words + intoffset / BITS_PER_WORD;
7712 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
7715 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
7719 intoffset /= BITS_PER_UNIT;
7722 regno = GP_ARG_MIN_REG + this_regno;
7723 reg = gen_rtx_REG (mode, regno);
7725 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
7728 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
7732 while (intregs > 0);
7735 /* Recursive workhorse for the following. */
7738 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
7739 HOST_WIDE_INT startbitpos, rtx rvec[],
7744 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
7745 if (TREE_CODE (f) == FIELD_DECL)
7747 HOST_WIDE_INT bitpos = startbitpos;
7748 tree ftype = TREE_TYPE (f);
7749 enum machine_mode mode;
7750 if (ftype == error_mark_node)
7752 mode = TYPE_MODE (ftype);
7754 if (DECL_SIZE (f) != 0
7755 && host_integerp (bit_position (f), 1))
7756 bitpos += int_bit_position (f);
7758 /* ??? FIXME: else assume zero offset. */
7760 if (TREE_CODE (ftype) == RECORD_TYPE)
7761 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
7762 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
7767 case SCmode: mode = SFmode; break;
7768 case DCmode: mode = DFmode; break;
7769 case TCmode: mode = TFmode; break;
7773 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7775 = gen_rtx_EXPR_LIST (VOIDmode,
7776 gen_rtx_REG (mode, cum->fregno++),
7777 GEN_INT (bitpos / BITS_PER_UNIT));
7778 if (mode == TFmode || mode == TDmode)
7781 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
7783 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
7785 = gen_rtx_EXPR_LIST (VOIDmode,
7786 gen_rtx_REG (mode, cum->vregno++),
7787 GEN_INT (bitpos / BITS_PER_UNIT));
7789 else if (cum->intoffset == -1)
7790 cum->intoffset = bitpos;
7794 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
7795 the register(s) to be used for each field and subfield of a struct
7796 being passed by value, along with the offset of where the
7797 register's value may be found in the block. FP fields go in FP
7798 register, vector fields go in vector registers, and everything
7799 else goes in int registers, packed as in memory.
7801 This code is also used for function return values. RETVAL indicates
7802 whether this is the case.
7804 Much of this is taken from the SPARC V9 port, which has a similar
7805 calling convention. */
7808 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
7809 int named, bool retval)
7811 rtx rvec[FIRST_PSEUDO_REGISTER];
7812 int k = 1, kbase = 1;
7813 HOST_WIDE_INT typesize = int_size_in_bytes (type);
7814 /* This is a copy; modifications are not visible to our caller. */
7815 CUMULATIVE_ARGS copy_cum = *orig_cum;
7816 CUMULATIVE_ARGS *cum = ©_cum;
7818 /* Pad to 16 byte boundary if needed. */
7819 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
7820 && (cum->words % 2) != 0)
7827 /* Put entries into rvec[] for individual FP and vector fields, and
7828 for the chunks of memory that go in int regs. Note we start at
7829 element 1; 0 is reserved for an indication of using memory, and
7830 may or may not be filled in below. */
7831 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
7832 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
7834 /* If any part of the struct went on the stack put all of it there.
7835 This hack is because the generic code for
7836 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
7837 parts of the struct are not at the beginning. */
7841 return NULL_RTX; /* doesn't go in registers at all */
7843 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7845 if (k > 1 || cum->use_stack)
7846 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
7851 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
7854 rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
7858 rtx rvec[GP_ARG_NUM_REG + 1];
7860 if (align_words >= GP_ARG_NUM_REG)
7863 n_units = rs6000_arg_size (mode, type);
7865 /* Optimize the simple case where the arg fits in one gpr, except in
7866 the case of BLKmode due to assign_parms assuming that registers are
7867 BITS_PER_WORD wide. */
7869 || (n_units == 1 && mode != BLKmode))
7870 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7873 if (align_words + n_units > GP_ARG_NUM_REG)
7874 /* Not all of the arg fits in gprs. Say that it goes in memory too,
7875 using a magic NULL_RTX component.
7876 This is not strictly correct. Only some of the arg belongs in
7877 memory, not all of it. However, the normal scheme using
7878 function_arg_partial_nregs can result in unusual subregs, eg.
7879 (subreg:SI (reg:DF) 4), which are not handled well. The code to
7880 store the whole arg to memory is often more efficient than code
7881 to store pieces, and we know that space is available in the right
7882 place for the whole arg. */
7883 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
7888 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
7889 rtx off = GEN_INT (i++ * 4);
7890 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
7892 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
7894 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
7897 /* Determine where to put an argument to a function.
7898 Value is zero to push the argument on the stack,
7899 or a hard register in which to store the argument.
7901 MODE is the argument's machine mode.
7902 TYPE is the data type of the argument (as a tree).
7903 This is null for libcalls where that information may
7905 CUM is a variable of type CUMULATIVE_ARGS which gives info about
7906 the preceding args and about the function being called. It is
7907 not modified in this routine.
7908 NAMED is nonzero if this argument is a named parameter
7909 (otherwise it is an extra parameter matching an ellipsis).
7911 On RS/6000 the first eight words of non-FP are normally in registers
7912 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
7913 Under V.4, the first 8 FP args are in registers.
7915 If this is floating-point and no prototype is specified, we use
7916 both an FP and integer register (or possibly FP reg and stack). Library
7917 functions (when CALL_LIBCALL is set) always have the proper types for args,
7918 so we can pass the FP value just in one register. emit_library_function
7919 doesn't support PARALLEL anyway.
7921 Note that for args passed by reference, function_arg will be called
7922 with MODE and TYPE set to that of the pointer to the arg, not the arg
7926 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
7927 tree type, int named)
7929 enum rs6000_abi abi = DEFAULT_ABI;
7931 /* Return a marker to indicate whether CR1 needs to set or clear the
7932 bit that V.4 uses to say fp args were passed in registers.
7933 Assume that we don't need the marker for software floating point,
7934 or compiler generated library calls. */
7935 if (mode == VOIDmode)
7938 && (cum->call_cookie & CALL_LIBCALL) == 0
7940 || (cum->nargs_prototype < 0
7941 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7943 /* For the SPE, we need to crxor CR6 always. */
7945 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
7946 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
7947 return GEN_INT (cum->call_cookie
7948 | ((cum->fregno == FP_ARG_MIN_REG)
7949 ? CALL_V4_SET_FP_ARGS
7950 : CALL_V4_CLEAR_FP_ARGS));
7953 return GEN_INT (cum->call_cookie);
7956 if (rs6000_darwin64_abi && mode == BLKmode
7957 && TREE_CODE (type) == RECORD_TYPE)
7959 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
7960 if (rslt != NULL_RTX)
7962 /* Else fall through to usual handling. */
7965 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
7966 if (TARGET_64BIT && ! cum->prototype)
7968 /* Vector parameters get passed in vector register
7969 and also in GPRs or memory, in absence of prototype. */
7972 align_words = (cum->words + 1) & ~1;
7974 if (align_words >= GP_ARG_NUM_REG)
7980 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
7982 return gen_rtx_PARALLEL (mode,
7984 gen_rtx_EXPR_LIST (VOIDmode,
7986 gen_rtx_EXPR_LIST (VOIDmode,
7987 gen_rtx_REG (mode, cum->vregno),
7991 return gen_rtx_REG (mode, cum->vregno);
7992 else if (TARGET_ALTIVEC_ABI
7993 && (ALTIVEC_VECTOR_MODE (mode)
7994 || VSX_VECTOR_MODE (mode)
7995 || (type && TREE_CODE (type) == VECTOR_TYPE
7996 && int_size_in_bytes (type) == 16)))
7998 if (named || abi == ABI_V4)
8002 /* Vector parameters to varargs functions under AIX or Darwin
8003 get passed in memory and possibly also in GPRs. */
8004 int align, align_words, n_words;
8005 enum machine_mode part_mode;
8007 /* Vector parameters must be 16-byte aligned. This places them at
8008 2 mod 4 in terms of words in 32-bit mode, since the parameter
8009 save area starts at offset 24 from the stack. In 64-bit mode,
8010 they just have to start on an even word, since the parameter
8011 save area is 16-byte aligned. */
8013 align = (2 - cum->words) & 3;
8015 align = cum->words & 1;
8016 align_words = cum->words + align;
8018 /* Out of registers? Memory, then. */
8019 if (align_words >= GP_ARG_NUM_REG)
8022 if (TARGET_32BIT && TARGET_POWERPC64)
8023 return rs6000_mixed_function_arg (mode, type, align_words);
8025 /* The vector value goes in GPRs. Only the part of the
8026 value in GPRs is reported here. */
8028 n_words = rs6000_arg_size (mode, type);
8029 if (align_words + n_words > GP_ARG_NUM_REG)
8030 /* Fortunately, there are only two possibilities, the value
8031 is either wholly in GPRs or half in GPRs and half not. */
8034 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8037 else if (TARGET_SPE_ABI && TARGET_SPE
8038 && (SPE_VECTOR_MODE (mode)
8039 || (TARGET_E500_DOUBLE && (mode == DFmode
8042 || mode == TCmode))))
8043 return rs6000_spe_function_arg (cum, mode, type);
8045 else if (abi == ABI_V4)
8047 if (TARGET_HARD_FLOAT && TARGET_FPRS
8048 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8049 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8050 || (mode == TFmode && !TARGET_IEEEQUAD)
8051 || mode == SDmode || mode == DDmode || mode == TDmode))
8053 /* _Decimal128 must use an even/odd register pair. This assumes
8054 that the register number is odd when fregno is odd. */
8055 if (mode == TDmode && (cum->fregno % 2) == 1)
8058 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8059 <= FP_ARG_V4_MAX_REG)
8060 return gen_rtx_REG (mode, cum->fregno);
8066 int n_words = rs6000_arg_size (mode, type);
8067 int gregno = cum->sysv_gregno;
8069 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8070 (r7,r8) or (r9,r10). As does any other 2 word item such
8071 as complex int due to a historical mistake. */
8073 gregno += (1 - gregno) & 1;
8075 /* Multi-reg args are not split between registers and stack. */
8076 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8079 if (TARGET_32BIT && TARGET_POWERPC64)
8080 return rs6000_mixed_function_arg (mode, type,
8081 gregno - GP_ARG_MIN_REG);
8082 return gen_rtx_REG (mode, gregno);
8087 int align_words = rs6000_parm_start (mode, type, cum->words);
8089 /* _Decimal128 must be passed in an even/odd float register pair.
8090 This assumes that the register number is odd when fregno is odd. */
8091 if (mode == TDmode && (cum->fregno % 2) == 1)
8094 if (USE_FP_FOR_ARG_P (cum, mode, type))
8096 rtx rvec[GP_ARG_NUM_REG + 1];
8100 enum machine_mode fmode = mode;
8101 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8103 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8105 /* Currently, we only ever need one reg here because complex
8106 doubles are split. */
8107 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8108 && (fmode == TFmode || fmode == TDmode));
8110 /* Long double or _Decimal128 split over regs and memory. */
8111 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8114 /* Do we also need to pass this arg in the parameter save
8117 && (cum->nargs_prototype <= 0
8118 || (DEFAULT_ABI == ABI_AIX
8120 && align_words >= GP_ARG_NUM_REG)));
8122 if (!needs_psave && mode == fmode)
8123 return gen_rtx_REG (fmode, cum->fregno);
8128 /* Describe the part that goes in gprs or the stack.
8129 This piece must come first, before the fprs. */
8130 if (align_words < GP_ARG_NUM_REG)
8132 unsigned long n_words = rs6000_arg_size (mode, type);
8134 if (align_words + n_words > GP_ARG_NUM_REG
8135 || (TARGET_32BIT && TARGET_POWERPC64))
8137 /* If this is partially on the stack, then we only
8138 include the portion actually in registers here. */
8139 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8142 if (align_words + n_words > GP_ARG_NUM_REG)
8143 /* Not all of the arg fits in gprs. Say that it
8144 goes in memory too, using a magic NULL_RTX
8145 component. Also see comment in
8146 rs6000_mixed_function_arg for why the normal
8147 function_arg_partial_nregs scheme doesn't work
8149 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8153 r = gen_rtx_REG (rmode,
8154 GP_ARG_MIN_REG + align_words);
8155 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8156 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8158 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8162 /* The whole arg fits in gprs. */
8163 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8164 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8168 /* It's entirely in memory. */
8169 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8172 /* Describe where this piece goes in the fprs. */
8173 r = gen_rtx_REG (fmode, cum->fregno);
8174 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8176 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8178 else if (align_words < GP_ARG_NUM_REG)
8180 if (TARGET_32BIT && TARGET_POWERPC64)
8181 return rs6000_mixed_function_arg (mode, type, align_words);
8183 if (mode == BLKmode)
8186 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8193 /* For an arg passed partly in registers and partly in memory, this is
8194 the number of bytes passed in registers. For args passed entirely in
8195 registers or entirely in memory, zero. When an arg is described by a
8196 PARALLEL, perhaps using more than one register type, this function
8197 returns the number of bytes used by the first element of the PARALLEL. */
8200 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8201 tree type, bool named)
8206 if (DEFAULT_ABI == ABI_V4)
8209 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8210 && cum->nargs_prototype >= 0)
8213 /* In this complicated case we just disable the partial_nregs code. */
8214 if (rs6000_darwin64_abi && mode == BLKmode
8215 && TREE_CODE (type) == RECORD_TYPE
8216 && int_size_in_bytes (type) > 0)
8219 align_words = rs6000_parm_start (mode, type, cum->words);
8221 if (USE_FP_FOR_ARG_P (cum, mode, type))
8223 /* If we are passing this arg in the fixed parameter save area
8224 (gprs or memory) as well as fprs, then this function should
8225 return the number of partial bytes passed in the parameter
8226 save area rather than partial bytes passed in fprs. */
8228 && (cum->nargs_prototype <= 0
8229 || (DEFAULT_ABI == ABI_AIX
8231 && align_words >= GP_ARG_NUM_REG)))
8233 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8234 > FP_ARG_MAX_REG + 1)
8235 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8236 else if (cum->nargs_prototype >= 0)
8240 if (align_words < GP_ARG_NUM_REG
8241 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8242 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8244 if (ret != 0 && TARGET_DEBUG_ARG)
8245 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8250 /* A C expression that indicates when an argument must be passed by
8251 reference. If nonzero for an argument, a copy of that argument is
8252 made in memory and a pointer to the argument is passed instead of
8253 the argument itself. The pointer is passed in whatever way is
8254 appropriate for passing a pointer to that type.
8256 Under V.4, aggregates and long double are passed by reference.
8258 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8259 reference unless the AltiVec vector extension ABI is in force.
8261 As an extension to all ABIs, variable sized types are passed by
8265 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8266 enum machine_mode mode, const_tree type,
8267 bool named ATTRIBUTE_UNUSED)
8269 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8271 if (TARGET_DEBUG_ARG)
8272 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8279 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8281 if (TARGET_DEBUG_ARG)
8282 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8286 if (int_size_in_bytes (type) < 0)
8288 if (TARGET_DEBUG_ARG)
8289 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8293 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8294 modes only exist for GCC vector types if -maltivec. */
8295 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8297 if (TARGET_DEBUG_ARG)
8298 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8302 /* Pass synthetic vectors in memory. */
8303 if (TREE_CODE (type) == VECTOR_TYPE
8304 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
8306 static bool warned_for_pass_big_vectors = false;
8307 if (TARGET_DEBUG_ARG)
8308 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
8309 if (!warned_for_pass_big_vectors)
8311 warning (0, "GCC vector passed by reference: "
8312 "non-standard ABI extension with no compatibility guarantee");
8313 warned_for_pass_big_vectors = true;
8322 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
8325 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
8330 for (i = 0; i < nregs; i++)
8332 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
8333 if (reload_completed)
8335 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
8338 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
8339 i * GET_MODE_SIZE (reg_mode));
8342 tem = replace_equiv_address (tem, XEXP (tem, 0));
8346 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
8350 /* Perform any needed actions needed for a function that is receiving a
8351 variable number of arguments.
8355 MODE and TYPE are the mode and type of the current parameter.
8357 PRETEND_SIZE is a variable that should be set to the amount of stack
8358 that must be pushed by the prolog to pretend that our caller pushed
8361 Normally, this macro will push all remaining incoming registers on the
8362 stack and set PRETEND_SIZE to the length of the registers pushed. */
8365 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8366 tree type, int *pretend_size ATTRIBUTE_UNUSED,
8369 CUMULATIVE_ARGS next_cum;
8370 int reg_size = TARGET_32BIT ? 4 : 8;
8371 rtx save_area = NULL_RTX, mem;
8372 int first_reg_offset;
8375 /* Skip the last named argument. */
8377 function_arg_advance (&next_cum, mode, type, 1, 0);
8379 if (DEFAULT_ABI == ABI_V4)
8381 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
8385 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
8386 HOST_WIDE_INT offset = 0;
8388 /* Try to optimize the size of the varargs save area.
8389 The ABI requires that ap.reg_save_area is doubleword
8390 aligned, but we don't need to allocate space for all
8391 the bytes, only those to which we actually will save
8393 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
8394 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
8395 if (TARGET_HARD_FLOAT && TARGET_FPRS
8396 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8397 && cfun->va_list_fpr_size)
8400 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
8401 * UNITS_PER_FP_WORD;
8402 if (cfun->va_list_fpr_size
8403 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8404 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
8406 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
8407 * UNITS_PER_FP_WORD;
8411 offset = -((first_reg_offset * reg_size) & ~7);
8412 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
8414 gpr_reg_num = cfun->va_list_gpr_size;
8415 if (reg_size == 4 && (first_reg_offset & 1))
8418 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
8421 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
8423 - (int) (GP_ARG_NUM_REG * reg_size);
8425 if (gpr_size + fpr_size)
8428 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
8429 gcc_assert (GET_CODE (reg_save_area) == MEM);
8430 reg_save_area = XEXP (reg_save_area, 0);
8431 if (GET_CODE (reg_save_area) == PLUS)
8433 gcc_assert (XEXP (reg_save_area, 0)
8434 == virtual_stack_vars_rtx);
8435 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
8436 offset += INTVAL (XEXP (reg_save_area, 1));
8439 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
8442 cfun->machine->varargs_save_offset = offset;
8443 save_area = plus_constant (virtual_stack_vars_rtx, offset);
8448 first_reg_offset = next_cum.words;
8449 save_area = virtual_incoming_args_rtx;
8451 if (targetm.calls.must_pass_in_stack (mode, type))
8452 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
8455 set = get_varargs_alias_set ();
8456 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
8457 && cfun->va_list_gpr_size)
8459 int nregs = GP_ARG_NUM_REG - first_reg_offset;
8461 if (va_list_gpr_counter_field)
8463 /* V4 va_list_gpr_size counts number of registers needed. */
8464 if (nregs > cfun->va_list_gpr_size)
8465 nregs = cfun->va_list_gpr_size;
8469 /* char * va_list instead counts number of bytes needed. */
8470 if (nregs > cfun->va_list_gpr_size / reg_size)
8471 nregs = cfun->va_list_gpr_size / reg_size;
8474 mem = gen_rtx_MEM (BLKmode,
8475 plus_constant (save_area,
8476 first_reg_offset * reg_size));
8477 MEM_NOTRAP_P (mem) = 1;
8478 set_mem_alias_set (mem, set);
8479 set_mem_align (mem, BITS_PER_WORD);
8481 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
8485 /* Save FP registers if needed. */
8486 if (DEFAULT_ABI == ABI_V4
8487 && TARGET_HARD_FLOAT && TARGET_FPRS
8489 && next_cum.fregno <= FP_ARG_V4_MAX_REG
8490 && cfun->va_list_fpr_size)
8492 int fregno = next_cum.fregno, nregs;
8493 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
8494 rtx lab = gen_label_rtx ();
8495 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
8496 * UNITS_PER_FP_WORD);
8499 (gen_rtx_SET (VOIDmode,
8501 gen_rtx_IF_THEN_ELSE (VOIDmode,
8502 gen_rtx_NE (VOIDmode, cr1,
8504 gen_rtx_LABEL_REF (VOIDmode, lab),
8508 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
8509 fregno++, off += UNITS_PER_FP_WORD, nregs++)
8511 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8513 plus_constant (save_area, off));
8514 MEM_NOTRAP_P (mem) = 1;
8515 set_mem_alias_set (mem, set);
8516 set_mem_align (mem, GET_MODE_ALIGNMENT (
8517 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8518 ? DFmode : SFmode));
8519 emit_move_insn (mem, gen_rtx_REG (
8520 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
8521 ? DFmode : SFmode, fregno));
8528 /* Create the va_list data type. */
8531 rs6000_build_builtin_va_list (void)
8533 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
8535 /* For AIX, prefer 'char *' because that's what the system
8536 header files like. */
8537 if (DEFAULT_ABI != ABI_V4)
8538 return build_pointer_type (char_type_node);
8540 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
8541 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
8542 get_identifier ("__va_list_tag"), record);
8544 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
8545 unsigned_char_type_node);
8546 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
8547 unsigned_char_type_node);
8548 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
8550 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8551 get_identifier ("reserved"), short_unsigned_type_node);
8552 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8553 get_identifier ("overflow_arg_area"),
8555 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
8556 get_identifier ("reg_save_area"),
8559 va_list_gpr_counter_field = f_gpr;
8560 va_list_fpr_counter_field = f_fpr;
8562 DECL_FIELD_CONTEXT (f_gpr) = record;
8563 DECL_FIELD_CONTEXT (f_fpr) = record;
8564 DECL_FIELD_CONTEXT (f_res) = record;
8565 DECL_FIELD_CONTEXT (f_ovf) = record;
8566 DECL_FIELD_CONTEXT (f_sav) = record;
8568 TREE_CHAIN (record) = type_decl;
8569 TYPE_NAME (record) = type_decl;
8570 TYPE_FIELDS (record) = f_gpr;
8571 TREE_CHAIN (f_gpr) = f_fpr;
8572 TREE_CHAIN (f_fpr) = f_res;
8573 TREE_CHAIN (f_res) = f_ovf;
8574 TREE_CHAIN (f_ovf) = f_sav;
8576 layout_type (record);
8578 /* The correct type is an array type of one element. */
8579 return build_array_type (record, build_index_type (size_zero_node));
8582 /* Implement va_start. */
8585 rs6000_va_start (tree valist, rtx nextarg)
8587 HOST_WIDE_INT words, n_gpr, n_fpr;
8588 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8589 tree gpr, fpr, ovf, sav, t;
8591 /* Only SVR4 needs something special. */
8592 if (DEFAULT_ABI != ABI_V4)
8594 std_expand_builtin_va_start (valist, nextarg);
8598 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8599 f_fpr = TREE_CHAIN (f_gpr);
8600 f_res = TREE_CHAIN (f_fpr);
8601 f_ovf = TREE_CHAIN (f_res);
8602 f_sav = TREE_CHAIN (f_ovf);
8604 valist = build_va_arg_indirect_ref (valist);
8605 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8606 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8608 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8610 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8613 /* Count number of gp and fp argument registers used. */
8614 words = crtl->args.info.words;
8615 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
8617 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
8620 if (TARGET_DEBUG_ARG)
8621 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
8622 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
8623 words, n_gpr, n_fpr);
8625 if (cfun->va_list_gpr_size)
8627 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
8628 build_int_cst (NULL_TREE, n_gpr));
8629 TREE_SIDE_EFFECTS (t) = 1;
8630 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8633 if (cfun->va_list_fpr_size)
8635 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
8636 build_int_cst (NULL_TREE, n_fpr));
8637 TREE_SIDE_EFFECTS (t) = 1;
8638 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8641 /* Find the overflow area. */
8642 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
8644 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
8645 size_int (words * UNITS_PER_WORD));
8646 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
8647 TREE_SIDE_EFFECTS (t) = 1;
8648 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8650 /* If there were no va_arg invocations, don't set up the register
8652 if (!cfun->va_list_gpr_size
8653 && !cfun->va_list_fpr_size
8654 && n_gpr < GP_ARG_NUM_REG
8655 && n_fpr < FP_ARG_V4_MAX_REG)
8658 /* Find the register save area. */
8659 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
8660 if (cfun->machine->varargs_save_offset)
8661 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
8662 size_int (cfun->machine->varargs_save_offset));
8663 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
8664 TREE_SIDE_EFFECTS (t) = 1;
8665 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
8668 /* Implement va_arg. */
8671 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
8674 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
8675 tree gpr, fpr, ovf, sav, reg, t, u;
8676 int size, rsize, n_reg, sav_ofs, sav_scale;
8677 tree lab_false, lab_over, addr;
8679 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
8683 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
8685 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
8686 return build_va_arg_indirect_ref (t);
8689 if (DEFAULT_ABI != ABI_V4)
8691 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
8693 tree elem_type = TREE_TYPE (type);
8694 enum machine_mode elem_mode = TYPE_MODE (elem_type);
8695 int elem_size = GET_MODE_SIZE (elem_mode);
8697 if (elem_size < UNITS_PER_WORD)
8699 tree real_part, imag_part;
8700 gimple_seq post = NULL;
8702 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8704 /* Copy the value into a temporary, lest the formal temporary
8705 be reused out from under us. */
8706 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
8707 gimple_seq_add_seq (pre_p, post);
8709 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
8712 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
8716 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
8719 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
8720 f_fpr = TREE_CHAIN (f_gpr);
8721 f_res = TREE_CHAIN (f_fpr);
8722 f_ovf = TREE_CHAIN (f_res);
8723 f_sav = TREE_CHAIN (f_ovf);
8725 valist = build_va_arg_indirect_ref (valist);
8726 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
8727 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
8729 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
8731 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
8734 size = int_size_in_bytes (type);
8735 rsize = (size + 3) / 4;
8738 if (TARGET_HARD_FLOAT && TARGET_FPRS
8739 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
8740 || (TARGET_DOUBLE_FLOAT
8741 && (TYPE_MODE (type) == DFmode
8742 || TYPE_MODE (type) == TFmode
8743 || TYPE_MODE (type) == SDmode
8744 || TYPE_MODE (type) == DDmode
8745 || TYPE_MODE (type) == TDmode))))
8747 /* FP args go in FP registers, if present. */
8749 n_reg = (size + 7) / 8;
8750 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
8751 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
8752 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
8757 /* Otherwise into GP registers. */
8766 /* Pull the value out of the saved registers.... */
8769 addr = create_tmp_var (ptr_type_node, "addr");
8771 /* AltiVec vectors never go in registers when -mabi=altivec. */
8772 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
8776 lab_false = create_artificial_label (input_location);
8777 lab_over = create_artificial_label (input_location);
8779 /* Long long and SPE vectors are aligned in the registers.
8780 As are any other 2 gpr item such as complex int due to a
8781 historical mistake. */
8783 if (n_reg == 2 && reg == gpr)
8786 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8787 build_int_cst (TREE_TYPE (reg), n_reg - 1));
8788 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
8789 unshare_expr (reg), u);
8791 /* _Decimal128 is passed in even/odd fpr pairs; the stored
8792 reg number is 0 for f1, so we want to make it odd. */
8793 else if (reg == fpr && TYPE_MODE (type) == TDmode)
8795 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8796 build_int_cst (TREE_TYPE (reg), 1));
8797 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
8800 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
8801 t = build2 (GE_EXPR, boolean_type_node, u, t);
8802 u = build1 (GOTO_EXPR, void_type_node, lab_false);
8803 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
8804 gimplify_and_add (t, pre_p);
8808 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
8810 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
8811 build_int_cst (TREE_TYPE (reg), n_reg));
8812 u = fold_convert (sizetype, u);
8813 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
8814 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
8816 /* _Decimal32 varargs are located in the second word of the 64-bit
8817 FP register for 32-bit binaries. */
8818 if (!TARGET_POWERPC64
8819 && TARGET_HARD_FLOAT && TARGET_FPRS
8820 && TYPE_MODE (type) == SDmode)
8821 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8823 gimplify_assign (addr, t, pre_p);
8825 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
8827 stmt = gimple_build_label (lab_false);
8828 gimple_seq_add_stmt (pre_p, stmt);
8830 if ((n_reg == 2 && !regalign) || n_reg > 2)
8832 /* Ensure that we don't find any more args in regs.
8833 Alignment has taken care of for special cases. */
8834 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
8838 /* ... otherwise out of the overflow area. */
8840 /* Care for on-stack alignment if needed. */
8844 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
8845 t = fold_convert (sizetype, t);
8846 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
8848 t = fold_convert (TREE_TYPE (ovf), t);
8850 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
8852 gimplify_assign (unshare_expr (addr), t, pre_p);
8854 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
8855 gimplify_assign (unshare_expr (ovf), t, pre_p);
8859 stmt = gimple_build_label (lab_over);
8860 gimple_seq_add_stmt (pre_p, stmt);
8863 if (STRICT_ALIGNMENT
8864 && (TYPE_ALIGN (type)
8865 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
8867 /* The value (of type complex double, for example) may not be
8868 aligned in memory in the saved registers, so copy via a
8869 temporary. (This is the same code as used for SPARC.) */
8870 tree tmp = create_tmp_var (type, "va_arg_tmp");
8871 tree dest_addr = build_fold_addr_expr (tmp);
8873 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
8874 3, dest_addr, addr, size_int (rsize * 4));
8876 gimplify_and_add (copy, pre_p);
8880 addr = fold_convert (ptrtype, addr);
8881 return build_va_arg_indirect_ref (addr);
8887 def_builtin (int mask, const char *name, tree type, int code)
8889 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
8892 if (rs6000_builtin_decls[code])
8893 fatal_error ("internal error: builtin function to %s already processed.",
8896 rs6000_builtin_decls[code] = t =
8897 add_builtin_function (name, type, code, BUILT_IN_MD,
8900 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
8901 switch (builtin_classify[code])
8906 /* assume builtin can do anything. */
8907 case RS6000_BTC_MISC:
8910 /* const function, function only depends on the inputs. */
8911 case RS6000_BTC_CONST:
8912 TREE_READONLY (t) = 1;
8913 TREE_NOTHROW (t) = 1;
8916 /* pure function, function can read global memory. */
8917 case RS6000_BTC_PURE:
8918 DECL_PURE_P (t) = 1;
8919 TREE_NOTHROW (t) = 1;
8922 /* Function is a math function. If rounding mode is on, then treat
8923 the function as not reading global memory, but it can have
8924 arbitrary side effects. If it is off, then assume the function is
8925 a const function. This mimics the ATTR_MATHFN_FPROUNDING
8926 attribute in builtin-attribute.def that is used for the math
8928 case RS6000_BTC_FP_PURE:
8929 TREE_NOTHROW (t) = 1;
8930 if (flag_rounding_math)
8932 DECL_PURE_P (t) = 1;
8933 DECL_IS_NOVOPS (t) = 1;
8936 TREE_READONLY (t) = 1;
8942 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
8944 static const struct builtin_description bdesc_3arg[] =
8946 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
8947 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
8948 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
8949 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
8950 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
8951 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
8952 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
8953 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
8954 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
8955 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
8956 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
8957 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
8958 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
8959 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
8960 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
8961 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
8962 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
8963 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
8964 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
8965 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
8966 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
8967 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
8968 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
8969 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
8970 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
8971 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
8972 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
8973 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
8974 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
8975 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
8976 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
8977 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
8978 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
8979 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
8980 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
8982 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
8983 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
8984 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
8985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
8986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
8987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
8988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
8989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
8990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
8991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
8992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
8993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
8994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
8995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
8996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
8998 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
8999 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9000 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9001 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9003 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9004 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9005 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9006 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9011 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9012 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9013 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9014 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9015 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9016 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9017 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9018 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9019 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9020 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9022 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9023 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9024 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9025 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9026 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9027 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9028 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9029 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9030 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9031 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9033 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9034 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9035 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9036 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9037 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9038 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9039 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9040 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9041 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9043 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9044 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9045 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9046 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9047 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9048 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9049 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9051 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9052 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9053 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9054 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9055 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9056 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9057 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9058 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9059 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9062 /* DST operations: void foo (void *, const int, const char). */
9064 static const struct builtin_description bdesc_dst[] =
9066 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9067 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9068 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9069 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9077 /* Simple binary operations: VECc = foo (VECa, VECb). */
9079 static struct builtin_description bdesc_2arg[] =
9081 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9082 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9083 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9084 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9085 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9086 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9087 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9088 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9089 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9090 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9091 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9092 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9093 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9094 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9095 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9096 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9097 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9098 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9099 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9100 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9101 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9102 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9103 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9104 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9105 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9106 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9107 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9108 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9109 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9110 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9111 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9112 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9113 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9114 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9115 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9116 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9117 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9118 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9119 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9120 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9121 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9122 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9123 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9124 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9125 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9126 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9127 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9128 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9129 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9130 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9131 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9132 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9133 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9134 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9135 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9136 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9137 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9138 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9139 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9140 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9141 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9142 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9143 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9144 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9145 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9146 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9147 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9148 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9149 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9150 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9151 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9152 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9153 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9154 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9155 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9156 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9157 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9158 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9159 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9160 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9161 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9162 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9163 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9164 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9165 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9166 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9167 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9168 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9169 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9170 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9171 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9172 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9173 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9174 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9175 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9176 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9177 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9178 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9179 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9180 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9181 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9182 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9183 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9184 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9185 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9186 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9187 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9188 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9189 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9190 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9191 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9192 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9193 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9194 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9195 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9196 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9197 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9199 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9200 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9201 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9202 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9203 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9204 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9205 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9206 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9207 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9208 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9209 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9210 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9212 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9213 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9214 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9215 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9216 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9217 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9218 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9219 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9220 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9221 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9222 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9223 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9225 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9226 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9227 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9228 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9229 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9230 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9232 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9233 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9234 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9235 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9236 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9237 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9238 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9239 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9240 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9241 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9242 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9243 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9245 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9246 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9257 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9258 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9259 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
9262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
9263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
9264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
9265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
9266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
9267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
9268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
9269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
9270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
9271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
9272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
9273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
9274 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
9275 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
9276 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
9277 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
9278 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
9279 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
9280 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
9281 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
9282 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
9283 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
9284 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
9285 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
9286 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
9287 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
9288 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
9289 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
9290 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
9291 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
9292 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
9293 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
9294 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
9295 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
9296 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
9297 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
9298 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
9299 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
9300 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
9301 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
9302 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
9303 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
9304 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
9305 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
9306 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
9307 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
9308 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
9309 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
9310 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
9311 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
9312 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
9313 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
9314 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
9315 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
9316 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
9317 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
9318 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
9319 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
9320 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
9321 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
9322 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
9323 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
9324 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
9325 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
9326 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
9327 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
9328 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
9329 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
9330 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
9331 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
9332 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
9333 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
9334 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
9335 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
9336 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
9337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
9338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
9339 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
9340 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
9341 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
9342 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
9343 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
9344 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
9345 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
9346 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
9347 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
9348 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
9349 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
9350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
9351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
9352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
9353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
9354 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
9355 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
9356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
9357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
9358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
9359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
9360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
9361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
9362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
9363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
9364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
9365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
9366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
9367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
9368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
9369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
9370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
9371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
9372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
9373 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
9375 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
9376 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
9378 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
9379 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
9380 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
9381 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
9382 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
9383 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
9384 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
9385 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
9386 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
9387 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
9389 /* Place holder, leave as first spe builtin. */
9390 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
9391 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
9392 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
9393 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
9394 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
9395 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
9396 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
9397 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
9398 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
9399 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
9400 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
9401 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
9402 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
9403 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
9404 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
9405 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
9406 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
9407 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
9408 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
9409 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
9410 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
9411 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
9412 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
9413 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
9414 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
9415 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
9416 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
9417 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
9418 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
9419 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
9420 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
9421 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
9422 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
9423 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
9424 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
9425 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
9426 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
9427 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
9428 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
9429 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
9430 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
9431 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
9432 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
9433 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
9434 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
9435 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
9436 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
9437 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
9438 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
9439 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
9440 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
9441 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
9442 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
9443 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
9444 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
9445 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
9446 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
9447 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
9448 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
9449 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
9450 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
9451 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
9452 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
9453 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
9454 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
9455 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
9456 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
9457 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
9458 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
9459 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
9460 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
9461 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
9462 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
9463 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
9464 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
9465 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
9466 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
9467 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
9468 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
9469 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
9470 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
9471 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
9472 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
9473 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
9474 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
9475 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
9476 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
9477 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
9478 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
9479 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
9480 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
9481 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
9482 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
9483 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
9484 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
9485 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
9486 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
9487 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
9488 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
9489 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
9490 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
9491 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
9492 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
9493 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
9494 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
9495 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
9496 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
9497 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
9498 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
9500 /* SPE binary operations expecting a 5-bit unsigned literal. */
9501 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
9503 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
9504 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
9505 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
9506 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
9507 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
9508 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
9509 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
9510 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
9511 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
9512 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
9513 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
9514 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
9515 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
9516 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
9517 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
9518 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
9519 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
9520 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
9521 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
9522 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
9523 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
9524 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
9525 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
9526 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
9527 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
9528 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
9530 /* Place-holder. Leave as last binary SPE builtin. */
9531 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
9534 /* AltiVec predicates. */
9536 struct builtin_description_predicates
9538 const unsigned int mask;
9539 const enum insn_code icode;
9540 const char *const name;
9541 const enum rs6000_builtins code;
9544 static const struct builtin_description_predicates bdesc_altivec_preds[] =
9546 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
9547 ALTIVEC_BUILTIN_VCMPBFP_P },
9548 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
9549 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
9550 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
9551 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
9552 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
9553 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
9554 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
9555 ALTIVEC_BUILTIN_VCMPEQUW_P },
9556 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
9557 ALTIVEC_BUILTIN_VCMPGTSW_P },
9558 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
9559 ALTIVEC_BUILTIN_VCMPGTUW_P },
9560 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
9561 ALTIVEC_BUILTIN_VCMPEQUH_P },
9562 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
9563 ALTIVEC_BUILTIN_VCMPGTSH_P },
9564 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
9565 ALTIVEC_BUILTIN_VCMPGTUH_P },
9566 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
9567 ALTIVEC_BUILTIN_VCMPEQUB_P },
9568 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
9569 ALTIVEC_BUILTIN_VCMPGTSB_P },
9570 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
9571 ALTIVEC_BUILTIN_VCMPGTUB_P },
9573 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
9574 VSX_BUILTIN_XVCMPEQSP_P },
9575 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
9576 VSX_BUILTIN_XVCMPGESP_P },
9577 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
9578 VSX_BUILTIN_XVCMPGTSP_P },
9579 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
9580 VSX_BUILTIN_XVCMPEQDP_P },
9581 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
9582 VSX_BUILTIN_XVCMPGEDP_P },
9583 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
9584 VSX_BUILTIN_XVCMPGTDP_P },
9586 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
9587 ALTIVEC_BUILTIN_VCMPEQ_P },
9588 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
9589 ALTIVEC_BUILTIN_VCMPGT_P },
9590 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
9591 ALTIVEC_BUILTIN_VCMPGE_P }
9594 /* SPE predicates. */
9595 static struct builtin_description bdesc_spe_predicates[] =
9597 /* Place-holder. Leave as first. */
9598 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
9599 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
9600 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
9601 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
9602 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
9603 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
9604 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
9605 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
9606 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
9607 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
9608 /* Place-holder. Leave as last. */
9609 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
9612 /* SPE evsel predicates. */
9613 static struct builtin_description bdesc_spe_evsel[] =
9615 /* Place-holder. Leave as first. */
9616 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
9617 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
9618 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
9619 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
9620 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
9621 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
9622 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
9623 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
9624 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
9625 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
9626 /* Place-holder. Leave as last. */
9627 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
9630 /* PAIRED predicates. */
9631 static const struct builtin_description bdesc_paired_preds[] =
9633 /* Place-holder. Leave as first. */
9634 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
9635 /* Place-holder. Leave as last. */
9636 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
9639 /* ABS* operations. */
9641 static const struct builtin_description bdesc_abs[] =
9643 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
9644 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
9645 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
9646 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
9647 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
9648 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
9649 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
9650 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
9651 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
9652 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
9653 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
9656 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
9659 static struct builtin_description bdesc_1arg[] =
9661 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
9662 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
9663 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
9664 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
9665 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
9666 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
9667 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
9668 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
9669 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
9670 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
9671 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
9672 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
9673 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
9674 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
9675 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
9676 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
9677 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
9678 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
9680 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
9681 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
9682 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
9683 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
9684 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
9685 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
9686 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
9688 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
9689 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
9690 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
9691 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
9692 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
9693 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
9694 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
9696 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
9697 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
9698 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
9699 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
9700 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
9701 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
9703 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
9704 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
9705 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
9706 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
9707 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
9708 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
9710 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
9711 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
9712 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
9713 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
9715 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
9716 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
9717 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
9718 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
9719 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
9720 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
9721 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
9722 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
9723 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
9725 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
9726 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
9727 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
9728 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
9729 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
9730 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
9731 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
9732 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
9733 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
9735 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
9736 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
9737 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
9738 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
9739 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
9741 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
9742 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
9743 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
9744 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
9745 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
9746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
9747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
9748 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
9749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
9750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
9751 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
9752 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
9753 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
9754 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
9755 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
9756 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
9757 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
9758 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
9759 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
9760 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
9762 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
9763 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
9764 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
9766 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
9767 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
9768 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
9769 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
9771 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
9772 end with SPE_BUILTIN_EVSUBFUSIAAW. */
9773 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
9774 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
9775 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
9776 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
9777 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
9778 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
9779 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
9780 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
9781 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
9782 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
9783 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
9784 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
9785 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
9786 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
9787 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
9788 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
9789 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
9790 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
9791 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
9792 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
9793 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
9794 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
9795 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
9796 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
9797 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
9798 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
9799 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
9800 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
9802 /* Place-holder. Leave as last unary SPE builtin. */
9803 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
9805 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
9806 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
9807 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
9808 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
9809 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
9813 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
9816 tree arg0 = CALL_EXPR_ARG (exp, 0);
9817 rtx op0 = expand_normal (arg0);
9818 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9819 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9821 if (icode == CODE_FOR_nothing)
9822 /* Builtin not supported on this processor. */
9825 /* If we got invalid arguments bail out before generating bad rtl. */
9826 if (arg0 == error_mark_node)
9829 if (icode == CODE_FOR_altivec_vspltisb
9830 || icode == CODE_FOR_altivec_vspltish
9831 || icode == CODE_FOR_altivec_vspltisw
9832 || icode == CODE_FOR_spe_evsplatfi
9833 || icode == CODE_FOR_spe_evsplati)
9835 /* Only allow 5-bit *signed* literals. */
9836 if (GET_CODE (op0) != CONST_INT
9837 || INTVAL (op0) > 15
9838 || INTVAL (op0) < -16)
9840 error ("argument 1 must be a 5-bit signed literal");
9846 || GET_MODE (target) != tmode
9847 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9848 target = gen_reg_rtx (tmode);
9850 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9851 op0 = copy_to_mode_reg (mode0, op0);
9853 pat = GEN_FCN (icode) (target, op0);
9862 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
9864 rtx pat, scratch1, scratch2;
9865 tree arg0 = CALL_EXPR_ARG (exp, 0);
9866 rtx op0 = expand_normal (arg0);
9867 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9868 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9870 /* If we have invalid arguments, bail out before generating bad rtl. */
9871 if (arg0 == error_mark_node)
9875 || GET_MODE (target) != tmode
9876 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9877 target = gen_reg_rtx (tmode);
9879 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9880 op0 = copy_to_mode_reg (mode0, op0);
9882 scratch1 = gen_reg_rtx (mode0);
9883 scratch2 = gen_reg_rtx (mode0);
9885 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
9894 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
9897 tree arg0 = CALL_EXPR_ARG (exp, 0);
9898 tree arg1 = CALL_EXPR_ARG (exp, 1);
9899 rtx op0 = expand_normal (arg0);
9900 rtx op1 = expand_normal (arg1);
9901 enum machine_mode tmode = insn_data[icode].operand[0].mode;
9902 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9903 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9905 if (icode == CODE_FOR_nothing)
9906 /* Builtin not supported on this processor. */
9909 /* If we got invalid arguments bail out before generating bad rtl. */
9910 if (arg0 == error_mark_node || arg1 == error_mark_node)
9913 if (icode == CODE_FOR_altivec_vcfux
9914 || icode == CODE_FOR_altivec_vcfsx
9915 || icode == CODE_FOR_altivec_vctsxs
9916 || icode == CODE_FOR_altivec_vctuxs
9917 || icode == CODE_FOR_altivec_vspltb
9918 || icode == CODE_FOR_altivec_vsplth
9919 || icode == CODE_FOR_altivec_vspltw
9920 || icode == CODE_FOR_spe_evaddiw
9921 || icode == CODE_FOR_spe_evldd
9922 || icode == CODE_FOR_spe_evldh
9923 || icode == CODE_FOR_spe_evldw
9924 || icode == CODE_FOR_spe_evlhhesplat
9925 || icode == CODE_FOR_spe_evlhhossplat
9926 || icode == CODE_FOR_spe_evlhhousplat
9927 || icode == CODE_FOR_spe_evlwhe
9928 || icode == CODE_FOR_spe_evlwhos
9929 || icode == CODE_FOR_spe_evlwhou
9930 || icode == CODE_FOR_spe_evlwhsplat
9931 || icode == CODE_FOR_spe_evlwwsplat
9932 || icode == CODE_FOR_spe_evrlwi
9933 || icode == CODE_FOR_spe_evslwi
9934 || icode == CODE_FOR_spe_evsrwis
9935 || icode == CODE_FOR_spe_evsubifw
9936 || icode == CODE_FOR_spe_evsrwiu)
9938 /* Only allow 5-bit unsigned literals. */
9940 if (TREE_CODE (arg1) != INTEGER_CST
9941 || TREE_INT_CST_LOW (arg1) & ~0x1f)
9943 error ("argument 2 must be a 5-bit unsigned literal");
9949 || GET_MODE (target) != tmode
9950 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9951 target = gen_reg_rtx (tmode);
9953 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9954 op0 = copy_to_mode_reg (mode0, op0);
9955 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
9956 op1 = copy_to_mode_reg (mode1, op1);
9958 pat = GEN_FCN (icode) (target, op0, op1);
9967 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
9970 tree cr6_form = CALL_EXPR_ARG (exp, 0);
9971 tree arg0 = CALL_EXPR_ARG (exp, 1);
9972 tree arg1 = CALL_EXPR_ARG (exp, 2);
9973 rtx op0 = expand_normal (arg0);
9974 rtx op1 = expand_normal (arg1);
9975 enum machine_mode tmode = SImode;
9976 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
9977 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
9980 if (TREE_CODE (cr6_form) != INTEGER_CST)
9982 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9986 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
9988 gcc_assert (mode0 == mode1);
9990 /* If we have invalid arguments, bail out before generating bad rtl. */
9991 if (arg0 == error_mark_node || arg1 == error_mark_node)
9995 || GET_MODE (target) != tmode
9996 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9997 target = gen_reg_rtx (tmode);
9999 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10000 op0 = copy_to_mode_reg (mode0, op0);
10001 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10002 op1 = copy_to_mode_reg (mode1, op1);
10004 scratch = gen_reg_rtx (mode0);
10006 pat = GEN_FCN (icode) (scratch, op0, op1);
10011 /* The vec_any* and vec_all* predicates use the same opcodes for two
10012 different operations, but the bits in CR6 will be different
10013 depending on what information we want. So we have to play tricks
10014 with CR6 to get the right bits out.
10016 If you think this is disgusting, look at the specs for the
10017 AltiVec predicates. */
10019 switch (cr6_form_int)
10022 emit_insn (gen_cr6_test_for_zero (target));
10025 emit_insn (gen_cr6_test_for_zero_reverse (target));
10028 emit_insn (gen_cr6_test_for_lt (target));
10031 emit_insn (gen_cr6_test_for_lt_reverse (target));
10034 error ("argument 1 of __builtin_altivec_predicate is out of range");
10042 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10045 tree arg0 = CALL_EXPR_ARG (exp, 0);
10046 tree arg1 = CALL_EXPR_ARG (exp, 1);
10047 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10048 enum machine_mode mode0 = Pmode;
10049 enum machine_mode mode1 = Pmode;
10050 rtx op0 = expand_normal (arg0);
10051 rtx op1 = expand_normal (arg1);
10053 if (icode == CODE_FOR_nothing)
10054 /* Builtin not supported on this processor. */
10057 /* If we got invalid arguments bail out before generating bad rtl. */
10058 if (arg0 == error_mark_node || arg1 == error_mark_node)
10062 || GET_MODE (target) != tmode
10063 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10064 target = gen_reg_rtx (tmode);
10066 op1 = copy_to_mode_reg (mode1, op1);
10068 if (op0 == const0_rtx)
10070 addr = gen_rtx_MEM (tmode, op1);
10074 op0 = copy_to_mode_reg (mode0, op0);
10075 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10078 pat = GEN_FCN (icode) (target, addr);
10088 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10091 tree arg0 = CALL_EXPR_ARG (exp, 0);
10092 tree arg1 = CALL_EXPR_ARG (exp, 1);
10093 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10094 enum machine_mode mode0 = Pmode;
10095 enum machine_mode mode1 = Pmode;
10096 rtx op0 = expand_normal (arg0);
10097 rtx op1 = expand_normal (arg1);
10099 if (icode == CODE_FOR_nothing)
10100 /* Builtin not supported on this processor. */
10103 /* If we got invalid arguments bail out before generating bad rtl. */
10104 if (arg0 == error_mark_node || arg1 == error_mark_node)
10108 || GET_MODE (target) != tmode
10109 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10110 target = gen_reg_rtx (tmode);
10112 op1 = copy_to_mode_reg (mode1, op1);
10114 if (op0 == const0_rtx)
10116 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10120 op0 = copy_to_mode_reg (mode0, op0);
10121 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10124 pat = GEN_FCN (icode) (target, addr);
10134 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10136 tree arg0 = CALL_EXPR_ARG (exp, 0);
10137 tree arg1 = CALL_EXPR_ARG (exp, 1);
10138 tree arg2 = CALL_EXPR_ARG (exp, 2);
10139 rtx op0 = expand_normal (arg0);
10140 rtx op1 = expand_normal (arg1);
10141 rtx op2 = expand_normal (arg2);
10143 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10144 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10145 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10147 /* Invalid arguments. Bail before doing anything stoopid! */
10148 if (arg0 == error_mark_node
10149 || arg1 == error_mark_node
10150 || arg2 == error_mark_node)
10153 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10154 op0 = copy_to_mode_reg (mode2, op0);
10155 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10156 op1 = copy_to_mode_reg (mode0, op1);
10157 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10158 op2 = copy_to_mode_reg (mode1, op2);
10160 pat = GEN_FCN (icode) (op1, op2, op0);
10167 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10169 tree arg0 = CALL_EXPR_ARG (exp, 0);
10170 tree arg1 = CALL_EXPR_ARG (exp, 1);
10171 tree arg2 = CALL_EXPR_ARG (exp, 2);
10172 rtx op0 = expand_normal (arg0);
10173 rtx op1 = expand_normal (arg1);
10174 rtx op2 = expand_normal (arg2);
10176 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10177 enum machine_mode mode1 = Pmode;
10178 enum machine_mode mode2 = Pmode;
10180 /* Invalid arguments. Bail before doing anything stoopid! */
10181 if (arg0 == error_mark_node
10182 || arg1 == error_mark_node
10183 || arg2 == error_mark_node)
10186 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10187 op0 = copy_to_mode_reg (tmode, op0);
10189 op2 = copy_to_mode_reg (mode2, op2);
10191 if (op1 == const0_rtx)
10193 addr = gen_rtx_MEM (tmode, op2);
10197 op1 = copy_to_mode_reg (mode1, op1);
10198 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10201 pat = GEN_FCN (icode) (addr, op0);
10208 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10210 tree arg0 = CALL_EXPR_ARG (exp, 0);
10211 tree arg1 = CALL_EXPR_ARG (exp, 1);
10212 tree arg2 = CALL_EXPR_ARG (exp, 2);
10213 rtx op0 = expand_normal (arg0);
10214 rtx op1 = expand_normal (arg1);
10215 rtx op2 = expand_normal (arg2);
10217 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10218 enum machine_mode mode1 = Pmode;
10219 enum machine_mode mode2 = Pmode;
10221 /* Invalid arguments. Bail before doing anything stoopid! */
10222 if (arg0 == error_mark_node
10223 || arg1 == error_mark_node
10224 || arg2 == error_mark_node)
10227 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10228 op0 = copy_to_mode_reg (tmode, op0);
10230 op2 = copy_to_mode_reg (mode2, op2);
10232 if (op1 == const0_rtx)
10234 addr = gen_rtx_MEM (tmode, op2);
10238 op1 = copy_to_mode_reg (mode1, op1);
10239 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10242 pat = GEN_FCN (icode) (addr, op0);
10249 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10252 tree arg0 = CALL_EXPR_ARG (exp, 0);
10253 tree arg1 = CALL_EXPR_ARG (exp, 1);
10254 tree arg2 = CALL_EXPR_ARG (exp, 2);
10255 rtx op0 = expand_normal (arg0);
10256 rtx op1 = expand_normal (arg1);
10257 rtx op2 = expand_normal (arg2);
10258 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10259 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10260 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10261 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
10263 if (icode == CODE_FOR_nothing)
10264 /* Builtin not supported on this processor. */
10267 /* If we got invalid arguments bail out before generating bad rtl. */
10268 if (arg0 == error_mark_node
10269 || arg1 == error_mark_node
10270 || arg2 == error_mark_node)
10275 case CODE_FOR_altivec_vsldoi_v4sf:
10276 case CODE_FOR_altivec_vsldoi_v4si:
10277 case CODE_FOR_altivec_vsldoi_v8hi:
10278 case CODE_FOR_altivec_vsldoi_v16qi:
10279 /* Only allow 4-bit unsigned literals. */
10281 if (TREE_CODE (arg2) != INTEGER_CST
10282 || TREE_INT_CST_LOW (arg2) & ~0xf)
10284 error ("argument 3 must be a 4-bit unsigned literal");
10289 case CODE_FOR_vsx_xxpermdi_v2df:
10290 case CODE_FOR_vsx_xxpermdi_v2di:
10291 case CODE_FOR_vsx_xxsldwi_v16qi:
10292 case CODE_FOR_vsx_xxsldwi_v8hi:
10293 case CODE_FOR_vsx_xxsldwi_v4si:
10294 case CODE_FOR_vsx_xxsldwi_v4sf:
10295 case CODE_FOR_vsx_xxsldwi_v2di:
10296 case CODE_FOR_vsx_xxsldwi_v2df:
10297 /* Only allow 2-bit unsigned literals. */
10299 if (TREE_CODE (arg2) != INTEGER_CST
10300 || TREE_INT_CST_LOW (arg2) & ~0x3)
10302 error ("argument 3 must be a 2-bit unsigned literal");
10307 case CODE_FOR_vsx_set_v2df:
10308 case CODE_FOR_vsx_set_v2di:
10309 /* Only allow 1-bit unsigned literals. */
10311 if (TREE_CODE (arg2) != INTEGER_CST
10312 || TREE_INT_CST_LOW (arg2) & ~0x1)
10314 error ("argument 3 must be a 1-bit unsigned literal");
10324 || GET_MODE (target) != tmode
10325 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10326 target = gen_reg_rtx (tmode);
10328 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10329 op0 = copy_to_mode_reg (mode0, op0);
10330 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10331 op1 = copy_to_mode_reg (mode1, op1);
10332 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
10333 op2 = copy_to_mode_reg (mode2, op2);
10335 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
10336 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
10338 pat = GEN_FCN (icode) (target, op0, op1, op2);
10346 /* Expand the lvx builtins. */
10348 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
10350 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10351 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10353 enum machine_mode tmode, mode0;
10355 enum insn_code icode;
10359 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
10360 icode = CODE_FOR_vector_load_v16qi;
10362 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
10363 icode = CODE_FOR_vector_load_v8hi;
10365 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
10366 icode = CODE_FOR_vector_load_v4si;
10368 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
10369 icode = CODE_FOR_vector_load_v4sf;
10372 *expandedp = false;
10378 arg0 = CALL_EXPR_ARG (exp, 0);
10379 op0 = expand_normal (arg0);
10380 tmode = insn_data[icode].operand[0].mode;
10381 mode0 = insn_data[icode].operand[1].mode;
10384 || GET_MODE (target) != tmode
10385 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10386 target = gen_reg_rtx (tmode);
10388 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10389 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10391 pat = GEN_FCN (icode) (target, op0);
10398 /* Expand the stvx builtins. */
10400 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10403 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10404 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10406 enum machine_mode mode0, mode1;
10408 enum insn_code icode;
10412 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
10413 icode = CODE_FOR_vector_store_v16qi;
10415 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
10416 icode = CODE_FOR_vector_store_v8hi;
10418 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
10419 icode = CODE_FOR_vector_store_v4si;
10421 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
10422 icode = CODE_FOR_vector_store_v4sf;
10425 *expandedp = false;
10429 arg0 = CALL_EXPR_ARG (exp, 0);
10430 arg1 = CALL_EXPR_ARG (exp, 1);
10431 op0 = expand_normal (arg0);
10432 op1 = expand_normal (arg1);
10433 mode0 = insn_data[icode].operand[0].mode;
10434 mode1 = insn_data[icode].operand[1].mode;
10436 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10437 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
10438 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
10439 op1 = copy_to_mode_reg (mode1, op1);
10441 pat = GEN_FCN (icode) (op0, op1);
10449 /* Expand the dst builtins. */
10451 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
10454 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10455 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10456 tree arg0, arg1, arg2;
10457 enum machine_mode mode0, mode1;
10458 rtx pat, op0, op1, op2;
10459 const struct builtin_description *d;
10462 *expandedp = false;
10464 /* Handle DST variants. */
10466 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
10467 if (d->code == fcode)
10469 arg0 = CALL_EXPR_ARG (exp, 0);
10470 arg1 = CALL_EXPR_ARG (exp, 1);
10471 arg2 = CALL_EXPR_ARG (exp, 2);
10472 op0 = expand_normal (arg0);
10473 op1 = expand_normal (arg1);
10474 op2 = expand_normal (arg2);
10475 mode0 = insn_data[d->icode].operand[0].mode;
10476 mode1 = insn_data[d->icode].operand[1].mode;
10478 /* Invalid arguments, bail out before generating bad rtl. */
10479 if (arg0 == error_mark_node
10480 || arg1 == error_mark_node
10481 || arg2 == error_mark_node)
10486 if (TREE_CODE (arg2) != INTEGER_CST
10487 || TREE_INT_CST_LOW (arg2) & ~0x3)
10489 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
10493 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
10494 op0 = copy_to_mode_reg (Pmode, op0);
10495 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
10496 op1 = copy_to_mode_reg (mode1, op1);
10498 pat = GEN_FCN (d->icode) (op0, op1, op2);
10508 /* Expand vec_init builtin. */
10510 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
10512 enum machine_mode tmode = TYPE_MODE (type);
10513 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
10514 int i, n_elt = GET_MODE_NUNITS (tmode);
10515 rtvec v = rtvec_alloc (n_elt);
10517 gcc_assert (VECTOR_MODE_P (tmode));
10518 gcc_assert (n_elt == call_expr_nargs (exp));
10520 for (i = 0; i < n_elt; ++i)
10522 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
10523 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
10526 if (!target || !register_operand (target, tmode))
10527 target = gen_reg_rtx (tmode);
10529 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
10533 /* Return the integer constant in ARG. Constrain it to be in the range
10534 of the subparts of VEC_TYPE; issue an error if not. */
10537 get_element_number (tree vec_type, tree arg)
10539 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
10541 if (!host_integerp (arg, 1)
10542 || (elt = tree_low_cst (arg, 1), elt > max))
10544 error ("selector must be an integer constant in the range 0..%wi", max);
10551 /* Expand vec_set builtin. */
10553 altivec_expand_vec_set_builtin (tree exp)
10555 enum machine_mode tmode, mode1;
10556 tree arg0, arg1, arg2;
10560 arg0 = CALL_EXPR_ARG (exp, 0);
10561 arg1 = CALL_EXPR_ARG (exp, 1);
10562 arg2 = CALL_EXPR_ARG (exp, 2);
10564 tmode = TYPE_MODE (TREE_TYPE (arg0));
10565 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10566 gcc_assert (VECTOR_MODE_P (tmode));
10568 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
10569 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
10570 elt = get_element_number (TREE_TYPE (arg0), arg2);
10572 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
10573 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
10575 op0 = force_reg (tmode, op0);
10576 op1 = force_reg (mode1, op1);
10578 rs6000_expand_vector_set (op0, op1, elt);
10583 /* Expand vec_ext builtin. */
10585 altivec_expand_vec_ext_builtin (tree exp, rtx target)
10587 enum machine_mode tmode, mode0;
10592 arg0 = CALL_EXPR_ARG (exp, 0);
10593 arg1 = CALL_EXPR_ARG (exp, 1);
10595 op0 = expand_normal (arg0);
10596 elt = get_element_number (TREE_TYPE (arg0), arg1);
10598 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
10599 mode0 = TYPE_MODE (TREE_TYPE (arg0));
10600 gcc_assert (VECTOR_MODE_P (mode0));
10602 op0 = force_reg (mode0, op0);
10604 if (optimize || !target || !register_operand (target, tmode))
10605 target = gen_reg_rtx (tmode);
10607 rs6000_expand_vector_extract (target, op0, elt);
10612 /* Expand the builtin in EXP and store the result in TARGET. Store
10613 true in *EXPANDEDP if we found a builtin to expand. */
10615 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
10617 const struct builtin_description *d;
10618 const struct builtin_description_predicates *dp;
10620 enum insn_code icode;
10621 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10624 enum machine_mode tmode, mode0;
10625 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10627 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10628 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
10629 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
10630 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
10633 error ("unresolved overload for Altivec builtin %qF", fndecl);
10637 target = altivec_expand_ld_builtin (exp, target, expandedp);
10641 target = altivec_expand_st_builtin (exp, target, expandedp);
10645 target = altivec_expand_dst_builtin (exp, target, expandedp);
10653 case ALTIVEC_BUILTIN_STVX:
10654 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
10655 case ALTIVEC_BUILTIN_STVEBX:
10656 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
10657 case ALTIVEC_BUILTIN_STVEHX:
10658 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
10659 case ALTIVEC_BUILTIN_STVEWX:
10660 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
10661 case ALTIVEC_BUILTIN_STVXL:
10662 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
10664 case ALTIVEC_BUILTIN_STVLX:
10665 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
10666 case ALTIVEC_BUILTIN_STVLXL:
10667 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
10668 case ALTIVEC_BUILTIN_STVRX:
10669 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
10670 case ALTIVEC_BUILTIN_STVRXL:
10671 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
10673 case ALTIVEC_BUILTIN_MFVSCR:
10674 icode = CODE_FOR_altivec_mfvscr;
10675 tmode = insn_data[icode].operand[0].mode;
10678 || GET_MODE (target) != tmode
10679 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10680 target = gen_reg_rtx (tmode);
10682 pat = GEN_FCN (icode) (target);
10688 case ALTIVEC_BUILTIN_MTVSCR:
10689 icode = CODE_FOR_altivec_mtvscr;
10690 arg0 = CALL_EXPR_ARG (exp, 0);
10691 op0 = expand_normal (arg0);
10692 mode0 = insn_data[icode].operand[0].mode;
10694 /* If we got invalid arguments bail out before generating bad rtl. */
10695 if (arg0 == error_mark_node)
10698 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10699 op0 = copy_to_mode_reg (mode0, op0);
10701 pat = GEN_FCN (icode) (op0);
10706 case ALTIVEC_BUILTIN_DSSALL:
10707 emit_insn (gen_altivec_dssall ());
10710 case ALTIVEC_BUILTIN_DSS:
10711 icode = CODE_FOR_altivec_dss;
10712 arg0 = CALL_EXPR_ARG (exp, 0);
10714 op0 = expand_normal (arg0);
10715 mode0 = insn_data[icode].operand[0].mode;
10717 /* If we got invalid arguments bail out before generating bad rtl. */
10718 if (arg0 == error_mark_node)
10721 if (TREE_CODE (arg0) != INTEGER_CST
10722 || TREE_INT_CST_LOW (arg0) & ~0x3)
10724 error ("argument to dss must be a 2-bit unsigned literal");
10728 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
10729 op0 = copy_to_mode_reg (mode0, op0);
10731 emit_insn (gen_altivec_dss (op0));
10734 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
10735 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
10736 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
10737 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
10738 case VSX_BUILTIN_VEC_INIT_V2DF:
10739 case VSX_BUILTIN_VEC_INIT_V2DI:
10740 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
10742 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
10743 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
10744 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
10745 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
10746 case VSX_BUILTIN_VEC_SET_V2DF:
10747 case VSX_BUILTIN_VEC_SET_V2DI:
10748 return altivec_expand_vec_set_builtin (exp);
10750 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
10751 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
10752 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
10753 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
10754 case VSX_BUILTIN_VEC_EXT_V2DF:
10755 case VSX_BUILTIN_VEC_EXT_V2DI:
10756 return altivec_expand_vec_ext_builtin (exp, target);
10760 /* Fall through. */
10763 /* Expand abs* operations. */
10765 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
10766 if (d->code == fcode)
10767 return altivec_expand_abs_builtin (d->icode, exp, target);
10769 /* Expand the AltiVec predicates. */
10770 dp = bdesc_altivec_preds;
10771 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
10772 if (dp->code == fcode)
10773 return altivec_expand_predicate_builtin (dp->icode, exp, target);
10775 /* LV* are funky. We initialized them differently. */
10778 case ALTIVEC_BUILTIN_LVSL:
10779 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
10780 exp, target, false);
10781 case ALTIVEC_BUILTIN_LVSR:
10782 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
10783 exp, target, false);
10784 case ALTIVEC_BUILTIN_LVEBX:
10785 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
10786 exp, target, false);
10787 case ALTIVEC_BUILTIN_LVEHX:
10788 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
10789 exp, target, false);
10790 case ALTIVEC_BUILTIN_LVEWX:
10791 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
10792 exp, target, false);
10793 case ALTIVEC_BUILTIN_LVXL:
10794 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
10795 exp, target, false);
10796 case ALTIVEC_BUILTIN_LVX:
10797 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
10798 exp, target, false);
10799 case ALTIVEC_BUILTIN_LVLX:
10800 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
10801 exp, target, true);
10802 case ALTIVEC_BUILTIN_LVLXL:
10803 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
10804 exp, target, true);
10805 case ALTIVEC_BUILTIN_LVRX:
10806 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
10807 exp, target, true);
10808 case ALTIVEC_BUILTIN_LVRXL:
10809 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
10810 exp, target, true);
10813 /* Fall through. */
10816 *expandedp = false;
10820 /* Expand the builtin in EXP and store the result in TARGET. Store
10821 true in *EXPANDEDP if we found a builtin to expand. */
10823 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
10825 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10826 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10827 const struct builtin_description *d;
10834 case PAIRED_BUILTIN_STX:
10835 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
10836 case PAIRED_BUILTIN_LX:
10837 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
10840 /* Fall through. */
10843 /* Expand the paired predicates. */
10844 d = bdesc_paired_preds;
10845 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
10846 if (d->code == fcode)
10847 return paired_expand_predicate_builtin (d->icode, exp, target);
10849 *expandedp = false;
10853 /* Binops that need to be initialized manually, but can be expanded
10854 automagically by rs6000_expand_binop_builtin. */
10855 static struct builtin_description bdesc_2arg_spe[] =
10857 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
10858 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
10859 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
10860 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
10861 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
10862 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
10863 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
10864 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
10865 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
10866 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
10867 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
10868 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
10869 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
10870 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
10871 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
10872 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
10873 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
10874 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
10875 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
10876 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
10877 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
10878 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
10881 /* Expand the builtin in EXP and store the result in TARGET. Store
10882 true in *EXPANDEDP if we found a builtin to expand.
10884 This expands the SPE builtins that are not simple unary and binary
10887 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
10889 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
10891 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
10892 enum insn_code icode;
10893 enum machine_mode tmode, mode0;
10895 struct builtin_description *d;
10900 /* Syntax check for a 5-bit unsigned immediate. */
10903 case SPE_BUILTIN_EVSTDD:
10904 case SPE_BUILTIN_EVSTDH:
10905 case SPE_BUILTIN_EVSTDW:
10906 case SPE_BUILTIN_EVSTWHE:
10907 case SPE_BUILTIN_EVSTWHO:
10908 case SPE_BUILTIN_EVSTWWE:
10909 case SPE_BUILTIN_EVSTWWO:
10910 arg1 = CALL_EXPR_ARG (exp, 2);
10911 if (TREE_CODE (arg1) != INTEGER_CST
10912 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10914 error ("argument 2 must be a 5-bit unsigned literal");
10922 /* The evsplat*i instructions are not quite generic. */
10925 case SPE_BUILTIN_EVSPLATFI:
10926 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
10928 case SPE_BUILTIN_EVSPLATI:
10929 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
10935 d = (struct builtin_description *) bdesc_2arg_spe;
10936 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
10937 if (d->code == fcode)
10938 return rs6000_expand_binop_builtin (d->icode, exp, target);
10940 d = (struct builtin_description *) bdesc_spe_predicates;
10941 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
10942 if (d->code == fcode)
10943 return spe_expand_predicate_builtin (d->icode, exp, target);
10945 d = (struct builtin_description *) bdesc_spe_evsel;
10946 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
10947 if (d->code == fcode)
10948 return spe_expand_evsel_builtin (d->icode, exp, target);
10952 case SPE_BUILTIN_EVSTDDX:
10953 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
10954 case SPE_BUILTIN_EVSTDHX:
10955 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
10956 case SPE_BUILTIN_EVSTDWX:
10957 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
10958 case SPE_BUILTIN_EVSTWHEX:
10959 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
10960 case SPE_BUILTIN_EVSTWHOX:
10961 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
10962 case SPE_BUILTIN_EVSTWWEX:
10963 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
10964 case SPE_BUILTIN_EVSTWWOX:
10965 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
10966 case SPE_BUILTIN_EVSTDD:
10967 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
10968 case SPE_BUILTIN_EVSTDH:
10969 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
10970 case SPE_BUILTIN_EVSTDW:
10971 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
10972 case SPE_BUILTIN_EVSTWHE:
10973 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
10974 case SPE_BUILTIN_EVSTWHO:
10975 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
10976 case SPE_BUILTIN_EVSTWWE:
10977 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
10978 case SPE_BUILTIN_EVSTWWO:
10979 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
10980 case SPE_BUILTIN_MFSPEFSCR:
10981 icode = CODE_FOR_spe_mfspefscr;
10982 tmode = insn_data[icode].operand[0].mode;
10985 || GET_MODE (target) != tmode
10986 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10987 target = gen_reg_rtx (tmode);
10989 pat = GEN_FCN (icode) (target);
10994 case SPE_BUILTIN_MTSPEFSCR:
10995 icode = CODE_FOR_spe_mtspefscr;
10996 arg0 = CALL_EXPR_ARG (exp, 0);
10997 op0 = expand_normal (arg0);
10998 mode0 = insn_data[icode].operand[0].mode;
11000 if (arg0 == error_mark_node)
11003 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11004 op0 = copy_to_mode_reg (mode0, op0);
11006 pat = GEN_FCN (icode) (op0);
11014 *expandedp = false;
11019 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11021 rtx pat, scratch, tmp;
11022 tree form = CALL_EXPR_ARG (exp, 0);
11023 tree arg0 = CALL_EXPR_ARG (exp, 1);
11024 tree arg1 = CALL_EXPR_ARG (exp, 2);
11025 rtx op0 = expand_normal (arg0);
11026 rtx op1 = expand_normal (arg1);
11027 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11028 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11030 enum rtx_code code;
11032 if (TREE_CODE (form) != INTEGER_CST)
11034 error ("argument 1 of __builtin_paired_predicate must be a constant");
11038 form_int = TREE_INT_CST_LOW (form);
11040 gcc_assert (mode0 == mode1);
11042 if (arg0 == error_mark_node || arg1 == error_mark_node)
11046 || GET_MODE (target) != SImode
11047 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11048 target = gen_reg_rtx (SImode);
11049 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11050 op0 = copy_to_mode_reg (mode0, op0);
11051 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11052 op1 = copy_to_mode_reg (mode1, op1);
11054 scratch = gen_reg_rtx (CCFPmode);
11056 pat = GEN_FCN (icode) (scratch, op0, op1);
11078 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11081 error ("argument 1 of __builtin_paired_predicate is out of range");
11085 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11086 emit_move_insn (target, tmp);
11091 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11093 rtx pat, scratch, tmp;
11094 tree form = CALL_EXPR_ARG (exp, 0);
11095 tree arg0 = CALL_EXPR_ARG (exp, 1);
11096 tree arg1 = CALL_EXPR_ARG (exp, 2);
11097 rtx op0 = expand_normal (arg0);
11098 rtx op1 = expand_normal (arg1);
11099 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11100 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11102 enum rtx_code code;
11104 if (TREE_CODE (form) != INTEGER_CST)
11106 error ("argument 1 of __builtin_spe_predicate must be a constant");
11110 form_int = TREE_INT_CST_LOW (form);
11112 gcc_assert (mode0 == mode1);
11114 if (arg0 == error_mark_node || arg1 == error_mark_node)
11118 || GET_MODE (target) != SImode
11119 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11120 target = gen_reg_rtx (SImode);
11122 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11123 op0 = copy_to_mode_reg (mode0, op0);
11124 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11125 op1 = copy_to_mode_reg (mode1, op1);
11127 scratch = gen_reg_rtx (CCmode);
11129 pat = GEN_FCN (icode) (scratch, op0, op1);
11134 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11135 _lower_. We use one compare, but look in different bits of the
11136 CR for each variant.
11138 There are 2 elements in each SPE simd type (upper/lower). The CR
11139 bits are set as follows:
11141 BIT0 | BIT 1 | BIT 2 | BIT 3
11142 U | L | (U | L) | (U & L)
11144 So, for an "all" relationship, BIT 3 would be set.
11145 For an "any" relationship, BIT 2 would be set. Etc.
11147 Following traditional nomenclature, these bits map to:
11149 BIT0 | BIT 1 | BIT 2 | BIT 3
11152 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11157 /* All variant. OV bit. */
11159 /* We need to get to the OV bit, which is the ORDERED bit. We
11160 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11161 that's ugly and will make validate_condition_mode die.
11162 So let's just use another pattern. */
11163 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11165 /* Any variant. EQ bit. */
11169 /* Upper variant. LT bit. */
11173 /* Lower variant. GT bit. */
11178 error ("argument 1 of __builtin_spe_predicate is out of range");
11182 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11183 emit_move_insn (target, tmp);
11188 /* The evsel builtins look like this:
11190 e = __builtin_spe_evsel_OP (a, b, c, d);
11192 and work like this:
11194 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11195 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11199 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11202 tree arg0 = CALL_EXPR_ARG (exp, 0);
11203 tree arg1 = CALL_EXPR_ARG (exp, 1);
11204 tree arg2 = CALL_EXPR_ARG (exp, 2);
11205 tree arg3 = CALL_EXPR_ARG (exp, 3);
11206 rtx op0 = expand_normal (arg0);
11207 rtx op1 = expand_normal (arg1);
11208 rtx op2 = expand_normal (arg2);
11209 rtx op3 = expand_normal (arg3);
11210 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11211 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11213 gcc_assert (mode0 == mode1);
11215 if (arg0 == error_mark_node || arg1 == error_mark_node
11216 || arg2 == error_mark_node || arg3 == error_mark_node)
11220 || GET_MODE (target) != mode0
11221 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11222 target = gen_reg_rtx (mode0);
11224 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11225 op0 = copy_to_mode_reg (mode0, op0);
11226 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11227 op1 = copy_to_mode_reg (mode0, op1);
11228 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11229 op2 = copy_to_mode_reg (mode0, op2);
11230 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11231 op3 = copy_to_mode_reg (mode0, op3);
11233 /* Generate the compare. */
11234 scratch = gen_reg_rtx (CCmode);
11235 pat = GEN_FCN (icode) (scratch, op0, op1);
11240 if (mode0 == V2SImode)
11241 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11243 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11248 /* Expand an expression EXP that calls a built-in function,
11249 with result going to TARGET if that's convenient
11250 (and in mode MODE if that's convenient).
11251 SUBTARGET may be used as the target for computing one of EXP's operands.
11252 IGNORE is nonzero if the value is to be ignored. */
11255 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11256 enum machine_mode mode ATTRIBUTE_UNUSED,
11257 int ignore ATTRIBUTE_UNUSED)
11259 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11260 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11261 const struct builtin_description *d;
11268 case RS6000_BUILTIN_RECIP:
11269 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
11271 case RS6000_BUILTIN_RECIPF:
11272 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
11274 case RS6000_BUILTIN_RSQRTF:
11275 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
11277 case RS6000_BUILTIN_RSQRT:
11278 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
11280 case RS6000_BUILTIN_BSWAP_HI:
11281 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
11283 case POWER7_BUILTIN_BPERMD:
11284 return rs6000_expand_binop_builtin (((TARGET_64BIT)
11285 ? CODE_FOR_bpermd_di
11286 : CODE_FOR_bpermd_si), exp, target);
11288 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
11289 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
11291 int icode = (int) CODE_FOR_altivec_lvsr;
11292 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11293 enum machine_mode mode = insn_data[icode].operand[1].mode;
11297 gcc_assert (TARGET_ALTIVEC);
11299 arg = CALL_EXPR_ARG (exp, 0);
11300 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
11301 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
11302 addr = memory_address (mode, op);
11303 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
11307 /* For the load case need to negate the address. */
11308 op = gen_reg_rtx (GET_MODE (addr));
11309 emit_insn (gen_rtx_SET (VOIDmode, op,
11310 gen_rtx_NEG (GET_MODE (addr), addr)));
11312 op = gen_rtx_MEM (mode, op);
11315 || GET_MODE (target) != tmode
11316 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11317 target = gen_reg_rtx (tmode);
11319 /*pat = gen_altivec_lvsr (target, op);*/
11320 pat = GEN_FCN (icode) (target, op);
11328 case ALTIVEC_BUILTIN_VCFUX:
11329 case ALTIVEC_BUILTIN_VCFSX:
11330 case ALTIVEC_BUILTIN_VCTUXS:
11331 case ALTIVEC_BUILTIN_VCTSXS:
11332 /* FIXME: There's got to be a nicer way to handle this case than
11333 constructing a new CALL_EXPR. */
11334 if (call_expr_nargs (exp) == 1)
11336 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
11337 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
11345 if (TARGET_ALTIVEC)
11347 ret = altivec_expand_builtin (exp, target, &success);
11354 ret = spe_expand_builtin (exp, target, &success);
11359 if (TARGET_PAIRED_FLOAT)
11361 ret = paired_expand_builtin (exp, target, &success);
11367 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
11369 /* Handle simple unary operations. */
11370 d = (struct builtin_description *) bdesc_1arg;
11371 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
11372 if (d->code == fcode)
11373 return rs6000_expand_unop_builtin (d->icode, exp, target);
11375 /* Handle simple binary operations. */
11376 d = (struct builtin_description *) bdesc_2arg;
11377 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
11378 if (d->code == fcode)
11379 return rs6000_expand_binop_builtin (d->icode, exp, target);
11381 /* Handle simple ternary operations. */
11383 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
11384 if (d->code == fcode)
11385 return rs6000_expand_ternop_builtin (d->icode, exp, target);
11387 gcc_unreachable ();
11391 rs6000_init_builtins (void)
11396 V2SI_type_node = build_vector_type (intSI_type_node, 2);
11397 V2SF_type_node = build_vector_type (float_type_node, 2);
11398 V2DI_type_node = build_vector_type (intDI_type_node, 2);
11399 V2DF_type_node = build_vector_type (double_type_node, 2);
11400 V4HI_type_node = build_vector_type (intHI_type_node, 4);
11401 V4SI_type_node = build_vector_type (intSI_type_node, 4);
11402 V4SF_type_node = build_vector_type (float_type_node, 4);
11403 V8HI_type_node = build_vector_type (intHI_type_node, 8);
11404 V16QI_type_node = build_vector_type (intQI_type_node, 16);
11406 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
11407 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
11408 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
11409 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
11411 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
11412 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
11413 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
11414 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
11416 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
11417 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
11418 'vector unsigned short'. */
11420 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
11421 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11422 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
11423 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
11424 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
11426 long_integer_type_internal_node = long_integer_type_node;
11427 long_unsigned_type_internal_node = long_unsigned_type_node;
11428 intQI_type_internal_node = intQI_type_node;
11429 uintQI_type_internal_node = unsigned_intQI_type_node;
11430 intHI_type_internal_node = intHI_type_node;
11431 uintHI_type_internal_node = unsigned_intHI_type_node;
11432 intSI_type_internal_node = intSI_type_node;
11433 uintSI_type_internal_node = unsigned_intSI_type_node;
11434 intDI_type_internal_node = intDI_type_node;
11435 uintDI_type_internal_node = unsigned_intDI_type_node;
11436 float_type_internal_node = float_type_node;
11437 double_type_internal_node = float_type_node;
11438 void_type_internal_node = void_type_node;
11440 /* Initialize the modes for builtin_function_type, mapping a machine mode to
11442 builtin_mode_to_type[QImode][0] = integer_type_node;
11443 builtin_mode_to_type[HImode][0] = integer_type_node;
11444 builtin_mode_to_type[SImode][0] = intSI_type_node;
11445 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
11446 builtin_mode_to_type[DImode][0] = intDI_type_node;
11447 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
11448 builtin_mode_to_type[SFmode][0] = float_type_node;
11449 builtin_mode_to_type[DFmode][0] = double_type_node;
11450 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
11451 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
11452 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
11453 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
11454 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
11455 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
11456 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
11457 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
11458 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
11459 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
11460 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
11461 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
11462 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
11464 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11465 get_identifier ("__bool char"),
11466 bool_char_type_node);
11467 TYPE_NAME (bool_char_type_node) = tdecl;
11468 (*lang_hooks.decls.pushdecl) (tdecl);
11469 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11470 get_identifier ("__bool short"),
11471 bool_short_type_node);
11472 TYPE_NAME (bool_short_type_node) = tdecl;
11473 (*lang_hooks.decls.pushdecl) (tdecl);
11474 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11475 get_identifier ("__bool int"),
11476 bool_int_type_node);
11477 TYPE_NAME (bool_int_type_node) = tdecl;
11478 (*lang_hooks.decls.pushdecl) (tdecl);
11479 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
11481 TYPE_NAME (pixel_type_node) = tdecl;
11482 (*lang_hooks.decls.pushdecl) (tdecl);
11484 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
11485 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
11486 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
11487 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
11488 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
11490 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11491 get_identifier ("__vector unsigned char"),
11492 unsigned_V16QI_type_node);
11493 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
11494 (*lang_hooks.decls.pushdecl) (tdecl);
11495 tdecl = build_decl (BUILTINS_LOCATION,
11496 TYPE_DECL, get_identifier ("__vector signed char"),
11498 TYPE_NAME (V16QI_type_node) = tdecl;
11499 (*lang_hooks.decls.pushdecl) (tdecl);
11500 tdecl = build_decl (BUILTINS_LOCATION,
11501 TYPE_DECL, get_identifier ("__vector __bool char"),
11502 bool_V16QI_type_node);
11503 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
11504 (*lang_hooks.decls.pushdecl) (tdecl);
11506 tdecl = build_decl (BUILTINS_LOCATION,
11507 TYPE_DECL, get_identifier ("__vector unsigned short"),
11508 unsigned_V8HI_type_node);
11509 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
11510 (*lang_hooks.decls.pushdecl) (tdecl);
11511 tdecl = build_decl (BUILTINS_LOCATION,
11512 TYPE_DECL, get_identifier ("__vector signed short"),
11514 TYPE_NAME (V8HI_type_node) = tdecl;
11515 (*lang_hooks.decls.pushdecl) (tdecl);
11516 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11517 get_identifier ("__vector __bool short"),
11518 bool_V8HI_type_node);
11519 TYPE_NAME (bool_V8HI_type_node) = tdecl;
11520 (*lang_hooks.decls.pushdecl) (tdecl);
11522 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
11523 get_identifier ("__vector unsigned int"),
11524 unsigned_V4SI_type_node);
11525 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
11526 (*lang_hooks.decls.pushdecl) (tdecl);
11527 tdecl = build_decl (BUILTINS_LOCATION,
11528 TYPE_DECL, get_identifier ("__vector signed int"),
11530 TYPE_NAME (V4SI_type_node) = tdecl;
11531 (*lang_hooks.decls.pushdecl) (tdecl);
11532 tdecl = build_decl (BUILTINS_LOCATION,
11533 TYPE_DECL, get_identifier ("__vector __bool int"),
11534 bool_V4SI_type_node);
11535 TYPE_NAME (bool_V4SI_type_node) = tdecl;
11536 (*lang_hooks.decls.pushdecl) (tdecl);
11538 tdecl = build_decl (BUILTINS_LOCATION,
11539 TYPE_DECL, get_identifier ("__vector float"),
11541 TYPE_NAME (V4SF_type_node) = tdecl;
11542 (*lang_hooks.decls.pushdecl) (tdecl);
11543 tdecl = build_decl (BUILTINS_LOCATION,
11544 TYPE_DECL, get_identifier ("__vector __pixel"),
11545 pixel_V8HI_type_node);
11546 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
11547 (*lang_hooks.decls.pushdecl) (tdecl);
11551 tdecl = build_decl (BUILTINS_LOCATION,
11552 TYPE_DECL, get_identifier ("__vector double"),
11554 TYPE_NAME (V2DF_type_node) = tdecl;
11555 (*lang_hooks.decls.pushdecl) (tdecl);
11557 tdecl = build_decl (BUILTINS_LOCATION,
11558 TYPE_DECL, get_identifier ("__vector long"),
11560 TYPE_NAME (V2DI_type_node) = tdecl;
11561 (*lang_hooks.decls.pushdecl) (tdecl);
11563 tdecl = build_decl (BUILTINS_LOCATION,
11564 TYPE_DECL, get_identifier ("__vector unsigned long"),
11565 unsigned_V2DI_type_node);
11566 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
11567 (*lang_hooks.decls.pushdecl) (tdecl);
11569 tdecl = build_decl (BUILTINS_LOCATION,
11570 TYPE_DECL, get_identifier ("__vector __bool long"),
11571 bool_V2DI_type_node);
11572 TYPE_NAME (bool_V2DI_type_node) = tdecl;
11573 (*lang_hooks.decls.pushdecl) (tdecl);
11576 if (TARGET_PAIRED_FLOAT)
11577 paired_init_builtins ();
11579 spe_init_builtins ();
11580 if (TARGET_ALTIVEC)
11581 altivec_init_builtins ();
11582 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
11583 rs6000_common_init_builtins ();
11586 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
11587 RS6000_BUILTIN_RECIP,
11588 "__builtin_recipdiv");
11589 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
11590 RS6000_BUILTIN_RECIP);
11594 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
11595 RS6000_BUILTIN_RECIPF,
11596 "__builtin_recipdivf");
11597 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
11598 RS6000_BUILTIN_RECIPF);
11600 if (TARGET_FRSQRTE)
11602 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
11603 RS6000_BUILTIN_RSQRT,
11604 "__builtin_rsqrt");
11605 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
11606 RS6000_BUILTIN_RSQRT);
11608 if (TARGET_FRSQRTES)
11610 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
11611 RS6000_BUILTIN_RSQRTF,
11612 "__builtin_rsqrtf");
11613 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
11614 RS6000_BUILTIN_RSQRTF);
11616 if (TARGET_POPCNTD)
11618 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
11619 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
11620 POWER7_BUILTIN_BPERMD,
11621 "__builtin_bpermd");
11622 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
11623 POWER7_BUILTIN_BPERMD);
11625 if (TARGET_POWERPC)
11627 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
11628 tree ftype = build_function_type_list (unsigned_intHI_type_node,
11629 unsigned_intHI_type_node,
11631 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
11632 RS6000_BUILTIN_BSWAP_HI);
11636 /* AIX libm provides clog as __clog. */
11637 if (built_in_decls [BUILT_IN_CLOG])
11638 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
11641 #ifdef SUBTARGET_INIT_BUILTINS
11642 SUBTARGET_INIT_BUILTINS;
11646 /* Returns the rs6000 builtin decl for CODE. */
11649 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
11651 if (code >= RS6000_BUILTIN_COUNT)
11652 return error_mark_node;
11654 return rs6000_builtin_decls[code];
11657 /* Search through a set of builtins and enable the mask bits.
11658 DESC is an array of builtins.
11659 SIZE is the total number of builtins.
11660 START is the builtin enum at which to start.
11661 END is the builtin enum at which to end. */
11663 enable_mask_for_builtins (struct builtin_description *desc, int size,
11664 enum rs6000_builtins start,
11665 enum rs6000_builtins end)
11669 for (i = 0; i < size; ++i)
11670 if (desc[i].code == start)
11676 for (; i < size; ++i)
11678 /* Flip all the bits on. */
11679 desc[i].mask = target_flags;
11680 if (desc[i].code == end)
11686 spe_init_builtins (void)
11688 tree endlink = void_list_node;
11689 tree puint_type_node = build_pointer_type (unsigned_type_node);
11690 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
11691 struct builtin_description *d;
11694 tree v2si_ftype_4_v2si
11695 = build_function_type
11696 (opaque_V2SI_type_node,
11697 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11698 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11699 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11700 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11703 tree v2sf_ftype_4_v2sf
11704 = build_function_type
11705 (opaque_V2SF_type_node,
11706 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11707 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11708 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11709 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11712 tree int_ftype_int_v2si_v2si
11713 = build_function_type
11714 (integer_type_node,
11715 tree_cons (NULL_TREE, integer_type_node,
11716 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11717 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11720 tree int_ftype_int_v2sf_v2sf
11721 = build_function_type
11722 (integer_type_node,
11723 tree_cons (NULL_TREE, integer_type_node,
11724 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11725 tree_cons (NULL_TREE, opaque_V2SF_type_node,
11728 tree void_ftype_v2si_puint_int
11729 = build_function_type (void_type_node,
11730 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11731 tree_cons (NULL_TREE, puint_type_node,
11732 tree_cons (NULL_TREE,
11736 tree void_ftype_v2si_puint_char
11737 = build_function_type (void_type_node,
11738 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11739 tree_cons (NULL_TREE, puint_type_node,
11740 tree_cons (NULL_TREE,
11744 tree void_ftype_v2si_pv2si_int
11745 = build_function_type (void_type_node,
11746 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11747 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11748 tree_cons (NULL_TREE,
11752 tree void_ftype_v2si_pv2si_char
11753 = build_function_type (void_type_node,
11754 tree_cons (NULL_TREE, opaque_V2SI_type_node,
11755 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11756 tree_cons (NULL_TREE,
11760 tree void_ftype_int
11761 = build_function_type (void_type_node,
11762 tree_cons (NULL_TREE, integer_type_node, endlink));
11764 tree int_ftype_void
11765 = build_function_type (integer_type_node, endlink);
11767 tree v2si_ftype_pv2si_int
11768 = build_function_type (opaque_V2SI_type_node,
11769 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
11770 tree_cons (NULL_TREE, integer_type_node,
11773 tree v2si_ftype_puint_int
11774 = build_function_type (opaque_V2SI_type_node,
11775 tree_cons (NULL_TREE, puint_type_node,
11776 tree_cons (NULL_TREE, integer_type_node,
11779 tree v2si_ftype_pushort_int
11780 = build_function_type (opaque_V2SI_type_node,
11781 tree_cons (NULL_TREE, pushort_type_node,
11782 tree_cons (NULL_TREE, integer_type_node,
11785 tree v2si_ftype_signed_char
11786 = build_function_type (opaque_V2SI_type_node,
11787 tree_cons (NULL_TREE, signed_char_type_node,
11790 /* The initialization of the simple binary and unary builtins is
11791 done in rs6000_common_init_builtins, but we have to enable the
11792 mask bits here manually because we have run out of `target_flags'
11793 bits. We really need to redesign this mask business. */
11795 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
11796 ARRAY_SIZE (bdesc_2arg),
11797 SPE_BUILTIN_EVADDW,
11798 SPE_BUILTIN_EVXOR);
11799 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
11800 ARRAY_SIZE (bdesc_1arg),
11802 SPE_BUILTIN_EVSUBFUSIAAW);
11803 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
11804 ARRAY_SIZE (bdesc_spe_predicates),
11805 SPE_BUILTIN_EVCMPEQ,
11806 SPE_BUILTIN_EVFSTSTLT);
11807 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
11808 ARRAY_SIZE (bdesc_spe_evsel),
11809 SPE_BUILTIN_EVSEL_CMPGTS,
11810 SPE_BUILTIN_EVSEL_FSTSTEQ);
11812 (*lang_hooks.decls.pushdecl)
11813 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
11814 get_identifier ("__ev64_opaque__"),
11815 opaque_V2SI_type_node));
11817 /* Initialize irregular SPE builtins. */
11819 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
11820 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
11821 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
11822 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
11823 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
11824 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
11825 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
11826 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
11827 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
11828 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
11829 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
11830 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
11831 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
11832 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
11833 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
11834 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
11835 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
11836 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
11839 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
11840 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
11841 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
11842 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
11843 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
11844 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
11845 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
11846 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
11847 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
11848 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
11849 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
11850 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
11851 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
11852 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
11853 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
11854 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
11855 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
11856 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
11857 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
11858 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
11859 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
11860 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
11863 d = (struct builtin_description *) bdesc_spe_predicates;
11864 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
11868 switch (insn_data[d->icode].operand[1].mode)
11871 type = int_ftype_int_v2si_v2si;
11874 type = int_ftype_int_v2sf_v2sf;
11877 gcc_unreachable ();
11880 def_builtin (d->mask, d->name, type, d->code);
11883 /* Evsel predicates. */
11884 d = (struct builtin_description *) bdesc_spe_evsel;
11885 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
11889 switch (insn_data[d->icode].operand[1].mode)
11892 type = v2si_ftype_4_v2si;
11895 type = v2sf_ftype_4_v2sf;
11898 gcc_unreachable ();
11901 def_builtin (d->mask, d->name, type, d->code);
11906 paired_init_builtins (void)
11908 const struct builtin_description *d;
11910 tree endlink = void_list_node;
11912 tree int_ftype_int_v2sf_v2sf
11913 = build_function_type
11914 (integer_type_node,
11915 tree_cons (NULL_TREE, integer_type_node,
11916 tree_cons (NULL_TREE, V2SF_type_node,
11917 tree_cons (NULL_TREE, V2SF_type_node,
11919 tree pcfloat_type_node =
11920 build_pointer_type (build_qualified_type
11921 (float_type_node, TYPE_QUAL_CONST));
11923 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
11924 long_integer_type_node,
11927 tree void_ftype_v2sf_long_pcfloat =
11928 build_function_type_list (void_type_node,
11930 long_integer_type_node,
11935 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
11936 PAIRED_BUILTIN_LX);
11939 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
11940 PAIRED_BUILTIN_STX);
11943 d = bdesc_paired_preds;
11944 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
11948 switch (insn_data[d->icode].operand[1].mode)
11951 type = int_ftype_int_v2sf_v2sf;
11954 gcc_unreachable ();
11957 def_builtin (d->mask, d->name, type, d->code);
11962 altivec_init_builtins (void)
11964 const struct builtin_description *d;
11965 const struct builtin_description_predicates *dp;
11969 tree pfloat_type_node = build_pointer_type (float_type_node);
11970 tree pint_type_node = build_pointer_type (integer_type_node);
11971 tree pshort_type_node = build_pointer_type (short_integer_type_node);
11972 tree pchar_type_node = build_pointer_type (char_type_node);
11974 tree pvoid_type_node = build_pointer_type (void_type_node);
11976 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
11977 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
11978 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
11979 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
11981 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
11983 tree int_ftype_opaque
11984 = build_function_type_list (integer_type_node,
11985 opaque_V4SI_type_node, NULL_TREE);
11986 tree opaque_ftype_opaque
11987 = build_function_type (integer_type_node,
11989 tree opaque_ftype_opaque_int
11990 = build_function_type_list (opaque_V4SI_type_node,
11991 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
11992 tree opaque_ftype_opaque_opaque_int
11993 = build_function_type_list (opaque_V4SI_type_node,
11994 opaque_V4SI_type_node, opaque_V4SI_type_node,
11995 integer_type_node, NULL_TREE);
11996 tree int_ftype_int_opaque_opaque
11997 = build_function_type_list (integer_type_node,
11998 integer_type_node, opaque_V4SI_type_node,
11999 opaque_V4SI_type_node, NULL_TREE);
12000 tree int_ftype_int_v4si_v4si
12001 = build_function_type_list (integer_type_node,
12002 integer_type_node, V4SI_type_node,
12003 V4SI_type_node, NULL_TREE);
12004 tree v4sf_ftype_pcfloat
12005 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12006 tree void_ftype_pfloat_v4sf
12007 = build_function_type_list (void_type_node,
12008 pfloat_type_node, V4SF_type_node, NULL_TREE);
12009 tree v4si_ftype_pcint
12010 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12011 tree void_ftype_pint_v4si
12012 = build_function_type_list (void_type_node,
12013 pint_type_node, V4SI_type_node, NULL_TREE);
12014 tree v8hi_ftype_pcshort
12015 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12016 tree void_ftype_pshort_v8hi
12017 = build_function_type_list (void_type_node,
12018 pshort_type_node, V8HI_type_node, NULL_TREE);
12019 tree v16qi_ftype_pcchar
12020 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12021 tree void_ftype_pchar_v16qi
12022 = build_function_type_list (void_type_node,
12023 pchar_type_node, V16QI_type_node, NULL_TREE);
12024 tree void_ftype_v4si
12025 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12026 tree v8hi_ftype_void
12027 = build_function_type (V8HI_type_node, void_list_node);
12028 tree void_ftype_void
12029 = build_function_type (void_type_node, void_list_node);
12030 tree void_ftype_int
12031 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12033 tree opaque_ftype_long_pcvoid
12034 = build_function_type_list (opaque_V4SI_type_node,
12035 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12036 tree v16qi_ftype_long_pcvoid
12037 = build_function_type_list (V16QI_type_node,
12038 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12039 tree v8hi_ftype_long_pcvoid
12040 = build_function_type_list (V8HI_type_node,
12041 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12042 tree v4si_ftype_long_pcvoid
12043 = build_function_type_list (V4SI_type_node,
12044 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12046 tree void_ftype_opaque_long_pvoid
12047 = build_function_type_list (void_type_node,
12048 opaque_V4SI_type_node, long_integer_type_node,
12049 pvoid_type_node, NULL_TREE);
12050 tree void_ftype_v4si_long_pvoid
12051 = build_function_type_list (void_type_node,
12052 V4SI_type_node, long_integer_type_node,
12053 pvoid_type_node, NULL_TREE);
12054 tree void_ftype_v16qi_long_pvoid
12055 = build_function_type_list (void_type_node,
12056 V16QI_type_node, long_integer_type_node,
12057 pvoid_type_node, NULL_TREE);
12058 tree void_ftype_v8hi_long_pvoid
12059 = build_function_type_list (void_type_node,
12060 V8HI_type_node, long_integer_type_node,
12061 pvoid_type_node, NULL_TREE);
12062 tree int_ftype_int_v8hi_v8hi
12063 = build_function_type_list (integer_type_node,
12064 integer_type_node, V8HI_type_node,
12065 V8HI_type_node, NULL_TREE);
12066 tree int_ftype_int_v16qi_v16qi
12067 = build_function_type_list (integer_type_node,
12068 integer_type_node, V16QI_type_node,
12069 V16QI_type_node, NULL_TREE);
12070 tree int_ftype_int_v4sf_v4sf
12071 = build_function_type_list (integer_type_node,
12072 integer_type_node, V4SF_type_node,
12073 V4SF_type_node, NULL_TREE);
12074 tree int_ftype_int_v2df_v2df
12075 = build_function_type_list (integer_type_node,
12076 integer_type_node, V2DF_type_node,
12077 V2DF_type_node, NULL_TREE);
12078 tree v4si_ftype_v4si
12079 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12080 tree v8hi_ftype_v8hi
12081 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12082 tree v16qi_ftype_v16qi
12083 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12084 tree v4sf_ftype_v4sf
12085 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12086 tree v2df_ftype_v2df
12087 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12088 tree void_ftype_pcvoid_int_int
12089 = build_function_type_list (void_type_node,
12090 pcvoid_type_node, integer_type_node,
12091 integer_type_node, NULL_TREE);
12093 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12094 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12095 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12096 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12097 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12098 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12099 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12100 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12101 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12102 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12103 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12104 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12105 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12106 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12107 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12108 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12109 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12110 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12111 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12112 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12113 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12114 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12115 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12116 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12117 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12118 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12119 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12120 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12121 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12122 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12123 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12124 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12125 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12126 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12127 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12128 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12129 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12130 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12131 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12132 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12133 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12134 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12135 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12136 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12137 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12138 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12140 if (rs6000_cpu == PROCESSOR_CELL)
12142 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12143 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12144 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12145 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12147 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12148 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12149 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12150 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12152 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12153 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12154 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12155 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12157 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12158 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12159 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12160 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12162 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12163 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12164 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12166 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12167 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12168 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12169 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12170 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12171 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12172 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12173 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12174 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12175 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12176 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12177 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12179 /* Add the DST variants. */
12181 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12182 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12184 /* Initialize the predicates. */
12185 dp = bdesc_altivec_preds;
12186 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12188 enum machine_mode mode1;
12190 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12191 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12192 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12193 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12198 mode1 = insn_data[dp->icode].operand[1].mode;
12203 type = int_ftype_int_opaque_opaque;
12206 type = int_ftype_int_v4si_v4si;
12209 type = int_ftype_int_v8hi_v8hi;
12212 type = int_ftype_int_v16qi_v16qi;
12215 type = int_ftype_int_v4sf_v4sf;
12218 type = int_ftype_int_v2df_v2df;
12221 gcc_unreachable ();
12224 def_builtin (dp->mask, dp->name, type, dp->code);
12227 /* Initialize the abs* operators. */
12229 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12231 enum machine_mode mode0;
12234 mode0 = insn_data[d->icode].operand[0].mode;
12239 type = v4si_ftype_v4si;
12242 type = v8hi_ftype_v8hi;
12245 type = v16qi_ftype_v16qi;
12248 type = v4sf_ftype_v4sf;
12251 type = v2df_ftype_v2df;
12254 gcc_unreachable ();
12257 def_builtin (d->mask, d->name, type, d->code);
12260 if (TARGET_ALTIVEC)
12264 /* Initialize target builtin that implements
12265 targetm.vectorize.builtin_mask_for_load. */
12267 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
12268 v16qi_ftype_long_pcvoid,
12269 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
12270 BUILT_IN_MD, NULL, NULL_TREE);
12271 TREE_READONLY (decl) = 1;
12272 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
12273 altivec_builtin_mask_for_load = decl;
12276 /* Access to the vec_init patterns. */
12277 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
12278 integer_type_node, integer_type_node,
12279 integer_type_node, NULL_TREE);
12280 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
12281 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
12283 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
12284 short_integer_type_node,
12285 short_integer_type_node,
12286 short_integer_type_node,
12287 short_integer_type_node,
12288 short_integer_type_node,
12289 short_integer_type_node,
12290 short_integer_type_node, NULL_TREE);
12291 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
12292 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
12294 ftype = build_function_type_list (V16QI_type_node, char_type_node,
12295 char_type_node, char_type_node,
12296 char_type_node, char_type_node,
12297 char_type_node, char_type_node,
12298 char_type_node, char_type_node,
12299 char_type_node, char_type_node,
12300 char_type_node, char_type_node,
12301 char_type_node, char_type_node,
12302 char_type_node, NULL_TREE);
12303 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
12304 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
12306 ftype = build_function_type_list (V4SF_type_node, float_type_node,
12307 float_type_node, float_type_node,
12308 float_type_node, NULL_TREE);
12309 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
12310 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
12314 ftype = build_function_type_list (V2DF_type_node, double_type_node,
12315 double_type_node, NULL_TREE);
12316 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
12317 VSX_BUILTIN_VEC_INIT_V2DF);
12319 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
12320 intDI_type_node, NULL_TREE);
12321 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
12322 VSX_BUILTIN_VEC_INIT_V2DI);
12325 /* Access to the vec_set patterns. */
12326 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
12328 integer_type_node, NULL_TREE);
12329 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
12330 ALTIVEC_BUILTIN_VEC_SET_V4SI);
12332 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
12334 integer_type_node, NULL_TREE);
12335 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
12336 ALTIVEC_BUILTIN_VEC_SET_V8HI);
12338 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
12340 integer_type_node, NULL_TREE);
12341 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
12342 ALTIVEC_BUILTIN_VEC_SET_V16QI);
12344 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
12346 integer_type_node, NULL_TREE);
12347 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
12348 ALTIVEC_BUILTIN_VEC_SET_V4SF);
12352 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
12354 integer_type_node, NULL_TREE);
12355 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
12356 VSX_BUILTIN_VEC_SET_V2DF);
12358 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
12360 integer_type_node, NULL_TREE);
12361 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
12362 VSX_BUILTIN_VEC_SET_V2DI);
12365 /* Access to the vec_extract patterns. */
12366 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
12367 integer_type_node, NULL_TREE);
12368 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
12369 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
12371 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
12372 integer_type_node, NULL_TREE);
12373 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
12374 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
12376 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
12377 integer_type_node, NULL_TREE);
12378 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
12379 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
12381 ftype = build_function_type_list (float_type_node, V4SF_type_node,
12382 integer_type_node, NULL_TREE);
12383 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
12384 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
12388 ftype = build_function_type_list (double_type_node, V2DF_type_node,
12389 integer_type_node, NULL_TREE);
12390 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
12391 VSX_BUILTIN_VEC_EXT_V2DF);
12393 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
12394 integer_type_node, NULL_TREE);
12395 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
12396 VSX_BUILTIN_VEC_EXT_V2DI);
12400 /* Hash function for builtin functions with up to 3 arguments and a return
12403 builtin_hash_function (const void *hash_entry)
12407 const struct builtin_hash_struct *bh =
12408 (const struct builtin_hash_struct *) hash_entry;
12410 for (i = 0; i < 4; i++)
12412 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
12413 ret = (ret * 2) + bh->uns_p[i];
12419 /* Compare builtin hash entries H1 and H2 for equivalence. */
12421 builtin_hash_eq (const void *h1, const void *h2)
12423 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
12424 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
12426 return ((p1->mode[0] == p2->mode[0])
12427 && (p1->mode[1] == p2->mode[1])
12428 && (p1->mode[2] == p2->mode[2])
12429 && (p1->mode[3] == p2->mode[3])
12430 && (p1->uns_p[0] == p2->uns_p[0])
12431 && (p1->uns_p[1] == p2->uns_p[1])
12432 && (p1->uns_p[2] == p2->uns_p[2])
12433 && (p1->uns_p[3] == p2->uns_p[3]));
12436 /* Map types for builtin functions with an explicit return type and up to 3
12437 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
12438 of the argument. */
12440 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
12441 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
12442 enum rs6000_builtins builtin, const char *name)
12444 struct builtin_hash_struct h;
12445 struct builtin_hash_struct *h2;
12449 tree ret_type = NULL_TREE;
12450 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
12453 /* Create builtin_hash_table. */
12454 if (builtin_hash_table == NULL)
12455 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
12456 builtin_hash_eq, NULL);
12458 h.type = NULL_TREE;
12459 h.mode[0] = mode_ret;
12460 h.mode[1] = mode_arg0;
12461 h.mode[2] = mode_arg1;
12462 h.mode[3] = mode_arg2;
12468 /* If the builtin is a type that produces unsigned results or takes unsigned
12469 arguments, and it is returned as a decl for the vectorizer (such as
12470 widening multiplies, permute), make sure the arguments and return value
12471 are type correct. */
12474 /* unsigned 2 argument functions. */
12475 case ALTIVEC_BUILTIN_VMULEUB_UNS:
12476 case ALTIVEC_BUILTIN_VMULEUH_UNS:
12477 case ALTIVEC_BUILTIN_VMULOUB_UNS:
12478 case ALTIVEC_BUILTIN_VMULOUH_UNS:
12484 /* unsigned 3 argument functions. */
12485 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
12486 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
12487 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
12488 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
12489 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
12490 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
12491 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
12492 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
12493 case VSX_BUILTIN_VPERM_16QI_UNS:
12494 case VSX_BUILTIN_VPERM_8HI_UNS:
12495 case VSX_BUILTIN_VPERM_4SI_UNS:
12496 case VSX_BUILTIN_VPERM_2DI_UNS:
12497 case VSX_BUILTIN_XXSEL_16QI_UNS:
12498 case VSX_BUILTIN_XXSEL_8HI_UNS:
12499 case VSX_BUILTIN_XXSEL_4SI_UNS:
12500 case VSX_BUILTIN_XXSEL_2DI_UNS:
12507 /* signed permute functions with unsigned char mask. */
12508 case ALTIVEC_BUILTIN_VPERM_16QI:
12509 case ALTIVEC_BUILTIN_VPERM_8HI:
12510 case ALTIVEC_BUILTIN_VPERM_4SI:
12511 case ALTIVEC_BUILTIN_VPERM_4SF:
12512 case ALTIVEC_BUILTIN_VPERM_2DI:
12513 case ALTIVEC_BUILTIN_VPERM_2DF:
12514 case VSX_BUILTIN_VPERM_16QI:
12515 case VSX_BUILTIN_VPERM_8HI:
12516 case VSX_BUILTIN_VPERM_4SI:
12517 case VSX_BUILTIN_VPERM_4SF:
12518 case VSX_BUILTIN_VPERM_2DI:
12519 case VSX_BUILTIN_VPERM_2DF:
12523 /* unsigned args, signed return. */
12524 case VSX_BUILTIN_XVCVUXDDP_UNS:
12525 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
12529 /* signed args, unsigned return. */
12530 case VSX_BUILTIN_XVCVDPUXDS_UNS:
12531 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
12539 /* Figure out how many args are present. */
12540 while (num_args > 0 && h.mode[num_args] == VOIDmode)
12544 fatal_error ("internal error: builtin function %s had no type", name);
12546 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
12547 if (!ret_type && h.uns_p[0])
12548 ret_type = builtin_mode_to_type[h.mode[0]][0];
12551 fatal_error ("internal error: builtin function %s had an unexpected "
12552 "return type %s", name, GET_MODE_NAME (h.mode[0]));
12554 for (i = 0; i < num_args; i++)
12556 int m = (int) h.mode[i+1];
12557 int uns_p = h.uns_p[i+1];
12559 arg_type[i] = builtin_mode_to_type[m][uns_p];
12560 if (!arg_type[i] && uns_p)
12561 arg_type[i] = builtin_mode_to_type[m][0];
12564 fatal_error ("internal error: builtin function %s, argument %d "
12565 "had unexpected argument type %s", name, i,
12566 GET_MODE_NAME (m));
12569 found = htab_find_slot (builtin_hash_table, &h, INSERT);
12570 if (*found == NULL)
12572 h2 = GGC_NEW (struct builtin_hash_struct);
12574 *found = (void *)h2;
12575 args = void_list_node;
12577 for (i = num_args - 1; i >= 0; i--)
12578 args = tree_cons (NULL_TREE, arg_type[i], args);
12580 h2->type = build_function_type (ret_type, args);
12583 return ((struct builtin_hash_struct *)(*found))->type;
12587 rs6000_common_init_builtins (void)
12589 const struct builtin_description *d;
12592 tree opaque_ftype_opaque = NULL_TREE;
12593 tree opaque_ftype_opaque_opaque = NULL_TREE;
12594 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
12595 tree v2si_ftype_qi = NULL_TREE;
12596 tree v2si_ftype_v2si_qi = NULL_TREE;
12597 tree v2si_ftype_int_qi = NULL_TREE;
12599 if (!TARGET_PAIRED_FLOAT)
12601 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
12602 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
12605 /* Add the ternary operators. */
12607 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12610 int mask = d->mask;
12612 if ((mask != 0 && (mask & target_flags) == 0)
12613 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12616 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12617 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12618 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12619 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12621 if (! (type = opaque_ftype_opaque_opaque_opaque))
12622 type = opaque_ftype_opaque_opaque_opaque
12623 = build_function_type_list (opaque_V4SI_type_node,
12624 opaque_V4SI_type_node,
12625 opaque_V4SI_type_node,
12626 opaque_V4SI_type_node,
12631 enum insn_code icode = d->icode;
12632 if (d->name == 0 || icode == CODE_FOR_nothing)
12635 type = builtin_function_type (insn_data[icode].operand[0].mode,
12636 insn_data[icode].operand[1].mode,
12637 insn_data[icode].operand[2].mode,
12638 insn_data[icode].operand[3].mode,
12642 def_builtin (d->mask, d->name, type, d->code);
12645 /* Add the binary operators. */
12647 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12649 enum machine_mode mode0, mode1, mode2;
12651 int mask = d->mask;
12653 if ((mask != 0 && (mask & target_flags) == 0)
12654 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12657 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12658 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12659 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12660 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12662 if (! (type = opaque_ftype_opaque_opaque))
12663 type = opaque_ftype_opaque_opaque
12664 = build_function_type_list (opaque_V4SI_type_node,
12665 opaque_V4SI_type_node,
12666 opaque_V4SI_type_node,
12671 enum insn_code icode = d->icode;
12672 if (d->name == 0 || icode == CODE_FOR_nothing)
12675 mode0 = insn_data[icode].operand[0].mode;
12676 mode1 = insn_data[icode].operand[1].mode;
12677 mode2 = insn_data[icode].operand[2].mode;
12679 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
12681 if (! (type = v2si_ftype_v2si_qi))
12682 type = v2si_ftype_v2si_qi
12683 = build_function_type_list (opaque_V2SI_type_node,
12684 opaque_V2SI_type_node,
12689 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
12690 && mode2 == QImode)
12692 if (! (type = v2si_ftype_int_qi))
12693 type = v2si_ftype_int_qi
12694 = build_function_type_list (opaque_V2SI_type_node,
12701 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
12705 def_builtin (d->mask, d->name, type, d->code);
12708 /* Add the simple unary operators. */
12709 d = (struct builtin_description *) bdesc_1arg;
12710 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12712 enum machine_mode mode0, mode1;
12714 int mask = d->mask;
12716 if ((mask != 0 && (mask & target_flags) == 0)
12717 || (mask == 0 && !TARGET_PAIRED_FLOAT))
12720 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12721 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12722 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
12723 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
12725 if (! (type = opaque_ftype_opaque))
12726 type = opaque_ftype_opaque
12727 = build_function_type_list (opaque_V4SI_type_node,
12728 opaque_V4SI_type_node,
12733 enum insn_code icode = d->icode;
12734 if (d->name == 0 || icode == CODE_FOR_nothing)
12737 mode0 = insn_data[icode].operand[0].mode;
12738 mode1 = insn_data[icode].operand[1].mode;
12740 if (mode0 == V2SImode && mode1 == QImode)
12742 if (! (type = v2si_ftype_qi))
12743 type = v2si_ftype_qi
12744 = build_function_type_list (opaque_V2SI_type_node,
12750 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
12754 def_builtin (d->mask, d->name, type, d->code);
12759 rs6000_init_libfuncs (void)
12761 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
12762 && !TARGET_POWER2 && !TARGET_POWERPC)
12764 /* AIX library routines for float->int conversion. */
12765 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
12766 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
12767 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
12768 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
12771 if (!TARGET_IEEEQUAD)
12772 /* AIX/Darwin/64-bit Linux quad floating point routines. */
12773 if (!TARGET_XL_COMPAT)
12775 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
12776 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
12777 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
12778 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
12780 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
12782 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
12783 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
12784 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
12785 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
12786 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
12787 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
12788 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
12790 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
12791 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
12792 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
12793 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
12794 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
12795 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
12796 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
12797 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
12800 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
12801 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
12805 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
12806 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
12807 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
12808 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
12812 /* 32-bit SVR4 quad floating point routines. */
12814 set_optab_libfunc (add_optab, TFmode, "_q_add");
12815 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
12816 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
12817 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
12818 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
12819 if (TARGET_PPC_GPOPT || TARGET_POWER2)
12820 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
12822 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
12823 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
12824 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
12825 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
12826 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
12827 set_optab_libfunc (le_optab, TFmode, "_q_fle");
12829 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
12830 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
12831 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
12832 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
12833 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
12834 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
12835 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
12836 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
12841 /* Expand a block clear operation, and return 1 if successful. Return 0
12842 if we should let the compiler generate normal code.
12844 operands[0] is the destination
12845 operands[1] is the length
12846 operands[3] is the alignment */
12849 expand_block_clear (rtx operands[])
12851 rtx orig_dest = operands[0];
12852 rtx bytes_rtx = operands[1];
12853 rtx align_rtx = operands[3];
12854 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
12855 HOST_WIDE_INT align;
12856 HOST_WIDE_INT bytes;
12861 /* If this is not a fixed size move, just call memcpy */
12865 /* This must be a fixed size alignment */
12866 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12867 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12869 /* Anything to clear? */
12870 bytes = INTVAL (bytes_rtx);
12874 /* Use the builtin memset after a point, to avoid huge code bloat.
12875 When optimize_size, avoid any significant code bloat; calling
12876 memset is about 4 instructions, so allow for one instruction to
12877 load zero and three to do clearing. */
12878 if (TARGET_ALTIVEC && align >= 128)
12880 else if (TARGET_POWERPC64 && align >= 32)
12882 else if (TARGET_SPE && align >= 64)
12887 if (optimize_size && bytes > 3 * clear_step)
12889 if (! optimize_size && bytes > 8 * clear_step)
12892 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
12894 enum machine_mode mode = BLKmode;
12897 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
12902 else if (bytes >= 8 && TARGET_SPE && align >= 64)
12907 else if (bytes >= 8 && TARGET_POWERPC64
12908 /* 64-bit loads and stores require word-aligned
12910 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
12915 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
12916 { /* move 4 bytes */
12920 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
12921 { /* move 2 bytes */
12925 else /* move 1 byte at a time */
12931 dest = adjust_address (orig_dest, mode, offset);
12933 emit_move_insn (dest, CONST0_RTX (mode));
12940 /* Expand a block move operation, and return 1 if successful. Return 0
12941 if we should let the compiler generate normal code.
12943 operands[0] is the destination
12944 operands[1] is the source
12945 operands[2] is the length
12946 operands[3] is the alignment */
12948 #define MAX_MOVE_REG 4
12951 expand_block_move (rtx operands[])
12953 rtx orig_dest = operands[0];
12954 rtx orig_src = operands[1];
12955 rtx bytes_rtx = operands[2];
12956 rtx align_rtx = operands[3];
12957 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
12962 rtx stores[MAX_MOVE_REG];
12965 /* If this is not a fixed size move, just call memcpy */
12969 /* This must be a fixed size alignment */
12970 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
12971 align = INTVAL (align_rtx) * BITS_PER_UNIT;
12973 /* Anything to move? */
12974 bytes = INTVAL (bytes_rtx);
12978 /* store_one_arg depends on expand_block_move to handle at least the size of
12979 reg_parm_stack_space. */
12980 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
12983 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
12986 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
12987 rtx (*mov) (rtx, rtx);
12989 enum machine_mode mode = BLKmode;
12992 /* Altivec first, since it will be faster than a string move
12993 when it applies, and usually not significantly larger. */
12994 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
12998 gen_func.mov = gen_movv4si;
13000 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13004 gen_func.mov = gen_movv2si;
13006 else if (TARGET_STRING
13007 && bytes > 24 /* move up to 32 bytes at a time */
13013 && ! fixed_regs[10]
13014 && ! fixed_regs[11]
13015 && ! fixed_regs[12])
13017 move_bytes = (bytes > 32) ? 32 : bytes;
13018 gen_func.movmemsi = gen_movmemsi_8reg;
13020 else if (TARGET_STRING
13021 && bytes > 16 /* move up to 24 bytes at a time */
13027 && ! fixed_regs[10])
13029 move_bytes = (bytes > 24) ? 24 : bytes;
13030 gen_func.movmemsi = gen_movmemsi_6reg;
13032 else if (TARGET_STRING
13033 && bytes > 8 /* move up to 16 bytes at a time */
13037 && ! fixed_regs[8])
13039 move_bytes = (bytes > 16) ? 16 : bytes;
13040 gen_func.movmemsi = gen_movmemsi_4reg;
13042 else if (bytes >= 8 && TARGET_POWERPC64
13043 /* 64-bit loads and stores require word-aligned
13045 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13049 gen_func.mov = gen_movdi;
13051 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13052 { /* move up to 8 bytes at a time */
13053 move_bytes = (bytes > 8) ? 8 : bytes;
13054 gen_func.movmemsi = gen_movmemsi_2reg;
13056 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13057 { /* move 4 bytes */
13060 gen_func.mov = gen_movsi;
13062 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13063 { /* move 2 bytes */
13066 gen_func.mov = gen_movhi;
13068 else if (TARGET_STRING && bytes > 1)
13069 { /* move up to 4 bytes at a time */
13070 move_bytes = (bytes > 4) ? 4 : bytes;
13071 gen_func.movmemsi = gen_movmemsi_1reg;
13073 else /* move 1 byte at a time */
13077 gen_func.mov = gen_movqi;
13080 src = adjust_address (orig_src, mode, offset);
13081 dest = adjust_address (orig_dest, mode, offset);
13083 if (mode != BLKmode)
13085 rtx tmp_reg = gen_reg_rtx (mode);
13087 emit_insn ((*gen_func.mov) (tmp_reg, src));
13088 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13091 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13094 for (i = 0; i < num_reg; i++)
13095 emit_insn (stores[i]);
13099 if (mode == BLKmode)
13101 /* Move the address into scratch registers. The movmemsi
13102 patterns require zero offset. */
13103 if (!REG_P (XEXP (src, 0)))
13105 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13106 src = replace_equiv_address (src, src_reg);
13108 set_mem_size (src, GEN_INT (move_bytes));
13110 if (!REG_P (XEXP (dest, 0)))
13112 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13113 dest = replace_equiv_address (dest, dest_reg);
13115 set_mem_size (dest, GEN_INT (move_bytes));
13117 emit_insn ((*gen_func.movmemsi) (dest, src,
13118 GEN_INT (move_bytes & 31),
13127 /* Return a string to perform a load_multiple operation.
13128 operands[0] is the vector.
13129 operands[1] is the source address.
13130 operands[2] is the first destination register. */
13133 rs6000_output_load_multiple (rtx operands[3])
13135 /* We have to handle the case where the pseudo used to contain the address
13136 is assigned to one of the output registers. */
13138 int words = XVECLEN (operands[0], 0);
13141 if (XVECLEN (operands[0], 0) == 1)
13142 return "{l|lwz} %2,0(%1)";
13144 for (i = 0; i < words; i++)
13145 if (refers_to_regno_p (REGNO (operands[2]) + i,
13146 REGNO (operands[2]) + i + 1, operands[1], 0))
13150 xop[0] = GEN_INT (4 * (words-1));
13151 xop[1] = operands[1];
13152 xop[2] = operands[2];
13153 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13158 xop[0] = GEN_INT (4 * (words-1));
13159 xop[1] = operands[1];
13160 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13161 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);
13166 for (j = 0; j < words; j++)
13169 xop[0] = GEN_INT (j * 4);
13170 xop[1] = operands[1];
13171 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13172 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13174 xop[0] = GEN_INT (i * 4);
13175 xop[1] = operands[1];
13176 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13181 return "{lsi|lswi} %2,%1,%N0";
13185 /* A validation routine: say whether CODE, a condition code, and MODE
13186 match. The other alternatives either don't make sense or should
13187 never be generated. */
13190 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13192 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13193 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13194 && GET_MODE_CLASS (mode) == MODE_CC);
13196 /* These don't make sense. */
13197 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13198 || mode != CCUNSmode);
13200 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13201 || mode == CCUNSmode);
13203 gcc_assert (mode == CCFPmode
13204 || (code != ORDERED && code != UNORDERED
13205 && code != UNEQ && code != LTGT
13206 && code != UNGT && code != UNLT
13207 && code != UNGE && code != UNLE));
13209 /* These should never be generated except for
13210 flag_finite_math_only. */
13211 gcc_assert (mode != CCFPmode
13212 || flag_finite_math_only
13213 || (code != LE && code != GE
13214 && code != UNEQ && code != LTGT
13215 && code != UNGT && code != UNLT));
13217 /* These are invalid; the information is not there. */
13218 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13222 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13223 mask required to convert the result of a rotate insn into a shift
13224 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13227 includes_lshift_p (rtx shiftop, rtx andop)
13229 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13231 shift_mask <<= INTVAL (shiftop);
13233 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13236 /* Similar, but for right shift. */
13239 includes_rshift_p (rtx shiftop, rtx andop)
13241 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13243 shift_mask >>= INTVAL (shiftop);
13245 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13248 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13249 to perform a left shift. It must have exactly SHIFTOP least
13250 significant 0's, then one or more 1's, then zero or more 0's. */
13253 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13255 if (GET_CODE (andop) == CONST_INT)
13257 HOST_WIDE_INT c, lsb, shift_mask;
13259 c = INTVAL (andop);
13260 if (c == 0 || c == ~0)
13264 shift_mask <<= INTVAL (shiftop);
13266 /* Find the least significant one bit. */
13269 /* It must coincide with the LSB of the shift mask. */
13270 if (-lsb != shift_mask)
13273 /* Invert to look for the next transition (if any). */
13276 /* Remove the low group of ones (originally low group of zeros). */
13279 /* Again find the lsb, and check we have all 1's above. */
13283 else if (GET_CODE (andop) == CONST_DOUBLE
13284 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13286 HOST_WIDE_INT low, high, lsb;
13287 HOST_WIDE_INT shift_mask_low, shift_mask_high;
13289 low = CONST_DOUBLE_LOW (andop);
13290 if (HOST_BITS_PER_WIDE_INT < 64)
13291 high = CONST_DOUBLE_HIGH (andop);
13293 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
13294 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
13297 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13299 shift_mask_high = ~0;
13300 if (INTVAL (shiftop) > 32)
13301 shift_mask_high <<= INTVAL (shiftop) - 32;
13303 lsb = high & -high;
13305 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
13311 lsb = high & -high;
13312 return high == -lsb;
13315 shift_mask_low = ~0;
13316 shift_mask_low <<= INTVAL (shiftop);
13320 if (-lsb != shift_mask_low)
13323 if (HOST_BITS_PER_WIDE_INT < 64)
13328 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
13330 lsb = high & -high;
13331 return high == -lsb;
13335 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
13341 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
13342 to perform a left shift. It must have SHIFTOP or more least
13343 significant 0's, with the remainder of the word 1's. */
13346 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
13348 if (GET_CODE (andop) == CONST_INT)
13350 HOST_WIDE_INT c, lsb, shift_mask;
13353 shift_mask <<= INTVAL (shiftop);
13354 c = INTVAL (andop);
13356 /* Find the least significant one bit. */
13359 /* It must be covered by the shift mask.
13360 This test also rejects c == 0. */
13361 if ((lsb & shift_mask) == 0)
13364 /* Check we have all 1's above the transition, and reject all 1's. */
13365 return c == -lsb && lsb != 1;
13367 else if (GET_CODE (andop) == CONST_DOUBLE
13368 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
13370 HOST_WIDE_INT low, lsb, shift_mask_low;
13372 low = CONST_DOUBLE_LOW (andop);
13374 if (HOST_BITS_PER_WIDE_INT < 64)
13376 HOST_WIDE_INT high, shift_mask_high;
13378 high = CONST_DOUBLE_HIGH (andop);
13382 shift_mask_high = ~0;
13383 if (INTVAL (shiftop) > 32)
13384 shift_mask_high <<= INTVAL (shiftop) - 32;
13386 lsb = high & -high;
13388 if ((lsb & shift_mask_high) == 0)
13391 return high == -lsb;
13397 shift_mask_low = ~0;
13398 shift_mask_low <<= INTVAL (shiftop);
13402 if ((lsb & shift_mask_low) == 0)
13405 return low == -lsb && lsb != 1;
13411 /* Return 1 if operands will generate a valid arguments to rlwimi
13412 instruction for insert with right shift in 64-bit mode. The mask may
13413 not start on the first bit or stop on the last bit because wrap-around
13414 effects of instruction do not correspond to semantics of RTL insn. */
13417 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
13419 if (INTVAL (startop) > 32
13420 && INTVAL (startop) < 64
13421 && INTVAL (sizeop) > 1
13422 && INTVAL (sizeop) + INTVAL (startop) < 64
13423 && INTVAL (shiftop) > 0
13424 && INTVAL (sizeop) + INTVAL (shiftop) < 32
13425 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
13431 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
13432 for lfq and stfq insns iff the registers are hard registers. */
13435 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
13437 /* We might have been passed a SUBREG. */
13438 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
13441 /* We might have been passed non floating point registers. */
13442 if (!FP_REGNO_P (REGNO (reg1))
13443 || !FP_REGNO_P (REGNO (reg2)))
13446 return (REGNO (reg1) == REGNO (reg2) - 1);
13449 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
13450 addr1 and addr2 must be in consecutive memory locations
13451 (addr2 == addr1 + 8). */
13454 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
13457 unsigned int reg1, reg2;
13458 int offset1, offset2;
13460 /* The mems cannot be volatile. */
13461 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
13464 addr1 = XEXP (mem1, 0);
13465 addr2 = XEXP (mem2, 0);
13467 /* Extract an offset (if used) from the first addr. */
13468 if (GET_CODE (addr1) == PLUS)
13470 /* If not a REG, return zero. */
13471 if (GET_CODE (XEXP (addr1, 0)) != REG)
13475 reg1 = REGNO (XEXP (addr1, 0));
13476 /* The offset must be constant! */
13477 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
13479 offset1 = INTVAL (XEXP (addr1, 1));
13482 else if (GET_CODE (addr1) != REG)
13486 reg1 = REGNO (addr1);
13487 /* This was a simple (mem (reg)) expression. Offset is 0. */
13491 /* And now for the second addr. */
13492 if (GET_CODE (addr2) == PLUS)
13494 /* If not a REG, return zero. */
13495 if (GET_CODE (XEXP (addr2, 0)) != REG)
13499 reg2 = REGNO (XEXP (addr2, 0));
13500 /* The offset must be constant. */
13501 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
13503 offset2 = INTVAL (XEXP (addr2, 1));
13506 else if (GET_CODE (addr2) != REG)
13510 reg2 = REGNO (addr2);
13511 /* This was a simple (mem (reg)) expression. Offset is 0. */
13515 /* Both of these must have the same base register. */
13519 /* The offset for the second addr must be 8 more than the first addr. */
13520 if (offset2 != offset1 + 8)
13523 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
13530 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
13532 static bool eliminated = false;
13535 if (mode != SDmode)
13536 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
13539 rtx mem = cfun->machine->sdmode_stack_slot;
13540 gcc_assert (mem != NULL_RTX);
13544 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
13545 cfun->machine->sdmode_stack_slot = mem;
13551 if (TARGET_DEBUG_ADDR)
13553 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
13554 GET_MODE_NAME (mode));
13556 fprintf (stderr, "\tNULL_RTX\n");
13565 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
13567 /* Don't walk into types. */
13568 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
13570 *walk_subtrees = 0;
13574 switch (TREE_CODE (*tp))
13583 case ALIGN_INDIRECT_REF:
13584 case MISALIGNED_INDIRECT_REF:
13585 case VIEW_CONVERT_EXPR:
13586 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
13596 enum reload_reg_type {
13598 VECTOR_REGISTER_TYPE,
13599 OTHER_REGISTER_TYPE
13602 static enum reload_reg_type
13603 rs6000_reload_register_type (enum reg_class rclass)
13609 return GPR_REGISTER_TYPE;
13614 return VECTOR_REGISTER_TYPE;
13617 return OTHER_REGISTER_TYPE;
13621 /* Inform reload about cases where moving X with a mode MODE to a register in
13622 RCLASS requires an extra scratch or immediate register. Return the class
13623 needed for the immediate register.
13625 For VSX and Altivec, we may need a register to convert sp+offset into
13628 static enum reg_class
13629 rs6000_secondary_reload (bool in_p,
13631 enum reg_class rclass,
13632 enum machine_mode mode,
13633 secondary_reload_info *sri)
13635 enum reg_class ret = ALL_REGS;
13636 enum insn_code icode;
13637 bool default_p = false;
13639 sri->icode = CODE_FOR_nothing;
13641 /* Convert vector loads and stores into gprs to use an additional base
13643 icode = rs6000_vector_reload[mode][in_p != false];
13644 if (icode != CODE_FOR_nothing)
13647 sri->icode = CODE_FOR_nothing;
13648 sri->extra_cost = 0;
13650 if (GET_CODE (x) == MEM)
13652 rtx addr = XEXP (x, 0);
13654 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
13655 an extra register in that case, but it would need an extra
13656 register if the addressing is reg+reg or (reg+reg)&(-16). */
13657 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
13659 if (!legitimate_indirect_address_p (addr, false)
13660 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13662 sri->icode = icode;
13663 /* account for splitting the loads, and converting the
13664 address from reg+reg to reg. */
13665 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
13666 + ((GET_CODE (addr) == AND) ? 1 : 0));
13669 /* Loads to and stores from vector registers can only do reg+reg
13670 addressing. Altivec registers can also do (reg+reg)&(-16). */
13671 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
13672 || rclass == FLOAT_REGS || rclass == NO_REGS)
13674 if (!VECTOR_MEM_ALTIVEC_P (mode)
13675 && GET_CODE (addr) == AND
13676 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13677 && INTVAL (XEXP (addr, 1)) == -16
13678 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
13679 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
13681 sri->icode = icode;
13682 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
13685 else if (!legitimate_indirect_address_p (addr, false)
13686 && (rclass == NO_REGS
13687 || !legitimate_indexed_address_p (addr, false)))
13689 sri->icode = icode;
13690 sri->extra_cost = 1;
13693 icode = CODE_FOR_nothing;
13695 /* Any other loads, including to pseudo registers which haven't been
13696 assigned to a register yet, default to require a scratch
13700 sri->icode = icode;
13701 sri->extra_cost = 2;
13704 else if (REG_P (x))
13706 int regno = true_regnum (x);
13708 icode = CODE_FOR_nothing;
13709 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
13713 enum reg_class xclass = REGNO_REG_CLASS (regno);
13714 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
13715 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
13717 /* If memory is needed, use default_secondary_reload to create the
13719 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
13732 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
13734 gcc_assert (ret != ALL_REGS);
13736 if (TARGET_DEBUG_ADDR)
13739 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
13741 reg_class_names[ret],
13742 in_p ? "true" : "false",
13743 reg_class_names[rclass],
13744 GET_MODE_NAME (mode));
13747 fprintf (stderr, ", default secondary reload");
13749 if (sri->icode != CODE_FOR_nothing)
13750 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
13751 insn_data[sri->icode].name, sri->extra_cost);
13753 fprintf (stderr, "\n");
13761 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
13762 to SP+reg addressing. */
13765 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
13767 int regno = true_regnum (reg);
13768 enum machine_mode mode = GET_MODE (reg);
13769 enum reg_class rclass;
13771 rtx and_op2 = NULL_RTX;
13774 rtx scratch_or_premodify = scratch;
13778 if (TARGET_DEBUG_ADDR)
13780 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
13781 store_p ? "store" : "load");
13782 fprintf (stderr, "reg:\n");
13784 fprintf (stderr, "mem:\n");
13786 fprintf (stderr, "scratch:\n");
13787 debug_rtx (scratch);
13790 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
13791 gcc_assert (GET_CODE (mem) == MEM);
13792 rclass = REGNO_REG_CLASS (regno);
13793 addr = XEXP (mem, 0);
13797 /* GPRs can handle reg + small constant, all other addresses need to use
13798 the scratch register. */
13801 if (GET_CODE (addr) == AND)
13803 and_op2 = XEXP (addr, 1);
13804 addr = XEXP (addr, 0);
13807 if (GET_CODE (addr) == PRE_MODIFY)
13809 scratch_or_premodify = XEXP (addr, 0);
13810 gcc_assert (REG_P (scratch_or_premodify));
13811 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13812 addr = XEXP (addr, 1);
13815 if (GET_CODE (addr) == PLUS
13816 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
13817 || and_op2 != NULL_RTX))
13819 addr_op1 = XEXP (addr, 0);
13820 addr_op2 = XEXP (addr, 1);
13821 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
13823 if (!REG_P (addr_op2)
13824 && (GET_CODE (addr_op2) != CONST_INT
13825 || !satisfies_constraint_I (addr_op2)))
13827 if (TARGET_DEBUG_ADDR)
13830 "\nMove plus addr to register %s, mode = %s: ",
13831 rs6000_reg_names[REGNO (scratch)],
13832 GET_MODE_NAME (mode));
13833 debug_rtx (addr_op2);
13835 rs6000_emit_move (scratch, addr_op2, Pmode);
13836 addr_op2 = scratch;
13839 emit_insn (gen_rtx_SET (VOIDmode,
13840 scratch_or_premodify,
13841 gen_rtx_PLUS (Pmode,
13845 addr = scratch_or_premodify;
13846 scratch_or_premodify = scratch;
13848 else if (!legitimate_indirect_address_p (addr, false)
13849 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
13851 if (TARGET_DEBUG_ADDR)
13853 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13854 rs6000_reg_names[REGNO (scratch_or_premodify)],
13855 GET_MODE_NAME (mode));
13858 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13859 addr = scratch_or_premodify;
13860 scratch_or_premodify = scratch;
13864 /* Float/Altivec registers can only handle reg+reg addressing. Move
13865 other addresses into a scratch register. */
13870 /* With float regs, we need to handle the AND ourselves, since we can't
13871 use the Altivec instruction with an implicit AND -16. Allow scalar
13872 loads to float registers to use reg+offset even if VSX. */
13873 if (GET_CODE (addr) == AND
13874 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
13875 || GET_CODE (XEXP (addr, 1)) != CONST_INT
13876 || INTVAL (XEXP (addr, 1)) != -16
13877 || !VECTOR_MEM_ALTIVEC_P (mode)))
13879 and_op2 = XEXP (addr, 1);
13880 addr = XEXP (addr, 0);
13883 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
13884 as the address later. */
13885 if (GET_CODE (addr) == PRE_MODIFY
13886 && (!VECTOR_MEM_VSX_P (mode)
13887 || and_op2 != NULL_RTX
13888 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
13890 scratch_or_premodify = XEXP (addr, 0);
13891 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
13893 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
13894 addr = XEXP (addr, 1);
13897 if (legitimate_indirect_address_p (addr, false) /* reg */
13898 || legitimate_indexed_address_p (addr, false) /* reg+reg */
13899 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
13900 || (GET_CODE (addr) == AND /* Altivec memory */
13901 && GET_CODE (XEXP (addr, 1)) == CONST_INT
13902 && INTVAL (XEXP (addr, 1)) == -16
13903 && VECTOR_MEM_ALTIVEC_P (mode))
13904 || (rclass == FLOAT_REGS /* legacy float mem */
13905 && GET_MODE_SIZE (mode) == 8
13906 && and_op2 == NULL_RTX
13907 && scratch_or_premodify == scratch
13908 && rs6000_legitimate_offset_address_p (mode, addr, false)))
13911 else if (GET_CODE (addr) == PLUS)
13913 addr_op1 = XEXP (addr, 0);
13914 addr_op2 = XEXP (addr, 1);
13915 gcc_assert (REG_P (addr_op1));
13917 if (TARGET_DEBUG_ADDR)
13919 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
13920 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13921 debug_rtx (addr_op2);
13923 rs6000_emit_move (scratch, addr_op2, Pmode);
13924 emit_insn (gen_rtx_SET (VOIDmode,
13925 scratch_or_premodify,
13926 gen_rtx_PLUS (Pmode,
13929 addr = scratch_or_premodify;
13930 scratch_or_premodify = scratch;
13933 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
13934 || GET_CODE (addr) == CONST_INT || REG_P (addr))
13936 if (TARGET_DEBUG_ADDR)
13938 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
13939 rs6000_reg_names[REGNO (scratch_or_premodify)],
13940 GET_MODE_NAME (mode));
13944 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
13945 addr = scratch_or_premodify;
13946 scratch_or_premodify = scratch;
13950 gcc_unreachable ();
13955 gcc_unreachable ();
13958 /* If the original address involved a pre-modify that we couldn't use the VSX
13959 memory instruction with update, and we haven't taken care of already,
13960 store the address in the pre-modify register and use that as the
13962 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
13964 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
13965 addr = scratch_or_premodify;
13968 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
13969 memory instruction, recreate the AND now, including the clobber which is
13970 generated by the general ANDSI3/ANDDI3 patterns for the
13971 andi. instruction. */
13972 if (and_op2 != NULL_RTX)
13974 if (! legitimate_indirect_address_p (addr, false))
13976 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
13980 if (TARGET_DEBUG_ADDR)
13982 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
13983 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
13984 debug_rtx (and_op2);
13987 and_rtx = gen_rtx_SET (VOIDmode,
13989 gen_rtx_AND (Pmode,
13993 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
13994 emit_insn (gen_rtx_PARALLEL (VOIDmode,
13995 gen_rtvec (2, and_rtx, cc_clobber)));
13999 /* Adjust the address if it changed. */
14000 if (addr != XEXP (mem, 0))
14002 mem = change_address (mem, mode, addr);
14003 if (TARGET_DEBUG_ADDR)
14004 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14007 /* Now create the move. */
14009 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14011 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14016 /* Target hook to return the cover classes for Integrated Register Allocator.
14017 Cover classes is a set of non-intersected register classes covering all hard
14018 registers used for register allocation purpose. Any move between two
14019 registers of a cover class should be cheaper than load or store of the
14020 registers. The value is array of register classes with LIM_REG_CLASSES used
14023 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14024 account for the Altivec and Floating registers being subsets of the VSX
14025 register set under VSX, but distinct register sets on pre-VSX machines. */
14027 static const enum reg_class *
14028 rs6000_ira_cover_classes (void)
14030 static const enum reg_class cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14031 static const enum reg_class cover_vsx[] = IRA_COVER_CLASSES_VSX;
14033 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14036 /* Allocate a 64-bit stack slot to be used for copying SDmode
14037 values through if this function has any SDmode references. */
14040 rs6000_alloc_sdmode_stack_slot (void)
14044 gimple_stmt_iterator gsi;
14046 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14049 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14051 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14054 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14055 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14061 /* Check for any SDmode parameters of the function. */
14062 for (t = DECL_ARGUMENTS (cfun->decl); t; t = TREE_CHAIN (t))
14064 if (TREE_TYPE (t) == error_mark_node)
14067 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14068 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14070 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14071 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14079 rs6000_instantiate_decls (void)
14081 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14082 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14085 /* Given an rtx X being reloaded into a reg required to be
14086 in class CLASS, return the class of reg to actually use.
14087 In general this is just CLASS; but on some machines
14088 in some cases it is preferable to use a more restrictive class.
14090 On the RS/6000, we have to return NO_REGS when we want to reload a
14091 floating-point CONST_DOUBLE to force it to be copied to memory.
14093 We also don't want to reload integer values into floating-point
14094 registers if we can at all help it. In fact, this can
14095 cause reload to die, if it tries to generate a reload of CTR
14096 into a FP register and discovers it doesn't have the memory location
14099 ??? Would it be a good idea to have reload do the converse, that is
14100 try to reload floating modes into FP registers if possible?
14103 static enum reg_class
14104 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14106 enum machine_mode mode = GET_MODE (x);
14108 if (VECTOR_UNIT_VSX_P (mode)
14109 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14112 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14113 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14114 && easy_vector_constant (x, mode))
14115 return ALTIVEC_REGS;
14117 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14120 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14121 return GENERAL_REGS;
14123 /* For VSX, prefer the traditional registers for 64-bit values because we can
14124 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14125 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14126 prefer Altivec loads.. */
14127 if (rclass == VSX_REGS)
14129 if (GET_MODE_SIZE (mode) <= 8)
14132 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14133 return ALTIVEC_REGS;
14141 /* Debug version of rs6000_preferred_reload_class. */
14142 static enum reg_class
14143 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14145 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14148 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14150 reg_class_names[ret], reg_class_names[rclass],
14151 GET_MODE_NAME (GET_MODE (x)));
14157 /* If we are copying between FP or AltiVec registers and anything else, we need
14158 a memory location. The exception is when we are targeting ppc64 and the
14159 move to/from fpr to gpr instructions are available. Also, under VSX, you
14160 can copy vector registers from the FP register set to the Altivec register
14161 set and vice versa. */
14164 rs6000_secondary_memory_needed (enum reg_class class1,
14165 enum reg_class class2,
14166 enum machine_mode mode)
14168 if (class1 == class2)
14171 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14172 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14173 between these classes. But we need memory for other things that can go in
14174 FLOAT_REGS like SFmode. */
14176 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14177 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14178 || class1 == FLOAT_REGS))
14179 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14180 && class2 != FLOAT_REGS);
14182 if (class1 == VSX_REGS || class2 == VSX_REGS)
14185 if (class1 == FLOAT_REGS
14186 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14187 || ((mode != DFmode)
14188 && (mode != DDmode)
14189 && (mode != DImode))))
14192 if (class2 == FLOAT_REGS
14193 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14194 || ((mode != DFmode)
14195 && (mode != DDmode)
14196 && (mode != DImode))))
14199 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14205 /* Debug version of rs6000_secondary_memory_needed. */
14207 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14208 enum reg_class class2,
14209 enum machine_mode mode)
14211 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14214 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14215 "class2 = %s, mode = %s\n",
14216 ret ? "true" : "false", reg_class_names[class1],
14217 reg_class_names[class2], GET_MODE_NAME (mode));
14222 /* Return the register class of a scratch register needed to copy IN into
14223 or out of a register in RCLASS in MODE. If it can be done directly,
14224 NO_REGS is returned. */
14226 static enum reg_class
14227 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14232 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14234 && MACHOPIC_INDIRECT
14238 /* We cannot copy a symbolic operand directly into anything
14239 other than BASE_REGS for TARGET_ELF. So indicate that a
14240 register from BASE_REGS is needed as an intermediate
14243 On Darwin, pic addresses require a load from memory, which
14244 needs a base register. */
14245 if (rclass != BASE_REGS
14246 && (GET_CODE (in) == SYMBOL_REF
14247 || GET_CODE (in) == HIGH
14248 || GET_CODE (in) == LABEL_REF
14249 || GET_CODE (in) == CONST))
14253 if (GET_CODE (in) == REG)
14255 regno = REGNO (in);
14256 if (regno >= FIRST_PSEUDO_REGISTER)
14258 regno = true_regnum (in);
14259 if (regno >= FIRST_PSEUDO_REGISTER)
14263 else if (GET_CODE (in) == SUBREG)
14265 regno = true_regnum (in);
14266 if (regno >= FIRST_PSEUDO_REGISTER)
14272 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
14274 if (rclass == GENERAL_REGS || rclass == BASE_REGS
14275 || (regno >= 0 && INT_REGNO_P (regno)))
14278 /* Constants, memory, and FP registers can go into FP registers. */
14279 if ((regno == -1 || FP_REGNO_P (regno))
14280 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
14281 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
14283 /* Memory, and FP/altivec registers can go into fp/altivec registers under
14286 && (regno == -1 || VSX_REGNO_P (regno))
14287 && VSX_REG_CLASS_P (rclass))
14290 /* Memory, and AltiVec registers can go into AltiVec registers. */
14291 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
14292 && rclass == ALTIVEC_REGS)
14295 /* We can copy among the CR registers. */
14296 if ((rclass == CR_REGS || rclass == CR0_REGS)
14297 && regno >= 0 && CR_REGNO_P (regno))
14300 /* Otherwise, we need GENERAL_REGS. */
14301 return GENERAL_REGS;
14304 /* Debug version of rs6000_secondary_reload_class. */
14305 static enum reg_class
14306 rs6000_debug_secondary_reload_class (enum reg_class rclass,
14307 enum machine_mode mode, rtx in)
14309 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
14311 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
14312 "mode = %s, input rtx:\n",
14313 reg_class_names[ret], reg_class_names[rclass],
14314 GET_MODE_NAME (mode));
14320 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
14323 rs6000_cannot_change_mode_class (enum machine_mode from,
14324 enum machine_mode to,
14325 enum reg_class rclass)
14327 unsigned from_size = GET_MODE_SIZE (from);
14328 unsigned to_size = GET_MODE_SIZE (to);
14330 if (from_size != to_size)
14332 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
14333 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
14334 && reg_classes_intersect_p (xclass, rclass));
14337 if (TARGET_E500_DOUBLE
14338 && ((((to) == DFmode) + ((from) == DFmode)) == 1
14339 || (((to) == TFmode) + ((from) == TFmode)) == 1
14340 || (((to) == DDmode) + ((from) == DDmode)) == 1
14341 || (((to) == TDmode) + ((from) == TDmode)) == 1
14342 || (((to) == DImode) + ((from) == DImode)) == 1))
14345 /* Since the VSX register set includes traditional floating point registers
14346 and altivec registers, just check for the size being different instead of
14347 trying to check whether the modes are vector modes. Otherwise it won't
14348 allow say DF and DI to change classes. */
14349 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
14350 return (from_size != 8 && from_size != 16);
14352 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
14353 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
14356 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
14357 && reg_classes_intersect_p (GENERAL_REGS, rclass))
14363 /* Debug version of rs6000_cannot_change_mode_class. */
14365 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
14366 enum machine_mode to,
14367 enum reg_class rclass)
14369 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
14372 "rs6000_cannot_change_mode_class, return %s, from = %s, "
14373 "to = %s, rclass = %s\n",
14374 ret ? "true" : "false",
14375 GET_MODE_NAME (from), GET_MODE_NAME (to),
14376 reg_class_names[rclass]);
14381 /* Given a comparison operation, return the bit number in CCR to test. We
14382 know this is a valid comparison.
14384 SCC_P is 1 if this is for an scc. That means that %D will have been
14385 used instead of %C, so the bits will be in different places.
14387 Return -1 if OP isn't a valid comparison for some reason. */
14390 ccr_bit (rtx op, int scc_p)
14392 enum rtx_code code = GET_CODE (op);
14393 enum machine_mode cc_mode;
14398 if (!COMPARISON_P (op))
14401 reg = XEXP (op, 0);
14403 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
14405 cc_mode = GET_MODE (reg);
14406 cc_regnum = REGNO (reg);
14407 base_bit = 4 * (cc_regnum - CR0_REGNO);
14409 validate_condition_mode (code, cc_mode);
14411 /* When generating a sCOND operation, only positive conditions are
14414 || code == EQ || code == GT || code == LT || code == UNORDERED
14415 || code == GTU || code == LTU);
14420 return scc_p ? base_bit + 3 : base_bit + 2;
14422 return base_bit + 2;
14423 case GT: case GTU: case UNLE:
14424 return base_bit + 1;
14425 case LT: case LTU: case UNGE:
14427 case ORDERED: case UNORDERED:
14428 return base_bit + 3;
14431 /* If scc, we will have done a cror to put the bit in the
14432 unordered position. So test that bit. For integer, this is ! LT
14433 unless this is an scc insn. */
14434 return scc_p ? base_bit + 3 : base_bit;
14437 return scc_p ? base_bit + 3 : base_bit + 1;
14440 gcc_unreachable ();
14444 /* Return the GOT register. */
14447 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
14449 /* The second flow pass currently (June 1999) can't update
14450 regs_ever_live without disturbing other parts of the compiler, so
14451 update it here to make the prolog/epilogue code happy. */
14452 if (!can_create_pseudo_p ()
14453 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
14454 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
14456 crtl->uses_pic_offset_table = 1;
14458 return pic_offset_table_rtx;
14461 /* Function to init struct machine_function.
14462 This will be called, via a pointer variable,
14463 from push_function_context. */
14465 static struct machine_function *
14466 rs6000_init_machine_status (void)
14468 return GGC_CNEW (machine_function);
14471 /* These macros test for integers and extract the low-order bits. */
14473 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
14474 && GET_MODE (X) == VOIDmode)
14476 #define INT_LOWPART(X) \
14477 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
14480 extract_MB (rtx op)
14483 unsigned long val = INT_LOWPART (op);
14485 /* If the high bit is zero, the value is the first 1 bit we find
14487 if ((val & 0x80000000) == 0)
14489 gcc_assert (val & 0xffffffff);
14492 while (((val <<= 1) & 0x80000000) == 0)
14497 /* If the high bit is set and the low bit is not, or the mask is all
14498 1's, the value is zero. */
14499 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
14502 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14505 while (((val >>= 1) & 1) != 0)
14512 extract_ME (rtx op)
14515 unsigned long val = INT_LOWPART (op);
14517 /* If the low bit is zero, the value is the first 1 bit we find from
14519 if ((val & 1) == 0)
14521 gcc_assert (val & 0xffffffff);
14524 while (((val >>= 1) & 1) == 0)
14530 /* If the low bit is set and the high bit is not, or the mask is all
14531 1's, the value is 31. */
14532 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
14535 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
14538 while (((val <<= 1) & 0x80000000) != 0)
14544 /* Locate some local-dynamic symbol still in use by this function
14545 so that we can print its name in some tls_ld pattern. */
14547 static const char *
14548 rs6000_get_some_local_dynamic_name (void)
14552 if (cfun->machine->some_ld_name)
14553 return cfun->machine->some_ld_name;
14555 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
14557 && for_each_rtx (&PATTERN (insn),
14558 rs6000_get_some_local_dynamic_name_1, 0))
14559 return cfun->machine->some_ld_name;
14561 gcc_unreachable ();
14564 /* Helper function for rs6000_get_some_local_dynamic_name. */
14567 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
14571 if (GET_CODE (x) == SYMBOL_REF)
14573 const char *str = XSTR (x, 0);
14574 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
14576 cfun->machine->some_ld_name = str;
14584 /* Write out a function code label. */
14587 rs6000_output_function_entry (FILE *file, const char *fname)
14589 if (fname[0] != '.')
14591 switch (DEFAULT_ABI)
14594 gcc_unreachable ();
14600 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
14609 RS6000_OUTPUT_BASENAME (file, fname);
14612 /* Print an operand. Recognize special options, documented below. */
14615 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
14616 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
14618 #define SMALL_DATA_RELOC "sda21"
14619 #define SMALL_DATA_REG 0
14623 print_operand (FILE *file, rtx x, int code)
14627 unsigned HOST_WIDE_INT uval;
14632 /* Write out an instruction after the call which may be replaced
14633 with glue code by the loader. This depends on the AIX version. */
14634 asm_fprintf (file, RS6000_CALL_GLUE);
14637 /* %a is output_address. */
14640 /* If X is a constant integer whose low-order 5 bits are zero,
14641 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
14642 in the AIX assembler where "sri" with a zero shift count
14643 writes a trash instruction. */
14644 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
14651 /* If constant, low-order 16 bits of constant, unsigned.
14652 Otherwise, write normally. */
14654 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
14656 print_operand (file, x, 0);
14660 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
14661 for 64-bit mask direction. */
14662 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
14665 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
14669 /* X is a CR register. Print the number of the GT bit of the CR. */
14670 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14671 output_operand_lossage ("invalid %%c value");
14673 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
14677 /* Like 'J' but get to the GT bit only. */
14678 gcc_assert (GET_CODE (x) == REG);
14680 /* Bit 1 is GT bit. */
14681 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
14683 /* Add one for shift count in rlinm for scc. */
14684 fprintf (file, "%d", i + 1);
14688 /* X is a CR register. Print the number of the EQ bit of the CR */
14689 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14690 output_operand_lossage ("invalid %%E value");
14692 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
14696 /* X is a CR register. Print the shift count needed to move it
14697 to the high-order four bits. */
14698 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14699 output_operand_lossage ("invalid %%f value");
14701 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
14705 /* Similar, but print the count for the rotate in the opposite
14707 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14708 output_operand_lossage ("invalid %%F value");
14710 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
14714 /* X is a constant integer. If it is negative, print "m",
14715 otherwise print "z". This is to make an aze or ame insn. */
14716 if (GET_CODE (x) != CONST_INT)
14717 output_operand_lossage ("invalid %%G value");
14718 else if (INTVAL (x) >= 0)
14725 /* If constant, output low-order five bits. Otherwise, write
14728 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
14730 print_operand (file, x, 0);
14734 /* If constant, output low-order six bits. Otherwise, write
14737 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
14739 print_operand (file, x, 0);
14743 /* Print `i' if this is a constant, else nothing. */
14749 /* Write the bit number in CCR for jump. */
14750 i = ccr_bit (x, 0);
14752 output_operand_lossage ("invalid %%j code");
14754 fprintf (file, "%d", i);
14758 /* Similar, but add one for shift count in rlinm for scc and pass
14759 scc flag to `ccr_bit'. */
14760 i = ccr_bit (x, 1);
14762 output_operand_lossage ("invalid %%J code");
14764 /* If we want bit 31, write a shift count of zero, not 32. */
14765 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14769 /* X must be a constant. Write the 1's complement of the
14772 output_operand_lossage ("invalid %%k value");
14774 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
14778 /* X must be a symbolic constant on ELF. Write an
14779 expression suitable for an 'addi' that adds in the low 16
14780 bits of the MEM. */
14781 if (GET_CODE (x) != CONST)
14783 print_operand_address (file, x);
14784 fputs ("@l", file);
14788 if (GET_CODE (XEXP (x, 0)) != PLUS
14789 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
14790 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
14791 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
14792 output_operand_lossage ("invalid %%K value");
14793 print_operand_address (file, XEXP (XEXP (x, 0), 0));
14794 fputs ("@l", file);
14795 /* For GNU as, there must be a non-alphanumeric character
14796 between 'l' and the number. The '-' is added by
14797 print_operand() already. */
14798 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
14800 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
14804 /* %l is output_asm_label. */
14807 /* Write second word of DImode or DFmode reference. Works on register
14808 or non-indexed memory only. */
14809 if (GET_CODE (x) == REG)
14810 fputs (reg_names[REGNO (x) + 1], file);
14811 else if (GET_CODE (x) == MEM)
14813 /* Handle possible auto-increment. Since it is pre-increment and
14814 we have already done it, we can just use an offset of word. */
14815 if (GET_CODE (XEXP (x, 0)) == PRE_INC
14816 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
14817 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14819 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
14820 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
14823 output_address (XEXP (adjust_address_nv (x, SImode,
14827 if (small_data_operand (x, GET_MODE (x)))
14828 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
14829 reg_names[SMALL_DATA_REG]);
14834 /* MB value for a mask operand. */
14835 if (! mask_operand (x, SImode))
14836 output_operand_lossage ("invalid %%m value");
14838 fprintf (file, "%d", extract_MB (x));
14842 /* ME value for a mask operand. */
14843 if (! mask_operand (x, SImode))
14844 output_operand_lossage ("invalid %%M value");
14846 fprintf (file, "%d", extract_ME (x));
14849 /* %n outputs the negative of its operand. */
14852 /* Write the number of elements in the vector times 4. */
14853 if (GET_CODE (x) != PARALLEL)
14854 output_operand_lossage ("invalid %%N value");
14856 fprintf (file, "%d", XVECLEN (x, 0) * 4);
14860 /* Similar, but subtract 1 first. */
14861 if (GET_CODE (x) != PARALLEL)
14862 output_operand_lossage ("invalid %%O value");
14864 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
14868 /* X is a CONST_INT that is a power of two. Output the logarithm. */
14870 || INT_LOWPART (x) < 0
14871 || (i = exact_log2 (INT_LOWPART (x))) < 0)
14872 output_operand_lossage ("invalid %%p value");
14874 fprintf (file, "%d", i);
14878 /* The operand must be an indirect memory reference. The result
14879 is the register name. */
14880 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
14881 || REGNO (XEXP (x, 0)) >= 32)
14882 output_operand_lossage ("invalid %%P value");
14884 fputs (reg_names[REGNO (XEXP (x, 0))], file);
14888 /* This outputs the logical code corresponding to a boolean
14889 expression. The expression may have one or both operands
14890 negated (if one, only the first one). For condition register
14891 logical operations, it will also treat the negated
14892 CR codes as NOTs, but not handle NOTs of them. */
14894 const char *const *t = 0;
14896 enum rtx_code code = GET_CODE (x);
14897 static const char * const tbl[3][3] = {
14898 { "and", "andc", "nor" },
14899 { "or", "orc", "nand" },
14900 { "xor", "eqv", "xor" } };
14904 else if (code == IOR)
14906 else if (code == XOR)
14909 output_operand_lossage ("invalid %%q value");
14911 if (GET_CODE (XEXP (x, 0)) != NOT)
14915 if (GET_CODE (XEXP (x, 1)) == NOT)
14933 /* X is a CR register. Print the mask for `mtcrf'. */
14934 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
14935 output_operand_lossage ("invalid %%R value");
14937 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
14941 /* Low 5 bits of 32 - value */
14943 output_operand_lossage ("invalid %%s value");
14945 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
14949 /* PowerPC64 mask position. All 0's is excluded.
14950 CONST_INT 32-bit mask is considered sign-extended so any
14951 transition must occur within the CONST_INT, not on the boundary. */
14952 if (! mask64_operand (x, DImode))
14953 output_operand_lossage ("invalid %%S value");
14955 uval = INT_LOWPART (x);
14957 if (uval & 1) /* Clear Left */
14959 #if HOST_BITS_PER_WIDE_INT > 64
14960 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14964 else /* Clear Right */
14967 #if HOST_BITS_PER_WIDE_INT > 64
14968 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
14974 gcc_assert (i >= 0);
14975 fprintf (file, "%d", i);
14979 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
14980 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
14982 /* Bit 3 is OV bit. */
14983 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
14985 /* If we want bit 31, write a shift count of zero, not 32. */
14986 fprintf (file, "%d", i == 31 ? 0 : i + 1);
14990 /* Print the symbolic name of a branch target register. */
14991 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
14992 && REGNO (x) != CTR_REGNO))
14993 output_operand_lossage ("invalid %%T value");
14994 else if (REGNO (x) == LR_REGNO)
14995 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
14997 fputs ("ctr", file);
15001 /* High-order 16 bits of constant for use in unsigned operand. */
15003 output_operand_lossage ("invalid %%u value");
15005 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15006 (INT_LOWPART (x) >> 16) & 0xffff);
15010 /* High-order 16 bits of constant for use in signed operand. */
15012 output_operand_lossage ("invalid %%v value");
15014 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15015 (INT_LOWPART (x) >> 16) & 0xffff);
15019 /* Print `u' if this has an auto-increment or auto-decrement. */
15020 if (GET_CODE (x) == MEM
15021 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15022 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15023 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15028 /* Print the trap code for this operand. */
15029 switch (GET_CODE (x))
15032 fputs ("eq", file); /* 4 */
15035 fputs ("ne", file); /* 24 */
15038 fputs ("lt", file); /* 16 */
15041 fputs ("le", file); /* 20 */
15044 fputs ("gt", file); /* 8 */
15047 fputs ("ge", file); /* 12 */
15050 fputs ("llt", file); /* 2 */
15053 fputs ("lle", file); /* 6 */
15056 fputs ("lgt", file); /* 1 */
15059 fputs ("lge", file); /* 5 */
15062 gcc_unreachable ();
15067 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15070 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15071 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15073 print_operand (file, x, 0);
15077 /* MB value for a PowerPC64 rldic operand. */
15078 val = (GET_CODE (x) == CONST_INT
15079 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15084 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15085 if ((val <<= 1) < 0)
15088 #if HOST_BITS_PER_WIDE_INT == 32
15089 if (GET_CODE (x) == CONST_INT && i >= 0)
15090 i += 32; /* zero-extend high-part was all 0's */
15091 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15093 val = CONST_DOUBLE_LOW (x);
15099 for ( ; i < 64; i++)
15100 if ((val <<= 1) < 0)
15105 fprintf (file, "%d", i + 1);
15109 /* X is a FPR or Altivec register used in a VSX context. */
15110 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15111 output_operand_lossage ("invalid %%x value");
15114 int reg = REGNO (x);
15115 int vsx_reg = (FP_REGNO_P (reg)
15117 : reg - FIRST_ALTIVEC_REGNO + 32);
15119 #ifdef TARGET_REGNAMES
15120 if (TARGET_REGNAMES)
15121 fprintf (file, "%%vs%d", vsx_reg);
15124 fprintf (file, "%d", vsx_reg);
15129 if (GET_CODE (x) == MEM
15130 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15131 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15132 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15137 /* Like 'L', for third word of TImode */
15138 if (GET_CODE (x) == REG)
15139 fputs (reg_names[REGNO (x) + 2], file);
15140 else if (GET_CODE (x) == MEM)
15142 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15143 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15144 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15145 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15146 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15148 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15149 if (small_data_operand (x, GET_MODE (x)))
15150 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15151 reg_names[SMALL_DATA_REG]);
15156 /* X is a SYMBOL_REF. Write out the name preceded by a
15157 period and without any trailing data in brackets. Used for function
15158 names. If we are configured for System V (or the embedded ABI) on
15159 the PowerPC, do not emit the period, since those systems do not use
15160 TOCs and the like. */
15161 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15163 /* Mark the decl as referenced so that cgraph will output the
15165 if (SYMBOL_REF_DECL (x))
15166 mark_decl_referenced (SYMBOL_REF_DECL (x));
15168 /* For macho, check to see if we need a stub. */
15171 const char *name = XSTR (x, 0);
15173 if (MACHOPIC_INDIRECT
15174 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15175 name = machopic_indirection_name (x, /*stub_p=*/true);
15177 assemble_name (file, name);
15179 else if (!DOT_SYMBOLS)
15180 assemble_name (file, XSTR (x, 0));
15182 rs6000_output_function_entry (file, XSTR (x, 0));
15186 /* Like 'L', for last word of TImode. */
15187 if (GET_CODE (x) == REG)
15188 fputs (reg_names[REGNO (x) + 3], file);
15189 else if (GET_CODE (x) == MEM)
15191 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15192 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15193 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15194 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15195 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15197 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15198 if (small_data_operand (x, GET_MODE (x)))
15199 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15200 reg_names[SMALL_DATA_REG]);
15204 /* Print AltiVec or SPE memory operand. */
15209 gcc_assert (GET_CODE (x) == MEM);
15213 /* Ugly hack because %y is overloaded. */
15214 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15215 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15216 || GET_MODE (x) == TFmode
15217 || GET_MODE (x) == TImode))
15219 /* Handle [reg]. */
15220 if (GET_CODE (tmp) == REG)
15222 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15225 /* Handle [reg+UIMM]. */
15226 else if (GET_CODE (tmp) == PLUS &&
15227 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15231 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15233 x = INTVAL (XEXP (tmp, 1));
15234 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15238 /* Fall through. Must be [reg+reg]. */
15240 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15241 && GET_CODE (tmp) == AND
15242 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15243 && INTVAL (XEXP (tmp, 1)) == -16)
15244 tmp = XEXP (tmp, 0);
15245 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15246 && GET_CODE (tmp) == PRE_MODIFY)
15247 tmp = XEXP (tmp, 1);
15248 if (GET_CODE (tmp) == REG)
15249 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15252 if (!GET_CODE (tmp) == PLUS
15253 || !REG_P (XEXP (tmp, 0))
15254 || !REG_P (XEXP (tmp, 1)))
15256 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15260 if (REGNO (XEXP (tmp, 0)) == 0)
15261 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15262 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15264 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15265 reg_names[ REGNO (XEXP (tmp, 1)) ]);
15271 if (GET_CODE (x) == REG)
15272 fprintf (file, "%s", reg_names[REGNO (x)]);
15273 else if (GET_CODE (x) == MEM)
15275 /* We need to handle PRE_INC and PRE_DEC here, since we need to
15276 know the width from the mode. */
15277 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
15278 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
15279 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15280 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
15281 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
15282 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
15283 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15284 output_address (XEXP (XEXP (x, 0), 1));
15286 output_address (XEXP (x, 0));
15289 output_addr_const (file, x);
15293 assemble_name (file, rs6000_get_some_local_dynamic_name ());
15297 output_operand_lossage ("invalid %%xn code");
15301 /* Print the address of an operand. */
15304 print_operand_address (FILE *file, rtx x)
15306 if (GET_CODE (x) == REG)
15307 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
15308 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
15309 || GET_CODE (x) == LABEL_REF)
15311 output_addr_const (file, x);
15312 if (small_data_operand (x, GET_MODE (x)))
15313 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15314 reg_names[SMALL_DATA_REG]);
15316 gcc_assert (!TARGET_TOC);
15318 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
15320 gcc_assert (REG_P (XEXP (x, 0)));
15321 if (REGNO (XEXP (x, 0)) == 0)
15322 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
15323 reg_names[ REGNO (XEXP (x, 0)) ]);
15325 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
15326 reg_names[ REGNO (XEXP (x, 1)) ]);
15328 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
15329 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
15330 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
15332 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15333 && CONSTANT_P (XEXP (x, 1)))
15335 output_addr_const (file, XEXP (x, 1));
15336 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15340 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
15341 && CONSTANT_P (XEXP (x, 1)))
15343 fprintf (file, "lo16(");
15344 output_addr_const (file, XEXP (x, 1));
15345 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
15348 else if (legitimate_constant_pool_address_p (x))
15350 output_addr_const (file, XEXP (x, 1));
15351 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
15354 gcc_unreachable ();
15357 /* Implement OUTPUT_ADDR_CONST_EXTRA for address X. */
15360 rs6000_output_addr_const_extra (FILE *file, rtx x)
15362 if (GET_CODE (x) == UNSPEC)
15363 switch (XINT (x, 1))
15365 case UNSPEC_TOCREL:
15366 x = XVECEXP (x, 0, 0);
15367 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15368 output_addr_const (file, x);
15369 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
15372 assemble_name (file, toc_label_name);
15374 else if (TARGET_ELF)
15375 fputs ("@toc", file);
15379 case UNSPEC_MACHOPIC_OFFSET:
15380 output_addr_const (file, XVECEXP (x, 0, 0));
15382 machopic_output_function_base_name (file);
15389 /* Target hook for assembling integer objects. The PowerPC version has
15390 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
15391 is defined. It also needs to handle DI-mode objects on 64-bit
15395 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
15397 #ifdef RELOCATABLE_NEEDS_FIXUP
15398 /* Special handling for SI values. */
15399 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
15401 static int recurse = 0;
15403 /* For -mrelocatable, we mark all addresses that need to be fixed up
15404 in the .fixup section. */
15405 if (TARGET_RELOCATABLE
15406 && in_section != toc_section
15407 && in_section != text_section
15408 && !unlikely_text_section_p (in_section)
15410 && GET_CODE (x) != CONST_INT
15411 && GET_CODE (x) != CONST_DOUBLE
15417 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
15419 ASM_OUTPUT_LABEL (asm_out_file, buf);
15420 fprintf (asm_out_file, "\t.long\t(");
15421 output_addr_const (asm_out_file, x);
15422 fprintf (asm_out_file, ")@fixup\n");
15423 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
15424 ASM_OUTPUT_ALIGN (asm_out_file, 2);
15425 fprintf (asm_out_file, "\t.long\t");
15426 assemble_name (asm_out_file, buf);
15427 fprintf (asm_out_file, "\n\t.previous\n");
15431 /* Remove initial .'s to turn a -mcall-aixdesc function
15432 address into the address of the descriptor, not the function
15434 else if (GET_CODE (x) == SYMBOL_REF
15435 && XSTR (x, 0)[0] == '.'
15436 && DEFAULT_ABI == ABI_AIX)
15438 const char *name = XSTR (x, 0);
15439 while (*name == '.')
15442 fprintf (asm_out_file, "\t.long\t%s\n", name);
15446 #endif /* RELOCATABLE_NEEDS_FIXUP */
15447 return default_assemble_integer (x, size, aligned_p);
15450 #ifdef HAVE_GAS_HIDDEN
15451 /* Emit an assembler directive to set symbol visibility for DECL to
15452 VISIBILITY_TYPE. */
15455 rs6000_assemble_visibility (tree decl, int vis)
15457 /* Functions need to have their entry point symbol visibility set as
15458 well as their descriptor symbol visibility. */
15459 if (DEFAULT_ABI == ABI_AIX
15461 && TREE_CODE (decl) == FUNCTION_DECL)
15463 static const char * const visibility_types[] = {
15464 NULL, "internal", "hidden", "protected"
15467 const char *name, *type;
15469 name = ((* targetm.strip_name_encoding)
15470 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
15471 type = visibility_types[vis];
15473 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
15474 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
15477 default_assemble_visibility (decl, vis);
15482 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
15484 /* Reversal of FP compares takes care -- an ordered compare
15485 becomes an unordered compare and vice versa. */
15486 if (mode == CCFPmode
15487 && (!flag_finite_math_only
15488 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
15489 || code == UNEQ || code == LTGT))
15490 return reverse_condition_maybe_unordered (code);
15492 return reverse_condition (code);
15495 /* Generate a compare for CODE. Return a brand-new rtx that
15496 represents the result of the compare. */
15499 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
15501 enum machine_mode comp_mode;
15502 rtx compare_result;
15503 enum rtx_code code = GET_CODE (cmp);
15504 rtx op0 = XEXP (cmp, 0);
15505 rtx op1 = XEXP (cmp, 1);
15507 if (FLOAT_MODE_P (mode))
15508 comp_mode = CCFPmode;
15509 else if (code == GTU || code == LTU
15510 || code == GEU || code == LEU)
15511 comp_mode = CCUNSmode;
15512 else if ((code == EQ || code == NE)
15513 && GET_CODE (op0) == SUBREG
15514 && GET_CODE (op1) == SUBREG
15515 && SUBREG_PROMOTED_UNSIGNED_P (op0)
15516 && SUBREG_PROMOTED_UNSIGNED_P (op1))
15517 /* These are unsigned values, perhaps there will be a later
15518 ordering compare that can be shared with this one.
15519 Unfortunately we cannot detect the signedness of the operands
15520 for non-subregs. */
15521 comp_mode = CCUNSmode;
15523 comp_mode = CCmode;
15525 /* First, the compare. */
15526 compare_result = gen_reg_rtx (comp_mode);
15528 /* E500 FP compare instructions on the GPRs. Yuck! */
15529 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
15530 && FLOAT_MODE_P (mode))
15532 rtx cmp, or_result, compare_result2;
15533 enum machine_mode op_mode = GET_MODE (op0);
15535 if (op_mode == VOIDmode)
15536 op_mode = GET_MODE (op1);
15538 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
15539 This explains the following mess. */
15543 case EQ: case UNEQ: case NE: case LTGT:
15547 cmp = (flag_finite_math_only && !flag_trapping_math)
15548 ? gen_tstsfeq_gpr (compare_result, op0, op1)
15549 : gen_cmpsfeq_gpr (compare_result, op0, op1);
15553 cmp = (flag_finite_math_only && !flag_trapping_math)
15554 ? gen_tstdfeq_gpr (compare_result, op0, op1)
15555 : gen_cmpdfeq_gpr (compare_result, op0, op1);
15559 cmp = (flag_finite_math_only && !flag_trapping_math)
15560 ? gen_tsttfeq_gpr (compare_result, op0, op1)
15561 : gen_cmptfeq_gpr (compare_result, op0, op1);
15565 gcc_unreachable ();
15569 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
15573 cmp = (flag_finite_math_only && !flag_trapping_math)
15574 ? gen_tstsfgt_gpr (compare_result, op0, op1)
15575 : gen_cmpsfgt_gpr (compare_result, op0, op1);
15579 cmp = (flag_finite_math_only && !flag_trapping_math)
15580 ? gen_tstdfgt_gpr (compare_result, op0, op1)
15581 : gen_cmpdfgt_gpr (compare_result, op0, op1);
15585 cmp = (flag_finite_math_only && !flag_trapping_math)
15586 ? gen_tsttfgt_gpr (compare_result, op0, op1)
15587 : gen_cmptfgt_gpr (compare_result, op0, op1);
15591 gcc_unreachable ();
15595 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
15599 cmp = (flag_finite_math_only && !flag_trapping_math)
15600 ? gen_tstsflt_gpr (compare_result, op0, op1)
15601 : gen_cmpsflt_gpr (compare_result, op0, op1);
15605 cmp = (flag_finite_math_only && !flag_trapping_math)
15606 ? gen_tstdflt_gpr (compare_result, op0, op1)
15607 : gen_cmpdflt_gpr (compare_result, op0, op1);
15611 cmp = (flag_finite_math_only && !flag_trapping_math)
15612 ? gen_tsttflt_gpr (compare_result, op0, op1)
15613 : gen_cmptflt_gpr (compare_result, op0, op1);
15617 gcc_unreachable ();
15621 gcc_unreachable ();
15624 /* Synthesize LE and GE from LT/GT || EQ. */
15625 if (code == LE || code == GE || code == LEU || code == GEU)
15631 case LE: code = LT; break;
15632 case GE: code = GT; break;
15633 case LEU: code = LT; break;
15634 case GEU: code = GT; break;
15635 default: gcc_unreachable ();
15638 compare_result2 = gen_reg_rtx (CCFPmode);
15644 cmp = (flag_finite_math_only && !flag_trapping_math)
15645 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
15646 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
15650 cmp = (flag_finite_math_only && !flag_trapping_math)
15651 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
15652 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
15656 cmp = (flag_finite_math_only && !flag_trapping_math)
15657 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
15658 : gen_cmptfeq_gpr (compare_result2, op0, op1);
15662 gcc_unreachable ();
15666 /* OR them together. */
15667 or_result = gen_reg_rtx (CCFPmode);
15668 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
15670 compare_result = or_result;
15675 if (code == NE || code == LTGT)
15685 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
15686 CLOBBERs to match cmptf_internal2 pattern. */
15687 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
15688 && GET_MODE (op0) == TFmode
15689 && !TARGET_IEEEQUAD
15690 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
15691 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15693 gen_rtx_SET (VOIDmode,
15695 gen_rtx_COMPARE (comp_mode, op0, op1)),
15696 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15697 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15698 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15699 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15700 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15701 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15702 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
15703 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
15704 else if (GET_CODE (op1) == UNSPEC
15705 && XINT (op1, 1) == UNSPEC_SP_TEST)
15707 rtx op1b = XVECEXP (op1, 0, 0);
15708 comp_mode = CCEQmode;
15709 compare_result = gen_reg_rtx (CCEQmode);
15711 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
15713 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
15716 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
15717 gen_rtx_COMPARE (comp_mode, op0, op1)));
15720 /* Some kinds of FP comparisons need an OR operation;
15721 under flag_finite_math_only we don't bother. */
15722 if (FLOAT_MODE_P (mode)
15723 && !flag_finite_math_only
15724 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
15725 && (code == LE || code == GE
15726 || code == UNEQ || code == LTGT
15727 || code == UNGT || code == UNLT))
15729 enum rtx_code or1, or2;
15730 rtx or1_rtx, or2_rtx, compare2_rtx;
15731 rtx or_result = gen_reg_rtx (CCEQmode);
15735 case LE: or1 = LT; or2 = EQ; break;
15736 case GE: or1 = GT; or2 = EQ; break;
15737 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
15738 case LTGT: or1 = LT; or2 = GT; break;
15739 case UNGT: or1 = UNORDERED; or2 = GT; break;
15740 case UNLT: or1 = UNORDERED; or2 = LT; break;
15741 default: gcc_unreachable ();
15743 validate_condition_mode (or1, comp_mode);
15744 validate_condition_mode (or2, comp_mode);
15745 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
15746 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
15747 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
15748 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
15750 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
15752 compare_result = or_result;
15756 validate_condition_mode (code, GET_MODE (compare_result));
15758 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
15762 /* Emit the RTL for an sCOND pattern. */
15765 rs6000_emit_sISEL (enum machine_mode mode, rtx operands[])
15768 enum machine_mode op_mode;
15769 enum rtx_code cond_code;
15770 rtx result = operands[0];
15772 condition_rtx = rs6000_generate_compare (operands[1], mode);
15773 cond_code = GET_CODE (condition_rtx);
15775 op_mode = GET_MODE (XEXP (operands[1], 0));
15776 if (op_mode == VOIDmode)
15777 op_mode = GET_MODE (XEXP (operands[1], 1));
15779 if (TARGET_POWERPC64 && GET_MODE (result) == DImode)
15781 PUT_MODE (condition_rtx, DImode);
15782 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15783 || cond_code == LTU)
15784 emit_insn (gen_isel_unsigned_di (result, condition_rtx,
15785 force_reg (DImode, const1_rtx),
15786 force_reg (DImode, const0_rtx),
15787 XEXP (condition_rtx, 0)));
15789 emit_insn (gen_isel_signed_di (result, condition_rtx,
15790 force_reg (DImode, const1_rtx),
15791 force_reg (DImode, const0_rtx),
15792 XEXP (condition_rtx, 0)));
15796 PUT_MODE (condition_rtx, SImode);
15797 if (cond_code == GEU || cond_code == GTU || cond_code == LEU
15798 || cond_code == LTU)
15799 emit_insn (gen_isel_unsigned_si (result, condition_rtx,
15800 force_reg (SImode, const1_rtx),
15801 force_reg (SImode, const0_rtx),
15802 XEXP (condition_rtx, 0)));
15804 emit_insn (gen_isel_signed_si (result, condition_rtx,
15805 force_reg (SImode, const1_rtx),
15806 force_reg (SImode, const0_rtx),
15807 XEXP (condition_rtx, 0)));
15812 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
15815 enum machine_mode op_mode;
15816 enum rtx_code cond_code;
15817 rtx result = operands[0];
15819 if (TARGET_ISEL && (mode == SImode || mode == DImode))
15821 rs6000_emit_sISEL (mode, operands);
15825 condition_rtx = rs6000_generate_compare (operands[1], mode);
15826 cond_code = GET_CODE (condition_rtx);
15828 if (FLOAT_MODE_P (mode)
15829 && !TARGET_FPRS && TARGET_HARD_FLOAT)
15833 PUT_MODE (condition_rtx, SImode);
15834 t = XEXP (condition_rtx, 0);
15836 gcc_assert (cond_code == NE || cond_code == EQ);
15838 if (cond_code == NE)
15839 emit_insn (gen_e500_flip_gt_bit (t, t));
15841 emit_insn (gen_move_from_CR_gt_bit (result, t));
15845 if (cond_code == NE
15846 || cond_code == GE || cond_code == LE
15847 || cond_code == GEU || cond_code == LEU
15848 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
15850 rtx not_result = gen_reg_rtx (CCEQmode);
15851 rtx not_op, rev_cond_rtx;
15852 enum machine_mode cc_mode;
15854 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
15856 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
15857 SImode, XEXP (condition_rtx, 0), const0_rtx);
15858 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
15859 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
15860 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
15863 op_mode = GET_MODE (XEXP (operands[1], 0));
15864 if (op_mode == VOIDmode)
15865 op_mode = GET_MODE (XEXP (operands[1], 1));
15867 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
15869 PUT_MODE (condition_rtx, DImode);
15870 convert_move (result, condition_rtx, 0);
15874 PUT_MODE (condition_rtx, SImode);
15875 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
15879 /* Emit a branch of kind CODE to location LOC. */
15882 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
15884 rtx condition_rtx, loc_ref;
15886 condition_rtx = rs6000_generate_compare (operands[0], mode);
15887 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
15888 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
15889 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
15890 loc_ref, pc_rtx)));
15893 /* Return the string to output a conditional branch to LABEL, which is
15894 the operand number of the label, or -1 if the branch is really a
15895 conditional return.
15897 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
15898 condition code register and its mode specifies what kind of
15899 comparison we made.
15901 REVERSED is nonzero if we should reverse the sense of the comparison.
15903 INSN is the insn. */
15906 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
15908 static char string[64];
15909 enum rtx_code code = GET_CODE (op);
15910 rtx cc_reg = XEXP (op, 0);
15911 enum machine_mode mode = GET_MODE (cc_reg);
15912 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
15913 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
15914 int really_reversed = reversed ^ need_longbranch;
15920 validate_condition_mode (code, mode);
15922 /* Work out which way this really branches. We could use
15923 reverse_condition_maybe_unordered here always but this
15924 makes the resulting assembler clearer. */
15925 if (really_reversed)
15927 /* Reversal of FP compares takes care -- an ordered compare
15928 becomes an unordered compare and vice versa. */
15929 if (mode == CCFPmode)
15930 code = reverse_condition_maybe_unordered (code);
15932 code = reverse_condition (code);
15935 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
15937 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
15942 /* Opposite of GT. */
15951 gcc_unreachable ();
15957 /* Not all of these are actually distinct opcodes, but
15958 we distinguish them for clarity of the resulting assembler. */
15959 case NE: case LTGT:
15960 ccode = "ne"; break;
15961 case EQ: case UNEQ:
15962 ccode = "eq"; break;
15964 ccode = "ge"; break;
15965 case GT: case GTU: case UNGT:
15966 ccode = "gt"; break;
15968 ccode = "le"; break;
15969 case LT: case LTU: case UNLT:
15970 ccode = "lt"; break;
15971 case UNORDERED: ccode = "un"; break;
15972 case ORDERED: ccode = "nu"; break;
15973 case UNGE: ccode = "nl"; break;
15974 case UNLE: ccode = "ng"; break;
15976 gcc_unreachable ();
15979 /* Maybe we have a guess as to how likely the branch is.
15980 The old mnemonics don't have a way to specify this information. */
15982 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
15983 if (note != NULL_RTX)
15985 /* PROB is the difference from 50%. */
15986 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
15988 /* Only hint for highly probable/improbable branches on newer
15989 cpus as static prediction overrides processor dynamic
15990 prediction. For older cpus we may as well always hint, but
15991 assume not taken for branches that are very close to 50% as a
15992 mispredicted taken branch is more expensive than a
15993 mispredicted not-taken branch. */
15994 if (rs6000_always_hint
15995 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
15996 && br_prob_note_reliable_p (note)))
15998 if (abs (prob) > REG_BR_PROB_BASE / 20
15999 && ((prob > 0) ^ need_longbranch))
16007 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16009 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16011 /* We need to escape any '%' characters in the reg_names string.
16012 Assume they'd only be the first character.... */
16013 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16015 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16019 /* If the branch distance was too far, we may have to use an
16020 unconditional branch to go the distance. */
16021 if (need_longbranch)
16022 s += sprintf (s, ",$+8\n\tb %s", label);
16024 s += sprintf (s, ",%s", label);
16030 /* Return the string to flip the GT bit on a CR. */
16032 output_e500_flip_gt_bit (rtx dst, rtx src)
16034 static char string[64];
16037 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16038 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16041 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16042 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16044 sprintf (string, "crnot %d,%d", a, b);
16048 /* Return insn for VSX or Altivec comparisons. */
16051 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16054 enum machine_mode mode = GET_MODE (op0);
16062 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16068 mask = gen_reg_rtx (mode);
16069 emit_insn (gen_rtx_SET (VOIDmode,
16071 gen_rtx_fmt_ee (code, mode, op0, op1)));
16078 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16079 DMODE is expected destination mode. This is a recursive function. */
16082 rs6000_emit_vector_compare (enum rtx_code rcode,
16084 enum machine_mode dmode)
16087 bool swap_operands = false;
16088 bool try_again = false;
16090 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16091 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16093 /* See if the comparison works as is. */
16094 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16102 swap_operands = true;
16107 swap_operands = true;
16115 /* Invert condition and try again.
16116 e.g., A != B becomes ~(A==B). */
16118 enum rtx_code rev_code;
16119 enum insn_code nor_code;
16122 rev_code = reverse_condition_maybe_unordered (rcode);
16123 if (rev_code == UNKNOWN)
16126 nor_code = optab_handler (one_cmpl_optab, (int)dmode)->insn_code;
16127 if (nor_code == CODE_FOR_nothing)
16130 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16134 mask = gen_reg_rtx (dmode);
16135 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16143 /* Try GT/GTU/LT/LTU OR EQ */
16146 enum insn_code ior_code;
16147 enum rtx_code new_code;
16168 gcc_unreachable ();
16171 ior_code = optab_handler (ior_optab, (int)dmode)->insn_code;
16172 if (ior_code == CODE_FOR_nothing)
16175 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16179 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16183 mask = gen_reg_rtx (dmode);
16184 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16202 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16207 /* You only get two chances. */
16211 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16212 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16213 operands for the relation operation COND. */
16216 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16217 rtx cond, rtx cc_op0, rtx cc_op1)
16219 enum machine_mode dest_mode = GET_MODE (dest);
16220 enum rtx_code rcode = GET_CODE (cond);
16221 enum machine_mode cc_mode = CCmode;
16225 bool invert_move = false;
16227 if (VECTOR_UNIT_NONE_P (dest_mode))
16232 /* Swap operands if we can, and fall back to doing the operation as
16233 specified, and doing a NOR to invert the test. */
16239 /* Invert condition and try again.
16240 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16241 invert_move = true;
16242 rcode = reverse_condition_maybe_unordered (rcode);
16243 if (rcode == UNKNOWN)
16247 /* Mark unsigned tests with CCUNSmode. */
16252 cc_mode = CCUNSmode;
16259 /* Get the vector mask for the given relational operations. */
16260 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16268 op_true = op_false;
16272 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16273 emit_insn (gen_rtx_SET (VOIDmode,
16275 gen_rtx_IF_THEN_ELSE (dest_mode,
16282 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16283 operands of the last comparison is nonzero/true, FALSE_COND if it
16284 is zero/false. Return 0 if the hardware has no such operation. */
16287 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16289 enum rtx_code code = GET_CODE (op);
16290 rtx op0 = XEXP (op, 0);
16291 rtx op1 = XEXP (op, 1);
16292 REAL_VALUE_TYPE c1;
16293 enum machine_mode compare_mode = GET_MODE (op0);
16294 enum machine_mode result_mode = GET_MODE (dest);
16296 bool is_against_zero;
16298 /* These modes should always match. */
16299 if (GET_MODE (op1) != compare_mode
16300 /* In the isel case however, we can use a compare immediate, so
16301 op1 may be a small constant. */
16302 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
16304 if (GET_MODE (true_cond) != result_mode)
16306 if (GET_MODE (false_cond) != result_mode)
16309 /* First, work out if the hardware can do this at all, or
16310 if it's too slow.... */
16311 if (!FLOAT_MODE_P (compare_mode))
16314 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
16317 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
16318 && SCALAR_FLOAT_MODE_P (compare_mode))
16321 is_against_zero = op1 == CONST0_RTX (compare_mode);
16323 /* A floating-point subtract might overflow, underflow, or produce
16324 an inexact result, thus changing the floating-point flags, so it
16325 can't be generated if we care about that. It's safe if one side
16326 of the construct is zero, since then no subtract will be
16328 if (SCALAR_FLOAT_MODE_P (compare_mode)
16329 && flag_trapping_math && ! is_against_zero)
16332 /* Eliminate half of the comparisons by switching operands, this
16333 makes the remaining code simpler. */
16334 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
16335 || code == LTGT || code == LT || code == UNLE)
16337 code = reverse_condition_maybe_unordered (code);
16339 true_cond = false_cond;
16343 /* UNEQ and LTGT take four instructions for a comparison with zero,
16344 it'll probably be faster to use a branch here too. */
16345 if (code == UNEQ && HONOR_NANS (compare_mode))
16348 if (GET_CODE (op1) == CONST_DOUBLE)
16349 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
16351 /* We're going to try to implement comparisons by performing
16352 a subtract, then comparing against zero. Unfortunately,
16353 Inf - Inf is NaN which is not zero, and so if we don't
16354 know that the operand is finite and the comparison
16355 would treat EQ different to UNORDERED, we can't do it. */
16356 if (HONOR_INFINITIES (compare_mode)
16357 && code != GT && code != UNGE
16358 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
16359 /* Constructs of the form (a OP b ? a : b) are safe. */
16360 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
16361 || (! rtx_equal_p (op0, true_cond)
16362 && ! rtx_equal_p (op1, true_cond))))
16365 /* At this point we know we can use fsel. */
16367 /* Reduce the comparison to a comparison against zero. */
16368 if (! is_against_zero)
16370 temp = gen_reg_rtx (compare_mode);
16371 emit_insn (gen_rtx_SET (VOIDmode, temp,
16372 gen_rtx_MINUS (compare_mode, op0, op1)));
16374 op1 = CONST0_RTX (compare_mode);
16377 /* If we don't care about NaNs we can reduce some of the comparisons
16378 down to faster ones. */
16379 if (! HONOR_NANS (compare_mode))
16385 true_cond = false_cond;
16398 /* Now, reduce everything down to a GE. */
16405 temp = gen_reg_rtx (compare_mode);
16406 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16411 temp = gen_reg_rtx (compare_mode);
16412 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
16417 temp = gen_reg_rtx (compare_mode);
16418 emit_insn (gen_rtx_SET (VOIDmode, temp,
16419 gen_rtx_NEG (compare_mode,
16420 gen_rtx_ABS (compare_mode, op0))));
16425 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
16426 temp = gen_reg_rtx (result_mode);
16427 emit_insn (gen_rtx_SET (VOIDmode, temp,
16428 gen_rtx_IF_THEN_ELSE (result_mode,
16429 gen_rtx_GE (VOIDmode,
16431 true_cond, false_cond)));
16432 false_cond = true_cond;
16435 temp = gen_reg_rtx (compare_mode);
16436 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16441 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
16442 temp = gen_reg_rtx (result_mode);
16443 emit_insn (gen_rtx_SET (VOIDmode, temp,
16444 gen_rtx_IF_THEN_ELSE (result_mode,
16445 gen_rtx_GE (VOIDmode,
16447 true_cond, false_cond)));
16448 true_cond = false_cond;
16451 temp = gen_reg_rtx (compare_mode);
16452 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
16457 gcc_unreachable ();
16460 emit_insn (gen_rtx_SET (VOIDmode, dest,
16461 gen_rtx_IF_THEN_ELSE (result_mode,
16462 gen_rtx_GE (VOIDmode,
16464 true_cond, false_cond)));
16468 /* Same as above, but for ints (isel). */
16471 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16473 rtx condition_rtx, cr;
16474 enum machine_mode mode = GET_MODE (dest);
16476 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
16479 /* We still have to do the compare, because isel doesn't do a
16480 compare, it just looks at the CRx bits set by a previous compare
16482 condition_rtx = rs6000_generate_compare (op, mode);
16483 cr = XEXP (condition_rtx, 0);
16485 if (mode == SImode)
16487 if (GET_MODE (cr) == CCmode)
16488 emit_insn (gen_isel_signed_si (dest, condition_rtx,
16489 true_cond, false_cond, cr));
16491 emit_insn (gen_isel_unsigned_si (dest, condition_rtx,
16492 true_cond, false_cond, cr));
16496 if (GET_MODE (cr) == CCmode)
16497 emit_insn (gen_isel_signed_di (dest, condition_rtx,
16498 true_cond, false_cond, cr));
16500 emit_insn (gen_isel_unsigned_di (dest, condition_rtx,
16501 true_cond, false_cond, cr));
16508 output_isel (rtx *operands)
16510 enum rtx_code code;
16512 code = GET_CODE (operands[1]);
16513 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
16515 PUT_CODE (operands[1], reverse_condition (code));
16516 return "isel %0,%3,%2,%j1";
16519 return "isel %0,%2,%3,%j1";
16523 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
16525 enum machine_mode mode = GET_MODE (op0);
16529 /* VSX/altivec have direct min/max insns. */
16530 if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
16532 emit_insn (gen_rtx_SET (VOIDmode,
16534 gen_rtx_fmt_ee (code, mode, op0, op1)));
16538 if (code == SMAX || code == SMIN)
16543 if (code == SMAX || code == UMAX)
16544 target = emit_conditional_move (dest, c, op0, op1, mode,
16545 op0, op1, mode, 0);
16547 target = emit_conditional_move (dest, c, op0, op1, mode,
16548 op1, op0, mode, 0);
16549 gcc_assert (target);
16550 if (target != dest)
16551 emit_move_insn (dest, target);
16554 /* Emit instructions to perform a load-reserved/store-conditional operation.
16555 The operation performed is an atomic
16556 (set M (CODE:MODE M OP))
16557 If not NULL, BEFORE is atomically set to M before the operation, and
16558 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
16559 If SYNC_P then a memory barrier is emitted before the operation.
16560 Either OP or M may be wrapped in a NOT operation. */
16563 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
16564 rtx m, rtx op, rtx before_param, rtx after_param,
16567 enum machine_mode used_mode;
16568 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
16571 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16572 rtx shift = NULL_RTX;
16575 emit_insn (gen_lwsync ());
16579 /* If this is smaller than SImode, we'll have to use SImode with
16581 if (mode == QImode || mode == HImode)
16585 if (MEM_ALIGN (used_m) >= 32)
16588 if (BYTES_BIG_ENDIAN)
16589 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
16591 shift = GEN_INT (ishift);
16592 used_m = change_address (used_m, SImode, 0);
16596 rtx addrSI, aligned_addr;
16597 int shift_mask = mode == QImode ? 0x18 : 0x10;
16599 addrSI = gen_lowpart_common (SImode,
16600 force_reg (Pmode, XEXP (used_m, 0)));
16601 addrSI = force_reg (SImode, addrSI);
16602 shift = gen_reg_rtx (SImode);
16604 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16605 GEN_INT (shift_mask)));
16606 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16608 aligned_addr = expand_binop (Pmode, and_optab,
16610 GEN_INT (-4), NULL_RTX,
16611 1, OPTAB_LIB_WIDEN);
16612 used_m = change_address (used_m, SImode, aligned_addr);
16613 set_mem_align (used_m, 32);
16615 /* It's safe to keep the old alias set of USED_M, because
16616 the operation is atomic and only affects the original
16620 if (GET_CODE (op) == NOT)
16622 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
16623 oldop = gen_rtx_NOT (SImode, oldop);
16626 oldop = lowpart_subreg (SImode, op, mode);
16632 newop = expand_binop (SImode, and_optab,
16633 oldop, GEN_INT (imask), NULL_RTX,
16634 1, OPTAB_LIB_WIDEN);
16635 emit_insn (gen_ashlsi3 (newop, newop, shift));
16638 case NOT: /* NAND */
16639 newop = expand_binop (SImode, ior_optab,
16640 oldop, GEN_INT (~imask), NULL_RTX,
16641 1, OPTAB_LIB_WIDEN);
16642 emit_insn (gen_rotlsi3 (newop, newop, shift));
16646 newop = expand_binop (SImode, ior_optab,
16647 oldop, GEN_INT (~imask), NULL_RTX,
16648 1, OPTAB_LIB_WIDEN);
16649 emit_insn (gen_rotlsi3 (newop, newop, shift));
16657 newop = expand_binop (SImode, and_optab,
16658 oldop, GEN_INT (imask), NULL_RTX,
16659 1, OPTAB_LIB_WIDEN);
16660 emit_insn (gen_ashlsi3 (newop, newop, shift));
16662 mask = gen_reg_rtx (SImode);
16663 emit_move_insn (mask, GEN_INT (imask));
16664 emit_insn (gen_ashlsi3 (mask, mask, shift));
16667 newop = gen_rtx_PLUS (SImode, m, newop);
16669 newop = gen_rtx_MINUS (SImode, m, newop);
16670 newop = gen_rtx_AND (SImode, newop, mask);
16671 newop = gen_rtx_IOR (SImode, newop,
16672 gen_rtx_AND (SImode,
16673 gen_rtx_NOT (SImode, mask),
16679 gcc_unreachable ();
16683 used_mode = SImode;
16684 before = gen_reg_rtx (used_mode);
16685 after = gen_reg_rtx (used_mode);
16690 before = before_param;
16691 after = after_param;
16693 if (before == NULL_RTX)
16694 before = gen_reg_rtx (used_mode);
16695 if (after == NULL_RTX)
16696 after = gen_reg_rtx (used_mode);
16699 if ((code == PLUS || code == MINUS)
16700 && used_mode != mode)
16701 the_op = op; /* Computed above. */
16702 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
16703 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
16704 else if (code == NOT)
16705 the_op = gen_rtx_fmt_ee (IOR, used_mode,
16706 gen_rtx_NOT (used_mode, m),
16707 gen_rtx_NOT (used_mode, op));
16709 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
16711 set_after = gen_rtx_SET (VOIDmode, after, the_op);
16712 set_before = gen_rtx_SET (VOIDmode, before, used_m);
16713 set_atomic = gen_rtx_SET (VOIDmode, used_m,
16714 gen_rtx_UNSPEC (used_mode,
16715 gen_rtvec (1, the_op),
16717 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
16719 if ((code == PLUS || code == MINUS) && used_mode != mode)
16720 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
16721 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
16723 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
16724 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
16726 /* Shift and mask the return values properly. */
16727 if (used_mode != mode && before_param)
16729 emit_insn (gen_lshrsi3 (before, before, shift));
16730 convert_move (before_param, before, 1);
16733 if (used_mode != mode && after_param)
16735 emit_insn (gen_lshrsi3 (after, after, shift));
16736 convert_move (after_param, after, 1);
16739 /* The previous sequence will end with a branch that's dependent on
16740 the conditional store, so placing an isync will ensure that no
16741 other instructions (especially, no load or store instructions)
16742 can start before the atomic operation completes. */
16744 emit_insn (gen_isync ());
16747 /* A subroutine of the atomic operation splitters. Jump to LABEL if
16748 COND is true. Mark the jump as unlikely to be taken. */
16751 emit_unlikely_jump (rtx cond, rtx label)
16753 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
16756 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
16757 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
16758 add_reg_note (x, REG_BR_PROB, very_unlikely);
16761 /* A subroutine of the atomic operation splitters. Emit a load-locked
16762 instruction in MODE. */
16765 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
16767 rtx (*fn) (rtx, rtx) = NULL;
16768 if (mode == SImode)
16769 fn = gen_load_locked_si;
16770 else if (mode == DImode)
16771 fn = gen_load_locked_di;
16772 emit_insn (fn (reg, mem));
16775 /* A subroutine of the atomic operation splitters. Emit a store-conditional
16776 instruction in MODE. */
16779 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
16781 rtx (*fn) (rtx, rtx, rtx) = NULL;
16782 if (mode == SImode)
16783 fn = gen_store_conditional_si;
16784 else if (mode == DImode)
16785 fn = gen_store_conditional_di;
16787 /* Emit sync before stwcx. to address PPC405 Erratum. */
16788 if (PPC405_ERRATUM77)
16789 emit_insn (gen_memory_barrier ());
16791 emit_insn (fn (res, mem, val));
16794 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
16795 to perform. MEM is the memory on which to operate. VAL is the second
16796 operand of the binary operator. BEFORE and AFTER are optional locations to
16797 return the value of MEM either before of after the operation. SCRATCH is
16798 a scratch register. */
16801 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
16802 rtx before, rtx after, rtx scratch)
16804 enum machine_mode mode = GET_MODE (mem);
16805 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16807 emit_insn (gen_lwsync ());
16809 label = gen_label_rtx ();
16810 emit_label (label);
16811 label = gen_rtx_LABEL_REF (VOIDmode, label);
16813 if (before == NULL_RTX)
16815 emit_load_locked (mode, before, mem);
16818 x = gen_rtx_IOR (mode,
16819 gen_rtx_NOT (mode, before),
16820 gen_rtx_NOT (mode, val));
16821 else if (code == AND)
16822 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
16824 x = gen_rtx_fmt_ee (code, mode, before, val);
16826 if (after != NULL_RTX)
16827 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
16828 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
16830 emit_store_conditional (mode, cond, mem, scratch);
16832 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16833 emit_unlikely_jump (x, label);
16835 emit_insn (gen_isync ());
16838 /* Expand an atomic compare and swap operation. MEM is the memory on which
16839 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
16840 value to be stored. SCRATCH is a scratch GPR. */
16843 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
16846 enum machine_mode mode = GET_MODE (mem);
16847 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16849 emit_insn (gen_lwsync ());
16851 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16852 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16853 emit_label (XEXP (label1, 0));
16855 emit_load_locked (mode, retval, mem);
16857 x = gen_rtx_COMPARE (CCmode, retval, oldval);
16858 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16860 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16861 emit_unlikely_jump (x, label2);
16863 emit_move_insn (scratch, newval);
16864 emit_store_conditional (mode, cond, mem, scratch);
16866 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16867 emit_unlikely_jump (x, label1);
16869 emit_insn (gen_isync ());
16870 emit_label (XEXP (label2, 0));
16873 /* Expand an atomic test and set operation. MEM is the memory on which
16874 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
16877 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
16879 enum machine_mode mode = GET_MODE (mem);
16880 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16882 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16883 emit_label (XEXP (label, 0));
16885 emit_load_locked (mode, retval, mem);
16886 emit_move_insn (scratch, val);
16887 emit_store_conditional (mode, cond, mem, scratch);
16889 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16890 emit_unlikely_jump (x, label);
16892 emit_insn (gen_isync ());
16896 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
16898 enum machine_mode mode = GET_MODE (mem);
16899 rtx addrSI, align, wdst, shift, mask;
16900 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
16901 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
16903 /* Shift amount for subword relative to aligned word. */
16904 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
16905 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
16906 shift = gen_reg_rtx (SImode);
16907 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
16908 GEN_INT (shift_mask)));
16909 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
16911 /* Shift and mask old value into position within word. */
16912 oldval = convert_modes (SImode, mode, oldval, 1);
16913 oldval = expand_binop (SImode, and_optab,
16914 oldval, GEN_INT (imask), NULL_RTX,
16915 1, OPTAB_LIB_WIDEN);
16916 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
16918 /* Shift and mask new value into position within word. */
16919 newval = convert_modes (SImode, mode, newval, 1);
16920 newval = expand_binop (SImode, and_optab,
16921 newval, GEN_INT (imask), NULL_RTX,
16922 1, OPTAB_LIB_WIDEN);
16923 emit_insn (gen_ashlsi3 (newval, newval, shift));
16925 /* Mask for insertion. */
16926 mask = gen_reg_rtx (SImode);
16927 emit_move_insn (mask, GEN_INT (imask));
16928 emit_insn (gen_ashlsi3 (mask, mask, shift));
16930 /* Address of aligned word containing subword. */
16931 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
16932 NULL_RTX, 1, OPTAB_LIB_WIDEN);
16933 mem = change_address (mem, SImode, align);
16934 set_mem_align (mem, 32);
16935 MEM_VOLATILE_P (mem) = 1;
16937 wdst = gen_reg_rtx (SImode);
16938 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
16939 oldval, newval, mem));
16941 /* Shift the result back. */
16942 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
16944 emit_move_insn (dst, gen_lowpart (mode, wdst));
16948 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
16949 rtx oldval, rtx newval, rtx mem,
16952 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
16954 emit_insn (gen_lwsync ());
16955 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16956 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
16957 emit_label (XEXP (label1, 0));
16959 emit_load_locked (SImode, scratch, mem);
16961 /* Mask subword within loaded value for comparison with oldval.
16962 Use UNSPEC_AND to avoid clobber.*/
16963 emit_insn (gen_rtx_SET (SImode, dest,
16964 gen_rtx_UNSPEC (SImode,
16965 gen_rtvec (2, scratch, mask),
16968 x = gen_rtx_COMPARE (CCmode, dest, oldval);
16969 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
16971 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16972 emit_unlikely_jump (x, label2);
16974 /* Clear subword within loaded value for insertion of new value. */
16975 emit_insn (gen_rtx_SET (SImode, scratch,
16976 gen_rtx_AND (SImode,
16977 gen_rtx_NOT (SImode, mask), scratch)));
16978 emit_insn (gen_iorsi3 (scratch, scratch, newval));
16979 emit_store_conditional (SImode, cond, mem, scratch);
16981 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
16982 emit_unlikely_jump (x, label1);
16984 emit_insn (gen_isync ());
16985 emit_label (XEXP (label2, 0));
16989 /* Emit instructions to move SRC to DST. Called by splitters for
16990 multi-register moves. It will emit at most one instruction for
16991 each register that is accessed; that is, it won't emit li/lis pairs
16992 (or equivalent for 64-bit code). One of SRC or DST must be a hard
16996 rs6000_split_multireg_move (rtx dst, rtx src)
16998 /* The register number of the first register being moved. */
17000 /* The mode that is to be moved. */
17001 enum machine_mode mode;
17002 /* The mode that the move is being done in, and its size. */
17003 enum machine_mode reg_mode;
17005 /* The number of registers that will be moved. */
17008 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17009 mode = GET_MODE (dst);
17010 nregs = hard_regno_nregs[reg][mode];
17011 if (FP_REGNO_P (reg))
17012 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17013 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17014 else if (ALTIVEC_REGNO_P (reg))
17015 reg_mode = V16QImode;
17016 else if (TARGET_E500_DOUBLE && mode == TFmode)
17019 reg_mode = word_mode;
17020 reg_mode_size = GET_MODE_SIZE (reg_mode);
17022 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17024 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17026 /* Move register range backwards, if we might have destructive
17029 for (i = nregs - 1; i >= 0; i--)
17030 emit_insn (gen_rtx_SET (VOIDmode,
17031 simplify_gen_subreg (reg_mode, dst, mode,
17032 i * reg_mode_size),
17033 simplify_gen_subreg (reg_mode, src, mode,
17034 i * reg_mode_size)));
17040 bool used_update = false;
17041 rtx restore_basereg = NULL_RTX;
17043 if (MEM_P (src) && INT_REGNO_P (reg))
17047 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17048 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17051 breg = XEXP (XEXP (src, 0), 0);
17052 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17053 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17054 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17055 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17056 src = replace_equiv_address (src, breg);
17058 else if (! rs6000_offsettable_memref_p (src))
17060 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17062 rtx basereg = XEXP (XEXP (src, 0), 0);
17065 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17066 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17067 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17068 used_update = true;
17071 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17072 XEXP (XEXP (src, 0), 1)));
17073 src = replace_equiv_address (src, basereg);
17077 rtx basereg = gen_rtx_REG (Pmode, reg);
17078 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17079 src = replace_equiv_address (src, basereg);
17083 breg = XEXP (src, 0);
17084 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17085 breg = XEXP (breg, 0);
17087 /* If the base register we are using to address memory is
17088 also a destination reg, then change that register last. */
17090 && REGNO (breg) >= REGNO (dst)
17091 && REGNO (breg) < REGNO (dst) + nregs)
17092 j = REGNO (breg) - REGNO (dst);
17094 else if (MEM_P (dst) && INT_REGNO_P (reg))
17098 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17099 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17102 breg = XEXP (XEXP (dst, 0), 0);
17103 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17104 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17105 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17107 /* We have to update the breg before doing the store.
17108 Use store with update, if available. */
17112 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17113 emit_insn (TARGET_32BIT
17114 ? (TARGET_POWERPC64
17115 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17116 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17117 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17118 used_update = true;
17121 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17122 dst = replace_equiv_address (dst, breg);
17124 else if (!rs6000_offsettable_memref_p (dst)
17125 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17127 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17129 rtx basereg = XEXP (XEXP (dst, 0), 0);
17132 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17133 emit_insn (gen_rtx_SET (VOIDmode,
17134 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17135 used_update = true;
17138 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17139 XEXP (XEXP (dst, 0), 1)));
17140 dst = replace_equiv_address (dst, basereg);
17144 rtx basereg = XEXP (XEXP (dst, 0), 0);
17145 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17146 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17148 && REG_P (offsetreg)
17149 && REGNO (basereg) != REGNO (offsetreg));
17150 if (REGNO (basereg) == 0)
17152 rtx tmp = offsetreg;
17153 offsetreg = basereg;
17156 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17157 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17158 dst = replace_equiv_address (dst, basereg);
17161 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17162 gcc_assert (rs6000_offsettable_memref_p (dst));
17165 for (i = 0; i < nregs; i++)
17167 /* Calculate index to next subword. */
17172 /* If compiler already emitted move of first word by
17173 store with update, no need to do anything. */
17174 if (j == 0 && used_update)
17177 emit_insn (gen_rtx_SET (VOIDmode,
17178 simplify_gen_subreg (reg_mode, dst, mode,
17179 j * reg_mode_size),
17180 simplify_gen_subreg (reg_mode, src, mode,
17181 j * reg_mode_size)));
17183 if (restore_basereg != NULL_RTX)
17184 emit_insn (restore_basereg);
17189 /* This page contains routines that are used to determine what the
17190 function prologue and epilogue code will do and write them out. */
17192 /* Return the first fixed-point register that is required to be
17193 saved. 32 if none. */
17196 first_reg_to_save (void)
17200 /* Find lowest numbered live register. */
17201 for (first_reg = 13; first_reg <= 31; first_reg++)
17202 if (df_regs_ever_live_p (first_reg)
17203 && (! call_used_regs[first_reg]
17204 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17205 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17206 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17207 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17212 && crtl->uses_pic_offset_table
17213 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17214 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17220 /* Similar, for FP regs. */
17223 first_fp_reg_to_save (void)
17227 /* Find lowest numbered live register. */
17228 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17229 if (df_regs_ever_live_p (first_reg))
17235 /* Similar, for AltiVec regs. */
17238 first_altivec_reg_to_save (void)
17242 /* Stack frame remains as is unless we are in AltiVec ABI. */
17243 if (! TARGET_ALTIVEC_ABI)
17244 return LAST_ALTIVEC_REGNO + 1;
17246 /* On Darwin, the unwind routines are compiled without
17247 TARGET_ALTIVEC, and use save_world to save/restore the
17248 altivec registers when necessary. */
17249 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17250 && ! TARGET_ALTIVEC)
17251 return FIRST_ALTIVEC_REGNO + 20;
17253 /* Find lowest numbered live register. */
17254 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17255 if (df_regs_ever_live_p (i))
17261 /* Return a 32-bit mask of the AltiVec registers we need to set in
17262 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17263 the 32-bit word is 0. */
17265 static unsigned int
17266 compute_vrsave_mask (void)
17268 unsigned int i, mask = 0;
17270 /* On Darwin, the unwind routines are compiled without
17271 TARGET_ALTIVEC, and use save_world to save/restore the
17272 call-saved altivec registers when necessary. */
17273 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17274 && ! TARGET_ALTIVEC)
17277 /* First, find out if we use _any_ altivec registers. */
17278 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
17279 if (df_regs_ever_live_p (i))
17280 mask |= ALTIVEC_REG_BIT (i);
17285 /* Next, remove the argument registers from the set. These must
17286 be in the VRSAVE mask set by the caller, so we don't need to add
17287 them in again. More importantly, the mask we compute here is
17288 used to generate CLOBBERs in the set_vrsave insn, and we do not
17289 wish the argument registers to die. */
17290 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
17291 mask &= ~ALTIVEC_REG_BIT (i);
17293 /* Similarly, remove the return value from the set. */
17296 diddle_return_value (is_altivec_return_reg, &yes);
17298 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
17304 /* For a very restricted set of circumstances, we can cut down the
17305 size of prologues/epilogues by calling our own save/restore-the-world
17309 compute_save_world_info (rs6000_stack_t *info_ptr)
17311 info_ptr->world_save_p = 1;
17312 info_ptr->world_save_p
17313 = (WORLD_SAVE_P (info_ptr)
17314 && DEFAULT_ABI == ABI_DARWIN
17315 && ! (cfun->calls_setjmp && flag_exceptions)
17316 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
17317 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
17318 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
17319 && info_ptr->cr_save_p);
17321 /* This will not work in conjunction with sibcalls. Make sure there
17322 are none. (This check is expensive, but seldom executed.) */
17323 if (WORLD_SAVE_P (info_ptr))
17326 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
17327 if ( GET_CODE (insn) == CALL_INSN
17328 && SIBLING_CALL_P (insn))
17330 info_ptr->world_save_p = 0;
17335 if (WORLD_SAVE_P (info_ptr))
17337 /* Even if we're not touching VRsave, make sure there's room on the
17338 stack for it, if it looks like we're calling SAVE_WORLD, which
17339 will attempt to save it. */
17340 info_ptr->vrsave_size = 4;
17342 /* If we are going to save the world, we need to save the link register too. */
17343 info_ptr->lr_save_p = 1;
17345 /* "Save" the VRsave register too if we're saving the world. */
17346 if (info_ptr->vrsave_mask == 0)
17347 info_ptr->vrsave_mask = compute_vrsave_mask ();
17349 /* Because the Darwin register save/restore routines only handle
17350 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
17352 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
17353 && (info_ptr->first_altivec_reg_save
17354 >= FIRST_SAVED_ALTIVEC_REGNO));
17361 is_altivec_return_reg (rtx reg, void *xyes)
17363 bool *yes = (bool *) xyes;
17364 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
17369 /* Calculate the stack information for the current function. This is
17370 complicated by having two separate calling sequences, the AIX calling
17371 sequence and the V.4 calling sequence.
17373 AIX (and Darwin/Mac OS X) stack frames look like:
17375 SP----> +---------------------------------------+
17376 | back chain to caller | 0 0
17377 +---------------------------------------+
17378 | saved CR | 4 8 (8-11)
17379 +---------------------------------------+
17381 +---------------------------------------+
17382 | reserved for compilers | 12 24
17383 +---------------------------------------+
17384 | reserved for binders | 16 32
17385 +---------------------------------------+
17386 | saved TOC pointer | 20 40
17387 +---------------------------------------+
17388 | Parameter save area (P) | 24 48
17389 +---------------------------------------+
17390 | Alloca space (A) | 24+P etc.
17391 +---------------------------------------+
17392 | Local variable space (L) | 24+P+A
17393 +---------------------------------------+
17394 | Float/int conversion temporary (X) | 24+P+A+L
17395 +---------------------------------------+
17396 | Save area for AltiVec registers (W) | 24+P+A+L+X
17397 +---------------------------------------+
17398 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
17399 +---------------------------------------+
17400 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
17401 +---------------------------------------+
17402 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
17403 +---------------------------------------+
17404 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
17405 +---------------------------------------+
17406 old SP->| back chain to caller's caller |
17407 +---------------------------------------+
17409 The required alignment for AIX configurations is two words (i.e., 8
17413 V.4 stack frames look like:
17415 SP----> +---------------------------------------+
17416 | back chain to caller | 0
17417 +---------------------------------------+
17418 | caller's saved LR | 4
17419 +---------------------------------------+
17420 | Parameter save area (P) | 8
17421 +---------------------------------------+
17422 | Alloca space (A) | 8+P
17423 +---------------------------------------+
17424 | Varargs save area (V) | 8+P+A
17425 +---------------------------------------+
17426 | Local variable space (L) | 8+P+A+V
17427 +---------------------------------------+
17428 | Float/int conversion temporary (X) | 8+P+A+V+L
17429 +---------------------------------------+
17430 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
17431 +---------------------------------------+
17432 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
17433 +---------------------------------------+
17434 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
17435 +---------------------------------------+
17436 | SPE: area for 64-bit GP registers |
17437 +---------------------------------------+
17438 | SPE alignment padding |
17439 +---------------------------------------+
17440 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
17441 +---------------------------------------+
17442 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
17443 +---------------------------------------+
17444 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
17445 +---------------------------------------+
17446 old SP->| back chain to caller's caller |
17447 +---------------------------------------+
17449 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
17450 given. (But note below and in sysv4.h that we require only 8 and
17451 may round up the size of our stack frame anyways. The historical
17452 reason is early versions of powerpc-linux which didn't properly
17453 align the stack at program startup. A happy side-effect is that
17454 -mno-eabi libraries can be used with -meabi programs.)
17456 The EABI configuration defaults to the V.4 layout. However,
17457 the stack alignment requirements may differ. If -mno-eabi is not
17458 given, the required stack alignment is 8 bytes; if -mno-eabi is
17459 given, the required alignment is 16 bytes. (But see V.4 comment
17462 #ifndef ABI_STACK_BOUNDARY
17463 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
17466 static rs6000_stack_t *
17467 rs6000_stack_info (void)
17469 static rs6000_stack_t info;
17470 rs6000_stack_t *info_ptr = &info;
17471 int reg_size = TARGET_32BIT ? 4 : 8;
17475 HOST_WIDE_INT non_fixed_size;
17477 memset (&info, 0, sizeof (info));
17481 /* Cache value so we don't rescan instruction chain over and over. */
17482 if (cfun->machine->insn_chain_scanned_p == 0)
17483 cfun->machine->insn_chain_scanned_p
17484 = spe_func_has_64bit_regs_p () + 1;
17485 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
17488 /* Select which calling sequence. */
17489 info_ptr->abi = DEFAULT_ABI;
17491 /* Calculate which registers need to be saved & save area size. */
17492 info_ptr->first_gp_reg_save = first_reg_to_save ();
17493 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
17494 even if it currently looks like we won't. Reload may need it to
17495 get at a constant; if so, it will have already created a constant
17496 pool entry for it. */
17497 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
17498 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
17499 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
17500 && crtl->uses_const_pool
17501 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
17502 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
17504 first_gp = info_ptr->first_gp_reg_save;
17506 info_ptr->gp_size = reg_size * (32 - first_gp);
17508 /* For the SPE, we have an additional upper 32-bits on each GPR.
17509 Ideally we should save the entire 64-bits only when the upper
17510 half is used in SIMD instructions. Since we only record
17511 registers live (not the size they are used in), this proves
17512 difficult because we'd have to traverse the instruction chain at
17513 the right time, taking reload into account. This is a real pain,
17514 so we opt to save the GPRs in 64-bits always if but one register
17515 gets used in 64-bits. Otherwise, all the registers in the frame
17516 get saved in 32-bits.
17518 So... since when we save all GPRs (except the SP) in 64-bits, the
17519 traditional GP save area will be empty. */
17520 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17521 info_ptr->gp_size = 0;
17523 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
17524 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
17526 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
17527 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
17528 - info_ptr->first_altivec_reg_save);
17530 /* Does this function call anything? */
17531 info_ptr->calls_p = (! current_function_is_leaf
17532 || cfun->machine->ra_needs_full_frame);
17534 /* Determine if we need to save the link register. */
17535 if ((DEFAULT_ABI == ABI_AIX
17537 && !TARGET_PROFILE_KERNEL)
17538 #ifdef TARGET_RELOCATABLE
17539 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
17541 || (info_ptr->first_fp_reg_save != 64
17542 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
17543 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
17544 || info_ptr->calls_p
17545 || rs6000_ra_ever_killed ())
17547 info_ptr->lr_save_p = 1;
17548 df_set_regs_ever_live (LR_REGNO, true);
17551 /* Determine if we need to save the condition code registers. */
17552 if (df_regs_ever_live_p (CR2_REGNO)
17553 || df_regs_ever_live_p (CR3_REGNO)
17554 || df_regs_ever_live_p (CR4_REGNO))
17556 info_ptr->cr_save_p = 1;
17557 if (DEFAULT_ABI == ABI_V4)
17558 info_ptr->cr_size = reg_size;
17561 /* If the current function calls __builtin_eh_return, then we need
17562 to allocate stack space for registers that will hold data for
17563 the exception handler. */
17564 if (crtl->calls_eh_return)
17567 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
17570 /* SPE saves EH registers in 64-bits. */
17571 ehrd_size = i * (TARGET_SPE_ABI
17572 && info_ptr->spe_64bit_regs_used != 0
17573 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
17578 /* Determine various sizes. */
17579 info_ptr->reg_size = reg_size;
17580 info_ptr->fixed_size = RS6000_SAVE_AREA;
17581 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
17582 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
17583 TARGET_ALTIVEC ? 16 : 8);
17584 if (FRAME_GROWS_DOWNWARD)
17585 info_ptr->vars_size
17586 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
17587 + info_ptr->parm_size,
17588 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
17589 - (info_ptr->fixed_size + info_ptr->vars_size
17590 + info_ptr->parm_size);
17592 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17593 info_ptr->spe_gp_size = 8 * (32 - first_gp);
17595 info_ptr->spe_gp_size = 0;
17597 if (TARGET_ALTIVEC_ABI)
17598 info_ptr->vrsave_mask = compute_vrsave_mask ();
17600 info_ptr->vrsave_mask = 0;
17602 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
17603 info_ptr->vrsave_size = 4;
17605 info_ptr->vrsave_size = 0;
17607 compute_save_world_info (info_ptr);
17609 /* Calculate the offsets. */
17610 switch (DEFAULT_ABI)
17614 gcc_unreachable ();
17618 info_ptr->fp_save_offset = - info_ptr->fp_size;
17619 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17621 if (TARGET_ALTIVEC_ABI)
17623 info_ptr->vrsave_save_offset
17624 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
17626 /* Align stack so vector save area is on a quadword boundary.
17627 The padding goes above the vectors. */
17628 if (info_ptr->altivec_size != 0)
17629 info_ptr->altivec_padding_size
17630 = info_ptr->vrsave_save_offset & 0xF;
17632 info_ptr->altivec_padding_size = 0;
17634 info_ptr->altivec_save_offset
17635 = info_ptr->vrsave_save_offset
17636 - info_ptr->altivec_padding_size
17637 - info_ptr->altivec_size;
17638 gcc_assert (info_ptr->altivec_size == 0
17639 || info_ptr->altivec_save_offset % 16 == 0);
17641 /* Adjust for AltiVec case. */
17642 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
17645 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
17646 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
17647 info_ptr->lr_save_offset = 2*reg_size;
17651 info_ptr->fp_save_offset = - info_ptr->fp_size;
17652 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
17653 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
17655 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
17657 /* Align stack so SPE GPR save area is aligned on a
17658 double-word boundary. */
17659 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
17660 info_ptr->spe_padding_size
17661 = 8 - (-info_ptr->cr_save_offset % 8);
17663 info_ptr->spe_padding_size = 0;
17665 info_ptr->spe_gp_save_offset
17666 = info_ptr->cr_save_offset
17667 - info_ptr->spe_padding_size
17668 - info_ptr->spe_gp_size;
17670 /* Adjust for SPE case. */
17671 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
17673 else if (TARGET_ALTIVEC_ABI)
17675 info_ptr->vrsave_save_offset
17676 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
17678 /* Align stack so vector save area is on a quadword boundary. */
17679 if (info_ptr->altivec_size != 0)
17680 info_ptr->altivec_padding_size
17681 = 16 - (-info_ptr->vrsave_save_offset % 16);
17683 info_ptr->altivec_padding_size = 0;
17685 info_ptr->altivec_save_offset
17686 = info_ptr->vrsave_save_offset
17687 - info_ptr->altivec_padding_size
17688 - info_ptr->altivec_size;
17690 /* Adjust for AltiVec case. */
17691 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
17694 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
17695 info_ptr->ehrd_offset -= ehrd_size;
17696 info_ptr->lr_save_offset = reg_size;
17700 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
17701 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
17702 + info_ptr->gp_size
17703 + info_ptr->altivec_size
17704 + info_ptr->altivec_padding_size
17705 + info_ptr->spe_gp_size
17706 + info_ptr->spe_padding_size
17708 + info_ptr->cr_size
17709 + info_ptr->vrsave_size,
17712 non_fixed_size = (info_ptr->vars_size
17713 + info_ptr->parm_size
17714 + info_ptr->save_size);
17716 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
17717 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
17719 /* Determine if we need to allocate any stack frame:
17721 For AIX we need to push the stack if a frame pointer is needed
17722 (because the stack might be dynamically adjusted), if we are
17723 debugging, if we make calls, or if the sum of fp_save, gp_save,
17724 and local variables are more than the space needed to save all
17725 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
17726 + 18*8 = 288 (GPR13 reserved).
17728 For V.4 we don't have the stack cushion that AIX uses, but assume
17729 that the debugger can handle stackless frames. */
17731 if (info_ptr->calls_p)
17732 info_ptr->push_p = 1;
17734 else if (DEFAULT_ABI == ABI_V4)
17735 info_ptr->push_p = non_fixed_size != 0;
17737 else if (frame_pointer_needed)
17738 info_ptr->push_p = 1;
17740 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
17741 info_ptr->push_p = 1;
17744 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
17746 /* Zero offsets if we're not saving those registers. */
17747 if (info_ptr->fp_size == 0)
17748 info_ptr->fp_save_offset = 0;
17750 if (info_ptr->gp_size == 0)
17751 info_ptr->gp_save_offset = 0;
17753 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
17754 info_ptr->altivec_save_offset = 0;
17756 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
17757 info_ptr->vrsave_save_offset = 0;
17759 if (! TARGET_SPE_ABI
17760 || info_ptr->spe_64bit_regs_used == 0
17761 || info_ptr->spe_gp_size == 0)
17762 info_ptr->spe_gp_save_offset = 0;
17764 if (! info_ptr->lr_save_p)
17765 info_ptr->lr_save_offset = 0;
17767 if (! info_ptr->cr_save_p)
17768 info_ptr->cr_save_offset = 0;
17773 /* Return true if the current function uses any GPRs in 64-bit SIMD
17777 spe_func_has_64bit_regs_p (void)
17781 /* Functions that save and restore all the call-saved registers will
17782 need to save/restore the registers in 64-bits. */
17783 if (crtl->calls_eh_return
17784 || cfun->calls_setjmp
17785 || crtl->has_nonlocal_goto)
17788 insns = get_insns ();
17790 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
17796 /* FIXME: This should be implemented with attributes...
17798 (set_attr "spe64" "true")....then,
17799 if (get_spe64(insn)) return true;
17801 It's the only reliable way to do the stuff below. */
17803 i = PATTERN (insn);
17804 if (GET_CODE (i) == SET)
17806 enum machine_mode mode = GET_MODE (SET_SRC (i));
17808 if (SPE_VECTOR_MODE (mode))
17810 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
17820 debug_stack_info (rs6000_stack_t *info)
17822 const char *abi_string;
17825 info = rs6000_stack_info ();
17827 fprintf (stderr, "\nStack information for function %s:\n",
17828 ((current_function_decl && DECL_NAME (current_function_decl))
17829 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
17834 default: abi_string = "Unknown"; break;
17835 case ABI_NONE: abi_string = "NONE"; break;
17836 case ABI_AIX: abi_string = "AIX"; break;
17837 case ABI_DARWIN: abi_string = "Darwin"; break;
17838 case ABI_V4: abi_string = "V.4"; break;
17841 fprintf (stderr, "\tABI = %5s\n", abi_string);
17843 if (TARGET_ALTIVEC_ABI)
17844 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
17846 if (TARGET_SPE_ABI)
17847 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
17849 if (info->first_gp_reg_save != 32)
17850 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
17852 if (info->first_fp_reg_save != 64)
17853 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
17855 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
17856 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
17857 info->first_altivec_reg_save);
17859 if (info->lr_save_p)
17860 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
17862 if (info->cr_save_p)
17863 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
17865 if (info->vrsave_mask)
17866 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
17869 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
17872 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
17874 if (info->gp_save_offset)
17875 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
17877 if (info->fp_save_offset)
17878 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
17880 if (info->altivec_save_offset)
17881 fprintf (stderr, "\taltivec_save_offset = %5d\n",
17882 info->altivec_save_offset);
17884 if (info->spe_gp_save_offset)
17885 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
17886 info->spe_gp_save_offset);
17888 if (info->vrsave_save_offset)
17889 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
17890 info->vrsave_save_offset);
17892 if (info->lr_save_offset)
17893 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
17895 if (info->cr_save_offset)
17896 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
17898 if (info->varargs_save_offset)
17899 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
17901 if (info->total_size)
17902 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17905 if (info->vars_size)
17906 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
17909 if (info->parm_size)
17910 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
17912 if (info->fixed_size)
17913 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
17916 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
17918 if (info->spe_gp_size)
17919 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
17922 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
17924 if (info->altivec_size)
17925 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
17927 if (info->vrsave_size)
17928 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
17930 if (info->altivec_padding_size)
17931 fprintf (stderr, "\taltivec_padding_size= %5d\n",
17932 info->altivec_padding_size);
17934 if (info->spe_padding_size)
17935 fprintf (stderr, "\tspe_padding_size = %5d\n",
17936 info->spe_padding_size);
17939 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
17941 if (info->save_size)
17942 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
17944 if (info->reg_size != 4)
17945 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
17947 fprintf (stderr, "\n");
17951 rs6000_return_addr (int count, rtx frame)
17953 /* Currently we don't optimize very well between prolog and body
17954 code and for PIC code the code can be actually quite bad, so
17955 don't try to be too clever here. */
17956 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
17958 cfun->machine->ra_needs_full_frame = 1;
17965 plus_constant (copy_to_reg
17966 (gen_rtx_MEM (Pmode,
17967 memory_address (Pmode, frame))),
17968 RETURN_ADDRESS_OFFSET)));
17971 cfun->machine->ra_need_lr = 1;
17972 return get_hard_reg_initial_val (Pmode, LR_REGNO);
17975 /* Say whether a function is a candidate for sibcall handling or not.
17976 We do not allow indirect calls to be optimized into sibling calls.
17977 Also, we can't do it if there are any vector parameters; there's
17978 nowhere to put the VRsave code so it works; note that functions with
17979 vector parameters are required to have a prototype, so the argument
17980 type info must be available here. (The tail recursion case can work
17981 with vector parameters, but there's no way to distinguish here.) */
17983 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
17988 if (TARGET_ALTIVEC_VRSAVE)
17990 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
17991 type; type = TREE_CHAIN (type))
17993 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
17997 if (DEFAULT_ABI == ABI_DARWIN
17998 || ((*targetm.binds_local_p) (decl)
17999 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18001 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18003 if (!lookup_attribute ("longcall", attr_list)
18004 || lookup_attribute ("shortcall", attr_list))
18011 /* NULL if INSN insn is valid within a low-overhead loop.
18012 Otherwise return why doloop cannot be applied.
18013 PowerPC uses the COUNT register for branch on table instructions. */
18015 static const char *
18016 rs6000_invalid_within_doloop (const_rtx insn)
18019 return "Function call in the loop.";
18022 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18023 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18024 return "Computed branch in the loop.";
18030 rs6000_ra_ever_killed (void)
18036 if (cfun->is_thunk)
18039 if (cfun->machine->lr_save_state)
18040 return cfun->machine->lr_save_state - 1;
18042 /* regs_ever_live has LR marked as used if any sibcalls are present,
18043 but this should not force saving and restoring in the
18044 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18045 clobbers LR, so that is inappropriate. */
18047 /* Also, the prologue can generate a store into LR that
18048 doesn't really count, like this:
18051 bcl to set PIC register
18055 When we're called from the epilogue, we need to avoid counting
18056 this as a store. */
18058 push_topmost_sequence ();
18059 top = get_insns ();
18060 pop_topmost_sequence ();
18061 reg = gen_rtx_REG (Pmode, LR_REGNO);
18063 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18069 if (!SIBLING_CALL_P (insn))
18072 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18074 else if (set_of (reg, insn) != NULL_RTX
18075 && !prologue_epilogue_contains (insn))
18082 /* Emit instructions needed to load the TOC register.
18083 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18084 a constant pool; or for SVR4 -fpic. */
18087 rs6000_emit_load_toc_table (int fromprolog)
18090 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18092 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18095 rtx lab, tmp1, tmp2, got;
18097 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18098 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18100 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18102 got = rs6000_got_sym ();
18103 tmp1 = tmp2 = dest;
18106 tmp1 = gen_reg_rtx (Pmode);
18107 tmp2 = gen_reg_rtx (Pmode);
18109 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18110 emit_move_insn (tmp1,
18111 gen_rtx_REG (Pmode, LR_REGNO));
18112 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18113 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18115 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18117 emit_insn (gen_load_toc_v4_pic_si ());
18118 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18120 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18123 rtx temp0 = (fromprolog
18124 ? gen_rtx_REG (Pmode, 0)
18125 : gen_reg_rtx (Pmode));
18131 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18132 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18134 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18135 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18137 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18138 emit_move_insn (dest,
18139 gen_rtx_REG (Pmode, LR_REGNO));
18140 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18146 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18147 lab = gen_label_rtx ();
18148 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18149 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18150 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
18152 emit_insn (gen_addsi3 (dest, temp0, dest));
18154 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
18156 /* This is for AIX code running in non-PIC ELF32. */
18159 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18160 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18162 emit_insn (gen_elf_high (dest, realsym));
18163 emit_insn (gen_elf_low (dest, dest, realsym));
18167 gcc_assert (DEFAULT_ABI == ABI_AIX);
18170 emit_insn (gen_load_toc_aix_si (dest));
18172 emit_insn (gen_load_toc_aix_di (dest));
18176 /* Emit instructions to restore the link register after determining where
18177 its value has been stored. */
18180 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
18182 rs6000_stack_t *info = rs6000_stack_info ();
18185 operands[0] = source;
18186 operands[1] = scratch;
18188 if (info->lr_save_p)
18190 rtx frame_rtx = stack_pointer_rtx;
18191 HOST_WIDE_INT sp_offset = 0;
18194 if (frame_pointer_needed
18195 || cfun->calls_alloca
18196 || info->total_size > 32767)
18198 tmp = gen_frame_mem (Pmode, frame_rtx);
18199 emit_move_insn (operands[1], tmp);
18200 frame_rtx = operands[1];
18202 else if (info->push_p)
18203 sp_offset = info->total_size;
18205 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
18206 tmp = gen_frame_mem (Pmode, tmp);
18207 emit_move_insn (tmp, operands[0]);
18210 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
18212 /* Freeze lr_save_p. We've just emitted rtl that depends on the
18213 state of lr_save_p so any change from here on would be a bug. In
18214 particular, stop rs6000_ra_ever_killed from considering the SET
18215 of lr we may have added just above. */
18216 cfun->machine->lr_save_state = info->lr_save_p + 1;
18219 static GTY(()) alias_set_type set = -1;
18222 get_TOC_alias_set (void)
18225 set = new_alias_set ();
18229 /* This returns nonzero if the current function uses the TOC. This is
18230 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
18231 is generated by the ABI_V4 load_toc_* patterns. */
18238 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
18241 rtx pat = PATTERN (insn);
18244 if (GET_CODE (pat) == PARALLEL)
18245 for (i = 0; i < XVECLEN (pat, 0); i++)
18247 rtx sub = XVECEXP (pat, 0, i);
18248 if (GET_CODE (sub) == USE)
18250 sub = XEXP (sub, 0);
18251 if (GET_CODE (sub) == UNSPEC
18252 && XINT (sub, 1) == UNSPEC_TOC)
18262 create_TOC_reference (rtx symbol)
18264 if (TARGET_DEBUG_ADDR)
18266 if (GET_CODE (symbol) == SYMBOL_REF)
18267 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
18271 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
18272 GET_RTX_NAME (GET_CODE (symbol)));
18273 debug_rtx (symbol);
18277 if (!can_create_pseudo_p ())
18278 df_set_regs_ever_live (TOC_REGISTER, true);
18279 return gen_rtx_PLUS (Pmode,
18280 gen_rtx_REG (Pmode, TOC_REGISTER),
18281 gen_rtx_CONST (Pmode,
18282 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol), UNSPEC_TOCREL)));
18285 /* Issue assembly directives that create a reference to the given DWARF
18286 FRAME_TABLE_LABEL from the current function section. */
18288 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
18290 fprintf (asm_out_file, "\t.ref %s\n",
18291 TARGET_STRIP_NAME_ENCODING (frame_table_label));
18294 /* If _Unwind_* has been called from within the same module,
18295 toc register is not guaranteed to be saved to 40(1) on function
18296 entry. Save it there in that case. */
18299 rs6000_aix_emit_builtin_unwind_init (void)
18302 rtx stack_top = gen_reg_rtx (Pmode);
18303 rtx opcode_addr = gen_reg_rtx (Pmode);
18304 rtx opcode = gen_reg_rtx (SImode);
18305 rtx tocompare = gen_reg_rtx (SImode);
18306 rtx no_toc_save_needed = gen_label_rtx ();
18308 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
18309 emit_move_insn (stack_top, mem);
18311 mem = gen_frame_mem (Pmode,
18312 gen_rtx_PLUS (Pmode, stack_top,
18313 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
18314 emit_move_insn (opcode_addr, mem);
18315 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
18316 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
18317 : 0xE8410028, SImode));
18319 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
18320 SImode, NULL_RTX, NULL_RTX,
18321 no_toc_save_needed, -1);
18323 mem = gen_frame_mem (Pmode,
18324 gen_rtx_PLUS (Pmode, stack_top,
18325 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
18326 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
18327 emit_label (no_toc_save_needed);
18330 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
18331 and the change to the stack pointer. */
18334 rs6000_emit_stack_tie (void)
18336 rtx mem = gen_frame_mem (BLKmode,
18337 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
18339 emit_insn (gen_stack_tie (mem));
18342 /* Emit the correct code for allocating stack space, as insns.
18343 If COPY_REG, make sure a copy of the old frame is left there.
18344 The generated code may use hard register 0 as a temporary. */
18347 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
18350 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
18351 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
18352 rtx todec = gen_int_mode (-size, Pmode);
18355 if (INTVAL (todec) != -size)
18357 warning (0, "stack frame too large");
18358 emit_insn (gen_trap ());
18362 if (crtl->limit_stack)
18364 if (REG_P (stack_limit_rtx)
18365 && REGNO (stack_limit_rtx) > 1
18366 && REGNO (stack_limit_rtx) <= 31)
18368 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
18369 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18372 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
18374 && DEFAULT_ABI == ABI_V4)
18376 rtx toload = gen_rtx_CONST (VOIDmode,
18377 gen_rtx_PLUS (Pmode,
18381 emit_insn (gen_elf_high (tmp_reg, toload));
18382 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
18383 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
18387 warning (0, "stack limit expression is not supported");
18391 emit_move_insn (copy_reg, stack_reg);
18395 /* Need a note here so that try_split doesn't get confused. */
18396 if (get_last_insn () == NULL_RTX)
18397 emit_note (NOTE_INSN_DELETED);
18398 insn = emit_move_insn (tmp_reg, todec);
18399 try_split (PATTERN (insn), insn, 0);
18403 insn = emit_insn (TARGET_32BIT
18404 ? gen_movsi_update_stack (stack_reg, stack_reg,
18406 : gen_movdi_di_update_stack (stack_reg, stack_reg,
18407 todec, stack_reg));
18408 /* Since we didn't use gen_frame_mem to generate the MEM, grab
18409 it now and set the alias set/attributes. The above gen_*_update
18410 calls will generate a PARALLEL with the MEM set being the first
18412 par = PATTERN (insn);
18413 gcc_assert (GET_CODE (par) == PARALLEL);
18414 set = XVECEXP (par, 0, 0);
18415 gcc_assert (GET_CODE (set) == SET);
18416 mem = SET_DEST (set);
18417 gcc_assert (MEM_P (mem));
18418 MEM_NOTRAP_P (mem) = 1;
18419 set_mem_alias_set (mem, get_frame_alias_set ());
18421 RTX_FRAME_RELATED_P (insn) = 1;
18422 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
18423 gen_rtx_SET (VOIDmode, stack_reg,
18424 gen_rtx_PLUS (Pmode, stack_reg,
18425 GEN_INT (-size))));
18428 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
18429 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
18430 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
18431 deduce these equivalences by itself so it wasn't necessary to hold
18432 its hand so much. */
18435 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
18436 rtx reg2, rtx rreg)
18440 /* copy_rtx will not make unique copies of registers, so we need to
18441 ensure we don't have unwanted sharing here. */
18443 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18446 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
18448 real = copy_rtx (PATTERN (insn));
18450 if (reg2 != NULL_RTX)
18451 real = replace_rtx (real, reg2, rreg);
18453 real = replace_rtx (real, reg,
18454 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
18455 STACK_POINTER_REGNUM),
18458 /* We expect that 'real' is either a SET or a PARALLEL containing
18459 SETs (and possibly other stuff). In a PARALLEL, all the SETs
18460 are important so they all have to be marked RTX_FRAME_RELATED_P. */
18462 if (GET_CODE (real) == SET)
18466 temp = simplify_rtx (SET_SRC (set));
18468 SET_SRC (set) = temp;
18469 temp = simplify_rtx (SET_DEST (set));
18471 SET_DEST (set) = temp;
18472 if (GET_CODE (SET_DEST (set)) == MEM)
18474 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18476 XEXP (SET_DEST (set), 0) = temp;
18483 gcc_assert (GET_CODE (real) == PARALLEL);
18484 for (i = 0; i < XVECLEN (real, 0); i++)
18485 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
18487 rtx set = XVECEXP (real, 0, i);
18489 temp = simplify_rtx (SET_SRC (set));
18491 SET_SRC (set) = temp;
18492 temp = simplify_rtx (SET_DEST (set));
18494 SET_DEST (set) = temp;
18495 if (GET_CODE (SET_DEST (set)) == MEM)
18497 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
18499 XEXP (SET_DEST (set), 0) = temp;
18501 RTX_FRAME_RELATED_P (set) = 1;
18505 RTX_FRAME_RELATED_P (insn) = 1;
18506 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
18509 /* Returns an insn that has a vrsave set operation with the
18510 appropriate CLOBBERs. */
18513 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
18516 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
18517 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
18520 = gen_rtx_SET (VOIDmode,
18522 gen_rtx_UNSPEC_VOLATILE (SImode,
18523 gen_rtvec (2, reg, vrsave),
18524 UNSPECV_SET_VRSAVE));
18528 /* We need to clobber the registers in the mask so the scheduler
18529 does not move sets to VRSAVE before sets of AltiVec registers.
18531 However, if the function receives nonlocal gotos, reload will set
18532 all call saved registers live. We will end up with:
18534 (set (reg 999) (mem))
18535 (parallel [ (set (reg vrsave) (unspec blah))
18536 (clobber (reg 999))])
18538 The clobber will cause the store into reg 999 to be dead, and
18539 flow will attempt to delete an epilogue insn. In this case, we
18540 need an unspec use/set of the register. */
18542 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18543 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
18545 if (!epiloguep || call_used_regs [i])
18546 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
18547 gen_rtx_REG (V4SImode, i));
18550 rtx reg = gen_rtx_REG (V4SImode, i);
18553 = gen_rtx_SET (VOIDmode,
18555 gen_rtx_UNSPEC (V4SImode,
18556 gen_rtvec (1, reg), 27));
18560 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
18562 for (i = 0; i < nclobs; ++i)
18563 XVECEXP (insn, 0, i) = clobs[i];
18568 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
18569 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
18572 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
18573 unsigned int regno, int offset, HOST_WIDE_INT total_size)
18575 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
18576 rtx replacea, replaceb;
18578 int_rtx = GEN_INT (offset);
18580 /* Some cases that need register indexed addressing. */
18581 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
18582 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
18583 || (TARGET_E500_DOUBLE && mode == DFmode)
18585 && SPE_VECTOR_MODE (mode)
18586 && !SPE_CONST_OFFSET_OK (offset)))
18588 /* Whomever calls us must make sure r11 is available in the
18589 flow path of instructions in the prologue. */
18590 offset_rtx = gen_rtx_REG (Pmode, 11);
18591 emit_move_insn (offset_rtx, int_rtx);
18593 replacea = offset_rtx;
18594 replaceb = int_rtx;
18598 offset_rtx = int_rtx;
18599 replacea = NULL_RTX;
18600 replaceb = NULL_RTX;
18603 reg = gen_rtx_REG (mode, regno);
18604 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
18605 mem = gen_frame_mem (mode, addr);
18607 insn = emit_move_insn (mem, reg);
18609 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
18612 /* Emit an offset memory reference suitable for a frame store, while
18613 converting to a valid addressing mode. */
18616 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
18618 rtx int_rtx, offset_rtx;
18620 int_rtx = GEN_INT (offset);
18622 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
18623 || (TARGET_E500_DOUBLE && mode == DFmode))
18625 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
18626 emit_move_insn (offset_rtx, int_rtx);
18629 offset_rtx = int_rtx;
18631 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
18634 /* Look for user-defined global regs. We should not save and restore these,
18635 and cannot use stmw/lmw if there are any in its range. */
18638 no_global_regs_above (int first, bool gpr)
18641 int last = gpr ? 32 : 64;
18642 for (i = first; i < last; i++)
18643 if (global_regs[i])
18648 #ifndef TARGET_FIX_AND_CONTINUE
18649 #define TARGET_FIX_AND_CONTINUE 0
18652 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
18653 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
18654 #define LAST_SAVRES_REGISTER 31
18655 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
18657 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
18659 /* Temporary holding space for an out-of-line register save/restore
18661 static char savres_routine_name[30];
18663 /* Return the name for an out-of-line register save/restore routine.
18664 We are saving/restoring GPRs if GPR is true. */
18667 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
18668 bool savep, bool gpr, bool lr)
18670 const char *prefix = "";
18671 const char *suffix = "";
18673 /* Different targets are supposed to define
18674 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
18675 routine name could be defined with:
18677 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
18679 This is a nice idea in practice, but in reality, things are
18680 complicated in several ways:
18682 - ELF targets have save/restore routines for GPRs.
18684 - SPE targets use different prefixes for 32/64-bit registers, and
18685 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
18687 - PPC64 ELF targets have routines for save/restore of GPRs that
18688 differ in what they do with the link register, so having a set
18689 prefix doesn't work. (We only use one of the save routines at
18690 the moment, though.)
18692 - PPC32 elf targets have "exit" versions of the restore routines
18693 that restore the link register and can save some extra space.
18694 These require an extra suffix. (There are also "tail" versions
18695 of the restore routines and "GOT" versions of the save routines,
18696 but we don't generate those at present. Same problems apply,
18699 We deal with all this by synthesizing our own prefix/suffix and
18700 using that for the simple sprintf call shown above. */
18703 /* No floating point saves on the SPE. */
18707 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
18709 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
18714 else if (DEFAULT_ABI == ABI_V4)
18720 prefix = savep ? "_savegpr_" : "_restgpr_";
18722 prefix = savep ? "_savefpr_" : "_restfpr_";
18727 else if (DEFAULT_ABI == ABI_AIX)
18729 #ifndef POWERPC_LINUX
18730 /* No out-of-line save/restore routines for GPRs on AIX. */
18731 gcc_assert (!TARGET_AIX || !gpr);
18737 ? (lr ? "_savegpr0_" : "_savegpr1_")
18738 : (lr ? "_restgpr0_" : "_restgpr1_"));
18739 #ifdef POWERPC_LINUX
18741 prefix = (savep ? "_savefpr_" : "_restfpr_");
18745 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
18746 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
18749 else if (DEFAULT_ABI == ABI_DARWIN)
18750 sorry ("Out-of-line save/restore routines not supported on Darwin");
18752 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
18754 return savres_routine_name;
18757 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
18758 We are saving/restoring GPRs if GPR is true. */
18761 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
18764 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
18766 int select = ((savep ? 1 : 0) << 2
18768 /* On the SPE, we never have any FPRs, but we do have
18769 32/64-bit versions of the routines. */
18770 ? (info->spe_64bit_regs_used ? 1 : 0)
18771 : (gpr ? 1 : 0)) << 1)
18774 /* Don't generate bogus routine names. */
18775 gcc_assert (FIRST_SAVRES_REGISTER <= regno
18776 && regno <= LAST_SAVRES_REGISTER);
18778 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
18784 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
18786 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
18787 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
18788 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
18794 /* Emit a sequence of insns, including a stack tie if needed, for
18795 resetting the stack pointer. If SAVRES is true, then don't reset the
18796 stack pointer, but move the base of the frame into r11 for use by
18797 out-of-line register restore routines. */
18800 rs6000_emit_stack_reset (rs6000_stack_t *info,
18801 rtx sp_reg_rtx, rtx frame_reg_rtx,
18802 int sp_offset, bool savres)
18804 /* This blockage is needed so that sched doesn't decide to move
18805 the sp change before the register restores. */
18806 if (frame_reg_rtx != sp_reg_rtx
18808 && info->spe_64bit_regs_used != 0
18809 && info->first_gp_reg_save != 32))
18810 rs6000_emit_stack_tie ();
18812 if (frame_reg_rtx != sp_reg_rtx)
18814 if (sp_offset != 0)
18816 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
18817 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
18818 GEN_INT (sp_offset)));
18821 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
18823 else if (sp_offset != 0)
18825 /* If we are restoring registers out-of-line, we will be using the
18826 "exit" variants of the restore routines, which will reset the
18827 stack for us. But we do need to point r11 into the right place
18828 for those routines. */
18829 rtx dest_reg = (savres
18830 ? gen_rtx_REG (Pmode, 11)
18833 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
18834 GEN_INT (sp_offset)));
18841 /* Construct a parallel rtx describing the effect of a call to an
18842 out-of-line register save/restore routine. */
18845 rs6000_make_savres_rtx (rs6000_stack_t *info,
18846 rtx frame_reg_rtx, int save_area_offset,
18847 enum machine_mode reg_mode,
18848 bool savep, bool gpr, bool lr)
18851 int offset, start_reg, end_reg, n_regs;
18852 int reg_size = GET_MODE_SIZE (reg_mode);
18858 ? info->first_gp_reg_save
18859 : info->first_fp_reg_save);
18860 end_reg = gpr ? 32 : 64;
18861 n_regs = end_reg - start_reg;
18862 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
18865 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
18867 RTVEC_ELT (p, offset++)
18868 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
18870 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
18871 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
18872 RTVEC_ELT (p, offset++)
18873 = gen_rtx_USE (VOIDmode,
18874 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
18878 for (i = 0; i < end_reg - start_reg; i++)
18880 rtx addr, reg, mem;
18881 reg = gen_rtx_REG (reg_mode, start_reg + i);
18882 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18883 GEN_INT (save_area_offset + reg_size*i));
18884 mem = gen_frame_mem (reg_mode, addr);
18886 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
18888 savep ? reg : mem);
18893 rtx addr, reg, mem;
18894 reg = gen_rtx_REG (Pmode, 0);
18895 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
18896 GEN_INT (info->lr_save_offset));
18897 mem = gen_frame_mem (Pmode, addr);
18898 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
18901 return gen_rtx_PARALLEL (VOIDmode, p);
18904 /* Determine whether the gp REG is really used. */
18907 rs6000_reg_live_or_pic_offset_p (int reg)
18909 return ((df_regs_ever_live_p (reg)
18910 && (!call_used_regs[reg]
18911 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18912 && TARGET_TOC && TARGET_MINIMAL_TOC)))
18913 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18914 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18915 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
18919 SAVRES_MULTIPLE = 0x1,
18920 SAVRES_INLINE_FPRS = 0x2,
18921 SAVRES_INLINE_GPRS = 0x4,
18922 SAVRES_NOINLINE_GPRS_SAVES_LR = 0x8,
18923 SAVRES_NOINLINE_FPRS_SAVES_LR = 0x10,
18924 SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x20
18927 /* Determine the strategy for savings/restoring registers. */
18930 rs6000_savres_strategy (rs6000_stack_t *info, bool savep,
18931 int using_static_chain_p, int sibcall)
18933 bool using_multiple_p;
18935 bool savres_fprs_inline;
18936 bool savres_gprs_inline;
18937 bool noclobber_global_gprs
18938 = no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true);
18941 using_multiple_p = (TARGET_MULTIPLE && ! TARGET_POWERPC64
18942 && (!TARGET_SPE_ABI
18943 || info->spe_64bit_regs_used == 0)
18944 && info->first_gp_reg_save < 31
18945 && noclobber_global_gprs);
18946 /* Don't bother to try to save things out-of-line if r11 is occupied
18947 by the static chain. It would require too much fiddling and the
18948 static chain is rarely used anyway. */
18949 common = (using_static_chain_p
18951 || crtl->calls_eh_return
18952 || !info->lr_save_p
18953 || cfun->machine->ra_need_lr
18954 || info->total_size > 32767);
18955 savres_fprs_inline = (common
18956 || info->first_fp_reg_save == 64
18957 || !no_global_regs_above (info->first_fp_reg_save,
18959 /* The out-of-line FP routines use
18960 double-precision stores; we can't use those
18961 routines if we don't have such stores. */
18962 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18963 || FP_SAVE_INLINE (info->first_fp_reg_save));
18964 savres_gprs_inline = (common
18965 /* Saving CR interferes with the exit routines
18966 used on the SPE, so just punt here. */
18969 && info->spe_64bit_regs_used != 0
18970 && info->cr_save_p != 0)
18971 || info->first_gp_reg_save == 32
18972 || !noclobber_global_gprs
18973 || GP_SAVE_INLINE (info->first_gp_reg_save));
18976 /* If we are going to use store multiple, then don't even bother
18977 with the out-of-line routines, since the store-multiple instruction
18978 will always be smaller. */
18979 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
18982 /* The situation is more complicated with load multiple. We'd
18983 prefer to use the out-of-line routines for restores, since the
18984 "exit" out-of-line routines can handle the restore of LR and
18985 the frame teardown. But we can only use the out-of-line
18986 routines if we know that we've used store multiple or
18987 out-of-line routines in the prologue, i.e. if we've saved all
18988 the registers from first_gp_reg_save. Otherwise, we risk
18989 loading garbage from the stack. Furthermore, we can only use
18990 the "exit" out-of-line gpr restore if we haven't saved any
18992 bool saved_all = !savres_gprs_inline || using_multiple_p;
18994 if (saved_all && info->first_fp_reg_save != 64)
18995 /* We can't use the exit routine; use load multiple if it's
18997 savres_gprs_inline = savres_gprs_inline || using_multiple_p;
19000 strategy = (using_multiple_p
19001 | (savres_fprs_inline << 1)
19002 | (savres_gprs_inline << 2));
19003 #ifdef POWERPC_LINUX
19006 if (!savres_fprs_inline)
19007 strategy |= SAVRES_NOINLINE_FPRS_SAVES_LR;
19008 else if (!savres_gprs_inline && info->first_fp_reg_save == 64)
19009 strategy |= SAVRES_NOINLINE_GPRS_SAVES_LR;
19012 if (TARGET_AIX && !savres_fprs_inline)
19013 strategy |= SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR;
19018 /* Emit function prologue as insns. */
19021 rs6000_emit_prologue (void)
19023 rs6000_stack_t *info = rs6000_stack_info ();
19024 enum machine_mode reg_mode = Pmode;
19025 int reg_size = TARGET_32BIT ? 4 : 8;
19026 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19027 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19028 rtx frame_reg_rtx = sp_reg_rtx;
19029 rtx cr_save_rtx = NULL_RTX;
19032 int saving_FPRs_inline;
19033 int saving_GPRs_inline;
19034 int using_store_multiple;
19035 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19036 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19037 && call_used_regs[STATIC_CHAIN_REGNUM]);
19038 HOST_WIDE_INT sp_offset = 0;
19040 if (TARGET_FIX_AND_CONTINUE)
19042 /* gdb on darwin arranges to forward a function from the old
19043 address by modifying the first 5 instructions of the function
19044 to branch to the overriding function. This is necessary to
19045 permit function pointers that point to the old function to
19046 actually forward to the new function. */
19047 emit_insn (gen_nop ());
19048 emit_insn (gen_nop ());
19049 emit_insn (gen_nop ());
19050 emit_insn (gen_nop ());
19051 emit_insn (gen_nop ());
19054 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19056 reg_mode = V2SImode;
19060 strategy = rs6000_savres_strategy (info, /*savep=*/true,
19061 /*static_chain_p=*/using_static_chain_p,
19063 using_store_multiple = strategy & SAVRES_MULTIPLE;
19064 saving_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19065 saving_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19067 /* For V.4, update stack before we do any saving and set back pointer. */
19068 if (! WORLD_SAVE_P (info)
19070 && (DEFAULT_ABI == ABI_V4
19071 || crtl->calls_eh_return))
19073 bool need_r11 = (TARGET_SPE
19074 ? (!saving_GPRs_inline
19075 && info->spe_64bit_regs_used == 0)
19076 : (!saving_FPRs_inline || !saving_GPRs_inline));
19077 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19079 if (info->total_size < 32767)
19080 sp_offset = info->total_size;
19082 frame_reg_rtx = copy_reg;
19083 else if (info->cr_save_p
19085 || info->first_fp_reg_save < 64
19086 || info->first_gp_reg_save < 32
19087 || info->altivec_size != 0
19088 || info->vrsave_mask != 0
19089 || crtl->calls_eh_return)
19091 copy_reg = frame_ptr_rtx;
19092 frame_reg_rtx = copy_reg;
19096 /* The prologue won't be saving any regs so there is no need
19097 to set up a frame register to access any frame save area.
19098 We also won't be using sp_offset anywhere below, but set
19099 the correct value anyway to protect against future
19100 changes to this function. */
19101 sp_offset = info->total_size;
19103 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19104 if (frame_reg_rtx != sp_reg_rtx)
19105 rs6000_emit_stack_tie ();
19108 /* Handle world saves specially here. */
19109 if (WORLD_SAVE_P (info))
19116 /* save_world expects lr in r0. */
19117 reg0 = gen_rtx_REG (Pmode, 0);
19118 if (info->lr_save_p)
19120 insn = emit_move_insn (reg0,
19121 gen_rtx_REG (Pmode, LR_REGNO));
19122 RTX_FRAME_RELATED_P (insn) = 1;
19125 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19126 assumptions about the offsets of various bits of the stack
19128 gcc_assert (info->gp_save_offset == -220
19129 && info->fp_save_offset == -144
19130 && info->lr_save_offset == 8
19131 && info->cr_save_offset == 4
19134 && (!crtl->calls_eh_return
19135 || info->ehrd_offset == -432)
19136 && info->vrsave_save_offset == -224
19137 && info->altivec_save_offset == -416);
19139 treg = gen_rtx_REG (SImode, 11);
19140 emit_move_insn (treg, GEN_INT (-info->total_size));
19142 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
19143 in R11. It also clobbers R12, so beware! */
19145 /* Preserve CR2 for save_world prologues */
19147 sz += 32 - info->first_gp_reg_save;
19148 sz += 64 - info->first_fp_reg_save;
19149 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
19150 p = rtvec_alloc (sz);
19152 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
19153 gen_rtx_REG (SImode,
19155 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19156 gen_rtx_SYMBOL_REF (Pmode,
19158 /* We do floats first so that the instruction pattern matches
19160 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19162 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19163 ? DFmode : SFmode),
19164 info->first_fp_reg_save + i);
19165 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19166 GEN_INT (info->fp_save_offset
19167 + sp_offset + 8 * i));
19168 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19169 ? DFmode : SFmode), addr);
19171 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19173 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19175 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19176 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19177 GEN_INT (info->altivec_save_offset
19178 + sp_offset + 16 * i));
19179 rtx mem = gen_frame_mem (V4SImode, addr);
19181 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19183 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19185 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19186 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19187 GEN_INT (info->gp_save_offset
19188 + sp_offset + reg_size * i));
19189 rtx mem = gen_frame_mem (reg_mode, addr);
19191 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19195 /* CR register traditionally saved as CR2. */
19196 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19197 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19198 GEN_INT (info->cr_save_offset
19200 rtx mem = gen_frame_mem (reg_mode, addr);
19202 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
19204 /* Explain about use of R0. */
19205 if (info->lr_save_p)
19207 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19208 GEN_INT (info->lr_save_offset
19210 rtx mem = gen_frame_mem (reg_mode, addr);
19212 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
19214 /* Explain what happens to the stack pointer. */
19216 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
19217 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
19220 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19221 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19222 treg, GEN_INT (-info->total_size));
19223 sp_offset = info->total_size;
19226 /* If we use the link register, get it into r0. */
19227 if (!WORLD_SAVE_P (info) && info->lr_save_p)
19229 rtx addr, reg, mem;
19231 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
19232 gen_rtx_REG (Pmode, LR_REGNO));
19233 RTX_FRAME_RELATED_P (insn) = 1;
19235 if (!(strategy & (SAVRES_NOINLINE_GPRS_SAVES_LR
19236 | SAVRES_NOINLINE_FPRS_SAVES_LR)))
19238 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19239 GEN_INT (info->lr_save_offset + sp_offset));
19240 reg = gen_rtx_REG (Pmode, 0);
19241 mem = gen_rtx_MEM (Pmode, addr);
19242 /* This should not be of rs6000_sr_alias_set, because of
19243 __builtin_return_address. */
19245 insn = emit_move_insn (mem, reg);
19246 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19247 NULL_RTX, NULL_RTX);
19251 /* If we need to save CR, put it into r12 or r11. */
19252 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
19257 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
19259 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19260 RTX_FRAME_RELATED_P (insn) = 1;
19261 /* Now, there's no way that dwarf2out_frame_debug_expr is going
19262 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
19263 But that's OK. All we have to do is specify that _one_ condition
19264 code register is saved in this stack slot. The thrower's epilogue
19265 will then restore all the call-saved registers.
19266 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
19267 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
19268 gen_rtx_REG (SImode, CR2_REGNO));
19269 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19272 /* Do any required saving of fpr's. If only one or two to save, do
19273 it ourselves. Otherwise, call function. */
19274 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
19277 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
19278 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
19279 && ! call_used_regs[info->first_fp_reg_save+i]))
19280 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
19281 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19283 info->first_fp_reg_save + i,
19284 info->fp_save_offset + sp_offset + 8 * i,
19287 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
19291 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19292 info->fp_save_offset + sp_offset,
19294 /*savep=*/true, /*gpr=*/false,
19296 & SAVRES_NOINLINE_FPRS_SAVES_LR)
19298 insn = emit_insn (par);
19299 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19300 NULL_RTX, NULL_RTX);
19303 /* Save GPRs. This is done as a PARALLEL if we are using
19304 the store-multiple instructions. */
19305 if (!WORLD_SAVE_P (info)
19307 && info->spe_64bit_regs_used != 0
19308 && info->first_gp_reg_save != 32)
19311 rtx spe_save_area_ptr;
19313 /* Determine whether we can address all of the registers that need
19314 to be saved with an offset from the stack pointer that fits in
19315 the small const field for SPE memory instructions. */
19316 int spe_regs_addressable_via_sp
19317 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
19318 + (32 - info->first_gp_reg_save - 1) * reg_size)
19319 && saving_GPRs_inline);
19322 if (spe_regs_addressable_via_sp)
19324 spe_save_area_ptr = frame_reg_rtx;
19325 spe_offset = info->spe_gp_save_offset + sp_offset;
19329 /* Make r11 point to the start of the SPE save area. We need
19330 to be careful here if r11 is holding the static chain. If
19331 it is, then temporarily save it in r0. We would use r0 as
19332 our base register here, but using r0 as a base register in
19333 loads and stores means something different from what we
19335 int ool_adjust = (saving_GPRs_inline
19337 : (info->first_gp_reg_save
19338 - (FIRST_SAVRES_REGISTER+1))*8);
19339 HOST_WIDE_INT offset = (info->spe_gp_save_offset
19340 + sp_offset - ool_adjust);
19342 if (using_static_chain_p)
19344 rtx r0 = gen_rtx_REG (Pmode, 0);
19345 gcc_assert (info->first_gp_reg_save > 11);
19347 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
19350 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
19351 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
19353 GEN_INT (offset)));
19354 /* We need to make sure the move to r11 gets noted for
19355 properly outputting unwind information. */
19356 if (!saving_GPRs_inline)
19357 rs6000_frame_related (insn, frame_reg_rtx, offset,
19358 NULL_RTX, NULL_RTX);
19362 if (saving_GPRs_inline)
19364 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19365 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19367 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19368 rtx offset, addr, mem;
19370 /* We're doing all this to ensure that the offset fits into
19371 the immediate offset of 'evstdd'. */
19372 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
19374 offset = GEN_INT (reg_size * i + spe_offset);
19375 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
19376 mem = gen_rtx_MEM (V2SImode, addr);
19378 insn = emit_move_insn (mem, reg);
19380 rs6000_frame_related (insn, spe_save_area_ptr,
19381 info->spe_gp_save_offset
19382 + sp_offset + reg_size * i,
19383 offset, const0_rtx);
19390 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
19392 /*savep=*/true, /*gpr=*/true,
19394 insn = emit_insn (par);
19395 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19396 NULL_RTX, NULL_RTX);
19400 /* Move the static chain pointer back. */
19401 if (using_static_chain_p && !spe_regs_addressable_via_sp)
19402 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
19404 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
19408 /* Need to adjust r11 (r12) if we saved any FPRs. */
19409 if (info->first_fp_reg_save != 64)
19411 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
19413 rtx offset = GEN_INT (sp_offset
19414 + (-8 * (64-info->first_fp_reg_save)));
19415 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
19418 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
19419 info->gp_save_offset + sp_offset,
19421 /*savep=*/true, /*gpr=*/true,
19423 & SAVRES_NOINLINE_GPRS_SAVES_LR)
19425 insn = emit_insn (par);
19426 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19427 NULL_RTX, NULL_RTX);
19429 else if (!WORLD_SAVE_P (info) && using_store_multiple)
19433 p = rtvec_alloc (32 - info->first_gp_reg_save);
19434 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19436 rtx addr, reg, mem;
19437 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19438 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19439 GEN_INT (info->gp_save_offset
19442 mem = gen_frame_mem (reg_mode, addr);
19444 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
19446 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19447 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19448 NULL_RTX, NULL_RTX);
19450 else if (!WORLD_SAVE_P (info))
19453 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19454 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
19456 rtx addr, reg, mem;
19457 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19459 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19460 GEN_INT (info->gp_save_offset
19463 mem = gen_frame_mem (reg_mode, addr);
19465 insn = emit_move_insn (mem, reg);
19466 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19467 NULL_RTX, NULL_RTX);
19471 /* ??? There's no need to emit actual instructions here, but it's the
19472 easiest way to get the frame unwind information emitted. */
19473 if (crtl->calls_eh_return)
19475 unsigned int i, regno;
19477 /* In AIX ABI we need to pretend we save r2 here. */
19480 rtx addr, reg, mem;
19482 reg = gen_rtx_REG (reg_mode, 2);
19483 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19484 GEN_INT (sp_offset + 5 * reg_size));
19485 mem = gen_frame_mem (reg_mode, addr);
19487 insn = emit_move_insn (mem, reg);
19488 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19489 NULL_RTX, NULL_RTX);
19490 PATTERN (insn) = gen_blockage ();
19495 regno = EH_RETURN_DATA_REGNO (i);
19496 if (regno == INVALID_REGNUM)
19499 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
19500 info->ehrd_offset + sp_offset
19501 + reg_size * (int) i,
19506 /* Save CR if we use any that must be preserved. */
19507 if (!WORLD_SAVE_P (info) && info->cr_save_p)
19509 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19510 GEN_INT (info->cr_save_offset + sp_offset));
19511 rtx mem = gen_frame_mem (SImode, addr);
19512 /* See the large comment above about why CR2_REGNO is used. */
19513 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
19515 /* If r12 was used to hold the original sp, copy cr into r0 now
19517 if (REGNO (frame_reg_rtx) == 12)
19521 cr_save_rtx = gen_rtx_REG (SImode, 0);
19522 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
19523 RTX_FRAME_RELATED_P (insn) = 1;
19524 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
19525 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
19527 insn = emit_move_insn (mem, cr_save_rtx);
19529 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19530 NULL_RTX, NULL_RTX);
19533 /* Update stack and set back pointer unless this is V.4,
19534 for which it was done previously. */
19535 if (!WORLD_SAVE_P (info) && info->push_p
19536 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
19538 rtx copy_reg = NULL;
19540 if (info->total_size < 32767)
19541 sp_offset = info->total_size;
19542 else if (info->altivec_size != 0
19543 || info->vrsave_mask != 0)
19545 copy_reg = frame_ptr_rtx;
19546 frame_reg_rtx = copy_reg;
19549 sp_offset = info->total_size;
19550 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19551 if (frame_reg_rtx != sp_reg_rtx)
19552 rs6000_emit_stack_tie ();
19555 /* Set frame pointer, if needed. */
19556 if (frame_pointer_needed)
19558 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
19560 RTX_FRAME_RELATED_P (insn) = 1;
19563 /* Save AltiVec registers if needed. Save here because the red zone does
19564 not include AltiVec registers. */
19565 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
19569 /* There should be a non inline version of this, for when we
19570 are saving lots of vector registers. */
19571 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
19572 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19574 rtx areg, savereg, mem;
19577 offset = info->altivec_save_offset + sp_offset
19578 + 16 * (i - info->first_altivec_reg_save);
19580 savereg = gen_rtx_REG (V4SImode, i);
19582 areg = gen_rtx_REG (Pmode, 0);
19583 emit_move_insn (areg, GEN_INT (offset));
19585 /* AltiVec addressing mode is [reg+reg]. */
19586 mem = gen_frame_mem (V4SImode,
19587 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
19589 insn = emit_move_insn (mem, savereg);
19591 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
19592 areg, GEN_INT (offset));
19596 /* VRSAVE is a bit vector representing which AltiVec registers
19597 are used. The OS uses this to determine which vector
19598 registers to save on a context switch. We need to save
19599 VRSAVE on the stack frame, add whatever AltiVec registers we
19600 used in this function, and do the corresponding magic in the
19603 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
19604 && info->vrsave_mask != 0)
19606 rtx reg, mem, vrsave;
19609 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
19610 as frame_reg_rtx and r11 as the static chain pointer for
19611 nested functions. */
19612 reg = gen_rtx_REG (SImode, 0);
19613 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19615 emit_insn (gen_get_vrsave_internal (reg));
19617 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
19619 if (!WORLD_SAVE_P (info))
19622 offset = info->vrsave_save_offset + sp_offset;
19623 mem = gen_frame_mem (SImode,
19624 gen_rtx_PLUS (Pmode, frame_reg_rtx,
19625 GEN_INT (offset)));
19626 insn = emit_move_insn (mem, reg);
19629 /* Include the registers in the mask. */
19630 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
19632 insn = emit_insn (generate_set_vrsave (reg, info, 0));
19635 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
19636 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
19637 || (DEFAULT_ABI == ABI_V4
19638 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
19639 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
19641 /* If emit_load_toc_table will use the link register, we need to save
19642 it. We use R12 for this purpose because emit_load_toc_table
19643 can use register 0. This allows us to use a plain 'blr' to return
19644 from the procedure more often. */
19645 int save_LR_around_toc_setup = (TARGET_ELF
19646 && DEFAULT_ABI != ABI_AIX
19648 && ! info->lr_save_p
19649 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
19650 if (save_LR_around_toc_setup)
19652 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19654 insn = emit_move_insn (frame_ptr_rtx, lr);
19655 RTX_FRAME_RELATED_P (insn) = 1;
19657 rs6000_emit_load_toc_table (TRUE);
19659 insn = emit_move_insn (lr, frame_ptr_rtx);
19660 RTX_FRAME_RELATED_P (insn) = 1;
19663 rs6000_emit_load_toc_table (TRUE);
19667 if (DEFAULT_ABI == ABI_DARWIN
19668 && flag_pic && crtl->uses_pic_offset_table)
19670 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
19671 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
19673 /* Save and restore LR locally around this call (in R0). */
19674 if (!info->lr_save_p)
19675 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
19677 emit_insn (gen_load_macho_picbase (src));
19679 emit_move_insn (gen_rtx_REG (Pmode,
19680 RS6000_PIC_OFFSET_TABLE_REGNUM),
19683 if (!info->lr_save_p)
19684 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
19689 /* Write function prologue. */
19692 rs6000_output_function_prologue (FILE *file,
19693 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
19695 rs6000_stack_t *info = rs6000_stack_info ();
19697 if (TARGET_DEBUG_STACK)
19698 debug_stack_info (info);
19700 /* Write .extern for any function we will call to save and restore
19702 if (info->first_fp_reg_save < 64
19703 && !FP_SAVE_INLINE (info->first_fp_reg_save))
19706 int regno = info->first_fp_reg_save - 32;
19708 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
19709 /*gpr=*/false, /*lr=*/false);
19710 fprintf (file, "\t.extern %s\n", name);
19712 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
19713 /*gpr=*/false, /*lr=*/true);
19714 fprintf (file, "\t.extern %s\n", name);
19717 /* Write .extern for AIX common mode routines, if needed. */
19718 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
19720 fputs ("\t.extern __mulh\n", file);
19721 fputs ("\t.extern __mull\n", file);
19722 fputs ("\t.extern __divss\n", file);
19723 fputs ("\t.extern __divus\n", file);
19724 fputs ("\t.extern __quoss\n", file);
19725 fputs ("\t.extern __quous\n", file);
19726 common_mode_defined = 1;
19729 if (! HAVE_prologue)
19735 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
19736 the "toplevel" insn chain. */
19737 emit_note (NOTE_INSN_DELETED);
19738 rs6000_emit_prologue ();
19739 emit_note (NOTE_INSN_DELETED);
19741 /* Expand INSN_ADDRESSES so final() doesn't crash. */
19745 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
19747 INSN_ADDRESSES_NEW (insn, addr);
19752 prologue = get_insns ();
19755 if (TARGET_DEBUG_STACK)
19756 debug_rtx_list (prologue, 100);
19758 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
19762 rs6000_pic_labelno++;
19765 /* Non-zero if vmx regs are restored before the frame pop, zero if
19766 we restore after the pop when possible. */
19767 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
19769 /* Reload CR from REG. */
19772 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
19777 if (using_mfcr_multiple)
19779 for (i = 0; i < 8; i++)
19780 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19782 gcc_assert (count);
19785 if (using_mfcr_multiple && count > 1)
19790 p = rtvec_alloc (count);
19793 for (i = 0; i < 8; i++)
19794 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19796 rtvec r = rtvec_alloc (2);
19797 RTVEC_ELT (r, 0) = reg;
19798 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
19799 RTVEC_ELT (p, ndx) =
19800 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
19801 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
19804 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
19805 gcc_assert (ndx == count);
19808 for (i = 0; i < 8; i++)
19809 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
19811 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
19817 /* Return true if OFFSET from stack pointer can be clobbered by signals.
19818 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
19819 below stack pointer not cloberred by signals. */
19822 offset_below_red_zone_p (HOST_WIDE_INT offset)
19824 return offset < (DEFAULT_ABI == ABI_V4
19826 : TARGET_32BIT ? -220 : -288);
19829 /* Emit function epilogue as insns. */
19832 rs6000_emit_epilogue (int sibcall)
19834 rs6000_stack_t *info;
19835 int restoring_GPRs_inline;
19836 int restoring_FPRs_inline;
19837 int using_load_multiple;
19838 int using_mtcr_multiple;
19839 int use_backchain_to_restore_sp;
19843 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
19844 rtx frame_reg_rtx = sp_reg_rtx;
19845 rtx cfa_restores = NULL_RTX;
19847 rtx cr_save_reg = NULL_RTX;
19848 enum machine_mode reg_mode = Pmode;
19849 int reg_size = TARGET_32BIT ? 4 : 8;
19852 info = rs6000_stack_info ();
19854 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19856 reg_mode = V2SImode;
19860 strategy = rs6000_savres_strategy (info, /*savep=*/false,
19861 /*static_chain_p=*/0, sibcall);
19862 using_load_multiple = strategy & SAVRES_MULTIPLE;
19863 restoring_FPRs_inline = strategy & SAVRES_INLINE_FPRS;
19864 restoring_GPRs_inline = strategy & SAVRES_INLINE_GPRS;
19865 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
19866 || rs6000_cpu == PROCESSOR_PPC603
19867 || rs6000_cpu == PROCESSOR_PPC750
19869 /* Restore via the backchain when we have a large frame, since this
19870 is more efficient than an addis, addi pair. The second condition
19871 here will not trigger at the moment; We don't actually need a
19872 frame pointer for alloca, but the generic parts of the compiler
19873 give us one anyway. */
19874 use_backchain_to_restore_sp = (info->total_size > 32767
19875 || info->total_size
19876 + (info->lr_save_p ? info->lr_save_offset : 0)
19878 || (cfun->calls_alloca
19879 && !frame_pointer_needed));
19880 restore_lr = (info->lr_save_p
19881 && (restoring_FPRs_inline
19882 || (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR))
19883 && (restoring_GPRs_inline
19884 || info->first_fp_reg_save < 64));
19886 if (WORLD_SAVE_P (info))
19890 const char *alloc_rname;
19893 /* eh_rest_world_r10 will return to the location saved in the LR
19894 stack slot (which is not likely to be our caller.)
19895 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
19896 rest_world is similar, except any R10 parameter is ignored.
19897 The exception-handling stuff that was here in 2.95 is no
19898 longer necessary. */
19902 + 32 - info->first_gp_reg_save
19903 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
19904 + 63 + 1 - info->first_fp_reg_save);
19906 strcpy (rname, ((crtl->calls_eh_return) ?
19907 "*eh_rest_world_r10" : "*rest_world"));
19908 alloc_rname = ggc_strdup (rname);
19911 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
19912 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
19913 gen_rtx_REG (Pmode,
19916 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
19917 /* The instruction pattern requires a clobber here;
19918 it is shared with the restVEC helper. */
19920 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
19923 /* CR register traditionally saved as CR2. */
19924 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
19925 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19926 GEN_INT (info->cr_save_offset));
19927 rtx mem = gen_frame_mem (reg_mode, addr);
19929 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19932 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
19934 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
19935 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19936 GEN_INT (info->gp_save_offset
19938 rtx mem = gen_frame_mem (reg_mode, addr);
19940 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19942 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
19944 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
19945 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19946 GEN_INT (info->altivec_save_offset
19948 rtx mem = gen_frame_mem (V4SImode, addr);
19950 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19952 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
19954 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19955 ? DFmode : SFmode),
19956 info->first_fp_reg_save + i);
19957 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19958 GEN_INT (info->fp_save_offset
19960 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
19961 ? DFmode : SFmode), addr);
19963 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
19966 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
19968 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
19970 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
19972 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
19974 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
19975 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
19980 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
19982 sp_offset = info->total_size;
19984 /* Restore AltiVec registers if we must do so before adjusting the
19986 if (TARGET_ALTIVEC_ABI
19987 && info->altivec_size != 0
19988 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
19989 || (DEFAULT_ABI != ABI_V4
19990 && offset_below_red_zone_p (info->altivec_save_offset))))
19994 if (use_backchain_to_restore_sp)
19996 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
19997 emit_move_insn (frame_reg_rtx,
19998 gen_rtx_MEM (Pmode, sp_reg_rtx));
20001 else if (frame_pointer_needed)
20002 frame_reg_rtx = hard_frame_pointer_rtx;
20004 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20005 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20007 rtx addr, areg, mem, reg;
20009 areg = gen_rtx_REG (Pmode, 0);
20011 (areg, GEN_INT (info->altivec_save_offset
20013 + 16 * (i - info->first_altivec_reg_save)));
20015 /* AltiVec addressing mode is [reg+reg]. */
20016 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20017 mem = gen_frame_mem (V4SImode, addr);
20019 reg = gen_rtx_REG (V4SImode, i);
20020 emit_move_insn (reg, mem);
20021 if (offset_below_red_zone_p (info->altivec_save_offset
20022 + (i - info->first_altivec_reg_save)
20024 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20029 /* Restore VRSAVE if we must do so before adjusting the stack. */
20031 && TARGET_ALTIVEC_VRSAVE
20032 && info->vrsave_mask != 0
20033 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20034 || (DEFAULT_ABI != ABI_V4
20035 && offset_below_red_zone_p (info->vrsave_save_offset))))
20037 rtx addr, mem, reg;
20039 if (frame_reg_rtx == sp_reg_rtx)
20041 if (use_backchain_to_restore_sp)
20043 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20044 emit_move_insn (frame_reg_rtx,
20045 gen_rtx_MEM (Pmode, sp_reg_rtx));
20048 else if (frame_pointer_needed)
20049 frame_reg_rtx = hard_frame_pointer_rtx;
20052 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20053 GEN_INT (info->vrsave_save_offset + sp_offset));
20054 mem = gen_frame_mem (SImode, addr);
20055 reg = gen_rtx_REG (SImode, 12);
20056 emit_move_insn (reg, mem);
20058 emit_insn (generate_set_vrsave (reg, info, 1));
20062 /* If we have a large stack frame, restore the old stack pointer
20063 using the backchain. */
20064 if (use_backchain_to_restore_sp)
20066 if (frame_reg_rtx == sp_reg_rtx)
20068 /* Under V.4, don't reset the stack pointer until after we're done
20069 loading the saved registers. */
20070 if (DEFAULT_ABI == ABI_V4)
20071 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20073 insn = emit_move_insn (frame_reg_rtx,
20074 gen_rtx_MEM (Pmode, sp_reg_rtx));
20077 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20078 && DEFAULT_ABI == ABI_V4)
20079 /* frame_reg_rtx has been set up by the altivec restore. */
20083 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20084 frame_reg_rtx = sp_reg_rtx;
20087 /* If we have a frame pointer, we can restore the old stack pointer
20089 else if (frame_pointer_needed)
20091 frame_reg_rtx = sp_reg_rtx;
20092 if (DEFAULT_ABI == ABI_V4)
20093 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20094 /* Prevent reordering memory accesses against stack pointer restore. */
20095 else if (cfun->calls_alloca
20096 || offset_below_red_zone_p (-info->total_size))
20098 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20099 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20100 MEM_NOTRAP_P (mem1) = 1;
20101 MEM_NOTRAP_P (mem2) = 1;
20102 emit_insn (gen_frame_tie (mem1, mem2));
20105 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
20106 GEN_INT (info->total_size)));
20109 else if (info->push_p
20110 && DEFAULT_ABI != ABI_V4
20111 && !crtl->calls_eh_return)
20113 /* Prevent reordering memory accesses against stack pointer restore. */
20114 if (cfun->calls_alloca
20115 || offset_below_red_zone_p (-info->total_size))
20117 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20118 MEM_NOTRAP_P (mem) = 1;
20119 emit_insn (gen_stack_tie (mem));
20121 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
20122 GEN_INT (info->total_size)));
20125 if (insn && frame_reg_rtx == sp_reg_rtx)
20129 REG_NOTES (insn) = cfa_restores;
20130 cfa_restores = NULL_RTX;
20132 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20133 RTX_FRAME_RELATED_P (insn) = 1;
20136 /* Restore AltiVec registers if we have not done so already. */
20137 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20138 && TARGET_ALTIVEC_ABI
20139 && info->altivec_size != 0
20140 && (DEFAULT_ABI == ABI_V4
20141 || !offset_below_red_zone_p (info->altivec_save_offset)))
20145 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20146 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20148 rtx addr, areg, mem, reg;
20150 areg = gen_rtx_REG (Pmode, 0);
20152 (areg, GEN_INT (info->altivec_save_offset
20154 + 16 * (i - info->first_altivec_reg_save)));
20156 /* AltiVec addressing mode is [reg+reg]. */
20157 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20158 mem = gen_frame_mem (V4SImode, addr);
20160 reg = gen_rtx_REG (V4SImode, i);
20161 emit_move_insn (reg, mem);
20162 if (DEFAULT_ABI == ABI_V4)
20163 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20168 /* Restore VRSAVE if we have not done so already. */
20169 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20171 && TARGET_ALTIVEC_VRSAVE
20172 && info->vrsave_mask != 0
20173 && (DEFAULT_ABI == ABI_V4
20174 || !offset_below_red_zone_p (info->vrsave_save_offset)))
20176 rtx addr, mem, reg;
20178 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20179 GEN_INT (info->vrsave_save_offset + sp_offset));
20180 mem = gen_frame_mem (SImode, addr);
20181 reg = gen_rtx_REG (SImode, 12);
20182 emit_move_insn (reg, mem);
20184 emit_insn (generate_set_vrsave (reg, info, 1));
20187 /* Get the old lr if we saved it. If we are restoring registers
20188 out-of-line, then the out-of-line routines can do this for us. */
20189 if (restore_lr && restoring_GPRs_inline)
20191 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20192 info->lr_save_offset + sp_offset);
20194 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20197 /* Get the old cr if we saved it. */
20198 if (info->cr_save_p)
20200 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20201 GEN_INT (info->cr_save_offset + sp_offset));
20202 rtx mem = gen_frame_mem (SImode, addr);
20204 cr_save_reg = gen_rtx_REG (SImode,
20205 DEFAULT_ABI == ABI_AIX
20206 && !restoring_GPRs_inline
20207 && info->first_fp_reg_save < 64
20209 emit_move_insn (cr_save_reg, mem);
20212 /* Set LR here to try to overlap restores below. LR is always saved
20213 above incoming stack, so it never needs REG_CFA_RESTORE. */
20214 if (restore_lr && restoring_GPRs_inline)
20215 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20216 gen_rtx_REG (Pmode, 0));
20218 /* Load exception handler data registers, if needed. */
20219 if (crtl->calls_eh_return)
20221 unsigned int i, regno;
20225 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20226 GEN_INT (sp_offset + 5 * reg_size));
20227 rtx mem = gen_frame_mem (reg_mode, addr);
20229 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
20236 regno = EH_RETURN_DATA_REGNO (i);
20237 if (regno == INVALID_REGNUM)
20240 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
20241 info->ehrd_offset + sp_offset
20242 + reg_size * (int) i);
20244 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
20248 /* Restore GPRs. This is done as a PARALLEL if we are using
20249 the load-multiple instructions. */
20251 && info->spe_64bit_regs_used != 0
20252 && info->first_gp_reg_save != 32)
20254 /* Determine whether we can address all of the registers that need
20255 to be saved with an offset from the stack pointer that fits in
20256 the small const field for SPE memory instructions. */
20257 int spe_regs_addressable_via_sp
20258 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20259 + (32 - info->first_gp_reg_save - 1) * reg_size)
20260 && restoring_GPRs_inline);
20263 if (spe_regs_addressable_via_sp)
20264 spe_offset = info->spe_gp_save_offset + sp_offset;
20267 rtx old_frame_reg_rtx = frame_reg_rtx;
20268 /* Make r11 point to the start of the SPE save area. We worried about
20269 not clobbering it when we were saving registers in the prologue.
20270 There's no need to worry here because the static chain is passed
20271 anew to every function. */
20272 int ool_adjust = (restoring_GPRs_inline
20274 : (info->first_gp_reg_save
20275 - (FIRST_SAVRES_REGISTER+1))*8);
20277 if (frame_reg_rtx == sp_reg_rtx)
20278 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20279 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
20280 GEN_INT (info->spe_gp_save_offset
20283 /* Keep the invariant that frame_reg_rtx + sp_offset points
20284 at the top of the stack frame. */
20285 sp_offset = -info->spe_gp_save_offset;
20290 if (restoring_GPRs_inline)
20292 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20293 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20295 rtx offset, addr, mem, reg;
20297 /* We're doing all this to ensure that the immediate offset
20298 fits into the immediate field of 'evldd'. */
20299 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
20301 offset = GEN_INT (spe_offset + reg_size * i);
20302 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
20303 mem = gen_rtx_MEM (V2SImode, addr);
20304 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20306 insn = emit_move_insn (reg, mem);
20307 if (DEFAULT_ABI == ABI_V4)
20309 if (frame_pointer_needed
20310 && info->first_gp_reg_save + i
20311 == HARD_FRAME_POINTER_REGNUM)
20313 add_reg_note (insn, REG_CFA_DEF_CFA,
20314 plus_constant (frame_reg_rtx,
20316 RTX_FRAME_RELATED_P (insn) = 1;
20319 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20328 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20330 /*savep=*/false, /*gpr=*/true,
20332 emit_jump_insn (par);
20333 /* We don't want anybody else emitting things after we jumped
20338 else if (!restoring_GPRs_inline)
20340 /* We are jumping to an out-of-line function. */
20341 bool can_use_exit = info->first_fp_reg_save == 64;
20344 /* Emit stack reset code if we need it. */
20346 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20347 sp_offset, can_use_exit);
20350 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
20353 GEN_INT (sp_offset - info->fp_size)));
20354 if (REGNO (frame_reg_rtx) == 11)
20355 sp_offset += info->fp_size;
20358 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20359 info->gp_save_offset, reg_mode,
20360 /*savep=*/false, /*gpr=*/true,
20361 /*lr=*/can_use_exit);
20365 if (info->cr_save_p)
20367 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20368 if (DEFAULT_ABI == ABI_V4)
20370 = alloc_reg_note (REG_CFA_RESTORE,
20371 gen_rtx_REG (SImode, CR2_REGNO),
20375 emit_jump_insn (par);
20377 /* We don't want anybody else emitting things after we jumped
20382 insn = emit_insn (par);
20383 if (DEFAULT_ABI == ABI_V4)
20385 if (frame_pointer_needed)
20387 add_reg_note (insn, REG_CFA_DEF_CFA,
20388 plus_constant (frame_reg_rtx, sp_offset));
20389 RTX_FRAME_RELATED_P (insn) = 1;
20392 for (i = info->first_gp_reg_save; i < 32; i++)
20394 = alloc_reg_note (REG_CFA_RESTORE,
20395 gen_rtx_REG (reg_mode, i), cfa_restores);
20398 else if (using_load_multiple)
20401 p = rtvec_alloc (32 - info->first_gp_reg_save);
20402 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20404 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20405 GEN_INT (info->gp_save_offset
20408 rtx mem = gen_frame_mem (reg_mode, addr);
20409 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20411 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
20412 if (DEFAULT_ABI == ABI_V4)
20413 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20416 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20417 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
20419 add_reg_note (insn, REG_CFA_DEF_CFA,
20420 plus_constant (frame_reg_rtx, sp_offset));
20421 RTX_FRAME_RELATED_P (insn) = 1;
20426 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20427 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20429 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20430 GEN_INT (info->gp_save_offset
20433 rtx mem = gen_frame_mem (reg_mode, addr);
20434 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20436 insn = emit_move_insn (reg, mem);
20437 if (DEFAULT_ABI == ABI_V4)
20439 if (frame_pointer_needed
20440 && info->first_gp_reg_save + i
20441 == HARD_FRAME_POINTER_REGNUM)
20443 add_reg_note (insn, REG_CFA_DEF_CFA,
20444 plus_constant (frame_reg_rtx, sp_offset));
20445 RTX_FRAME_RELATED_P (insn) = 1;
20448 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20454 if (restore_lr && !restoring_GPRs_inline)
20456 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
20457 info->lr_save_offset + sp_offset);
20459 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
20460 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
20461 gen_rtx_REG (Pmode, 0));
20464 /* Restore fpr's if we need to do it without calling a function. */
20465 if (restoring_FPRs_inline)
20466 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20467 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20468 && ! call_used_regs[info->first_fp_reg_save+i]))
20470 rtx addr, mem, reg;
20471 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20472 GEN_INT (info->fp_save_offset
20475 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20476 ? DFmode : SFmode), addr);
20477 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20478 ? DFmode : SFmode),
20479 info->first_fp_reg_save + i);
20481 emit_move_insn (reg, mem);
20482 if (DEFAULT_ABI == ABI_V4)
20483 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20487 /* If we saved cr, restore it here. Just those that were used. */
20488 if (info->cr_save_p)
20490 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
20491 if (DEFAULT_ABI == ABI_V4)
20493 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
20497 /* If this is V.4, unwind the stack pointer after all of the loads
20499 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
20500 sp_offset, !restoring_FPRs_inline);
20505 REG_NOTES (insn) = cfa_restores;
20506 cfa_restores = NULL_RTX;
20508 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
20509 RTX_FRAME_RELATED_P (insn) = 1;
20512 if (crtl->calls_eh_return)
20514 rtx sa = EH_RETURN_STACKADJ_RTX;
20515 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
20521 bool lr = (strategy & SAVRES_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
20522 if (! restoring_FPRs_inline)
20523 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
20525 p = rtvec_alloc (2);
20527 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
20528 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
20529 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
20530 : gen_rtx_CLOBBER (VOIDmode,
20531 gen_rtx_REG (Pmode, 65)));
20533 /* If we have to restore more than two FP registers, branch to the
20534 restore function. It will return to our caller. */
20535 if (! restoring_FPRs_inline)
20540 sym = rs6000_savres_routine_sym (info,
20544 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
20545 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
20546 gen_rtx_REG (Pmode,
20547 DEFAULT_ABI == ABI_AIX
20549 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20552 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
20553 GEN_INT (info->fp_save_offset + 8*i));
20554 mem = gen_frame_mem (DFmode, addr);
20556 RTVEC_ELT (p, i+4) =
20557 gen_rtx_SET (VOIDmode,
20558 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
20563 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20567 /* Write function epilogue. */
20570 rs6000_output_function_epilogue (FILE *file,
20571 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20573 if (! HAVE_epilogue)
20575 rtx insn = get_last_insn ();
20576 /* If the last insn was a BARRIER, we don't have to write anything except
20577 the trace table. */
20578 if (GET_CODE (insn) == NOTE)
20579 insn = prev_nonnote_insn (insn);
20580 if (insn == 0 || GET_CODE (insn) != BARRIER)
20582 /* This is slightly ugly, but at least we don't have two
20583 copies of the epilogue-emitting code. */
20586 /* A NOTE_INSN_DELETED is supposed to be at the start
20587 and end of the "toplevel" insn chain. */
20588 emit_note (NOTE_INSN_DELETED);
20589 rs6000_emit_epilogue (FALSE);
20590 emit_note (NOTE_INSN_DELETED);
20592 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20596 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20598 INSN_ADDRESSES_NEW (insn, addr);
20603 if (TARGET_DEBUG_STACK)
20604 debug_rtx_list (get_insns (), 100);
20605 final (get_insns (), file, FALSE);
20611 macho_branch_islands ();
20612 /* Mach-O doesn't support labels at the end of objects, so if
20613 it looks like we might want one, insert a NOP. */
20615 rtx insn = get_last_insn ();
20618 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
20619 insn = PREV_INSN (insn);
20623 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
20624 fputs ("\tnop\n", file);
20628 /* Output a traceback table here. See /usr/include/sys/debug.h for info
20631 We don't output a traceback table if -finhibit-size-directive was
20632 used. The documentation for -finhibit-size-directive reads
20633 ``don't output a @code{.size} assembler directive, or anything
20634 else that would cause trouble if the function is split in the
20635 middle, and the two halves are placed at locations far apart in
20636 memory.'' The traceback table has this property, since it
20637 includes the offset from the start of the function to the
20638 traceback table itself.
20640 System V.4 Powerpc's (and the embedded ABI derived from it) use a
20641 different traceback table. */
20642 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
20643 && rs6000_traceback != traceback_none && !cfun->is_thunk)
20645 const char *fname = NULL;
20646 const char *language_string = lang_hooks.name;
20647 int fixed_parms = 0, float_parms = 0, parm_info = 0;
20649 int optional_tbtab;
20650 rs6000_stack_t *info = rs6000_stack_info ();
20652 if (rs6000_traceback == traceback_full)
20653 optional_tbtab = 1;
20654 else if (rs6000_traceback == traceback_part)
20655 optional_tbtab = 0;
20657 optional_tbtab = !optimize_size && !TARGET_ELF;
20659 if (optional_tbtab)
20661 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
20662 while (*fname == '.') /* V.4 encodes . in the name */
20665 /* Need label immediately before tbtab, so we can compute
20666 its offset from the function start. */
20667 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20668 ASM_OUTPUT_LABEL (file, fname);
20671 /* The .tbtab pseudo-op can only be used for the first eight
20672 expressions, since it can't handle the possibly variable
20673 length fields that follow. However, if you omit the optional
20674 fields, the assembler outputs zeros for all optional fields
20675 anyways, giving each variable length field is minimum length
20676 (as defined in sys/debug.h). Thus we can not use the .tbtab
20677 pseudo-op at all. */
20679 /* An all-zero word flags the start of the tbtab, for debuggers
20680 that have to find it by searching forward from the entry
20681 point or from the current pc. */
20682 fputs ("\t.long 0\n", file);
20684 /* Tbtab format type. Use format type 0. */
20685 fputs ("\t.byte 0,", file);
20687 /* Language type. Unfortunately, there does not seem to be any
20688 official way to discover the language being compiled, so we
20689 use language_string.
20690 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
20691 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
20692 a number, so for now use 9. LTO isn't assigned a number either,
20693 so for now use 0. */
20694 if (! strcmp (language_string, "GNU C")
20695 || ! strcmp (language_string, "GNU GIMPLE"))
20697 else if (! strcmp (language_string, "GNU F77")
20698 || ! strcmp (language_string, "GNU Fortran"))
20700 else if (! strcmp (language_string, "GNU Pascal"))
20702 else if (! strcmp (language_string, "GNU Ada"))
20704 else if (! strcmp (language_string, "GNU C++")
20705 || ! strcmp (language_string, "GNU Objective-C++"))
20707 else if (! strcmp (language_string, "GNU Java"))
20709 else if (! strcmp (language_string, "GNU Objective-C"))
20712 gcc_unreachable ();
20713 fprintf (file, "%d,", i);
20715 /* 8 single bit fields: global linkage (not set for C extern linkage,
20716 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
20717 from start of procedure stored in tbtab, internal function, function
20718 has controlled storage, function has no toc, function uses fp,
20719 function logs/aborts fp operations. */
20720 /* Assume that fp operations are used if any fp reg must be saved. */
20721 fprintf (file, "%d,",
20722 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
20724 /* 6 bitfields: function is interrupt handler, name present in
20725 proc table, function calls alloca, on condition directives
20726 (controls stack walks, 3 bits), saves condition reg, saves
20728 /* The `function calls alloca' bit seems to be set whenever reg 31 is
20729 set up as a frame pointer, even when there is no alloca call. */
20730 fprintf (file, "%d,",
20731 ((optional_tbtab << 6)
20732 | ((optional_tbtab & frame_pointer_needed) << 5)
20733 | (info->cr_save_p << 1)
20734 | (info->lr_save_p)));
20736 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
20738 fprintf (file, "%d,",
20739 (info->push_p << 7) | (64 - info->first_fp_reg_save));
20741 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
20742 fprintf (file, "%d,", (32 - first_reg_to_save ()));
20744 if (optional_tbtab)
20746 /* Compute the parameter info from the function decl argument
20749 int next_parm_info_bit = 31;
20751 for (decl = DECL_ARGUMENTS (current_function_decl);
20752 decl; decl = TREE_CHAIN (decl))
20754 rtx parameter = DECL_INCOMING_RTL (decl);
20755 enum machine_mode mode = GET_MODE (parameter);
20757 if (GET_CODE (parameter) == REG)
20759 if (SCALAR_FLOAT_MODE_P (mode))
20780 gcc_unreachable ();
20783 /* If only one bit will fit, don't or in this entry. */
20784 if (next_parm_info_bit > 0)
20785 parm_info |= (bits << (next_parm_info_bit - 1));
20786 next_parm_info_bit -= 2;
20790 fixed_parms += ((GET_MODE_SIZE (mode)
20791 + (UNITS_PER_WORD - 1))
20793 next_parm_info_bit -= 1;
20799 /* Number of fixed point parameters. */
20800 /* This is actually the number of words of fixed point parameters; thus
20801 an 8 byte struct counts as 2; and thus the maximum value is 8. */
20802 fprintf (file, "%d,", fixed_parms);
20804 /* 2 bitfields: number of floating point parameters (7 bits), parameters
20806 /* This is actually the number of fp registers that hold parameters;
20807 and thus the maximum value is 13. */
20808 /* Set parameters on stack bit if parameters are not in their original
20809 registers, regardless of whether they are on the stack? Xlc
20810 seems to set the bit when not optimizing. */
20811 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
20813 if (! optional_tbtab)
20816 /* Optional fields follow. Some are variable length. */
20818 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
20819 11 double float. */
20820 /* There is an entry for each parameter in a register, in the order that
20821 they occur in the parameter list. Any intervening arguments on the
20822 stack are ignored. If the list overflows a long (max possible length
20823 34 bits) then completely leave off all elements that don't fit. */
20824 /* Only emit this long if there was at least one parameter. */
20825 if (fixed_parms || float_parms)
20826 fprintf (file, "\t.long %d\n", parm_info);
20828 /* Offset from start of code to tb table. */
20829 fputs ("\t.long ", file);
20830 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
20831 RS6000_OUTPUT_BASENAME (file, fname);
20833 rs6000_output_function_entry (file, fname);
20836 /* Interrupt handler mask. */
20837 /* Omit this long, since we never set the interrupt handler bit
20840 /* Number of CTL (controlled storage) anchors. */
20841 /* Omit this long, since the has_ctl bit is never set above. */
20843 /* Displacement into stack of each CTL anchor. */
20844 /* Omit this list of longs, because there are no CTL anchors. */
20846 /* Length of function name. */
20849 fprintf (file, "\t.short %d\n", (int) strlen (fname));
20851 /* Function name. */
20852 assemble_string (fname, strlen (fname));
20854 /* Register for alloca automatic storage; this is always reg 31.
20855 Only emit this if the alloca bit was set above. */
20856 if (frame_pointer_needed)
20857 fputs ("\t.byte 31\n", file);
20859 fputs ("\t.align 2\n", file);
20863 /* A C compound statement that outputs the assembler code for a thunk
20864 function, used to implement C++ virtual function calls with
20865 multiple inheritance. The thunk acts as a wrapper around a virtual
20866 function, adjusting the implicit object parameter before handing
20867 control off to the real function.
20869 First, emit code to add the integer DELTA to the location that
20870 contains the incoming first argument. Assume that this argument
20871 contains a pointer, and is the one used to pass the `this' pointer
20872 in C++. This is the incoming argument *before* the function
20873 prologue, e.g. `%o0' on a sparc. The addition must preserve the
20874 values of all other incoming arguments.
20876 After the addition, emit code to jump to FUNCTION, which is a
20877 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
20878 not touch the return address. Hence returning from FUNCTION will
20879 return to whoever called the current `thunk'.
20881 The effect must be as if FUNCTION had been called directly with the
20882 adjusted first argument. This macro is responsible for emitting
20883 all of the code for a thunk function; output_function_prologue()
20884 and output_function_epilogue() are not invoked.
20886 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
20887 been extracted from it.) It might possibly be useful on some
20888 targets, but probably not.
20890 If you do not define this macro, the target-independent code in the
20891 C++ frontend will generate a less efficient heavyweight thunk that
20892 calls FUNCTION instead of jumping to it. The generic approach does
20893 not support varargs. */
20896 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
20897 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
20900 rtx this_rtx, insn, funexp;
20902 reload_completed = 1;
20903 epilogue_completed = 1;
20905 /* Mark the end of the (empty) prologue. */
20906 emit_note (NOTE_INSN_PROLOGUE_END);
20908 /* Find the "this" pointer. If the function returns a structure,
20909 the structure return pointer is in r3. */
20910 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
20911 this_rtx = gen_rtx_REG (Pmode, 4);
20913 this_rtx = gen_rtx_REG (Pmode, 3);
20915 /* Apply the constant offset, if required. */
20917 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
20919 /* Apply the offset from the vtable, if required. */
20922 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
20923 rtx tmp = gen_rtx_REG (Pmode, 12);
20925 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
20926 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
20928 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
20929 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
20933 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
20935 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
20937 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
20940 /* Generate a tail call to the target function. */
20941 if (!TREE_USED (function))
20943 assemble_external (function);
20944 TREE_USED (function) = 1;
20946 funexp = XEXP (DECL_RTL (function), 0);
20947 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
20950 if (MACHOPIC_INDIRECT)
20951 funexp = machopic_indirect_call_target (funexp);
20954 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
20955 generate sibcall RTL explicitly. */
20956 insn = emit_call_insn (
20957 gen_rtx_PARALLEL (VOIDmode,
20959 gen_rtx_CALL (VOIDmode,
20960 funexp, const0_rtx),
20961 gen_rtx_USE (VOIDmode, const0_rtx),
20962 gen_rtx_USE (VOIDmode,
20963 gen_rtx_REG (SImode,
20965 gen_rtx_RETURN (VOIDmode))));
20966 SIBLING_CALL_P (insn) = 1;
20969 /* Run just enough of rest_of_compilation to get the insns emitted.
20970 There's not really enough bulk here to make other passes such as
20971 instruction scheduling worth while. Note that use_thunk calls
20972 assemble_start_function and assemble_end_function. */
20973 insn = get_insns ();
20974 insn_locators_alloc ();
20975 shorten_branches (insn);
20976 final_start_function (insn, file, 1);
20977 final (insn, file, 1);
20978 final_end_function ();
20980 reload_completed = 0;
20981 epilogue_completed = 0;
20984 /* A quick summary of the various types of 'constant-pool tables'
20987 Target Flags Name One table per
20988 AIX (none) AIX TOC object file
20989 AIX -mfull-toc AIX TOC object file
20990 AIX -mminimal-toc AIX minimal TOC translation unit
20991 SVR4/EABI (none) SVR4 SDATA object file
20992 SVR4/EABI -fpic SVR4 pic object file
20993 SVR4/EABI -fPIC SVR4 PIC translation unit
20994 SVR4/EABI -mrelocatable EABI TOC function
20995 SVR4/EABI -maix AIX TOC object file
20996 SVR4/EABI -maix -mminimal-toc
20997 AIX minimal TOC translation unit
20999 Name Reg. Set by entries contains:
21000 made by addrs? fp? sum?
21002 AIX TOC 2 crt0 as Y option option
21003 AIX minimal TOC 30 prolog gcc Y Y option
21004 SVR4 SDATA 13 crt0 gcc N Y N
21005 SVR4 pic 30 prolog ld Y not yet N
21006 SVR4 PIC 30 prolog gcc Y option option
21007 EABI TOC 30 prolog gcc Y option option
21011 /* Hash functions for the hash table. */
21014 rs6000_hash_constant (rtx k)
21016 enum rtx_code code = GET_CODE (k);
21017 enum machine_mode mode = GET_MODE (k);
21018 unsigned result = (code << 3) ^ mode;
21019 const char *format;
21022 format = GET_RTX_FORMAT (code);
21023 flen = strlen (format);
21029 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21032 if (mode != VOIDmode)
21033 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21045 for (; fidx < flen; fidx++)
21046 switch (format[fidx])
21051 const char *str = XSTR (k, fidx);
21052 len = strlen (str);
21053 result = result * 613 + len;
21054 for (i = 0; i < len; i++)
21055 result = result * 613 + (unsigned) str[i];
21060 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21064 result = result * 613 + (unsigned) XINT (k, fidx);
21067 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21068 result = result * 613 + (unsigned) XWINT (k, fidx);
21072 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21073 result = result * 613 + (unsigned) (XWINT (k, fidx)
21080 gcc_unreachable ();
21087 toc_hash_function (const void *hash_entry)
21089 const struct toc_hash_struct *thc =
21090 (const struct toc_hash_struct *) hash_entry;
21091 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21094 /* Compare H1 and H2 for equivalence. */
21097 toc_hash_eq (const void *h1, const void *h2)
21099 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21100 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
21102 if (((const struct toc_hash_struct *) h1)->key_mode
21103 != ((const struct toc_hash_struct *) h2)->key_mode)
21106 return rtx_equal_p (r1, r2);
21109 /* These are the names given by the C++ front-end to vtables, and
21110 vtable-like objects. Ideally, this logic should not be here;
21111 instead, there should be some programmatic way of inquiring as
21112 to whether or not an object is a vtable. */
21114 #define VTABLE_NAME_P(NAME) \
21115 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
21116 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
21117 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
21118 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
21119 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
21121 #ifdef NO_DOLLAR_IN_LABEL
21122 /* Return a GGC-allocated character string translating dollar signs in
21123 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
21126 rs6000_xcoff_strip_dollar (const char *name)
21131 p = strchr (name, '$');
21133 if (p == 0 || p == name)
21136 len = strlen (name);
21137 strip = (char *) alloca (len + 1);
21138 strcpy (strip, name);
21139 p = strchr (strip, '$');
21143 p = strchr (p + 1, '$');
21146 return ggc_alloc_string (strip, len);
21151 rs6000_output_symbol_ref (FILE *file, rtx x)
21153 /* Currently C++ toc references to vtables can be emitted before it
21154 is decided whether the vtable is public or private. If this is
21155 the case, then the linker will eventually complain that there is
21156 a reference to an unknown section. Thus, for vtables only,
21157 we emit the TOC reference to reference the symbol and not the
21159 const char *name = XSTR (x, 0);
21161 if (VTABLE_NAME_P (name))
21163 RS6000_OUTPUT_BASENAME (file, name);
21166 assemble_name (file, name);
21169 /* Output a TOC entry. We derive the entry name from what is being
21173 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
21176 const char *name = buf;
21178 HOST_WIDE_INT offset = 0;
21180 gcc_assert (!TARGET_NO_TOC);
21182 /* When the linker won't eliminate them, don't output duplicate
21183 TOC entries (this happens on AIX if there is any kind of TOC,
21184 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
21186 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
21188 struct toc_hash_struct *h;
21191 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
21192 time because GGC is not initialized at that point. */
21193 if (toc_hash_table == NULL)
21194 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
21195 toc_hash_eq, NULL);
21197 h = GGC_NEW (struct toc_hash_struct);
21199 h->key_mode = mode;
21200 h->labelno = labelno;
21202 found = htab_find_slot (toc_hash_table, h, INSERT);
21203 if (*found == NULL)
21205 else /* This is indeed a duplicate.
21206 Set this label equal to that label. */
21208 fputs ("\t.set ", file);
21209 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21210 fprintf (file, "%d,", labelno);
21211 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
21212 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
21218 /* If we're going to put a double constant in the TOC, make sure it's
21219 aligned properly when strict alignment is on. */
21220 if (GET_CODE (x) == CONST_DOUBLE
21221 && STRICT_ALIGNMENT
21222 && GET_MODE_BITSIZE (mode) >= 64
21223 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
21224 ASM_OUTPUT_ALIGN (file, 3);
21227 (*targetm.asm_out.internal_label) (file, "LC", labelno);
21229 /* Handle FP constants specially. Note that if we have a minimal
21230 TOC, things we put here aren't actually in the TOC, so we can allow
21232 if (GET_CODE (x) == CONST_DOUBLE &&
21233 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
21235 REAL_VALUE_TYPE rv;
21238 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21239 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21240 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
21242 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
21246 if (TARGET_MINIMAL_TOC)
21247 fputs (DOUBLE_INT_ASM_OP, file);
21249 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21250 k[0] & 0xffffffff, k[1] & 0xffffffff,
21251 k[2] & 0xffffffff, k[3] & 0xffffffff);
21252 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
21253 k[0] & 0xffffffff, k[1] & 0xffffffff,
21254 k[2] & 0xffffffff, k[3] & 0xffffffff);
21259 if (TARGET_MINIMAL_TOC)
21260 fputs ("\t.long ", file);
21262 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
21263 k[0] & 0xffffffff, k[1] & 0xffffffff,
21264 k[2] & 0xffffffff, k[3] & 0xffffffff);
21265 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
21266 k[0] & 0xffffffff, k[1] & 0xffffffff,
21267 k[2] & 0xffffffff, k[3] & 0xffffffff);
21271 else if (GET_CODE (x) == CONST_DOUBLE &&
21272 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
21274 REAL_VALUE_TYPE rv;
21277 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21279 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21280 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
21282 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
21286 if (TARGET_MINIMAL_TOC)
21287 fputs (DOUBLE_INT_ASM_OP, file);
21289 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21290 k[0] & 0xffffffff, k[1] & 0xffffffff);
21291 fprintf (file, "0x%lx%08lx\n",
21292 k[0] & 0xffffffff, k[1] & 0xffffffff);
21297 if (TARGET_MINIMAL_TOC)
21298 fputs ("\t.long ", file);
21300 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
21301 k[0] & 0xffffffff, k[1] & 0xffffffff);
21302 fprintf (file, "0x%lx,0x%lx\n",
21303 k[0] & 0xffffffff, k[1] & 0xffffffff);
21307 else if (GET_CODE (x) == CONST_DOUBLE &&
21308 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
21310 REAL_VALUE_TYPE rv;
21313 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
21314 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
21315 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
21317 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
21321 if (TARGET_MINIMAL_TOC)
21322 fputs (DOUBLE_INT_ASM_OP, file);
21324 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21325 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
21330 if (TARGET_MINIMAL_TOC)
21331 fputs ("\t.long ", file);
21333 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
21334 fprintf (file, "0x%lx\n", l & 0xffffffff);
21338 else if (GET_MODE (x) == VOIDmode
21339 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
21341 unsigned HOST_WIDE_INT low;
21342 HOST_WIDE_INT high;
21344 if (GET_CODE (x) == CONST_DOUBLE)
21346 low = CONST_DOUBLE_LOW (x);
21347 high = CONST_DOUBLE_HIGH (x);
21350 #if HOST_BITS_PER_WIDE_INT == 32
21353 high = (low & 0x80000000) ? ~0 : 0;
21357 low = INTVAL (x) & 0xffffffff;
21358 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
21362 /* TOC entries are always Pmode-sized, but since this
21363 is a bigendian machine then if we're putting smaller
21364 integer constants in the TOC we have to pad them.
21365 (This is still a win over putting the constants in
21366 a separate constant pool, because then we'd have
21367 to have both a TOC entry _and_ the actual constant.)
21369 For a 32-bit target, CONST_INT values are loaded and shifted
21370 entirely within `low' and can be stored in one TOC entry. */
21372 /* It would be easy to make this work, but it doesn't now. */
21373 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
21375 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
21377 #if HOST_BITS_PER_WIDE_INT == 32
21378 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
21379 POINTER_SIZE, &low, &high, 0);
21382 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
21383 high = (HOST_WIDE_INT) low >> 32;
21390 if (TARGET_MINIMAL_TOC)
21391 fputs (DOUBLE_INT_ASM_OP, file);
21393 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21394 (long) high & 0xffffffff, (long) low & 0xffffffff);
21395 fprintf (file, "0x%lx%08lx\n",
21396 (long) high & 0xffffffff, (long) low & 0xffffffff);
21401 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
21403 if (TARGET_MINIMAL_TOC)
21404 fputs ("\t.long ", file);
21406 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
21407 (long) high & 0xffffffff, (long) low & 0xffffffff);
21408 fprintf (file, "0x%lx,0x%lx\n",
21409 (long) high & 0xffffffff, (long) low & 0xffffffff);
21413 if (TARGET_MINIMAL_TOC)
21414 fputs ("\t.long ", file);
21416 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
21417 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
21423 if (GET_CODE (x) == CONST)
21425 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
21426 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
21428 base = XEXP (XEXP (x, 0), 0);
21429 offset = INTVAL (XEXP (XEXP (x, 0), 1));
21432 switch (GET_CODE (base))
21435 name = XSTR (base, 0);
21439 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
21440 CODE_LABEL_NUMBER (XEXP (base, 0)));
21444 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
21448 gcc_unreachable ();
21451 if (TARGET_MINIMAL_TOC)
21452 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
21455 fputs ("\t.tc ", file);
21456 RS6000_OUTPUT_BASENAME (file, name);
21459 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
21461 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
21463 fputs ("[TC],", file);
21466 /* Currently C++ toc references to vtables can be emitted before it
21467 is decided whether the vtable is public or private. If this is
21468 the case, then the linker will eventually complain that there is
21469 a TOC reference to an unknown section. Thus, for vtables only,
21470 we emit the TOC reference to reference the symbol and not the
21472 if (VTABLE_NAME_P (name))
21474 RS6000_OUTPUT_BASENAME (file, name);
21476 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
21477 else if (offset > 0)
21478 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
21481 output_addr_const (file, x);
21485 /* Output an assembler pseudo-op to write an ASCII string of N characters
21486 starting at P to FILE.
21488 On the RS/6000, we have to do this using the .byte operation and
21489 write out special characters outside the quoted string.
21490 Also, the assembler is broken; very long strings are truncated,
21491 so we must artificially break them up early. */
21494 output_ascii (FILE *file, const char *p, int n)
21497 int i, count_string;
21498 const char *for_string = "\t.byte \"";
21499 const char *for_decimal = "\t.byte ";
21500 const char *to_close = NULL;
21503 for (i = 0; i < n; i++)
21506 if (c >= ' ' && c < 0177)
21509 fputs (for_string, file);
21512 /* Write two quotes to get one. */
21520 for_decimal = "\"\n\t.byte ";
21524 if (count_string >= 512)
21526 fputs (to_close, file);
21528 for_string = "\t.byte \"";
21529 for_decimal = "\t.byte ";
21537 fputs (for_decimal, file);
21538 fprintf (file, "%d", c);
21540 for_string = "\n\t.byte \"";
21541 for_decimal = ", ";
21547 /* Now close the string if we have written one. Then end the line. */
21549 fputs (to_close, file);
21552 /* Generate a unique section name for FILENAME for a section type
21553 represented by SECTION_DESC. Output goes into BUF.
21555 SECTION_DESC can be any string, as long as it is different for each
21556 possible section type.
21558 We name the section in the same manner as xlc. The name begins with an
21559 underscore followed by the filename (after stripping any leading directory
21560 names) with the last period replaced by the string SECTION_DESC. If
21561 FILENAME does not contain a period, SECTION_DESC is appended to the end of
21565 rs6000_gen_section_name (char **buf, const char *filename,
21566 const char *section_desc)
21568 const char *q, *after_last_slash, *last_period = 0;
21572 after_last_slash = filename;
21573 for (q = filename; *q; q++)
21576 after_last_slash = q + 1;
21577 else if (*q == '.')
21581 len = strlen (after_last_slash) + strlen (section_desc) + 2;
21582 *buf = (char *) xmalloc (len);
21587 for (q = after_last_slash; *q; q++)
21589 if (q == last_period)
21591 strcpy (p, section_desc);
21592 p += strlen (section_desc);
21596 else if (ISALNUM (*q))
21600 if (last_period == 0)
21601 strcpy (p, section_desc);
21606 /* Emit profile function. */
21609 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
21611 /* Non-standard profiling for kernels, which just saves LR then calls
21612 _mcount without worrying about arg saves. The idea is to change
21613 the function prologue as little as possible as it isn't easy to
21614 account for arg save/restore code added just for _mcount. */
21615 if (TARGET_PROFILE_KERNEL)
21618 if (DEFAULT_ABI == ABI_AIX)
21620 #ifndef NO_PROFILE_COUNTERS
21621 # define NO_PROFILE_COUNTERS 0
21623 if (NO_PROFILE_COUNTERS)
21624 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21625 LCT_NORMAL, VOIDmode, 0);
21629 const char *label_name;
21632 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21633 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
21634 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
21636 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
21637 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
21640 else if (DEFAULT_ABI == ABI_DARWIN)
21642 const char *mcount_name = RS6000_MCOUNT;
21643 int caller_addr_regno = LR_REGNO;
21645 /* Be conservative and always set this, at least for now. */
21646 crtl->uses_pic_offset_table = 1;
21649 /* For PIC code, set up a stub and collect the caller's address
21650 from r0, which is where the prologue puts it. */
21651 if (MACHOPIC_INDIRECT
21652 && crtl->uses_pic_offset_table)
21653 caller_addr_regno = 0;
21655 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
21656 LCT_NORMAL, VOIDmode, 1,
21657 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
21661 /* Write function profiler code. */
21664 output_function_profiler (FILE *file, int labelno)
21668 switch (DEFAULT_ABI)
21671 gcc_unreachable ();
21676 warning (0, "no profiling of 64-bit code for this ABI");
21679 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
21680 fprintf (file, "\tmflr %s\n", reg_names[0]);
21681 if (NO_PROFILE_COUNTERS)
21683 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21684 reg_names[0], reg_names[1]);
21686 else if (TARGET_SECURE_PLT && flag_pic)
21688 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
21689 reg_names[0], reg_names[1]);
21690 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21691 asm_fprintf (file, "\t{cau|addis} %s,%s,",
21692 reg_names[12], reg_names[12]);
21693 assemble_name (file, buf);
21694 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
21695 assemble_name (file, buf);
21696 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
21698 else if (flag_pic == 1)
21700 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
21701 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21702 reg_names[0], reg_names[1]);
21703 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
21704 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
21705 assemble_name (file, buf);
21706 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
21708 else if (flag_pic > 1)
21710 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21711 reg_names[0], reg_names[1]);
21712 /* Now, we need to get the address of the label. */
21713 fputs ("\tbcl 20,31,1f\n\t.long ", file);
21714 assemble_name (file, buf);
21715 fputs ("-.\n1:", file);
21716 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
21717 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
21718 reg_names[0], reg_names[11]);
21719 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
21720 reg_names[0], reg_names[0], reg_names[11]);
21724 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
21725 assemble_name (file, buf);
21726 fputs ("@ha\n", file);
21727 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
21728 reg_names[0], reg_names[1]);
21729 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
21730 assemble_name (file, buf);
21731 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
21734 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
21735 fprintf (file, "\tbl %s%s\n",
21736 RS6000_MCOUNT, flag_pic ? "@plt" : "");
21741 if (!TARGET_PROFILE_KERNEL)
21743 /* Don't do anything, done in output_profile_hook (). */
21747 gcc_assert (!TARGET_32BIT);
21749 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
21750 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
21752 if (cfun->static_chain_decl != NULL)
21754 asm_fprintf (file, "\tstd %s,24(%s)\n",
21755 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21756 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21757 asm_fprintf (file, "\tld %s,24(%s)\n",
21758 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
21761 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
21769 /* The following variable value is the last issued insn. */
21771 static rtx last_scheduled_insn;
21773 /* The following variable helps to balance issuing of load and
21774 store instructions */
21776 static int load_store_pendulum;
21778 /* Power4 load update and store update instructions are cracked into a
21779 load or store and an integer insn which are executed in the same cycle.
21780 Branches have their own dispatch slot which does not count against the
21781 GCC issue rate, but it changes the program flow so there are no other
21782 instructions to issue in this cycle. */
21785 rs6000_variable_issue_1 (rtx insn, int more)
21787 last_scheduled_insn = insn;
21788 if (GET_CODE (PATTERN (insn)) == USE
21789 || GET_CODE (PATTERN (insn)) == CLOBBER)
21791 cached_can_issue_more = more;
21792 return cached_can_issue_more;
21795 if (insn_terminates_group_p (insn, current_group))
21797 cached_can_issue_more = 0;
21798 return cached_can_issue_more;
21801 /* If no reservation, but reach here */
21802 if (recog_memoized (insn) < 0)
21805 if (rs6000_sched_groups)
21807 if (is_microcoded_insn (insn))
21808 cached_can_issue_more = 0;
21809 else if (is_cracked_insn (insn))
21810 cached_can_issue_more = more > 2 ? more - 2 : 0;
21812 cached_can_issue_more = more - 1;
21814 return cached_can_issue_more;
21817 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
21820 cached_can_issue_more = more - 1;
21821 return cached_can_issue_more;
21825 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
21827 int r = rs6000_variable_issue_1 (insn, more);
21829 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
21833 /* Adjust the cost of a scheduling dependency. Return the new cost of
21834 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
21837 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
21839 enum attr_type attr_type;
21841 if (! recog_memoized (insn))
21844 switch (REG_NOTE_KIND (link))
21848 /* Data dependency; DEP_INSN writes a register that INSN reads
21849 some cycles later. */
21851 /* Separate a load from a narrower, dependent store. */
21852 if (rs6000_sched_groups
21853 && GET_CODE (PATTERN (insn)) == SET
21854 && GET_CODE (PATTERN (dep_insn)) == SET
21855 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
21856 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
21857 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
21858 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
21861 attr_type = get_attr_type (insn);
21866 /* Tell the first scheduling pass about the latency between
21867 a mtctr and bctr (and mtlr and br/blr). The first
21868 scheduling pass will not know about this latency since
21869 the mtctr instruction, which has the latency associated
21870 to it, will be generated by reload. */
21871 return TARGET_POWER ? 5 : 4;
21873 /* Leave some extra cycles between a compare and its
21874 dependent branch, to inhibit expensive mispredicts. */
21875 if ((rs6000_cpu_attr == CPU_PPC603
21876 || rs6000_cpu_attr == CPU_PPC604
21877 || rs6000_cpu_attr == CPU_PPC604E
21878 || rs6000_cpu_attr == CPU_PPC620
21879 || rs6000_cpu_attr == CPU_PPC630
21880 || rs6000_cpu_attr == CPU_PPC750
21881 || rs6000_cpu_attr == CPU_PPC7400
21882 || rs6000_cpu_attr == CPU_PPC7450
21883 || rs6000_cpu_attr == CPU_POWER4
21884 || rs6000_cpu_attr == CPU_POWER5
21885 || rs6000_cpu_attr == CPU_POWER7
21886 || rs6000_cpu_attr == CPU_CELL)
21887 && recog_memoized (dep_insn)
21888 && (INSN_CODE (dep_insn) >= 0))
21890 switch (get_attr_type (dep_insn))
21894 case TYPE_DELAYED_COMPARE:
21895 case TYPE_IMUL_COMPARE:
21896 case TYPE_LMUL_COMPARE:
21897 case TYPE_FPCOMPARE:
21898 case TYPE_CR_LOGICAL:
21899 case TYPE_DELAYED_CR:
21908 case TYPE_STORE_UX:
21910 case TYPE_FPSTORE_U:
21911 case TYPE_FPSTORE_UX:
21912 if ((rs6000_cpu == PROCESSOR_POWER6)
21913 && recog_memoized (dep_insn)
21914 && (INSN_CODE (dep_insn) >= 0))
21917 if (GET_CODE (PATTERN (insn)) != SET)
21918 /* If this happens, we have to extend this to schedule
21919 optimally. Return default for now. */
21922 /* Adjust the cost for the case where the value written
21923 by a fixed point operation is used as the address
21924 gen value on a store. */
21925 switch (get_attr_type (dep_insn))
21932 if (! store_data_bypass_p (dep_insn, insn))
21936 case TYPE_LOAD_EXT:
21937 case TYPE_LOAD_EXT_U:
21938 case TYPE_LOAD_EXT_UX:
21939 case TYPE_VAR_SHIFT_ROTATE:
21940 case TYPE_VAR_DELAYED_COMPARE:
21942 if (! store_data_bypass_p (dep_insn, insn))
21948 case TYPE_FAST_COMPARE:
21951 case TYPE_INSERT_WORD:
21952 case TYPE_INSERT_DWORD:
21953 case TYPE_FPLOAD_U:
21954 case TYPE_FPLOAD_UX:
21956 case TYPE_STORE_UX:
21957 case TYPE_FPSTORE_U:
21958 case TYPE_FPSTORE_UX:
21960 if (! store_data_bypass_p (dep_insn, insn))
21968 case TYPE_IMUL_COMPARE:
21969 case TYPE_LMUL_COMPARE:
21971 if (! store_data_bypass_p (dep_insn, insn))
21977 if (! store_data_bypass_p (dep_insn, insn))
21983 if (! store_data_bypass_p (dep_insn, insn))
21996 case TYPE_LOAD_EXT:
21997 case TYPE_LOAD_EXT_U:
21998 case TYPE_LOAD_EXT_UX:
21999 if ((rs6000_cpu == PROCESSOR_POWER6)
22000 && recog_memoized (dep_insn)
22001 && (INSN_CODE (dep_insn) >= 0))
22004 /* Adjust the cost for the case where the value written
22005 by a fixed point instruction is used within the address
22006 gen portion of a subsequent load(u)(x) */
22007 switch (get_attr_type (dep_insn))
22014 if (set_to_load_agen (dep_insn, insn))
22018 case TYPE_LOAD_EXT:
22019 case TYPE_LOAD_EXT_U:
22020 case TYPE_LOAD_EXT_UX:
22021 case TYPE_VAR_SHIFT_ROTATE:
22022 case TYPE_VAR_DELAYED_COMPARE:
22024 if (set_to_load_agen (dep_insn, insn))
22030 case TYPE_FAST_COMPARE:
22033 case TYPE_INSERT_WORD:
22034 case TYPE_INSERT_DWORD:
22035 case TYPE_FPLOAD_U:
22036 case TYPE_FPLOAD_UX:
22038 case TYPE_STORE_UX:
22039 case TYPE_FPSTORE_U:
22040 case TYPE_FPSTORE_UX:
22042 if (set_to_load_agen (dep_insn, insn))
22050 case TYPE_IMUL_COMPARE:
22051 case TYPE_LMUL_COMPARE:
22053 if (set_to_load_agen (dep_insn, insn))
22059 if (set_to_load_agen (dep_insn, insn))
22065 if (set_to_load_agen (dep_insn, insn))
22076 if ((rs6000_cpu == PROCESSOR_POWER6)
22077 && recog_memoized (dep_insn)
22078 && (INSN_CODE (dep_insn) >= 0)
22079 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22086 /* Fall out to return default cost. */
22090 case REG_DEP_OUTPUT:
22091 /* Output dependency; DEP_INSN writes a register that INSN writes some
22093 if ((rs6000_cpu == PROCESSOR_POWER6)
22094 && recog_memoized (dep_insn)
22095 && (INSN_CODE (dep_insn) >= 0))
22097 attr_type = get_attr_type (insn);
22102 if (get_attr_type (dep_insn) == TYPE_FP)
22106 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
22114 /* Anti dependency; DEP_INSN reads a register that INSN writes some
22119 gcc_unreachable ();
22125 /* Debug version of rs6000_adjust_cost. */
22128 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22130 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
22136 switch (REG_NOTE_KIND (link))
22138 default: dep = "unknown depencency"; break;
22139 case REG_DEP_TRUE: dep = "data dependency"; break;
22140 case REG_DEP_OUTPUT: dep = "output dependency"; break;
22141 case REG_DEP_ANTI: dep = "anti depencency"; break;
22145 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
22146 "%s, insn:\n", ret, cost, dep);
22154 /* The function returns a true if INSN is microcoded.
22155 Return false otherwise. */
22158 is_microcoded_insn (rtx insn)
22160 if (!insn || !NONDEBUG_INSN_P (insn)
22161 || GET_CODE (PATTERN (insn)) == USE
22162 || GET_CODE (PATTERN (insn)) == CLOBBER)
22165 if (rs6000_cpu_attr == CPU_CELL)
22166 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
22168 if (rs6000_sched_groups)
22170 enum attr_type type = get_attr_type (insn);
22171 if (type == TYPE_LOAD_EXT_U
22172 || type == TYPE_LOAD_EXT_UX
22173 || type == TYPE_LOAD_UX
22174 || type == TYPE_STORE_UX
22175 || type == TYPE_MFCR)
22182 /* The function returns true if INSN is cracked into 2 instructions
22183 by the processor (and therefore occupies 2 issue slots). */
22186 is_cracked_insn (rtx insn)
22188 if (!insn || !NONDEBUG_INSN_P (insn)
22189 || GET_CODE (PATTERN (insn)) == USE
22190 || GET_CODE (PATTERN (insn)) == CLOBBER)
22193 if (rs6000_sched_groups)
22195 enum attr_type type = get_attr_type (insn);
22196 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
22197 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
22198 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
22199 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
22200 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
22201 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
22202 || type == TYPE_IDIV || type == TYPE_LDIV
22203 || type == TYPE_INSERT_WORD)
22210 /* The function returns true if INSN can be issued only from
22211 the branch slot. */
22214 is_branch_slot_insn (rtx insn)
22216 if (!insn || !NONDEBUG_INSN_P (insn)
22217 || GET_CODE (PATTERN (insn)) == USE
22218 || GET_CODE (PATTERN (insn)) == CLOBBER)
22221 if (rs6000_sched_groups)
22223 enum attr_type type = get_attr_type (insn);
22224 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
22232 /* The function returns true if out_inst sets a value that is
22233 used in the address generation computation of in_insn */
22235 set_to_load_agen (rtx out_insn, rtx in_insn)
22237 rtx out_set, in_set;
22239 /* For performance reasons, only handle the simple case where
22240 both loads are a single_set. */
22241 out_set = single_set (out_insn);
22244 in_set = single_set (in_insn);
22246 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
22252 /* The function returns true if the target storage location of
22253 out_insn is adjacent to the target storage location of in_insn */
22254 /* Return 1 if memory locations are adjacent. */
22257 adjacent_mem_locations (rtx insn1, rtx insn2)
22260 rtx a = get_store_dest (PATTERN (insn1));
22261 rtx b = get_store_dest (PATTERN (insn2));
22263 if ((GET_CODE (XEXP (a, 0)) == REG
22264 || (GET_CODE (XEXP (a, 0)) == PLUS
22265 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
22266 && (GET_CODE (XEXP (b, 0)) == REG
22267 || (GET_CODE (XEXP (b, 0)) == PLUS
22268 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
22270 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
22273 if (GET_CODE (XEXP (a, 0)) == PLUS)
22275 reg0 = XEXP (XEXP (a, 0), 0);
22276 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
22279 reg0 = XEXP (a, 0);
22281 if (GET_CODE (XEXP (b, 0)) == PLUS)
22283 reg1 = XEXP (XEXP (b, 0), 0);
22284 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
22287 reg1 = XEXP (b, 0);
22289 val_diff = val1 - val0;
22291 return ((REGNO (reg0) == REGNO (reg1))
22292 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
22293 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
22299 /* A C statement (sans semicolon) to update the integer scheduling
22300 priority INSN_PRIORITY (INSN). Increase the priority to execute the
22301 INSN earlier, reduce the priority to execute INSN later. Do not
22302 define this macro if you do not need to adjust the scheduling
22303 priorities of insns. */
22306 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
22308 /* On machines (like the 750) which have asymmetric integer units,
22309 where one integer unit can do multiply and divides and the other
22310 can't, reduce the priority of multiply/divide so it is scheduled
22311 before other integer operations. */
22314 if (! INSN_P (insn))
22317 if (GET_CODE (PATTERN (insn)) == USE)
22320 switch (rs6000_cpu_attr) {
22322 switch (get_attr_type (insn))
22329 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
22330 priority, priority);
22331 if (priority >= 0 && priority < 0x01000000)
22338 if (insn_must_be_first_in_group (insn)
22339 && reload_completed
22340 && current_sched_info->sched_max_insns_priority
22341 && rs6000_sched_restricted_insns_priority)
22344 /* Prioritize insns that can be dispatched only in the first
22346 if (rs6000_sched_restricted_insns_priority == 1)
22347 /* Attach highest priority to insn. This means that in
22348 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
22349 precede 'priority' (critical path) considerations. */
22350 return current_sched_info->sched_max_insns_priority;
22351 else if (rs6000_sched_restricted_insns_priority == 2)
22352 /* Increase priority of insn by a minimal amount. This means that in
22353 haifa-sched.c:ready_sort(), only 'priority' (critical path)
22354 considerations precede dispatch-slot restriction considerations. */
22355 return (priority + 1);
22358 if (rs6000_cpu == PROCESSOR_POWER6
22359 && ((load_store_pendulum == -2 && is_load_insn (insn))
22360 || (load_store_pendulum == 2 && is_store_insn (insn))))
22361 /* Attach highest priority to insn if the scheduler has just issued two
22362 stores and this instruction is a load, or two loads and this instruction
22363 is a store. Power6 wants loads and stores scheduled alternately
22365 return current_sched_info->sched_max_insns_priority;
22370 /* Return true if the instruction is nonpipelined on the Cell. */
22372 is_nonpipeline_insn (rtx insn)
22374 enum attr_type type;
22375 if (!insn || !NONDEBUG_INSN_P (insn)
22376 || GET_CODE (PATTERN (insn)) == USE
22377 || GET_CODE (PATTERN (insn)) == CLOBBER)
22380 type = get_attr_type (insn);
22381 if (type == TYPE_IMUL
22382 || type == TYPE_IMUL2
22383 || type == TYPE_IMUL3
22384 || type == TYPE_LMUL
22385 || type == TYPE_IDIV
22386 || type == TYPE_LDIV
22387 || type == TYPE_SDIV
22388 || type == TYPE_DDIV
22389 || type == TYPE_SSQRT
22390 || type == TYPE_DSQRT
22391 || type == TYPE_MFCR
22392 || type == TYPE_MFCRF
22393 || type == TYPE_MFJMPR)
22401 /* Return how many instructions the machine can issue per cycle. */
22404 rs6000_issue_rate (void)
22406 /* Unless scheduling for register pressure, use issue rate of 1 for
22407 first scheduling pass to decrease degradation. */
22408 if (!reload_completed && !flag_sched_pressure)
22411 switch (rs6000_cpu_attr) {
22412 case CPU_RIOS1: /* ? */
22414 case CPU_PPC601: /* ? */
22423 case CPU_PPCE300C2:
22424 case CPU_PPCE300C3:
22425 case CPU_PPCE500MC:
22426 case CPU_PPCE500MC64:
22445 /* Return how many instructions to look ahead for better insn
22449 rs6000_use_sched_lookahead (void)
22451 if (rs6000_cpu_attr == CPU_PPC8540)
22453 if (rs6000_cpu_attr == CPU_CELL)
22454 return (reload_completed ? 8 : 0);
22458 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
22460 rs6000_use_sched_lookahead_guard (rtx insn)
22462 if (rs6000_cpu_attr != CPU_CELL)
22465 if (insn == NULL_RTX || !INSN_P (insn))
22468 if (!reload_completed
22469 || is_nonpipeline_insn (insn)
22470 || is_microcoded_insn (insn))
22476 /* Determine is PAT refers to memory. */
22479 is_mem_ref (rtx pat)
22485 /* stack_tie does not produce any real memory traffic. */
22486 if (GET_CODE (pat) == UNSPEC
22487 && XINT (pat, 1) == UNSPEC_TIE)
22490 if (GET_CODE (pat) == MEM)
22493 /* Recursively process the pattern. */
22494 fmt = GET_RTX_FORMAT (GET_CODE (pat));
22496 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
22499 ret |= is_mem_ref (XEXP (pat, i));
22500 else if (fmt[i] == 'E')
22501 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
22502 ret |= is_mem_ref (XVECEXP (pat, i, j));
22508 /* Determine if PAT is a PATTERN of a load insn. */
22511 is_load_insn1 (rtx pat)
22513 if (!pat || pat == NULL_RTX)
22516 if (GET_CODE (pat) == SET)
22517 return is_mem_ref (SET_SRC (pat));
22519 if (GET_CODE (pat) == PARALLEL)
22523 for (i = 0; i < XVECLEN (pat, 0); i++)
22524 if (is_load_insn1 (XVECEXP (pat, 0, i)))
22531 /* Determine if INSN loads from memory. */
22534 is_load_insn (rtx insn)
22536 if (!insn || !INSN_P (insn))
22539 if (GET_CODE (insn) == CALL_INSN)
22542 return is_load_insn1 (PATTERN (insn));
22545 /* Determine if PAT is a PATTERN of a store insn. */
22548 is_store_insn1 (rtx pat)
22550 if (!pat || pat == NULL_RTX)
22553 if (GET_CODE (pat) == SET)
22554 return is_mem_ref (SET_DEST (pat));
22556 if (GET_CODE (pat) == PARALLEL)
22560 for (i = 0; i < XVECLEN (pat, 0); i++)
22561 if (is_store_insn1 (XVECEXP (pat, 0, i)))
22568 /* Determine if INSN stores to memory. */
22571 is_store_insn (rtx insn)
22573 if (!insn || !INSN_P (insn))
22576 return is_store_insn1 (PATTERN (insn));
22579 /* Return the dest of a store insn. */
22582 get_store_dest (rtx pat)
22584 gcc_assert (is_store_insn1 (pat));
22586 if (GET_CODE (pat) == SET)
22587 return SET_DEST (pat);
22588 else if (GET_CODE (pat) == PARALLEL)
22592 for (i = 0; i < XVECLEN (pat, 0); i++)
22594 rtx inner_pat = XVECEXP (pat, 0, i);
22595 if (GET_CODE (inner_pat) == SET
22596 && is_mem_ref (SET_DEST (inner_pat)))
22600 /* We shouldn't get here, because we should have either a simple
22601 store insn or a store with update which are covered above. */
22605 /* Returns whether the dependence between INSN and NEXT is considered
22606 costly by the given target. */
22609 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
22614 /* If the flag is not enabled - no dependence is considered costly;
22615 allow all dependent insns in the same group.
22616 This is the most aggressive option. */
22617 if (rs6000_sched_costly_dep == no_dep_costly)
22620 /* If the flag is set to 1 - a dependence is always considered costly;
22621 do not allow dependent instructions in the same group.
22622 This is the most conservative option. */
22623 if (rs6000_sched_costly_dep == all_deps_costly)
22626 insn = DEP_PRO (dep);
22627 next = DEP_CON (dep);
22629 if (rs6000_sched_costly_dep == store_to_load_dep_costly
22630 && is_load_insn (next)
22631 && is_store_insn (insn))
22632 /* Prevent load after store in the same group. */
22635 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
22636 && is_load_insn (next)
22637 && is_store_insn (insn)
22638 && DEP_TYPE (dep) == REG_DEP_TRUE)
22639 /* Prevent load after store in the same group if it is a true
22643 /* The flag is set to X; dependences with latency >= X are considered costly,
22644 and will not be scheduled in the same group. */
22645 if (rs6000_sched_costly_dep <= max_dep_latency
22646 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
22652 /* Return the next insn after INSN that is found before TAIL is reached,
22653 skipping any "non-active" insns - insns that will not actually occupy
22654 an issue slot. Return NULL_RTX if such an insn is not found. */
22657 get_next_active_insn (rtx insn, rtx tail)
22659 if (insn == NULL_RTX || insn == tail)
22664 insn = NEXT_INSN (insn);
22665 if (insn == NULL_RTX || insn == tail)
22670 || (NONJUMP_INSN_P (insn)
22671 && GET_CODE (PATTERN (insn)) != USE
22672 && GET_CODE (PATTERN (insn)) != CLOBBER
22673 && INSN_CODE (insn) != CODE_FOR_stack_tie))
22679 /* We are about to begin issuing insns for this clock cycle. */
22682 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
22683 rtx *ready ATTRIBUTE_UNUSED,
22684 int *pn_ready ATTRIBUTE_UNUSED,
22685 int clock_var ATTRIBUTE_UNUSED)
22687 int n_ready = *pn_ready;
22690 fprintf (dump, "// rs6000_sched_reorder :\n");
22692 /* Reorder the ready list, if the second to last ready insn
22693 is a nonepipeline insn. */
22694 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
22696 if (is_nonpipeline_insn (ready[n_ready - 1])
22697 && (recog_memoized (ready[n_ready - 2]) > 0))
22698 /* Simply swap first two insns. */
22700 rtx tmp = ready[n_ready - 1];
22701 ready[n_ready - 1] = ready[n_ready - 2];
22702 ready[n_ready - 2] = tmp;
22706 if (rs6000_cpu == PROCESSOR_POWER6)
22707 load_store_pendulum = 0;
22709 return rs6000_issue_rate ();
22712 /* Like rs6000_sched_reorder, but called after issuing each insn. */
22715 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
22716 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
22719 fprintf (dump, "// rs6000_sched_reorder2 :\n");
22721 /* For Power6, we need to handle some special cases to try and keep the
22722 store queue from overflowing and triggering expensive flushes.
22724 This code monitors how load and store instructions are being issued
22725 and skews the ready list one way or the other to increase the likelihood
22726 that a desired instruction is issued at the proper time.
22728 A couple of things are done. First, we maintain a "load_store_pendulum"
22729 to track the current state of load/store issue.
22731 - If the pendulum is at zero, then no loads or stores have been
22732 issued in the current cycle so we do nothing.
22734 - If the pendulum is 1, then a single load has been issued in this
22735 cycle and we attempt to locate another load in the ready list to
22738 - If the pendulum is -2, then two stores have already been
22739 issued in this cycle, so we increase the priority of the first load
22740 in the ready list to increase it's likelihood of being chosen first
22743 - If the pendulum is -1, then a single store has been issued in this
22744 cycle and we attempt to locate another store in the ready list to
22745 issue with it, preferring a store to an adjacent memory location to
22746 facilitate store pairing in the store queue.
22748 - If the pendulum is 2, then two loads have already been
22749 issued in this cycle, so we increase the priority of the first store
22750 in the ready list to increase it's likelihood of being chosen first
22753 - If the pendulum < -2 or > 2, then do nothing.
22755 Note: This code covers the most common scenarios. There exist non
22756 load/store instructions which make use of the LSU and which
22757 would need to be accounted for to strictly model the behavior
22758 of the machine. Those instructions are currently unaccounted
22759 for to help minimize compile time overhead of this code.
22761 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
22767 if (is_store_insn (last_scheduled_insn))
22768 /* Issuing a store, swing the load_store_pendulum to the left */
22769 load_store_pendulum--;
22770 else if (is_load_insn (last_scheduled_insn))
22771 /* Issuing a load, swing the load_store_pendulum to the right */
22772 load_store_pendulum++;
22774 return cached_can_issue_more;
22776 /* If the pendulum is balanced, or there is only one instruction on
22777 the ready list, then all is well, so return. */
22778 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
22779 return cached_can_issue_more;
22781 if (load_store_pendulum == 1)
22783 /* A load has been issued in this cycle. Scan the ready list
22784 for another load to issue with it */
22789 if (is_load_insn (ready[pos]))
22791 /* Found a load. Move it to the head of the ready list,
22792 and adjust it's priority so that it is more likely to
22795 for (i=pos; i<*pn_ready-1; i++)
22796 ready[i] = ready[i + 1];
22797 ready[*pn_ready-1] = tmp;
22799 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22800 INSN_PRIORITY (tmp)++;
22806 else if (load_store_pendulum == -2)
22808 /* Two stores have been issued in this cycle. Increase the
22809 priority of the first load in the ready list to favor it for
22810 issuing in the next cycle. */
22815 if (is_load_insn (ready[pos])
22817 && INSN_PRIORITY_KNOWN (ready[pos]))
22819 INSN_PRIORITY (ready[pos])++;
22821 /* Adjust the pendulum to account for the fact that a load
22822 was found and increased in priority. This is to prevent
22823 increasing the priority of multiple loads */
22824 load_store_pendulum--;
22831 else if (load_store_pendulum == -1)
22833 /* A store has been issued in this cycle. Scan the ready list for
22834 another store to issue with it, preferring a store to an adjacent
22836 int first_store_pos = -1;
22842 if (is_store_insn (ready[pos]))
22844 /* Maintain the index of the first store found on the
22846 if (first_store_pos == -1)
22847 first_store_pos = pos;
22849 if (is_store_insn (last_scheduled_insn)
22850 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
22852 /* Found an adjacent store. Move it to the head of the
22853 ready list, and adjust it's priority so that it is
22854 more likely to stay there */
22856 for (i=pos; i<*pn_ready-1; i++)
22857 ready[i] = ready[i + 1];
22858 ready[*pn_ready-1] = tmp;
22860 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22861 INSN_PRIORITY (tmp)++;
22863 first_store_pos = -1;
22871 if (first_store_pos >= 0)
22873 /* An adjacent store wasn't found, but a non-adjacent store was,
22874 so move the non-adjacent store to the front of the ready
22875 list, and adjust its priority so that it is more likely to
22877 tmp = ready[first_store_pos];
22878 for (i=first_store_pos; i<*pn_ready-1; i++)
22879 ready[i] = ready[i + 1];
22880 ready[*pn_ready-1] = tmp;
22881 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
22882 INSN_PRIORITY (tmp)++;
22885 else if (load_store_pendulum == 2)
22887 /* Two loads have been issued in this cycle. Increase the priority
22888 of the first store in the ready list to favor it for issuing in
22894 if (is_store_insn (ready[pos])
22896 && INSN_PRIORITY_KNOWN (ready[pos]))
22898 INSN_PRIORITY (ready[pos])++;
22900 /* Adjust the pendulum to account for the fact that a store
22901 was found and increased in priority. This is to prevent
22902 increasing the priority of multiple stores */
22903 load_store_pendulum++;
22912 return cached_can_issue_more;
22915 /* Return whether the presence of INSN causes a dispatch group termination
22916 of group WHICH_GROUP.
22918 If WHICH_GROUP == current_group, this function will return true if INSN
22919 causes the termination of the current group (i.e, the dispatch group to
22920 which INSN belongs). This means that INSN will be the last insn in the
22921 group it belongs to.
22923 If WHICH_GROUP == previous_group, this function will return true if INSN
22924 causes the termination of the previous group (i.e, the dispatch group that
22925 precedes the group to which INSN belongs). This means that INSN will be
22926 the first insn in the group it belongs to). */
22929 insn_terminates_group_p (rtx insn, enum group_termination which_group)
22936 first = insn_must_be_first_in_group (insn);
22937 last = insn_must_be_last_in_group (insn);
22942 if (which_group == current_group)
22944 else if (which_group == previous_group)
22952 insn_must_be_first_in_group (rtx insn)
22954 enum attr_type type;
22957 || GET_CODE (insn) == NOTE
22958 || DEBUG_INSN_P (insn)
22959 || GET_CODE (PATTERN (insn)) == USE
22960 || GET_CODE (PATTERN (insn)) == CLOBBER)
22963 switch (rs6000_cpu)
22965 case PROCESSOR_POWER5:
22966 if (is_cracked_insn (insn))
22968 case PROCESSOR_POWER4:
22969 if (is_microcoded_insn (insn))
22972 if (!rs6000_sched_groups)
22975 type = get_attr_type (insn);
22982 case TYPE_DELAYED_CR:
22983 case TYPE_CR_LOGICAL:
22997 case PROCESSOR_POWER6:
22998 type = get_attr_type (insn);
23002 case TYPE_INSERT_DWORD:
23006 case TYPE_VAR_SHIFT_ROTATE:
23013 case TYPE_INSERT_WORD:
23014 case TYPE_DELAYED_COMPARE:
23015 case TYPE_IMUL_COMPARE:
23016 case TYPE_LMUL_COMPARE:
23017 case TYPE_FPCOMPARE:
23028 case TYPE_LOAD_EXT_UX:
23030 case TYPE_STORE_UX:
23031 case TYPE_FPLOAD_U:
23032 case TYPE_FPLOAD_UX:
23033 case TYPE_FPSTORE_U:
23034 case TYPE_FPSTORE_UX:
23040 case PROCESSOR_POWER7:
23041 type = get_attr_type (insn);
23045 case TYPE_CR_LOGICAL:
23052 case TYPE_DELAYED_COMPARE:
23053 case TYPE_VAR_DELAYED_COMPARE:
23059 case TYPE_LOAD_EXT:
23060 case TYPE_LOAD_EXT_U:
23061 case TYPE_LOAD_EXT_UX:
23063 case TYPE_STORE_UX:
23064 case TYPE_FPLOAD_U:
23065 case TYPE_FPLOAD_UX:
23066 case TYPE_FPSTORE_U:
23067 case TYPE_FPSTORE_UX:
23083 insn_must_be_last_in_group (rtx insn)
23085 enum attr_type type;
23088 || GET_CODE (insn) == NOTE
23089 || DEBUG_INSN_P (insn)
23090 || GET_CODE (PATTERN (insn)) == USE
23091 || GET_CODE (PATTERN (insn)) == CLOBBER)
23094 switch (rs6000_cpu) {
23095 case PROCESSOR_POWER4:
23096 case PROCESSOR_POWER5:
23097 if (is_microcoded_insn (insn))
23100 if (is_branch_slot_insn (insn))
23104 case PROCESSOR_POWER6:
23105 type = get_attr_type (insn);
23112 case TYPE_VAR_SHIFT_ROTATE:
23119 case TYPE_DELAYED_COMPARE:
23120 case TYPE_IMUL_COMPARE:
23121 case TYPE_LMUL_COMPARE:
23122 case TYPE_FPCOMPARE:
23136 case PROCESSOR_POWER7:
23137 type = get_attr_type (insn);
23145 case TYPE_LOAD_EXT_U:
23146 case TYPE_LOAD_EXT_UX:
23147 case TYPE_STORE_UX:
23160 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
23161 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
23164 is_costly_group (rtx *group_insns, rtx next_insn)
23167 int issue_rate = rs6000_issue_rate ();
23169 for (i = 0; i < issue_rate; i++)
23171 sd_iterator_def sd_it;
23173 rtx insn = group_insns[i];
23178 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
23180 rtx next = DEP_CON (dep);
23182 if (next == next_insn
23183 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
23191 /* Utility of the function redefine_groups.
23192 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
23193 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
23194 to keep it "far" (in a separate group) from GROUP_INSNS, following
23195 one of the following schemes, depending on the value of the flag
23196 -minsert_sched_nops = X:
23197 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
23198 in order to force NEXT_INSN into a separate group.
23199 (2) X < sched_finish_regroup_exact: insert exactly X nops.
23200 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
23201 insertion (has a group just ended, how many vacant issue slots remain in the
23202 last group, and how many dispatch groups were encountered so far). */
23205 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
23206 rtx next_insn, bool *group_end, int can_issue_more,
23211 int issue_rate = rs6000_issue_rate ();
23212 bool end = *group_end;
23215 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
23216 return can_issue_more;
23218 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
23219 return can_issue_more;
23221 force = is_costly_group (group_insns, next_insn);
23223 return can_issue_more;
23225 if (sched_verbose > 6)
23226 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
23227 *group_count ,can_issue_more);
23229 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
23232 can_issue_more = 0;
23234 /* Since only a branch can be issued in the last issue_slot, it is
23235 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
23236 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
23237 in this case the last nop will start a new group and the branch
23238 will be forced to the new group. */
23239 if (can_issue_more && !is_branch_slot_insn (next_insn))
23242 while (can_issue_more > 0)
23245 emit_insn_before (nop, next_insn);
23253 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
23255 int n_nops = rs6000_sched_insert_nops;
23257 /* Nops can't be issued from the branch slot, so the effective
23258 issue_rate for nops is 'issue_rate - 1'. */
23259 if (can_issue_more == 0)
23260 can_issue_more = issue_rate;
23262 if (can_issue_more == 0)
23264 can_issue_more = issue_rate - 1;
23267 for (i = 0; i < issue_rate; i++)
23269 group_insns[i] = 0;
23276 emit_insn_before (nop, next_insn);
23277 if (can_issue_more == issue_rate - 1) /* new group begins */
23280 if (can_issue_more == 0)
23282 can_issue_more = issue_rate - 1;
23285 for (i = 0; i < issue_rate; i++)
23287 group_insns[i] = 0;
23293 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
23296 /* Is next_insn going to start a new group? */
23299 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23300 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23301 || (can_issue_more < issue_rate &&
23302 insn_terminates_group_p (next_insn, previous_group)));
23303 if (*group_end && end)
23306 if (sched_verbose > 6)
23307 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
23308 *group_count, can_issue_more);
23309 return can_issue_more;
23312 return can_issue_more;
23315 /* This function tries to synch the dispatch groups that the compiler "sees"
23316 with the dispatch groups that the processor dispatcher is expected to
23317 form in practice. It tries to achieve this synchronization by forcing the
23318 estimated processor grouping on the compiler (as opposed to the function
23319 'pad_goups' which tries to force the scheduler's grouping on the processor).
23321 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
23322 examines the (estimated) dispatch groups that will be formed by the processor
23323 dispatcher. It marks these group boundaries to reflect the estimated
23324 processor grouping, overriding the grouping that the scheduler had marked.
23325 Depending on the value of the flag '-minsert-sched-nops' this function can
23326 force certain insns into separate groups or force a certain distance between
23327 them by inserting nops, for example, if there exists a "costly dependence"
23330 The function estimates the group boundaries that the processor will form as
23331 follows: It keeps track of how many vacant issue slots are available after
23332 each insn. A subsequent insn will start a new group if one of the following
23334 - no more vacant issue slots remain in the current dispatch group.
23335 - only the last issue slot, which is the branch slot, is vacant, but the next
23336 insn is not a branch.
23337 - only the last 2 or less issue slots, including the branch slot, are vacant,
23338 which means that a cracked insn (which occupies two issue slots) can't be
23339 issued in this group.
23340 - less than 'issue_rate' slots are vacant, and the next insn always needs to
23341 start a new group. */
23344 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23346 rtx insn, next_insn;
23348 int can_issue_more;
23351 int group_count = 0;
23355 issue_rate = rs6000_issue_rate ();
23356 group_insns = XALLOCAVEC (rtx, issue_rate);
23357 for (i = 0; i < issue_rate; i++)
23359 group_insns[i] = 0;
23361 can_issue_more = issue_rate;
23363 insn = get_next_active_insn (prev_head_insn, tail);
23366 while (insn != NULL_RTX)
23368 slot = (issue_rate - can_issue_more);
23369 group_insns[slot] = insn;
23371 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23372 if (insn_terminates_group_p (insn, current_group))
23373 can_issue_more = 0;
23375 next_insn = get_next_active_insn (insn, tail);
23376 if (next_insn == NULL_RTX)
23377 return group_count + 1;
23379 /* Is next_insn going to start a new group? */
23381 = (can_issue_more == 0
23382 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
23383 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
23384 || (can_issue_more < issue_rate &&
23385 insn_terminates_group_p (next_insn, previous_group)));
23387 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
23388 next_insn, &group_end, can_issue_more,
23394 can_issue_more = 0;
23395 for (i = 0; i < issue_rate; i++)
23397 group_insns[i] = 0;
23401 if (GET_MODE (next_insn) == TImode && can_issue_more)
23402 PUT_MODE (next_insn, VOIDmode);
23403 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
23404 PUT_MODE (next_insn, TImode);
23407 if (can_issue_more == 0)
23408 can_issue_more = issue_rate;
23411 return group_count;
23414 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
23415 dispatch group boundaries that the scheduler had marked. Pad with nops
23416 any dispatch groups which have vacant issue slots, in order to force the
23417 scheduler's grouping on the processor dispatcher. The function
23418 returns the number of dispatch groups found. */
23421 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
23423 rtx insn, next_insn;
23426 int can_issue_more;
23428 int group_count = 0;
23430 /* Initialize issue_rate. */
23431 issue_rate = rs6000_issue_rate ();
23432 can_issue_more = issue_rate;
23434 insn = get_next_active_insn (prev_head_insn, tail);
23435 next_insn = get_next_active_insn (insn, tail);
23437 while (insn != NULL_RTX)
23440 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
23442 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
23444 if (next_insn == NULL_RTX)
23449 /* If the scheduler had marked group termination at this location
23450 (between insn and next_insn), and neither insn nor next_insn will
23451 force group termination, pad the group with nops to force group
23454 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
23455 && !insn_terminates_group_p (insn, current_group)
23456 && !insn_terminates_group_p (next_insn, previous_group))
23458 if (!is_branch_slot_insn (next_insn))
23461 while (can_issue_more)
23464 emit_insn_before (nop, next_insn);
23469 can_issue_more = issue_rate;
23474 next_insn = get_next_active_insn (insn, tail);
23477 return group_count;
23480 /* We're beginning a new block. Initialize data structures as necessary. */
23483 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
23484 int sched_verbose ATTRIBUTE_UNUSED,
23485 int max_ready ATTRIBUTE_UNUSED)
23487 last_scheduled_insn = NULL_RTX;
23488 load_store_pendulum = 0;
23491 /* The following function is called at the end of scheduling BB.
23492 After reload, it inserts nops at insn group bundling. */
23495 rs6000_sched_finish (FILE *dump, int sched_verbose)
23500 fprintf (dump, "=== Finishing schedule.\n");
23502 if (reload_completed && rs6000_sched_groups)
23504 /* Do not run sched_finish hook when selective scheduling enabled. */
23505 if (sel_sched_p ())
23508 if (rs6000_sched_insert_nops == sched_finish_none)
23511 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
23512 n_groups = pad_groups (dump, sched_verbose,
23513 current_sched_info->prev_head,
23514 current_sched_info->next_tail);
23516 n_groups = redefine_groups (dump, sched_verbose,
23517 current_sched_info->prev_head,
23518 current_sched_info->next_tail);
23520 if (sched_verbose >= 6)
23522 fprintf (dump, "ngroups = %d\n", n_groups);
23523 print_rtl (dump, current_sched_info->prev_head);
23524 fprintf (dump, "Done finish_sched\n");
23529 struct _rs6000_sched_context
23531 short cached_can_issue_more;
23532 rtx last_scheduled_insn;
23533 int load_store_pendulum;
23536 typedef struct _rs6000_sched_context rs6000_sched_context_def;
23537 typedef rs6000_sched_context_def *rs6000_sched_context_t;
23539 /* Allocate store for new scheduling context. */
23541 rs6000_alloc_sched_context (void)
23543 return xmalloc (sizeof (rs6000_sched_context_def));
23546 /* If CLEAN_P is true then initializes _SC with clean data,
23547 and from the global context otherwise. */
23549 rs6000_init_sched_context (void *_sc, bool clean_p)
23551 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23555 sc->cached_can_issue_more = 0;
23556 sc->last_scheduled_insn = NULL_RTX;
23557 sc->load_store_pendulum = 0;
23561 sc->cached_can_issue_more = cached_can_issue_more;
23562 sc->last_scheduled_insn = last_scheduled_insn;
23563 sc->load_store_pendulum = load_store_pendulum;
23567 /* Sets the global scheduling context to the one pointed to by _SC. */
23569 rs6000_set_sched_context (void *_sc)
23571 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
23573 gcc_assert (sc != NULL);
23575 cached_can_issue_more = sc->cached_can_issue_more;
23576 last_scheduled_insn = sc->last_scheduled_insn;
23577 load_store_pendulum = sc->load_store_pendulum;
23582 rs6000_free_sched_context (void *_sc)
23584 gcc_assert (_sc != NULL);
23590 /* Length in units of the trampoline for entering a nested function. */
23593 rs6000_trampoline_size (void)
23597 switch (DEFAULT_ABI)
23600 gcc_unreachable ();
23603 ret = (TARGET_32BIT) ? 12 : 24;
23608 ret = (TARGET_32BIT) ? 40 : 48;
23615 /* Emit RTL insns to initialize the variable parts of a trampoline.
23616 FNADDR is an RTX for the address of the function's pure code.
23617 CXT is an RTX for the static chain value for the function. */
23620 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
23622 int regsize = (TARGET_32BIT) ? 4 : 8;
23623 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
23624 rtx ctx_reg = force_reg (Pmode, cxt);
23625 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
23627 switch (DEFAULT_ABI)
23630 gcc_unreachable ();
23632 /* Under AIX, just build the 3 word function descriptor */
23635 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
23636 rtx fn_reg = gen_reg_rtx (Pmode);
23637 rtx toc_reg = gen_reg_rtx (Pmode);
23639 /* Macro to shorten the code expansions below. */
23640 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
23642 m_tramp = replace_equiv_address (m_tramp, addr);
23644 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
23645 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
23646 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
23647 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
23648 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
23654 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
23657 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
23658 LCT_NORMAL, VOIDmode, 4,
23660 GEN_INT (rs6000_trampoline_size ()), SImode,
23668 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
23669 identifier as an argument, so the front end shouldn't look it up. */
23672 rs6000_attribute_takes_identifier_p (const_tree attr_id)
23674 return is_attribute_p ("altivec", attr_id);
23677 /* Handle the "altivec" attribute. The attribute may have
23678 arguments as follows:
23680 __attribute__((altivec(vector__)))
23681 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
23682 __attribute__((altivec(bool__))) (always followed by 'unsigned')
23684 and may appear more than once (e.g., 'vector bool char') in a
23685 given declaration. */
23688 rs6000_handle_altivec_attribute (tree *node,
23689 tree name ATTRIBUTE_UNUSED,
23691 int flags ATTRIBUTE_UNUSED,
23692 bool *no_add_attrs)
23694 tree type = *node, result = NULL_TREE;
23695 enum machine_mode mode;
23698 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
23699 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
23700 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
23703 while (POINTER_TYPE_P (type)
23704 || TREE_CODE (type) == FUNCTION_TYPE
23705 || TREE_CODE (type) == METHOD_TYPE
23706 || TREE_CODE (type) == ARRAY_TYPE)
23707 type = TREE_TYPE (type);
23709 mode = TYPE_MODE (type);
23711 /* Check for invalid AltiVec type qualifiers. */
23712 if (type == long_double_type_node)
23713 error ("use of %<long double%> in AltiVec types is invalid");
23714 else if (type == boolean_type_node)
23715 error ("use of boolean types in AltiVec types is invalid");
23716 else if (TREE_CODE (type) == COMPLEX_TYPE)
23717 error ("use of %<complex%> in AltiVec types is invalid");
23718 else if (DECIMAL_FLOAT_MODE_P (mode))
23719 error ("use of decimal floating point types in AltiVec types is invalid");
23720 else if (!TARGET_VSX)
23722 if (type == long_unsigned_type_node || type == long_integer_type_node)
23725 error ("use of %<long%> in AltiVec types is invalid for "
23726 "64-bit code without -mvsx");
23727 else if (rs6000_warn_altivec_long)
23728 warning (0, "use of %<long%> in AltiVec types is deprecated; "
23731 else if (type == long_long_unsigned_type_node
23732 || type == long_long_integer_type_node)
23733 error ("use of %<long long%> in AltiVec types is invalid without "
23735 else if (type == double_type_node)
23736 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
23739 switch (altivec_type)
23742 unsigned_p = TYPE_UNSIGNED (type);
23746 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
23749 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
23752 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
23755 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
23757 case SFmode: result = V4SF_type_node; break;
23758 case DFmode: result = V2DF_type_node; break;
23759 /* If the user says 'vector int bool', we may be handed the 'bool'
23760 attribute _before_ the 'vector' attribute, and so select the
23761 proper type in the 'b' case below. */
23762 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
23763 case V2DImode: case V2DFmode:
23771 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
23772 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
23773 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
23774 case QImode: case V16QImode: result = bool_V16QI_type_node;
23781 case V8HImode: result = pixel_V8HI_type_node;
23787 /* Propagate qualifiers attached to the element type
23788 onto the vector type. */
23789 if (result && result != type && TYPE_QUALS (type))
23790 result = build_qualified_type (result, TYPE_QUALS (type));
23792 *no_add_attrs = true; /* No need to hang on to the attribute. */
23795 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
23800 /* AltiVec defines four built-in scalar types that serve as vector
23801 elements; we must teach the compiler how to mangle them. */
23803 static const char *
23804 rs6000_mangle_type (const_tree type)
23806 type = TYPE_MAIN_VARIANT (type);
23808 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
23809 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
23812 if (type == bool_char_type_node) return "U6__boolc";
23813 if (type == bool_short_type_node) return "U6__bools";
23814 if (type == pixel_type_node) return "u7__pixel";
23815 if (type == bool_int_type_node) return "U6__booli";
23816 if (type == bool_long_type_node) return "U6__booll";
23818 /* Mangle IBM extended float long double as `g' (__float128) on
23819 powerpc*-linux where long-double-64 previously was the default. */
23820 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
23822 && TARGET_LONG_DOUBLE_128
23823 && !TARGET_IEEEQUAD)
23826 /* For all other types, use normal C++ mangling. */
23830 /* Handle a "longcall" or "shortcall" attribute; arguments as in
23831 struct attribute_spec.handler. */
23834 rs6000_handle_longcall_attribute (tree *node, tree name,
23835 tree args ATTRIBUTE_UNUSED,
23836 int flags ATTRIBUTE_UNUSED,
23837 bool *no_add_attrs)
23839 if (TREE_CODE (*node) != FUNCTION_TYPE
23840 && TREE_CODE (*node) != FIELD_DECL
23841 && TREE_CODE (*node) != TYPE_DECL)
23843 warning (OPT_Wattributes, "%qE attribute only applies to functions",
23845 *no_add_attrs = true;
23851 /* Set longcall attributes on all functions declared when
23852 rs6000_default_long_calls is true. */
23854 rs6000_set_default_type_attributes (tree type)
23856 if (rs6000_default_long_calls
23857 && (TREE_CODE (type) == FUNCTION_TYPE
23858 || TREE_CODE (type) == METHOD_TYPE))
23859 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
23861 TYPE_ATTRIBUTES (type));
23864 darwin_set_default_type_attributes (type);
23868 /* Return a reference suitable for calling a function with the
23869 longcall attribute. */
23872 rs6000_longcall_ref (rtx call_ref)
23874 const char *call_name;
23877 if (GET_CODE (call_ref) != SYMBOL_REF)
23880 /* System V adds '.' to the internal name, so skip them. */
23881 call_name = XSTR (call_ref, 0);
23882 if (*call_name == '.')
23884 while (*call_name == '.')
23887 node = get_identifier (call_name);
23888 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
23891 return force_reg (Pmode, call_ref);
23894 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
23895 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
23898 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
23899 struct attribute_spec.handler. */
23901 rs6000_handle_struct_attribute (tree *node, tree name,
23902 tree args ATTRIBUTE_UNUSED,
23903 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
23906 if (DECL_P (*node))
23908 if (TREE_CODE (*node) == TYPE_DECL)
23909 type = &TREE_TYPE (*node);
23914 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
23915 || TREE_CODE (*type) == UNION_TYPE)))
23917 warning (OPT_Wattributes, "%qE attribute ignored", name);
23918 *no_add_attrs = true;
23921 else if ((is_attribute_p ("ms_struct", name)
23922 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
23923 || ((is_attribute_p ("gcc_struct", name)
23924 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
23926 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
23928 *no_add_attrs = true;
23935 rs6000_ms_bitfield_layout_p (const_tree record_type)
23937 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
23938 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23939 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
23942 #ifdef USING_ELFOS_H
23944 /* A get_unnamed_section callback, used for switching to toc_section. */
23947 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
23949 if (DEFAULT_ABI == ABI_AIX
23950 && TARGET_MINIMAL_TOC
23951 && !TARGET_RELOCATABLE)
23953 if (!toc_initialized)
23955 toc_initialized = 1;
23956 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23957 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
23958 fprintf (asm_out_file, "\t.tc ");
23959 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
23960 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23961 fprintf (asm_out_file, "\n");
23963 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23964 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23965 fprintf (asm_out_file, " = .+32768\n");
23968 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23970 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
23971 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
23974 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
23975 if (!toc_initialized)
23977 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
23978 fprintf (asm_out_file, " = .+32768\n");
23979 toc_initialized = 1;
23984 /* Implement TARGET_ASM_INIT_SECTIONS. */
23987 rs6000_elf_asm_init_sections (void)
23990 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
23993 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
23994 SDATA2_SECTION_ASM_OP);
23997 /* Implement TARGET_SELECT_RTX_SECTION. */
24000 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24001 unsigned HOST_WIDE_INT align)
24003 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24004 return toc_section;
24006 return default_elf_select_rtx_section (mode, x, align);
24009 /* For a SYMBOL_REF, set generic flags and then perform some
24010 target-specific processing.
24012 When the AIX ABI is requested on a non-AIX system, replace the
24013 function name with the real name (with a leading .) rather than the
24014 function descriptor name. This saves a lot of overriding code to
24015 read the prefixes. */
24018 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24020 default_encode_section_info (decl, rtl, first);
24023 && TREE_CODE (decl) == FUNCTION_DECL
24025 && DEFAULT_ABI == ABI_AIX)
24027 rtx sym_ref = XEXP (rtl, 0);
24028 size_t len = strlen (XSTR (sym_ref, 0));
24029 char *str = XALLOCAVEC (char, len + 2);
24031 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24032 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24037 compare_section_name (const char *section, const char *templ)
24041 len = strlen (templ);
24042 return (strncmp (section, templ, len) == 0
24043 && (section[len] == 0 || section[len] == '.'));
24047 rs6000_elf_in_small_data_p (const_tree decl)
24049 if (rs6000_sdata == SDATA_NONE)
24052 /* We want to merge strings, so we never consider them small data. */
24053 if (TREE_CODE (decl) == STRING_CST)
24056 /* Functions are never in the small data area. */
24057 if (TREE_CODE (decl) == FUNCTION_DECL)
24060 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24062 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24063 if (compare_section_name (section, ".sdata")
24064 || compare_section_name (section, ".sdata2")
24065 || compare_section_name (section, ".gnu.linkonce.s")
24066 || compare_section_name (section, ".sbss")
24067 || compare_section_name (section, ".sbss2")
24068 || compare_section_name (section, ".gnu.linkonce.sb")
24069 || strcmp (section, ".PPC.EMB.sdata0") == 0
24070 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24075 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24078 && (unsigned HOST_WIDE_INT) size <= g_switch_value
24079 /* If it's not public, and we're not going to reference it there,
24080 there's no need to put it in the small data section. */
24081 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24088 #endif /* USING_ELFOS_H */
24090 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24093 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24095 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24098 /* Return a REG that occurs in ADDR with coefficient 1.
24099 ADDR can be effectively incremented by incrementing REG.
24101 r0 is special and we must not select it as an address
24102 register by this routine since our caller will try to
24103 increment the returned register via an "la" instruction. */
24106 find_addr_reg (rtx addr)
24108 while (GET_CODE (addr) == PLUS)
24110 if (GET_CODE (XEXP (addr, 0)) == REG
24111 && REGNO (XEXP (addr, 0)) != 0)
24112 addr = XEXP (addr, 0);
24113 else if (GET_CODE (XEXP (addr, 1)) == REG
24114 && REGNO (XEXP (addr, 1)) != 0)
24115 addr = XEXP (addr, 1);
24116 else if (CONSTANT_P (XEXP (addr, 0)))
24117 addr = XEXP (addr, 1);
24118 else if (CONSTANT_P (XEXP (addr, 1)))
24119 addr = XEXP (addr, 0);
24121 gcc_unreachable ();
24123 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
24128 rs6000_fatal_bad_address (rtx op)
24130 fatal_insn ("bad address", op);
24135 static tree branch_island_list = 0;
24137 /* Remember to generate a branch island for far calls to the given
24141 add_compiler_branch_island (tree label_name, tree function_name,
24144 tree branch_island = build_tree_list (function_name, label_name);
24145 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
24146 TREE_CHAIN (branch_island) = branch_island_list;
24147 branch_island_list = branch_island;
24150 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
24151 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
24152 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
24153 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
24155 /* Generate far-jump branch islands for everything on the
24156 branch_island_list. Invoked immediately after the last instruction
24157 of the epilogue has been emitted; the branch-islands must be
24158 appended to, and contiguous with, the function body. Mach-O stubs
24159 are generated in machopic_output_stub(). */
24162 macho_branch_islands (void)
24165 tree branch_island;
24167 for (branch_island = branch_island_list;
24169 branch_island = TREE_CHAIN (branch_island))
24171 const char *label =
24172 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
24174 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
24175 char name_buf[512];
24176 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
24177 if (name[0] == '*' || name[0] == '&')
24178 strcpy (name_buf, name+1);
24182 strcpy (name_buf+1, name);
24184 strcpy (tmp_buf, "\n");
24185 strcat (tmp_buf, label);
24186 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24187 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24188 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24189 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24192 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
24193 strcat (tmp_buf, label);
24194 strcat (tmp_buf, "_pic\n");
24195 strcat (tmp_buf, label);
24196 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
24198 strcat (tmp_buf, "\taddis r11,r11,ha16(");
24199 strcat (tmp_buf, name_buf);
24200 strcat (tmp_buf, " - ");
24201 strcat (tmp_buf, label);
24202 strcat (tmp_buf, "_pic)\n");
24204 strcat (tmp_buf, "\tmtlr r0\n");
24206 strcat (tmp_buf, "\taddi r12,r11,lo16(");
24207 strcat (tmp_buf, name_buf);
24208 strcat (tmp_buf, " - ");
24209 strcat (tmp_buf, label);
24210 strcat (tmp_buf, "_pic)\n");
24212 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
24216 strcat (tmp_buf, ":\nlis r12,hi16(");
24217 strcat (tmp_buf, name_buf);
24218 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
24219 strcat (tmp_buf, name_buf);
24220 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
24222 output_asm_insn (tmp_buf, 0);
24223 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
24224 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
24225 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
24226 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
24229 branch_island_list = 0;
24232 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
24233 already there or not. */
24236 no_previous_def (tree function_name)
24238 tree branch_island;
24239 for (branch_island = branch_island_list;
24241 branch_island = TREE_CHAIN (branch_island))
24242 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24247 /* GET_PREV_LABEL gets the label name from the previous definition of
24251 get_prev_label (tree function_name)
24253 tree branch_island;
24254 for (branch_island = branch_island_list;
24256 branch_island = TREE_CHAIN (branch_island))
24257 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
24258 return BRANCH_ISLAND_LABEL_NAME (branch_island);
24262 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
24263 #define DARWIN_LINKER_GENERATES_ISLANDS 0
24266 /* KEXTs still need branch islands. */
24267 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
24268 || flag_mkernel || flag_apple_kext)
24270 /* INSN is either a function call or a millicode call. It may have an
24271 unconditional jump in its delay slot.
24273 CALL_DEST is the routine we are calling. */
24276 output_call (rtx insn, rtx *operands, int dest_operand_number,
24277 int cookie_operand_number)
24279 static char buf[256];
24280 if (DARWIN_GENERATE_ISLANDS
24281 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
24282 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
24285 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
24287 if (no_previous_def (funname))
24289 rtx label_rtx = gen_label_rtx ();
24290 char *label_buf, temp_buf[256];
24291 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
24292 CODE_LABEL_NUMBER (label_rtx));
24293 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
24294 labelname = get_identifier (label_buf);
24295 add_compiler_branch_island (labelname, funname, insn_line (insn));
24298 labelname = get_prev_label (funname);
24300 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
24301 instruction will reach 'foo', otherwise link as 'bl L42'".
24302 "L42" should be a 'branch island', that will do a far jump to
24303 'foo'. Branch islands are generated in
24304 macho_branch_islands(). */
24305 sprintf (buf, "jbsr %%z%d,%.246s",
24306 dest_operand_number, IDENTIFIER_POINTER (labelname));
24309 sprintf (buf, "bl %%z%d", dest_operand_number);
24313 /* Generate PIC and indirect symbol stubs. */
24316 machopic_output_stub (FILE *file, const char *symb, const char *stub)
24318 unsigned int length;
24319 char *symbol_name, *lazy_ptr_name;
24320 char *local_label_0;
24321 static int label = 0;
24323 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
24324 symb = (*targetm.strip_name_encoding) (symb);
24327 length = strlen (symb);
24328 symbol_name = XALLOCAVEC (char, length + 32);
24329 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
24331 lazy_ptr_name = XALLOCAVEC (char, length + 32);
24332 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
24335 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
24337 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
24341 fprintf (file, "\t.align 5\n");
24343 fprintf (file, "%s:\n", stub);
24344 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24347 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
24348 sprintf (local_label_0, "\"L%011d$spb\"", label);
24350 fprintf (file, "\tmflr r0\n");
24351 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
24352 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
24353 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
24354 lazy_ptr_name, local_label_0);
24355 fprintf (file, "\tmtlr r0\n");
24356 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
24357 (TARGET_64BIT ? "ldu" : "lwzu"),
24358 lazy_ptr_name, local_label_0);
24359 fprintf (file, "\tmtctr r12\n");
24360 fprintf (file, "\tbctr\n");
24364 fprintf (file, "\t.align 4\n");
24366 fprintf (file, "%s:\n", stub);
24367 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24369 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
24370 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
24371 (TARGET_64BIT ? "ldu" : "lwzu"),
24373 fprintf (file, "\tmtctr r12\n");
24374 fprintf (file, "\tbctr\n");
24377 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
24378 fprintf (file, "%s:\n", lazy_ptr_name);
24379 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
24380 fprintf (file, "%sdyld_stub_binding_helper\n",
24381 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
24384 /* Legitimize PIC addresses. If the address is already
24385 position-independent, we return ORIG. Newly generated
24386 position-independent addresses go into a reg. This is REG if non
24387 zero, otherwise we allocate register(s) as necessary. */
24389 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
24392 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
24397 if (reg == NULL && ! reload_in_progress && ! reload_completed)
24398 reg = gen_reg_rtx (Pmode);
24400 if (GET_CODE (orig) == CONST)
24404 if (GET_CODE (XEXP (orig, 0)) == PLUS
24405 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
24408 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
24410 /* Use a different reg for the intermediate value, as
24411 it will be marked UNCHANGING. */
24412 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
24413 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
24416 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
24419 if (GET_CODE (offset) == CONST_INT)
24421 if (SMALL_INT (offset))
24422 return plus_constant (base, INTVAL (offset));
24423 else if (! reload_in_progress && ! reload_completed)
24424 offset = force_reg (Pmode, offset);
24427 rtx mem = force_const_mem (Pmode, orig);
24428 return machopic_legitimize_pic_address (mem, Pmode, reg);
24431 return gen_rtx_PLUS (Pmode, base, offset);
24434 /* Fall back on generic machopic code. */
24435 return machopic_legitimize_pic_address (orig, mode, reg);
24438 /* Output a .machine directive for the Darwin assembler, and call
24439 the generic start_file routine. */
24442 rs6000_darwin_file_start (void)
24444 static const struct
24450 { "ppc64", "ppc64", MASK_64BIT },
24451 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
24452 { "power4", "ppc970", 0 },
24453 { "G5", "ppc970", 0 },
24454 { "7450", "ppc7450", 0 },
24455 { "7400", "ppc7400", MASK_ALTIVEC },
24456 { "G4", "ppc7400", 0 },
24457 { "750", "ppc750", 0 },
24458 { "740", "ppc750", 0 },
24459 { "G3", "ppc750", 0 },
24460 { "604e", "ppc604e", 0 },
24461 { "604", "ppc604", 0 },
24462 { "603e", "ppc603", 0 },
24463 { "603", "ppc603", 0 },
24464 { "601", "ppc601", 0 },
24465 { NULL, "ppc", 0 } };
24466 const char *cpu_id = "";
24469 rs6000_file_start ();
24470 darwin_file_start ();
24472 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
24473 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
24474 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
24475 && rs6000_select[i].string[0] != '\0')
24476 cpu_id = rs6000_select[i].string;
24478 /* Look through the mapping array. Pick the first name that either
24479 matches the argument, has a bit set in IF_SET that is also set
24480 in the target flags, or has a NULL name. */
24483 while (mapping[i].arg != NULL
24484 && strcmp (mapping[i].arg, cpu_id) != 0
24485 && (mapping[i].if_set & target_flags) == 0)
24488 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
24491 #endif /* TARGET_MACHO */
24495 rs6000_elf_reloc_rw_mask (void)
24499 else if (DEFAULT_ABI == ABI_AIX)
24505 /* Record an element in the table of global constructors. SYMBOL is
24506 a SYMBOL_REF of the function to be called; PRIORITY is a number
24507 between 0 and MAX_INIT_PRIORITY.
24509 This differs from default_named_section_asm_out_constructor in
24510 that we have special handling for -mrelocatable. */
24513 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
24515 const char *section = ".ctors";
24518 if (priority != DEFAULT_INIT_PRIORITY)
24520 sprintf (buf, ".ctors.%.5u",
24521 /* Invert the numbering so the linker puts us in the proper
24522 order; constructors are run from right to left, and the
24523 linker sorts in increasing order. */
24524 MAX_INIT_PRIORITY - priority);
24528 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24529 assemble_align (POINTER_SIZE);
24531 if (TARGET_RELOCATABLE)
24533 fputs ("\t.long (", asm_out_file);
24534 output_addr_const (asm_out_file, symbol);
24535 fputs (")@fixup\n", asm_out_file);
24538 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24542 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
24544 const char *section = ".dtors";
24547 if (priority != DEFAULT_INIT_PRIORITY)
24549 sprintf (buf, ".dtors.%.5u",
24550 /* Invert the numbering so the linker puts us in the proper
24551 order; constructors are run from right to left, and the
24552 linker sorts in increasing order. */
24553 MAX_INIT_PRIORITY - priority);
24557 switch_to_section (get_section (section, SECTION_WRITE, NULL));
24558 assemble_align (POINTER_SIZE);
24560 if (TARGET_RELOCATABLE)
24562 fputs ("\t.long (", asm_out_file);
24563 output_addr_const (asm_out_file, symbol);
24564 fputs (")@fixup\n", asm_out_file);
24567 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
24571 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
24575 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
24576 ASM_OUTPUT_LABEL (file, name);
24577 fputs (DOUBLE_INT_ASM_OP, file);
24578 rs6000_output_function_entry (file, name);
24579 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
24582 fputs ("\t.size\t", file);
24583 assemble_name (file, name);
24584 fputs (",24\n\t.type\t.", file);
24585 assemble_name (file, name);
24586 fputs (",@function\n", file);
24587 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
24589 fputs ("\t.globl\t.", file);
24590 assemble_name (file, name);
24595 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24596 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24597 rs6000_output_function_entry (file, name);
24598 fputs (":\n", file);
24602 if (TARGET_RELOCATABLE
24603 && !TARGET_SECURE_PLT
24604 && (get_pool_size () != 0 || crtl->profile)
24609 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
24611 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
24612 fprintf (file, "\t.long ");
24613 assemble_name (file, buf);
24615 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
24616 assemble_name (file, buf);
24620 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
24621 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
24623 if (DEFAULT_ABI == ABI_AIX)
24625 const char *desc_name, *orig_name;
24627 orig_name = (*targetm.strip_name_encoding) (name);
24628 desc_name = orig_name;
24629 while (*desc_name == '.')
24632 if (TREE_PUBLIC (decl))
24633 fprintf (file, "\t.globl %s\n", desc_name);
24635 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24636 fprintf (file, "%s:\n", desc_name);
24637 fprintf (file, "\t.long %s\n", orig_name);
24638 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
24639 if (DEFAULT_ABI == ABI_AIX)
24640 fputs ("\t.long 0\n", file);
24641 fprintf (file, "\t.previous\n");
24643 ASM_OUTPUT_LABEL (file, name);
24647 rs6000_elf_end_indicate_exec_stack (void)
24650 file_end_indicate_exec_stack ();
24656 rs6000_xcoff_asm_output_anchor (rtx symbol)
24660 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
24661 SYMBOL_REF_BLOCK_OFFSET (symbol));
24662 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
24666 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
24668 fputs (GLOBAL_ASM_OP, stream);
24669 RS6000_OUTPUT_BASENAME (stream, name);
24670 putc ('\n', stream);
24673 /* A get_unnamed_decl callback, used for read-only sections. PTR
24674 points to the section string variable. */
24677 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
24679 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
24680 *(const char *const *) directive,
24681 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24684 /* Likewise for read-write sections. */
24687 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
24689 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
24690 *(const char *const *) directive,
24691 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
24694 /* A get_unnamed_section callback, used for switching to toc_section. */
24697 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24699 if (TARGET_MINIMAL_TOC)
24701 /* toc_section is always selected at least once from
24702 rs6000_xcoff_file_start, so this is guaranteed to
24703 always be defined once and only once in each file. */
24704 if (!toc_initialized)
24706 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
24707 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
24708 toc_initialized = 1;
24710 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
24711 (TARGET_32BIT ? "" : ",3"));
24714 fputs ("\t.toc\n", asm_out_file);
24717 /* Implement TARGET_ASM_INIT_SECTIONS. */
24720 rs6000_xcoff_asm_init_sections (void)
24722 read_only_data_section
24723 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24724 &xcoff_read_only_section_name);
24726 private_data_section
24727 = get_unnamed_section (SECTION_WRITE,
24728 rs6000_xcoff_output_readwrite_section_asm_op,
24729 &xcoff_private_data_section_name);
24731 read_only_private_data_section
24732 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
24733 &xcoff_private_data_section_name);
24736 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
24738 readonly_data_section = read_only_data_section;
24739 exception_section = data_section;
24743 rs6000_xcoff_reloc_rw_mask (void)
24749 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
24750 tree decl ATTRIBUTE_UNUSED)
24753 static const char * const suffix[3] = { "PR", "RO", "RW" };
24755 if (flags & SECTION_CODE)
24757 else if (flags & SECTION_WRITE)
24762 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
24763 (flags & SECTION_CODE) ? "." : "",
24764 name, suffix[smclass], flags & SECTION_ENTSIZE);
24768 rs6000_xcoff_select_section (tree decl, int reloc,
24769 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24771 if (decl_readonly_section (decl, reloc))
24773 if (TREE_PUBLIC (decl))
24774 return read_only_data_section;
24776 return read_only_private_data_section;
24780 if (TREE_PUBLIC (decl))
24781 return data_section;
24783 return private_data_section;
24788 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
24792 /* Use select_section for private and uninitialized data. */
24793 if (!TREE_PUBLIC (decl)
24794 || DECL_COMMON (decl)
24795 || DECL_INITIAL (decl) == NULL_TREE
24796 || DECL_INITIAL (decl) == error_mark_node
24797 || (flag_zero_initialized_in_bss
24798 && initializer_zerop (DECL_INITIAL (decl))))
24801 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
24802 name = (*targetm.strip_name_encoding) (name);
24803 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
24806 /* Select section for constant in constant pool.
24808 On RS/6000, all constants are in the private read-only data area.
24809 However, if this is being placed in the TOC it must be output as a
24813 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
24814 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
24816 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24817 return toc_section;
24819 return read_only_private_data_section;
24822 /* Remove any trailing [DS] or the like from the symbol name. */
24824 static const char *
24825 rs6000_xcoff_strip_name_encoding (const char *name)
24830 len = strlen (name);
24831 if (name[len - 1] == ']')
24832 return ggc_alloc_string (name, len - 4);
24837 /* Section attributes. AIX is always PIC. */
24839 static unsigned int
24840 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
24842 unsigned int align;
24843 unsigned int flags = default_section_type_flags (decl, name, reloc);
24845 /* Align to at least UNIT size. */
24846 if (flags & SECTION_CODE)
24847 align = MIN_UNITS_PER_WORD;
24849 /* Increase alignment of large objects if not already stricter. */
24850 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
24851 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
24852 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
24854 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
24857 /* Output at beginning of assembler file.
24859 Initialize the section names for the RS/6000 at this point.
24861 Specify filename, including full path, to assembler.
24863 We want to go into the TOC section so at least one .toc will be emitted.
24864 Also, in order to output proper .bs/.es pairs, we need at least one static
24865 [RW] section emitted.
24867 Finally, declare mcount when profiling to make the assembler happy. */
24870 rs6000_xcoff_file_start (void)
24872 rs6000_gen_section_name (&xcoff_bss_section_name,
24873 main_input_filename, ".bss_");
24874 rs6000_gen_section_name (&xcoff_private_data_section_name,
24875 main_input_filename, ".rw_");
24876 rs6000_gen_section_name (&xcoff_read_only_section_name,
24877 main_input_filename, ".ro_");
24879 fputs ("\t.file\t", asm_out_file);
24880 output_quoted_string (asm_out_file, main_input_filename);
24881 fputc ('\n', asm_out_file);
24882 if (write_symbols != NO_DEBUG)
24883 switch_to_section (private_data_section);
24884 switch_to_section (text_section);
24886 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
24887 rs6000_file_start ();
24890 /* Output at end of assembler file.
24891 On the RS/6000, referencing data should automatically pull in text. */
24894 rs6000_xcoff_file_end (void)
24896 switch_to_section (text_section);
24897 fputs ("_section_.text:\n", asm_out_file);
24898 switch_to_section (data_section);
24899 fputs (TARGET_32BIT
24900 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
24903 #endif /* TARGET_XCOFF */
24905 /* Compute a (partial) cost for rtx X. Return true if the complete
24906 cost has been computed, and false if subexpressions should be
24907 scanned. In either case, *TOTAL contains the cost result. */
24910 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
24913 enum machine_mode mode = GET_MODE (x);
24917 /* On the RS/6000, if it is valid in the insn, it is free. */
24919 if (((outer_code == SET
24920 || outer_code == PLUS
24921 || outer_code == MINUS)
24922 && (satisfies_constraint_I (x)
24923 || satisfies_constraint_L (x)))
24924 || (outer_code == AND
24925 && (satisfies_constraint_K (x)
24927 ? satisfies_constraint_L (x)
24928 : satisfies_constraint_J (x))
24929 || mask_operand (x, mode)
24931 && mask64_operand (x, DImode))))
24932 || ((outer_code == IOR || outer_code == XOR)
24933 && (satisfies_constraint_K (x)
24935 ? satisfies_constraint_L (x)
24936 : satisfies_constraint_J (x))))
24937 || outer_code == ASHIFT
24938 || outer_code == ASHIFTRT
24939 || outer_code == LSHIFTRT
24940 || outer_code == ROTATE
24941 || outer_code == ROTATERT
24942 || outer_code == ZERO_EXTRACT
24943 || (outer_code == MULT
24944 && satisfies_constraint_I (x))
24945 || ((outer_code == DIV || outer_code == UDIV
24946 || outer_code == MOD || outer_code == UMOD)
24947 && exact_log2 (INTVAL (x)) >= 0)
24948 || (outer_code == COMPARE
24949 && (satisfies_constraint_I (x)
24950 || satisfies_constraint_K (x)))
24951 || (outer_code == EQ
24952 && (satisfies_constraint_I (x)
24953 || satisfies_constraint_K (x)
24955 ? satisfies_constraint_L (x)
24956 : satisfies_constraint_J (x))))
24957 || (outer_code == GTU
24958 && satisfies_constraint_I (x))
24959 || (outer_code == LTU
24960 && satisfies_constraint_P (x)))
24965 else if ((outer_code == PLUS
24966 && reg_or_add_cint_operand (x, VOIDmode))
24967 || (outer_code == MINUS
24968 && reg_or_sub_cint_operand (x, VOIDmode))
24969 || ((outer_code == SET
24970 || outer_code == IOR
24971 || outer_code == XOR)
24973 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
24975 *total = COSTS_N_INSNS (1);
24981 if (mode == DImode && code == CONST_DOUBLE)
24983 if ((outer_code == IOR || outer_code == XOR)
24984 && CONST_DOUBLE_HIGH (x) == 0
24985 && (CONST_DOUBLE_LOW (x)
24986 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
24991 else if ((outer_code == AND && and64_2_operand (x, DImode))
24992 || ((outer_code == SET
24993 || outer_code == IOR
24994 || outer_code == XOR)
24995 && CONST_DOUBLE_HIGH (x) == 0))
24997 *total = COSTS_N_INSNS (1);
25007 /* When optimizing for size, MEM should be slightly more expensive
25008 than generating address, e.g., (plus (reg) (const)).
25009 L1 cache latency is about two instructions. */
25010 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25018 if (mode == DFmode)
25020 if (GET_CODE (XEXP (x, 0)) == MULT)
25022 /* FNMA accounted in outer NEG. */
25023 if (outer_code == NEG)
25024 *total = rs6000_cost->dmul - rs6000_cost->fp;
25026 *total = rs6000_cost->dmul;
25029 *total = rs6000_cost->fp;
25031 else if (mode == SFmode)
25033 /* FNMA accounted in outer NEG. */
25034 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25037 *total = rs6000_cost->fp;
25040 *total = COSTS_N_INSNS (1);
25044 if (mode == DFmode)
25046 if (GET_CODE (XEXP (x, 0)) == MULT
25047 || GET_CODE (XEXP (x, 1)) == MULT)
25049 /* FNMA accounted in outer NEG. */
25050 if (outer_code == NEG)
25051 *total = rs6000_cost->dmul - rs6000_cost->fp;
25053 *total = rs6000_cost->dmul;
25056 *total = rs6000_cost->fp;
25058 else if (mode == SFmode)
25060 /* FNMA accounted in outer NEG. */
25061 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25064 *total = rs6000_cost->fp;
25067 *total = COSTS_N_INSNS (1);
25071 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25072 && satisfies_constraint_I (XEXP (x, 1)))
25074 if (INTVAL (XEXP (x, 1)) >= -256
25075 && INTVAL (XEXP (x, 1)) <= 255)
25076 *total = rs6000_cost->mulsi_const9;
25078 *total = rs6000_cost->mulsi_const;
25080 /* FMA accounted in outer PLUS/MINUS. */
25081 else if ((mode == DFmode || mode == SFmode)
25082 && (outer_code == PLUS || outer_code == MINUS))
25084 else if (mode == DFmode)
25085 *total = rs6000_cost->dmul;
25086 else if (mode == SFmode)
25087 *total = rs6000_cost->fp;
25088 else if (mode == DImode)
25089 *total = rs6000_cost->muldi;
25091 *total = rs6000_cost->mulsi;
25096 if (FLOAT_MODE_P (mode))
25098 *total = mode == DFmode ? rs6000_cost->ddiv
25099 : rs6000_cost->sdiv;
25106 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25107 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
25109 if (code == DIV || code == MOD)
25111 *total = COSTS_N_INSNS (2);
25114 *total = COSTS_N_INSNS (1);
25118 if (GET_MODE (XEXP (x, 1)) == DImode)
25119 *total = rs6000_cost->divdi;
25121 *total = rs6000_cost->divsi;
25123 /* Add in shift and subtract for MOD. */
25124 if (code == MOD || code == UMOD)
25125 *total += COSTS_N_INSNS (2);
25130 *total = COSTS_N_INSNS (4);
25134 *total = COSTS_N_INSNS (6);
25138 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
25150 *total = COSTS_N_INSNS (1);
25158 /* Handle mul_highpart. */
25159 if (outer_code == TRUNCATE
25160 && GET_CODE (XEXP (x, 0)) == MULT)
25162 if (mode == DImode)
25163 *total = rs6000_cost->muldi;
25165 *total = rs6000_cost->mulsi;
25168 else if (outer_code == AND)
25171 *total = COSTS_N_INSNS (1);
25176 if (GET_CODE (XEXP (x, 0)) == MEM)
25179 *total = COSTS_N_INSNS (1);
25185 if (!FLOAT_MODE_P (mode))
25187 *total = COSTS_N_INSNS (1);
25193 case UNSIGNED_FLOAT:
25196 case FLOAT_TRUNCATE:
25197 *total = rs6000_cost->fp;
25201 if (mode == DFmode)
25204 *total = rs6000_cost->fp;
25208 switch (XINT (x, 1))
25211 *total = rs6000_cost->fp;
25223 *total = COSTS_N_INSNS (1);
25226 else if (FLOAT_MODE_P (mode)
25227 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
25229 *total = rs6000_cost->fp;
25237 /* Carry bit requires mode == Pmode.
25238 NEG or PLUS already counted so only add one. */
25240 && (outer_code == NEG || outer_code == PLUS))
25242 *total = COSTS_N_INSNS (1);
25245 if (outer_code == SET)
25247 if (XEXP (x, 1) == const0_rtx)
25249 if (TARGET_ISEL && !TARGET_MFCRF)
25250 *total = COSTS_N_INSNS (8);
25252 *total = COSTS_N_INSNS (2);
25255 else if (mode == Pmode)
25257 *total = COSTS_N_INSNS (3);
25266 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
25268 if (TARGET_ISEL && !TARGET_MFCRF)
25269 *total = COSTS_N_INSNS (8);
25271 *total = COSTS_N_INSNS (2);
25275 if (outer_code == COMPARE)
25289 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
25292 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
25295 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
25298 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
25299 "total = %d, speed = %s, x:\n",
25300 ret ? "complete" : "scan inner",
25301 GET_RTX_NAME (code),
25302 GET_RTX_NAME (outer_code),
25304 speed ? "true" : "false");
25311 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
25314 rs6000_debug_address_cost (rtx x, bool speed)
25316 int ret = TARGET_ADDRESS_COST (x, speed);
25318 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
25319 ret, speed ? "true" : "false");
25326 /* A C expression returning the cost of moving data from a register of class
25327 CLASS1 to one of CLASS2. */
25330 rs6000_register_move_cost (enum machine_mode mode,
25331 enum reg_class from, enum reg_class to)
25335 /* Moves from/to GENERAL_REGS. */
25336 if (reg_classes_intersect_p (to, GENERAL_REGS)
25337 || reg_classes_intersect_p (from, GENERAL_REGS))
25339 if (! reg_classes_intersect_p (to, GENERAL_REGS))
25342 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
25343 ret = (rs6000_memory_move_cost (mode, from, 0)
25344 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
25346 /* It's more expensive to move CR_REGS than CR0_REGS because of the
25348 else if (from == CR_REGS)
25351 /* Power6 has slower LR/CTR moves so make them more expensive than
25352 memory in order to bias spills to memory .*/
25353 else if (rs6000_cpu == PROCESSOR_POWER6
25354 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
25355 ret = 6 * hard_regno_nregs[0][mode];
25358 /* A move will cost one instruction per GPR moved. */
25359 ret = 2 * hard_regno_nregs[0][mode];
25362 /* If we have VSX, we can easily move between FPR or Altivec registers. */
25363 else if (VECTOR_UNIT_VSX_P (mode)
25364 && reg_classes_intersect_p (to, VSX_REGS)
25365 && reg_classes_intersect_p (from, VSX_REGS))
25366 ret = 2 * hard_regno_nregs[32][mode];
25368 /* Moving between two similar registers is just one instruction. */
25369 else if (reg_classes_intersect_p (to, from))
25370 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
25372 /* Everything else has to go through GENERAL_REGS. */
25374 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
25375 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
25377 if (TARGET_DEBUG_COST)
25379 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
25380 ret, GET_MODE_NAME (mode), reg_class_names[from],
25381 reg_class_names[to]);
25386 /* A C expressions returning the cost of moving data of MODE from a register to
25390 rs6000_memory_move_cost (enum machine_mode mode, enum reg_class rclass,
25391 int in ATTRIBUTE_UNUSED)
25395 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
25396 ret = 4 * hard_regno_nregs[0][mode];
25397 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
25398 ret = 4 * hard_regno_nregs[32][mode];
25399 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
25400 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
25402 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
25404 if (TARGET_DEBUG_COST)
25406 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
25407 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
25412 /* Returns a code for a target-specific builtin that implements
25413 reciprocal of the function, or NULL_TREE if not available. */
25416 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
25417 bool sqrt ATTRIBUTE_UNUSED)
25419 if (optimize_insn_for_size_p ())
25425 case VSX_BUILTIN_XVSQRTDP:
25426 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
25429 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
25431 case VSX_BUILTIN_XVSQRTSP:
25432 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
25435 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
25444 case BUILT_IN_SQRT:
25445 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
25448 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
25450 case BUILT_IN_SQRTF:
25451 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
25454 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
25461 /* Load up a constant. If the mode is a vector mode, splat the value across
25462 all of the vector elements. */
25465 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
25469 if (mode == SFmode || mode == DFmode)
25471 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
25472 reg = force_reg (mode, d);
25474 else if (mode == V4SFmode)
25476 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
25477 rtvec v = gen_rtvec (4, d, d, d, d);
25478 reg = gen_reg_rtx (mode);
25479 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25481 else if (mode == V2DFmode)
25483 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
25484 rtvec v = gen_rtvec (2, d, d);
25485 reg = gen_reg_rtx (mode);
25486 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
25489 gcc_unreachable ();
25494 /* Generate a FMADD instruction:
25495 dst = (m1 * m2) + a
25497 generating different RTL based on the fused multiply/add switch. */
25500 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
25502 enum machine_mode mode = GET_MODE (dst);
25504 if (!TARGET_FUSED_MADD)
25506 /* For the simple ops, use the generator function, rather than assuming
25507 that the RTL is standard. */
25508 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25509 enum insn_code acode = optab_handler (add_optab, mode)->insn_code;
25510 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25511 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
25512 rtx mreg = gen_reg_rtx (mode);
25514 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
25515 emit_insn (gen_mul (mreg, m1, m2));
25516 emit_insn (gen_add (dst, mreg, a));
25520 emit_insn (gen_rtx_SET (VOIDmode, dst,
25521 gen_rtx_PLUS (mode,
25522 gen_rtx_MULT (mode, m1, m2),
25526 /* Generate a FMSUB instruction:
25527 dst = (m1 * m2) - a
25529 generating different RTL based on the fused multiply/add switch. */
25532 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
25534 enum machine_mode mode = GET_MODE (dst);
25536 if (!TARGET_FUSED_MADD
25537 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
25539 /* For the simple ops, use the generator function, rather than assuming
25540 that the RTL is standard. */
25541 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25542 enum insn_code scode = optab_handler (add_optab, mode)->insn_code;
25543 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25544 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25545 rtx mreg = gen_reg_rtx (mode);
25547 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25548 emit_insn (gen_mul (mreg, m1, m2));
25549 emit_insn (gen_sub (dst, mreg, a));
25553 emit_insn (gen_rtx_SET (VOIDmode, dst,
25554 gen_rtx_MINUS (mode,
25555 gen_rtx_MULT (mode, m1, m2),
25559 /* Generate a FNMSUB instruction:
25560 dst = - ((m1 * m2) - a)
25562 Which is equivalent to (except in the prescence of -0.0):
25563 dst = a - (m1 * m2)
25565 generating different RTL based on the fast-math and fused multiply/add
25569 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
25571 enum machine_mode mode = GET_MODE (dst);
25573 if (!TARGET_FUSED_MADD)
25575 /* For the simple ops, use the generator function, rather than assuming
25576 that the RTL is standard. */
25577 enum insn_code mcode = optab_handler (smul_optab, mode)->insn_code;
25578 enum insn_code scode = optab_handler (sub_optab, mode)->insn_code;
25579 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
25580 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
25581 rtx mreg = gen_reg_rtx (mode);
25583 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
25584 emit_insn (gen_mul (mreg, m1, m2));
25585 emit_insn (gen_sub (dst, a, mreg));
25590 rtx m = gen_rtx_MULT (mode, m1, m2);
25592 if (!HONOR_SIGNED_ZEROS (mode))
25593 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
25596 emit_insn (gen_rtx_SET (VOIDmode, dst,
25598 gen_rtx_MINUS (mode, m, a))));
25602 /* Newton-Raphson approximation of floating point divide with just 2 passes
25603 (either single precision floating point, or newer machines with higher
25604 accuracy estimates). Support both scalar and vector divide. Assumes no
25605 trapping math and finite arguments. */
25608 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
25610 enum machine_mode mode = GET_MODE (dst);
25611 rtx x0, e0, e1, y1, u0, v0;
25612 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25613 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25614 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
25616 gcc_assert (code != CODE_FOR_nothing);
25618 /* x0 = 1./d estimate */
25619 x0 = gen_reg_rtx (mode);
25620 emit_insn (gen_rtx_SET (VOIDmode, x0,
25621 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25624 e0 = gen_reg_rtx (mode);
25625 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
25627 e1 = gen_reg_rtx (mode);
25628 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
25630 y1 = gen_reg_rtx (mode);
25631 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
25633 u0 = gen_reg_rtx (mode);
25634 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
25636 v0 = gen_reg_rtx (mode);
25637 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
25639 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
25642 /* Newton-Raphson approximation of floating point divide that has a low
25643 precision estimate. Assumes no trapping math and finite arguments. */
25646 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
25648 enum machine_mode mode = GET_MODE (dst);
25649 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
25650 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25651 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25653 gcc_assert (code != CODE_FOR_nothing);
25655 one = rs6000_load_constant_and_splat (mode, dconst1);
25657 /* x0 = 1./d estimate */
25658 x0 = gen_reg_rtx (mode);
25659 emit_insn (gen_rtx_SET (VOIDmode, x0,
25660 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
25663 e0 = gen_reg_rtx (mode);
25664 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
25666 y1 = gen_reg_rtx (mode);
25667 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
25669 e1 = gen_reg_rtx (mode);
25670 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
25672 y2 = gen_reg_rtx (mode);
25673 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
25675 e2 = gen_reg_rtx (mode);
25676 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
25678 y3 = gen_reg_rtx (mode);
25679 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
25681 u0 = gen_reg_rtx (mode);
25682 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
25684 v0 = gen_reg_rtx (mode);
25685 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
25687 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
25690 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
25691 add a reg_note saying that this was a division. Support both scalar and
25692 vector divide. Assumes no trapping math and finite arguments. */
25695 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
25697 enum machine_mode mode = GET_MODE (dst);
25699 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
25700 rs6000_emit_swdiv_high_precision (dst, n, d);
25702 rs6000_emit_swdiv_low_precision (dst, n, d);
25705 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
25708 /* Newton-Raphson approximation of single/double-precision floating point
25709 rsqrt. Assumes no trapping math and finite arguments. */
25712 rs6000_emit_swrsqrt (rtx dst, rtx src)
25714 enum machine_mode mode = GET_MODE (src);
25715 rtx x0 = gen_reg_rtx (mode);
25716 rtx y = gen_reg_rtx (mode);
25717 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
25718 REAL_VALUE_TYPE dconst3_2;
25721 enum insn_code code = optab_handler (smul_optab, mode)->insn_code;
25722 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
25724 gcc_assert (code != CODE_FOR_nothing);
25726 /* Load up the constant 1.5 either as a scalar, or as a vector. */
25727 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
25728 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
25730 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
25732 /* x0 = rsqrt estimate */
25733 emit_insn (gen_rtx_SET (VOIDmode, x0,
25734 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
25737 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
25738 rs6000_emit_msub (y, src, halfthree, src);
25740 for (i = 0; i < passes; i++)
25742 rtx x1 = gen_reg_rtx (mode);
25743 rtx u = gen_reg_rtx (mode);
25744 rtx v = gen_reg_rtx (mode);
25746 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
25747 emit_insn (gen_mul (u, x0, x0));
25748 rs6000_emit_nmsub (v, y, u, halfthree);
25749 emit_insn (gen_mul (x1, x0, v));
25753 emit_move_insn (dst, x0);
25757 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
25758 (Power7) targets. DST is the target, and SRC is the argument operand. */
25761 rs6000_emit_popcount (rtx dst, rtx src)
25763 enum machine_mode mode = GET_MODE (dst);
25766 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
25767 if (TARGET_POPCNTD)
25769 if (mode == SImode)
25770 emit_insn (gen_popcntwsi2 (dst, src));
25772 emit_insn (gen_popcntddi2 (dst, src));
25776 tmp1 = gen_reg_rtx (mode);
25778 if (mode == SImode)
25780 emit_insn (gen_popcntbsi2 (tmp1, src));
25781 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
25783 tmp2 = force_reg (SImode, tmp2);
25784 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
25788 emit_insn (gen_popcntbdi2 (tmp1, src));
25789 tmp2 = expand_mult (DImode, tmp1,
25790 GEN_INT ((HOST_WIDE_INT)
25791 0x01010101 << 32 | 0x01010101),
25793 tmp2 = force_reg (DImode, tmp2);
25794 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
25799 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
25800 target, and SRC is the argument operand. */
25803 rs6000_emit_parity (rtx dst, rtx src)
25805 enum machine_mode mode = GET_MODE (dst);
25808 tmp = gen_reg_rtx (mode);
25809 if (mode == SImode)
25811 /* Is mult+shift >= shift+xor+shift+xor? */
25812 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
25814 rtx tmp1, tmp2, tmp3, tmp4;
25816 tmp1 = gen_reg_rtx (SImode);
25817 emit_insn (gen_popcntbsi2 (tmp1, src));
25819 tmp2 = gen_reg_rtx (SImode);
25820 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
25821 tmp3 = gen_reg_rtx (SImode);
25822 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
25824 tmp4 = gen_reg_rtx (SImode);
25825 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
25826 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
25829 rs6000_emit_popcount (tmp, src);
25830 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
25834 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
25835 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
25837 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
25839 tmp1 = gen_reg_rtx (DImode);
25840 emit_insn (gen_popcntbdi2 (tmp1, src));
25842 tmp2 = gen_reg_rtx (DImode);
25843 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
25844 tmp3 = gen_reg_rtx (DImode);
25845 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
25847 tmp4 = gen_reg_rtx (DImode);
25848 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
25849 tmp5 = gen_reg_rtx (DImode);
25850 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
25852 tmp6 = gen_reg_rtx (DImode);
25853 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
25854 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
25857 rs6000_emit_popcount (tmp, src);
25858 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
25862 /* Return an RTX representing where to find the function value of a
25863 function returning MODE. */
25865 rs6000_complex_function_value (enum machine_mode mode)
25867 unsigned int regno;
25869 enum machine_mode inner = GET_MODE_INNER (mode);
25870 unsigned int inner_bytes = GET_MODE_SIZE (inner);
25872 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25873 regno = FP_ARG_RETURN;
25876 regno = GP_ARG_RETURN;
25878 /* 32-bit is OK since it'll go in r3/r4. */
25879 if (TARGET_32BIT && inner_bytes >= 4)
25880 return gen_rtx_REG (mode, regno);
25883 if (inner_bytes >= 8)
25884 return gen_rtx_REG (mode, regno);
25886 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
25888 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
25889 GEN_INT (inner_bytes));
25890 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
25893 /* Target hook for TARGET_FUNCTION_VALUE.
25895 On the SPE, both FPs and vectors are returned in r3.
25897 On RS/6000 an integer value is in r3 and a floating-point value is in
25898 fp1, unless -msoft-float. */
25901 rs6000_function_value (const_tree valtype,
25902 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
25903 bool outgoing ATTRIBUTE_UNUSED)
25905 enum machine_mode mode;
25906 unsigned int regno;
25908 /* Special handling for structs in darwin64. */
25909 if (rs6000_darwin64_abi
25910 && TYPE_MODE (valtype) == BLKmode
25911 && TREE_CODE (valtype) == RECORD_TYPE
25912 && int_size_in_bytes (valtype) > 0)
25914 CUMULATIVE_ARGS valcum;
25918 valcum.fregno = FP_ARG_MIN_REG;
25919 valcum.vregno = ALTIVEC_ARG_MIN_REG;
25920 /* Do a trial code generation as if this were going to be passed as
25921 an argument; if any part goes in memory, we return NULL. */
25922 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
25925 /* Otherwise fall through to standard ABI rules. */
25928 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
25930 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
25931 return gen_rtx_PARALLEL (DImode,
25933 gen_rtx_EXPR_LIST (VOIDmode,
25934 gen_rtx_REG (SImode, GP_ARG_RETURN),
25936 gen_rtx_EXPR_LIST (VOIDmode,
25937 gen_rtx_REG (SImode,
25938 GP_ARG_RETURN + 1),
25941 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
25943 return gen_rtx_PARALLEL (DCmode,
25945 gen_rtx_EXPR_LIST (VOIDmode,
25946 gen_rtx_REG (SImode, GP_ARG_RETURN),
25948 gen_rtx_EXPR_LIST (VOIDmode,
25949 gen_rtx_REG (SImode,
25950 GP_ARG_RETURN + 1),
25952 gen_rtx_EXPR_LIST (VOIDmode,
25953 gen_rtx_REG (SImode,
25954 GP_ARG_RETURN + 2),
25956 gen_rtx_EXPR_LIST (VOIDmode,
25957 gen_rtx_REG (SImode,
25958 GP_ARG_RETURN + 3),
25962 mode = TYPE_MODE (valtype);
25963 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
25964 || POINTER_TYPE_P (valtype))
25965 mode = TARGET_32BIT ? SImode : DImode;
25967 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
25968 /* _Decimal128 must use an even/odd register pair. */
25969 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
25970 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
25971 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
25972 regno = FP_ARG_RETURN;
25973 else if (TREE_CODE (valtype) == COMPLEX_TYPE
25974 && targetm.calls.split_complex_arg)
25975 return rs6000_complex_function_value (mode);
25976 else if (TREE_CODE (valtype) == VECTOR_TYPE
25977 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
25978 && ALTIVEC_VECTOR_MODE (mode))
25979 regno = ALTIVEC_ARG_RETURN;
25980 else if (TREE_CODE (valtype) == VECTOR_TYPE
25981 && TARGET_VSX && TARGET_ALTIVEC_ABI
25982 && VSX_VECTOR_MODE (mode))
25983 regno = ALTIVEC_ARG_RETURN;
25984 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
25985 && (mode == DFmode || mode == DCmode
25986 || mode == TFmode || mode == TCmode))
25987 return spe_build_register_parallel (mode, GP_ARG_RETURN);
25989 regno = GP_ARG_RETURN;
25991 return gen_rtx_REG (mode, regno);
25994 /* Define how to find the value returned by a library function
25995 assuming the value has mode MODE. */
25997 rs6000_libcall_value (enum machine_mode mode)
25999 unsigned int regno;
26001 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26003 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26004 return gen_rtx_PARALLEL (DImode,
26006 gen_rtx_EXPR_LIST (VOIDmode,
26007 gen_rtx_REG (SImode, GP_ARG_RETURN),
26009 gen_rtx_EXPR_LIST (VOIDmode,
26010 gen_rtx_REG (SImode,
26011 GP_ARG_RETURN + 1),
26015 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26016 /* _Decimal128 must use an even/odd register pair. */
26017 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26018 else if (SCALAR_FLOAT_MODE_P (mode)
26019 && TARGET_HARD_FLOAT && TARGET_FPRS
26020 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26021 regno = FP_ARG_RETURN;
26022 else if (ALTIVEC_VECTOR_MODE (mode)
26023 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26024 regno = ALTIVEC_ARG_RETURN;
26025 else if (VSX_VECTOR_MODE (mode)
26026 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26027 regno = ALTIVEC_ARG_RETURN;
26028 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26029 return rs6000_complex_function_value (mode);
26030 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26031 && (mode == DFmode || mode == DCmode
26032 || mode == TFmode || mode == TCmode))
26033 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26035 regno = GP_ARG_RETURN;
26037 return gen_rtx_REG (mode, regno);
26041 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26042 Frame pointer elimination is automatically handled.
26044 For the RS/6000, if frame pointer elimination is being done, we would like
26045 to convert ap into fp, not sp.
26047 We need r30 if -mminimal-toc was specified, and there are constant pool
26051 rs6000_can_eliminate (const int from, const int to)
26053 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26054 ? ! frame_pointer_needed
26055 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26056 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26060 /* Define the offset between two registers, FROM to be eliminated and its
26061 replacement TO, at the start of a routine. */
26063 rs6000_initial_elimination_offset (int from, int to)
26065 rs6000_stack_t *info = rs6000_stack_info ();
26066 HOST_WIDE_INT offset;
26068 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26069 offset = info->push_p ? 0 : -info->total_size;
26070 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26072 offset = info->push_p ? 0 : -info->total_size;
26073 if (FRAME_GROWS_DOWNWARD)
26074 offset += info->fixed_size + info->vars_size + info->parm_size;
26076 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26077 offset = FRAME_GROWS_DOWNWARD
26078 ? info->fixed_size + info->vars_size + info->parm_size
26080 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26081 offset = info->total_size;
26082 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26083 offset = info->push_p ? info->total_size : 0;
26084 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26087 gcc_unreachable ();
26093 rs6000_dwarf_register_span (rtx reg)
26097 unsigned regno = REGNO (reg);
26098 enum machine_mode mode = GET_MODE (reg);
26102 && (SPE_VECTOR_MODE (GET_MODE (reg))
26103 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
26104 && mode != SFmode && mode != SDmode && mode != SCmode)))
26109 regno = REGNO (reg);
26111 /* The duality of the SPE register size wreaks all kinds of havoc.
26112 This is a way of distinguishing r0 in 32-bits from r0 in
26114 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
26115 gcc_assert (words <= 4);
26116 for (i = 0; i < words; i++, regno++)
26118 if (BYTES_BIG_ENDIAN)
26120 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
26121 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
26125 parts[2 * i] = gen_rtx_REG (SImode, regno);
26126 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
26130 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
26133 /* Fill in sizes for SPE register high parts in table used by unwinder. */
26136 rs6000_init_dwarf_reg_sizes_extra (tree address)
26141 enum machine_mode mode = TYPE_MODE (char_type_node);
26142 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
26143 rtx mem = gen_rtx_MEM (BLKmode, addr);
26144 rtx value = gen_int_mode (4, mode);
26146 for (i = 1201; i < 1232; i++)
26148 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
26149 HOST_WIDE_INT offset
26150 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
26152 emit_move_insn (adjust_address (mem, mode, offset), value);
26157 /* Map internal gcc register numbers to DWARF2 register numbers. */
26160 rs6000_dbx_register_number (unsigned int regno)
26162 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
26164 if (regno == MQ_REGNO)
26166 if (regno == LR_REGNO)
26168 if (regno == CTR_REGNO)
26170 if (CR_REGNO_P (regno))
26171 return regno - CR0_REGNO + 86;
26172 if (regno == CA_REGNO)
26173 return 101; /* XER */
26174 if (ALTIVEC_REGNO_P (regno))
26175 return regno - FIRST_ALTIVEC_REGNO + 1124;
26176 if (regno == VRSAVE_REGNO)
26178 if (regno == VSCR_REGNO)
26180 if (regno == SPE_ACC_REGNO)
26182 if (regno == SPEFSCR_REGNO)
26184 /* SPE high reg number. We get these values of regno from
26185 rs6000_dwarf_register_span. */
26186 gcc_assert (regno >= 1200 && regno < 1232);
26190 /* target hook eh_return_filter_mode */
26191 static enum machine_mode
26192 rs6000_eh_return_filter_mode (void)
26194 return TARGET_32BIT ? SImode : word_mode;
26197 /* Target hook for scalar_mode_supported_p. */
26199 rs6000_scalar_mode_supported_p (enum machine_mode mode)
26201 if (DECIMAL_FLOAT_MODE_P (mode))
26202 return default_decimal_float_supported_p ();
26204 return default_scalar_mode_supported_p (mode);
26207 /* Target hook for vector_mode_supported_p. */
26209 rs6000_vector_mode_supported_p (enum machine_mode mode)
26212 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
26215 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
26218 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
26225 /* Target hook for invalid_arg_for_unprototyped_fn. */
26226 static const char *
26227 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
26229 return (!rs6000_darwin64_abi
26231 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
26232 && (funcdecl == NULL_TREE
26233 || (TREE_CODE (funcdecl) == FUNCTION_DECL
26234 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
26235 ? N_("AltiVec argument passed to unprototyped function")
26239 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
26240 setup by using __stack_chk_fail_local hidden function instead of
26241 calling __stack_chk_fail directly. Otherwise it is better to call
26242 __stack_chk_fail directly. */
26245 rs6000_stack_protect_fail (void)
26247 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
26248 ? default_hidden_stack_protect_fail ()
26249 : default_external_stack_protect_fail ();
26253 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
26254 int num_operands ATTRIBUTE_UNUSED)
26256 if (rs6000_warn_cell_microcode)
26259 int insn_code_number = recog_memoized (insn);
26260 location_t location = locator_location (INSN_LOCATOR (insn));
26262 /* Punt on insns we cannot recognize. */
26263 if (insn_code_number < 0)
26266 temp = get_insn_template (insn_code_number, insn);
26268 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
26269 warning_at (location, OPT_mwarn_cell_microcode,
26270 "emitting microcode insn %s\t[%s] #%d",
26271 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26272 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
26273 warning_at (location, OPT_mwarn_cell_microcode,
26274 "emitting conditional microcode insn %s\t[%s] #%d",
26275 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
26279 #include "gt-rs6000.h"