1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-attr.h"
42 #include "basic-block.h"
43 #include "integrate.h"
44 #include "diagnostic-core.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
55 #include "sched-int.h"
57 #include "tree-flow.h"
60 #include "tm-constrs.h"
62 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
65 #include "gstab.h" /* for N_SLINE */
68 #ifndef TARGET_NO_PROTOTYPE
69 #define TARGET_NO_PROTOTYPE 0
72 #define min(A,B) ((A) < (B) ? (A) : (B))
73 #define max(A,B) ((A) > (B) ? (A) : (B))
75 /* Structure used to define the rs6000 stack */
76 typedef struct rs6000_stack {
77 int reload_completed; /* stack info won't change from here on */
78 int first_gp_reg_save; /* first callee saved GP register used */
79 int first_fp_reg_save; /* first callee saved FP register used */
80 int first_altivec_reg_save; /* first callee saved AltiVec register used */
81 int lr_save_p; /* true if the link reg needs to be saved */
82 int cr_save_p; /* true if the CR reg needs to be saved */
83 unsigned int vrsave_mask; /* mask of vec registers to save */
84 int push_p; /* true if we need to allocate stack space */
85 int calls_p; /* true if the function makes any calls */
86 int world_save_p; /* true if we're saving *everything*:
87 r13-r31, cr, f14-f31, vrsave, v20-v31 */
88 enum rs6000_abi abi; /* which ABI to use */
89 int gp_save_offset; /* offset to save GP regs from initial SP */
90 int fp_save_offset; /* offset to save FP regs from initial SP */
91 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
92 int lr_save_offset; /* offset to save LR from initial SP */
93 int cr_save_offset; /* offset to save CR from initial SP */
94 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
95 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
96 int varargs_save_offset; /* offset to save the varargs registers */
97 int ehrd_offset; /* offset to EH return data */
98 int reg_size; /* register size (4 or 8) */
99 HOST_WIDE_INT vars_size; /* variable save area size */
100 int parm_size; /* outgoing parameter size */
101 int save_size; /* save area size */
102 int fixed_size; /* fixed size of stack frame */
103 int gp_size; /* size of saved GP registers */
104 int fp_size; /* size of saved FP registers */
105 int altivec_size; /* size of saved AltiVec registers */
106 int cr_size; /* size to hold CR if not in save_size */
107 int vrsave_size; /* size to hold VRSAVE if not in save_size */
108 int altivec_padding_size; /* size of altivec alignment padding if
110 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
111 int spe_padding_size;
112 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
113 int spe_64bit_regs_used;
117 /* A C structure for machine-specific, per-function data.
118 This is added to the cfun structure. */
119 typedef struct GTY(()) machine_function
121 /* Some local-dynamic symbol. */
122 const char *some_ld_name;
123 /* Whether the instruction chain has been scanned already. */
124 int insn_chain_scanned_p;
125 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
126 int ra_needs_full_frame;
127 /* Flags if __builtin_return_address (0) was used. */
129 /* Cache lr_save_p after expansion of builtin_eh_return. */
131 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
132 varargs save area. */
133 HOST_WIDE_INT varargs_save_offset;
134 /* Temporary stack slot to use for SDmode copies. This slot is
135 64-bits wide and is allocated early enough so that the offset
136 does not overflow the 16-bit load/store offset field. */
137 rtx sdmode_stack_slot;
140 /* Target cpu type */
142 enum processor_type rs6000_cpu;
143 struct rs6000_cpu_select rs6000_select[3] =
145 /* switch name, tune arch */
146 { (const char *)0, "--with-cpu=", 1, 1 },
147 { (const char *)0, "-mcpu=", 1, 1 },
148 { (const char *)0, "-mtune=", 1, 0 },
151 /* Always emit branch hint bits. */
152 static GTY(()) bool rs6000_always_hint;
154 /* Schedule instructions for group formation. */
155 static GTY(()) bool rs6000_sched_groups;
157 /* Align branch targets. */
158 static GTY(()) bool rs6000_align_branch_targets;
160 /* Non-zero to allow overriding loop alignment. */
161 static int can_override_loop_align = 0;
163 /* Support for -msched-costly-dep option. */
164 const char *rs6000_sched_costly_dep_str;
165 enum rs6000_dependence_cost rs6000_sched_costly_dep;
167 /* Support for -minsert-sched-nops option. */
168 const char *rs6000_sched_insert_nops_str;
169 enum rs6000_nop_insertion rs6000_sched_insert_nops;
171 /* Support targetm.vectorize.builtin_mask_for_load. */
172 static GTY(()) tree altivec_builtin_mask_for_load;
174 /* Size of long double. */
175 int rs6000_long_double_type_size;
177 /* IEEE quad extended precision long double. */
180 /* Nonzero to use AltiVec ABI. */
181 int rs6000_altivec_abi;
183 /* Nonzero if we want SPE SIMD instructions. */
186 /* Nonzero if we want SPE ABI extensions. */
189 /* Nonzero if floating point operations are done in the GPRs. */
190 int rs6000_float_gprs = 0;
192 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
193 int rs6000_darwin64_abi;
195 /* Set to nonzero once AIX common-mode calls have been defined. */
196 static GTY(()) int common_mode_defined;
198 /* Label number of label created for -mrelocatable, to call to so we can
199 get the address of the GOT section */
200 static int rs6000_pic_labelno;
203 /* Which abi to adhere to */
204 const char *rs6000_abi_name;
206 /* Semantics of the small data area */
207 enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
209 /* Which small data model to use */
210 const char *rs6000_sdata_name = (char *)0;
212 /* Counter for labels which are to be placed in .fixup. */
213 int fixuplabelno = 0;
216 /* Bit size of immediate TLS offsets and string from which it is decoded. */
217 int rs6000_tls_size = 32;
218 const char *rs6000_tls_size_string;
220 /* ABI enumeration available for subtarget to use. */
221 enum rs6000_abi rs6000_current_abi;
223 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
227 const char *rs6000_debug_name;
228 int rs6000_debug_stack; /* debug stack applications */
229 int rs6000_debug_arg; /* debug argument handling */
230 int rs6000_debug_reg; /* debug register classes */
231 int rs6000_debug_addr; /* debug memory addressing */
232 int rs6000_debug_cost; /* debug rtx_costs */
234 /* Specify the machine mode that pointers have. After generation of rtl, the
235 compiler makes no further distinction between pointers and any other objects
236 of this machine mode. The type is unsigned since not all things that
237 include rs6000.h also include machmode.h. */
238 unsigned rs6000_pmode;
240 /* Width in bits of a pointer. */
241 unsigned rs6000_pointer_size;
244 /* Value is TRUE if register/mode pair is acceptable. */
245 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
247 /* Maximum number of registers needed for a given register class and mode. */
248 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
250 /* How many registers are needed for a given register and mode. */
251 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
253 /* Map register number to register class. */
254 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
256 /* Reload functions based on the type and the vector unit. */
257 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
259 /* Built in types. */
260 tree rs6000_builtin_types[RS6000_BTI_MAX];
261 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
263 const char *rs6000_traceback_name;
265 traceback_default = 0,
271 /* Flag to say the TOC is initialized */
273 char toc_label_name[10];
275 /* Cached value of rs6000_variable_issue. This is cached in
276 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
277 static short cached_can_issue_more;
279 static GTY(()) section *read_only_data_section;
280 static GTY(()) section *private_data_section;
281 static GTY(()) section *read_only_private_data_section;
282 static GTY(()) section *sdata2_section;
283 static GTY(()) section *toc_section;
285 /* Control alignment for fields within structures. */
286 /* String from -malign-XXXXX. */
287 int rs6000_alignment_flags;
289 /* Code model for 64-bit linux. */
290 enum rs6000_cmodel cmodel;
292 /* True for any options that were explicitly set. */
294 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
295 bool alignment; /* True if -malign- was used. */
296 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
297 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
298 bool spe; /* True if -mspe= was used. */
299 bool float_gprs; /* True if -mfloat-gprs= was used. */
300 bool long_double; /* True if -mlong-double- was used. */
301 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
302 bool vrsave; /* True if -mvrsave was used. */
303 bool cmodel; /* True if -mcmodel was used. */
304 } rs6000_explicit_options;
306 struct builtin_description
308 /* mask is not const because we're going to alter it below. This
309 nonsense will go away when we rewrite the -march infrastructure
310 to give us more target flag bits. */
312 const enum insn_code icode;
313 const char *const name;
314 const enum rs6000_builtins code;
317 /* Describe the vector unit used for modes. */
318 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
319 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
321 /* Register classes for various constraints that are based on the target
323 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
325 /* Describe the alignment of a vector. */
326 int rs6000_vector_align[NUM_MACHINE_MODES];
328 /* Map selected modes to types for builtins. */
329 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
331 /* What modes to automatically generate reciprocal divide estimate (fre) and
332 reciprocal sqrt (frsqrte) for. */
333 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
335 /* Masks to determine which reciprocal esitmate instructions to generate
337 enum rs6000_recip_mask {
338 RECIP_SF_DIV = 0x001, /* Use divide estimate */
339 RECIP_DF_DIV = 0x002,
340 RECIP_V4SF_DIV = 0x004,
341 RECIP_V2DF_DIV = 0x008,
343 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
344 RECIP_DF_RSQRT = 0x020,
345 RECIP_V4SF_RSQRT = 0x040,
346 RECIP_V2DF_RSQRT = 0x080,
348 /* Various combination of flags for -mrecip=xxx. */
350 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
351 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
352 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
354 RECIP_HIGH_PRECISION = RECIP_ALL,
356 /* On low precision machines like the power5, don't enable double precision
357 reciprocal square root estimate, since it isn't accurate enough. */
358 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
361 static unsigned int rs6000_recip_control;
362 static const char *rs6000_recip_name;
364 /* -mrecip options. */
367 const char *string; /* option name */
368 unsigned int mask; /* mask bits to set */
369 } recip_options[] = {
370 { "all", RECIP_ALL },
371 { "none", RECIP_NONE },
372 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
374 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
375 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
376 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
377 | RECIP_V2DF_RSQRT) },
378 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
379 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
382 /* 2 argument gen function typedef. */
383 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
386 /* Target cpu costs. */
388 struct processor_costs {
389 const int mulsi; /* cost of SImode multiplication. */
390 const int mulsi_const; /* cost of SImode multiplication by constant. */
391 const int mulsi_const9; /* cost of SImode mult by short constant. */
392 const int muldi; /* cost of DImode multiplication. */
393 const int divsi; /* cost of SImode division. */
394 const int divdi; /* cost of DImode division. */
395 const int fp; /* cost of simple SFmode and DFmode insns. */
396 const int dmul; /* cost of DFmode multiplication (and fmadd). */
397 const int sdiv; /* cost of SFmode division (fdivs). */
398 const int ddiv; /* cost of DFmode division (fdiv). */
399 const int cache_line_size; /* cache line size in bytes. */
400 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
401 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
402 const int simultaneous_prefetches; /* number of parallel prefetch
406 const struct processor_costs *rs6000_cost;
408 /* Processor costs (relative to an add) */
410 /* Instruction size costs on 32bit processors. */
412 struct processor_costs size32_cost = {
413 COSTS_N_INSNS (1), /* mulsi */
414 COSTS_N_INSNS (1), /* mulsi_const */
415 COSTS_N_INSNS (1), /* mulsi_const9 */
416 COSTS_N_INSNS (1), /* muldi */
417 COSTS_N_INSNS (1), /* divsi */
418 COSTS_N_INSNS (1), /* divdi */
419 COSTS_N_INSNS (1), /* fp */
420 COSTS_N_INSNS (1), /* dmul */
421 COSTS_N_INSNS (1), /* sdiv */
422 COSTS_N_INSNS (1), /* ddiv */
429 /* Instruction size costs on 64bit processors. */
431 struct processor_costs size64_cost = {
432 COSTS_N_INSNS (1), /* mulsi */
433 COSTS_N_INSNS (1), /* mulsi_const */
434 COSTS_N_INSNS (1), /* mulsi_const9 */
435 COSTS_N_INSNS (1), /* muldi */
436 COSTS_N_INSNS (1), /* divsi */
437 COSTS_N_INSNS (1), /* divdi */
438 COSTS_N_INSNS (1), /* fp */
439 COSTS_N_INSNS (1), /* dmul */
440 COSTS_N_INSNS (1), /* sdiv */
441 COSTS_N_INSNS (1), /* ddiv */
448 /* Instruction costs on RIOS1 processors. */
450 struct processor_costs rios1_cost = {
451 COSTS_N_INSNS (5), /* mulsi */
452 COSTS_N_INSNS (4), /* mulsi_const */
453 COSTS_N_INSNS (3), /* mulsi_const9 */
454 COSTS_N_INSNS (5), /* muldi */
455 COSTS_N_INSNS (19), /* divsi */
456 COSTS_N_INSNS (19), /* divdi */
457 COSTS_N_INSNS (2), /* fp */
458 COSTS_N_INSNS (2), /* dmul */
459 COSTS_N_INSNS (19), /* sdiv */
460 COSTS_N_INSNS (19), /* ddiv */
461 128, /* cache line size */
467 /* Instruction costs on RIOS2 processors. */
469 struct processor_costs rios2_cost = {
470 COSTS_N_INSNS (2), /* mulsi */
471 COSTS_N_INSNS (2), /* mulsi_const */
472 COSTS_N_INSNS (2), /* mulsi_const9 */
473 COSTS_N_INSNS (2), /* muldi */
474 COSTS_N_INSNS (13), /* divsi */
475 COSTS_N_INSNS (13), /* divdi */
476 COSTS_N_INSNS (2), /* fp */
477 COSTS_N_INSNS (2), /* dmul */
478 COSTS_N_INSNS (17), /* sdiv */
479 COSTS_N_INSNS (17), /* ddiv */
480 256, /* cache line size */
486 /* Instruction costs on RS64A processors. */
488 struct processor_costs rs64a_cost = {
489 COSTS_N_INSNS (20), /* mulsi */
490 COSTS_N_INSNS (12), /* mulsi_const */
491 COSTS_N_INSNS (8), /* mulsi_const9 */
492 COSTS_N_INSNS (34), /* muldi */
493 COSTS_N_INSNS (65), /* divsi */
494 COSTS_N_INSNS (67), /* divdi */
495 COSTS_N_INSNS (4), /* fp */
496 COSTS_N_INSNS (4), /* dmul */
497 COSTS_N_INSNS (31), /* sdiv */
498 COSTS_N_INSNS (31), /* ddiv */
499 128, /* cache line size */
505 /* Instruction costs on MPCCORE processors. */
507 struct processor_costs mpccore_cost = {
508 COSTS_N_INSNS (2), /* mulsi */
509 COSTS_N_INSNS (2), /* mulsi_const */
510 COSTS_N_INSNS (2), /* mulsi_const9 */
511 COSTS_N_INSNS (2), /* muldi */
512 COSTS_N_INSNS (6), /* divsi */
513 COSTS_N_INSNS (6), /* divdi */
514 COSTS_N_INSNS (4), /* fp */
515 COSTS_N_INSNS (5), /* dmul */
516 COSTS_N_INSNS (10), /* sdiv */
517 COSTS_N_INSNS (17), /* ddiv */
518 32, /* cache line size */
524 /* Instruction costs on PPC403 processors. */
526 struct processor_costs ppc403_cost = {
527 COSTS_N_INSNS (4), /* mulsi */
528 COSTS_N_INSNS (4), /* mulsi_const */
529 COSTS_N_INSNS (4), /* mulsi_const9 */
530 COSTS_N_INSNS (4), /* muldi */
531 COSTS_N_INSNS (33), /* divsi */
532 COSTS_N_INSNS (33), /* divdi */
533 COSTS_N_INSNS (11), /* fp */
534 COSTS_N_INSNS (11), /* dmul */
535 COSTS_N_INSNS (11), /* sdiv */
536 COSTS_N_INSNS (11), /* ddiv */
537 32, /* cache line size */
543 /* Instruction costs on PPC405 processors. */
545 struct processor_costs ppc405_cost = {
546 COSTS_N_INSNS (5), /* mulsi */
547 COSTS_N_INSNS (4), /* mulsi_const */
548 COSTS_N_INSNS (3), /* mulsi_const9 */
549 COSTS_N_INSNS (5), /* muldi */
550 COSTS_N_INSNS (35), /* divsi */
551 COSTS_N_INSNS (35), /* divdi */
552 COSTS_N_INSNS (11), /* fp */
553 COSTS_N_INSNS (11), /* dmul */
554 COSTS_N_INSNS (11), /* sdiv */
555 COSTS_N_INSNS (11), /* ddiv */
556 32, /* cache line size */
562 /* Instruction costs on PPC440 processors. */
564 struct processor_costs ppc440_cost = {
565 COSTS_N_INSNS (3), /* mulsi */
566 COSTS_N_INSNS (2), /* mulsi_const */
567 COSTS_N_INSNS (2), /* mulsi_const9 */
568 COSTS_N_INSNS (3), /* muldi */
569 COSTS_N_INSNS (34), /* divsi */
570 COSTS_N_INSNS (34), /* divdi */
571 COSTS_N_INSNS (5), /* fp */
572 COSTS_N_INSNS (5), /* dmul */
573 COSTS_N_INSNS (19), /* sdiv */
574 COSTS_N_INSNS (33), /* ddiv */
575 32, /* cache line size */
581 /* Instruction costs on PPC476 processors. */
583 struct processor_costs ppc476_cost = {
584 COSTS_N_INSNS (4), /* mulsi */
585 COSTS_N_INSNS (4), /* mulsi_const */
586 COSTS_N_INSNS (4), /* mulsi_const9 */
587 COSTS_N_INSNS (4), /* muldi */
588 COSTS_N_INSNS (11), /* divsi */
589 COSTS_N_INSNS (11), /* divdi */
590 COSTS_N_INSNS (6), /* fp */
591 COSTS_N_INSNS (6), /* dmul */
592 COSTS_N_INSNS (19), /* sdiv */
593 COSTS_N_INSNS (33), /* ddiv */
594 32, /* l1 cache line size */
600 /* Instruction costs on PPC601 processors. */
602 struct processor_costs ppc601_cost = {
603 COSTS_N_INSNS (5), /* mulsi */
604 COSTS_N_INSNS (5), /* mulsi_const */
605 COSTS_N_INSNS (5), /* mulsi_const9 */
606 COSTS_N_INSNS (5), /* muldi */
607 COSTS_N_INSNS (36), /* divsi */
608 COSTS_N_INSNS (36), /* divdi */
609 COSTS_N_INSNS (4), /* fp */
610 COSTS_N_INSNS (5), /* dmul */
611 COSTS_N_INSNS (17), /* sdiv */
612 COSTS_N_INSNS (31), /* ddiv */
613 32, /* cache line size */
619 /* Instruction costs on PPC603 processors. */
621 struct processor_costs ppc603_cost = {
622 COSTS_N_INSNS (5), /* mulsi */
623 COSTS_N_INSNS (3), /* mulsi_const */
624 COSTS_N_INSNS (2), /* mulsi_const9 */
625 COSTS_N_INSNS (5), /* muldi */
626 COSTS_N_INSNS (37), /* divsi */
627 COSTS_N_INSNS (37), /* divdi */
628 COSTS_N_INSNS (3), /* fp */
629 COSTS_N_INSNS (4), /* dmul */
630 COSTS_N_INSNS (18), /* sdiv */
631 COSTS_N_INSNS (33), /* ddiv */
632 32, /* cache line size */
638 /* Instruction costs on PPC604 processors. */
640 struct processor_costs ppc604_cost = {
641 COSTS_N_INSNS (4), /* mulsi */
642 COSTS_N_INSNS (4), /* mulsi_const */
643 COSTS_N_INSNS (4), /* mulsi_const9 */
644 COSTS_N_INSNS (4), /* muldi */
645 COSTS_N_INSNS (20), /* divsi */
646 COSTS_N_INSNS (20), /* divdi */
647 COSTS_N_INSNS (3), /* fp */
648 COSTS_N_INSNS (3), /* dmul */
649 COSTS_N_INSNS (18), /* sdiv */
650 COSTS_N_INSNS (32), /* ddiv */
651 32, /* cache line size */
657 /* Instruction costs on PPC604e processors. */
659 struct processor_costs ppc604e_cost = {
660 COSTS_N_INSNS (2), /* mulsi */
661 COSTS_N_INSNS (2), /* mulsi_const */
662 COSTS_N_INSNS (2), /* mulsi_const9 */
663 COSTS_N_INSNS (2), /* muldi */
664 COSTS_N_INSNS (20), /* divsi */
665 COSTS_N_INSNS (20), /* divdi */
666 COSTS_N_INSNS (3), /* fp */
667 COSTS_N_INSNS (3), /* dmul */
668 COSTS_N_INSNS (18), /* sdiv */
669 COSTS_N_INSNS (32), /* ddiv */
670 32, /* cache line size */
676 /* Instruction costs on PPC620 processors. */
678 struct processor_costs ppc620_cost = {
679 COSTS_N_INSNS (5), /* mulsi */
680 COSTS_N_INSNS (4), /* mulsi_const */
681 COSTS_N_INSNS (3), /* mulsi_const9 */
682 COSTS_N_INSNS (7), /* muldi */
683 COSTS_N_INSNS (21), /* divsi */
684 COSTS_N_INSNS (37), /* divdi */
685 COSTS_N_INSNS (3), /* fp */
686 COSTS_N_INSNS (3), /* dmul */
687 COSTS_N_INSNS (18), /* sdiv */
688 COSTS_N_INSNS (32), /* ddiv */
689 128, /* cache line size */
695 /* Instruction costs on PPC630 processors. */
697 struct processor_costs ppc630_cost = {
698 COSTS_N_INSNS (5), /* mulsi */
699 COSTS_N_INSNS (4), /* mulsi_const */
700 COSTS_N_INSNS (3), /* mulsi_const9 */
701 COSTS_N_INSNS (7), /* muldi */
702 COSTS_N_INSNS (21), /* divsi */
703 COSTS_N_INSNS (37), /* divdi */
704 COSTS_N_INSNS (3), /* fp */
705 COSTS_N_INSNS (3), /* dmul */
706 COSTS_N_INSNS (17), /* sdiv */
707 COSTS_N_INSNS (21), /* ddiv */
708 128, /* cache line size */
714 /* Instruction costs on Cell processor. */
715 /* COSTS_N_INSNS (1) ~ one add. */
717 struct processor_costs ppccell_cost = {
718 COSTS_N_INSNS (9/2)+2, /* mulsi */
719 COSTS_N_INSNS (6/2), /* mulsi_const */
720 COSTS_N_INSNS (6/2), /* mulsi_const9 */
721 COSTS_N_INSNS (15/2)+2, /* muldi */
722 COSTS_N_INSNS (38/2), /* divsi */
723 COSTS_N_INSNS (70/2), /* divdi */
724 COSTS_N_INSNS (10/2), /* fp */
725 COSTS_N_INSNS (10/2), /* dmul */
726 COSTS_N_INSNS (74/2), /* sdiv */
727 COSTS_N_INSNS (74/2), /* ddiv */
728 128, /* cache line size */
734 /* Instruction costs on PPC750 and PPC7400 processors. */
736 struct processor_costs ppc750_cost = {
737 COSTS_N_INSNS (5), /* mulsi */
738 COSTS_N_INSNS (3), /* mulsi_const */
739 COSTS_N_INSNS (2), /* mulsi_const9 */
740 COSTS_N_INSNS (5), /* muldi */
741 COSTS_N_INSNS (17), /* divsi */
742 COSTS_N_INSNS (17), /* divdi */
743 COSTS_N_INSNS (3), /* fp */
744 COSTS_N_INSNS (3), /* dmul */
745 COSTS_N_INSNS (17), /* sdiv */
746 COSTS_N_INSNS (31), /* ddiv */
747 32, /* cache line size */
753 /* Instruction costs on PPC7450 processors. */
755 struct processor_costs ppc7450_cost = {
756 COSTS_N_INSNS (4), /* mulsi */
757 COSTS_N_INSNS (3), /* mulsi_const */
758 COSTS_N_INSNS (3), /* mulsi_const9 */
759 COSTS_N_INSNS (4), /* muldi */
760 COSTS_N_INSNS (23), /* divsi */
761 COSTS_N_INSNS (23), /* divdi */
762 COSTS_N_INSNS (5), /* fp */
763 COSTS_N_INSNS (5), /* dmul */
764 COSTS_N_INSNS (21), /* sdiv */
765 COSTS_N_INSNS (35), /* ddiv */
766 32, /* cache line size */
772 /* Instruction costs on PPC8540 processors. */
774 struct processor_costs ppc8540_cost = {
775 COSTS_N_INSNS (4), /* mulsi */
776 COSTS_N_INSNS (4), /* mulsi_const */
777 COSTS_N_INSNS (4), /* mulsi_const9 */
778 COSTS_N_INSNS (4), /* muldi */
779 COSTS_N_INSNS (19), /* divsi */
780 COSTS_N_INSNS (19), /* divdi */
781 COSTS_N_INSNS (4), /* fp */
782 COSTS_N_INSNS (4), /* dmul */
783 COSTS_N_INSNS (29), /* sdiv */
784 COSTS_N_INSNS (29), /* ddiv */
785 32, /* cache line size */
788 1, /* prefetch streams /*/
791 /* Instruction costs on E300C2 and E300C3 cores. */
793 struct processor_costs ppce300c2c3_cost = {
794 COSTS_N_INSNS (4), /* mulsi */
795 COSTS_N_INSNS (4), /* mulsi_const */
796 COSTS_N_INSNS (4), /* mulsi_const9 */
797 COSTS_N_INSNS (4), /* muldi */
798 COSTS_N_INSNS (19), /* divsi */
799 COSTS_N_INSNS (19), /* divdi */
800 COSTS_N_INSNS (3), /* fp */
801 COSTS_N_INSNS (4), /* dmul */
802 COSTS_N_INSNS (18), /* sdiv */
803 COSTS_N_INSNS (33), /* ddiv */
807 1, /* prefetch streams /*/
810 /* Instruction costs on PPCE500MC processors. */
812 struct processor_costs ppce500mc_cost = {
813 COSTS_N_INSNS (4), /* mulsi */
814 COSTS_N_INSNS (4), /* mulsi_const */
815 COSTS_N_INSNS (4), /* mulsi_const9 */
816 COSTS_N_INSNS (4), /* muldi */
817 COSTS_N_INSNS (14), /* divsi */
818 COSTS_N_INSNS (14), /* divdi */
819 COSTS_N_INSNS (8), /* fp */
820 COSTS_N_INSNS (10), /* dmul */
821 COSTS_N_INSNS (36), /* sdiv */
822 COSTS_N_INSNS (66), /* ddiv */
823 64, /* cache line size */
826 1, /* prefetch streams /*/
829 /* Instruction costs on PPCE500MC64 processors. */
831 struct processor_costs ppce500mc64_cost = {
832 COSTS_N_INSNS (4), /* mulsi */
833 COSTS_N_INSNS (4), /* mulsi_const */
834 COSTS_N_INSNS (4), /* mulsi_const9 */
835 COSTS_N_INSNS (4), /* muldi */
836 COSTS_N_INSNS (14), /* divsi */
837 COSTS_N_INSNS (14), /* divdi */
838 COSTS_N_INSNS (4), /* fp */
839 COSTS_N_INSNS (10), /* dmul */
840 COSTS_N_INSNS (36), /* sdiv */
841 COSTS_N_INSNS (66), /* ddiv */
842 64, /* cache line size */
845 1, /* prefetch streams /*/
848 /* Instruction costs on AppliedMicro Titan processors. */
850 struct processor_costs titan_cost = {
851 COSTS_N_INSNS (5), /* mulsi */
852 COSTS_N_INSNS (5), /* mulsi_const */
853 COSTS_N_INSNS (5), /* mulsi_const9 */
854 COSTS_N_INSNS (5), /* muldi */
855 COSTS_N_INSNS (18), /* divsi */
856 COSTS_N_INSNS (18), /* divdi */
857 COSTS_N_INSNS (10), /* fp */
858 COSTS_N_INSNS (10), /* dmul */
859 COSTS_N_INSNS (46), /* sdiv */
860 COSTS_N_INSNS (72), /* ddiv */
861 32, /* cache line size */
864 1, /* prefetch streams /*/
867 /* Instruction costs on POWER4 and POWER5 processors. */
869 struct processor_costs power4_cost = {
870 COSTS_N_INSNS (3), /* mulsi */
871 COSTS_N_INSNS (2), /* mulsi_const */
872 COSTS_N_INSNS (2), /* mulsi_const9 */
873 COSTS_N_INSNS (4), /* muldi */
874 COSTS_N_INSNS (18), /* divsi */
875 COSTS_N_INSNS (34), /* divdi */
876 COSTS_N_INSNS (3), /* fp */
877 COSTS_N_INSNS (3), /* dmul */
878 COSTS_N_INSNS (17), /* sdiv */
879 COSTS_N_INSNS (17), /* ddiv */
880 128, /* cache line size */
883 8, /* prefetch streams /*/
886 /* Instruction costs on POWER6 processors. */
888 struct processor_costs power6_cost = {
889 COSTS_N_INSNS (8), /* mulsi */
890 COSTS_N_INSNS (8), /* mulsi_const */
891 COSTS_N_INSNS (8), /* mulsi_const9 */
892 COSTS_N_INSNS (8), /* muldi */
893 COSTS_N_INSNS (22), /* divsi */
894 COSTS_N_INSNS (28), /* divdi */
895 COSTS_N_INSNS (3), /* fp */
896 COSTS_N_INSNS (3), /* dmul */
897 COSTS_N_INSNS (13), /* sdiv */
898 COSTS_N_INSNS (16), /* ddiv */
899 128, /* cache line size */
902 16, /* prefetch streams */
905 /* Instruction costs on POWER7 processors. */
907 struct processor_costs power7_cost = {
908 COSTS_N_INSNS (2), /* mulsi */
909 COSTS_N_INSNS (2), /* mulsi_const */
910 COSTS_N_INSNS (2), /* mulsi_const9 */
911 COSTS_N_INSNS (2), /* muldi */
912 COSTS_N_INSNS (18), /* divsi */
913 COSTS_N_INSNS (34), /* divdi */
914 COSTS_N_INSNS (3), /* fp */
915 COSTS_N_INSNS (3), /* dmul */
916 COSTS_N_INSNS (13), /* sdiv */
917 COSTS_N_INSNS (16), /* ddiv */
918 128, /* cache line size */
921 12, /* prefetch streams */
924 /* Instruction costs on POWER A2 processors. */
926 struct processor_costs ppca2_cost = {
927 COSTS_N_INSNS (16), /* mulsi */
928 COSTS_N_INSNS (16), /* mulsi_const */
929 COSTS_N_INSNS (16), /* mulsi_const9 */
930 COSTS_N_INSNS (16), /* muldi */
931 COSTS_N_INSNS (22), /* divsi */
932 COSTS_N_INSNS (28), /* divdi */
933 COSTS_N_INSNS (3), /* fp */
934 COSTS_N_INSNS (3), /* dmul */
935 COSTS_N_INSNS (59), /* sdiv */
936 COSTS_N_INSNS (72), /* ddiv */
940 16, /* prefetch streams */
944 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
945 #undef RS6000_BUILTIN
946 #undef RS6000_BUILTIN_EQUATE
947 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
948 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
950 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
952 #include "rs6000-builtin.def"
955 #undef RS6000_BUILTIN
956 #undef RS6000_BUILTIN_EQUATE
958 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
959 static tree (*rs6000_veclib_handler) (tree, tree, tree);
962 static bool rs6000_function_ok_for_sibcall (tree, tree);
963 static const char *rs6000_invalid_within_doloop (const_rtx);
964 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
965 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
966 static rtx rs6000_generate_compare (rtx, enum machine_mode);
967 static void rs6000_emit_stack_tie (void);
968 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
969 static bool spe_func_has_64bit_regs_p (void);
970 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
972 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
973 static unsigned rs6000_hash_constant (rtx);
974 static unsigned toc_hash_function (const void *);
975 static int toc_hash_eq (const void *, const void *);
976 static bool reg_offset_addressing_ok_p (enum machine_mode);
977 static bool virtual_stack_registers_memory_p (rtx);
978 static bool constant_pool_expr_p (rtx);
979 static bool legitimate_small_data_p (enum machine_mode, rtx);
980 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
981 static struct machine_function * rs6000_init_machine_status (void);
982 static bool rs6000_assemble_integer (rtx, unsigned int, int);
983 static bool no_global_regs_above (int, bool);
984 #ifdef HAVE_GAS_HIDDEN
985 static void rs6000_assemble_visibility (tree, int);
987 static int rs6000_ra_ever_killed (void);
988 static bool rs6000_attribute_takes_identifier_p (const_tree);
989 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
990 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
991 static bool rs6000_ms_bitfield_layout_p (const_tree);
992 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
993 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
994 static const char *rs6000_mangle_type (const_tree);
995 static void rs6000_set_default_type_attributes (tree);
996 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
997 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
998 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
999 enum machine_mode, bool, bool, bool);
1000 static bool rs6000_reg_live_or_pic_offset_p (int);
1001 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
1002 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
1003 static void rs6000_restore_saved_cr (rtx, int);
1004 static bool rs6000_output_addr_const_extra (FILE *, rtx);
1005 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
1006 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
1007 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
1009 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
1010 static bool rs6000_return_in_memory (const_tree, const_tree);
1011 static rtx rs6000_function_value (const_tree, const_tree, bool);
1012 static void rs6000_file_start (void);
1014 static int rs6000_elf_reloc_rw_mask (void);
1015 static void rs6000_elf_asm_out_constructor (rtx, int);
1016 static void rs6000_elf_asm_out_destructor (rtx, int);
1017 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
1018 static void rs6000_elf_asm_init_sections (void);
1019 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
1020 unsigned HOST_WIDE_INT);
1021 static void rs6000_elf_encode_section_info (tree, rtx, int)
1024 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
1025 static void rs6000_alloc_sdmode_stack_slot (void);
1026 static void rs6000_instantiate_decls (void);
1028 static void rs6000_xcoff_asm_output_anchor (rtx);
1029 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
1030 static void rs6000_xcoff_asm_init_sections (void);
1031 static int rs6000_xcoff_reloc_rw_mask (void);
1032 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
1033 static section *rs6000_xcoff_select_section (tree, int,
1034 unsigned HOST_WIDE_INT);
1035 static void rs6000_xcoff_unique_section (tree, int);
1036 static section *rs6000_xcoff_select_rtx_section
1037 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
1038 static const char * rs6000_xcoff_strip_name_encoding (const char *);
1039 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
1040 static void rs6000_xcoff_file_start (void);
1041 static void rs6000_xcoff_file_end (void);
1043 static int rs6000_variable_issue (FILE *, int, rtx, int);
1044 static int rs6000_register_move_cost (enum machine_mode,
1045 reg_class_t, reg_class_t);
1046 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
1047 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
1048 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
1049 static int rs6000_debug_address_cost (rtx, bool);
1050 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
1051 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
1052 static void rs6000_sched_init (FILE *, int, int);
1053 static bool is_microcoded_insn (rtx);
1054 static bool is_nonpipeline_insn (rtx);
1055 static bool is_cracked_insn (rtx);
1056 static bool is_branch_slot_insn (rtx);
1057 static bool is_load_insn (rtx);
1058 static rtx get_store_dest (rtx pat);
1059 static bool is_store_insn (rtx);
1060 static bool set_to_load_agen (rtx,rtx);
1061 static bool adjacent_mem_locations (rtx,rtx);
1062 static int rs6000_adjust_priority (rtx, int);
1063 static int rs6000_issue_rate (void);
1064 static bool rs6000_is_costly_dependence (dep_t, int, int);
1065 static rtx get_next_active_insn (rtx, rtx);
1066 static bool insn_terminates_group_p (rtx , enum group_termination);
1067 static bool insn_must_be_first_in_group (rtx);
1068 static bool insn_must_be_last_in_group (rtx);
1069 static bool is_costly_group (rtx *, rtx);
1070 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1071 static int redefine_groups (FILE *, int, rtx, rtx);
1072 static int pad_groups (FILE *, int, rtx, rtx);
1073 static void rs6000_sched_finish (FILE *, int);
1074 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1075 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1076 static int rs6000_use_sched_lookahead (void);
1077 static int rs6000_use_sched_lookahead_guard (rtx);
1078 static void * rs6000_alloc_sched_context (void);
1079 static void rs6000_init_sched_context (void *, bool);
1080 static void rs6000_set_sched_context (void *);
1081 static void rs6000_free_sched_context (void *);
1082 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1083 static tree rs6000_builtin_mask_for_load (void);
1084 static tree rs6000_builtin_mul_widen_even (tree);
1085 static tree rs6000_builtin_mul_widen_odd (tree);
1086 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1087 static tree rs6000_builtin_vec_perm (tree, tree *);
1088 static bool rs6000_builtin_support_vector_misalignment (enum
1092 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1094 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1096 static void def_builtin (int, const char *, tree, int);
1097 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1098 static void rs6000_init_builtins (void);
1099 static tree rs6000_builtin_decl (unsigned, bool);
1101 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1102 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1103 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1104 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1105 static void altivec_init_builtins (void);
1106 static unsigned builtin_hash_function (const void *);
1107 static int builtin_hash_eq (const void *, const void *);
1108 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1109 enum machine_mode, enum machine_mode,
1110 enum rs6000_builtins, const char *name);
1111 static void rs6000_common_init_builtins (void);
1112 static void rs6000_init_libfuncs (void);
1114 static void paired_init_builtins (void);
1115 static rtx paired_expand_builtin (tree, rtx, bool *);
1116 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1117 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1118 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1120 static void enable_mask_for_builtins (struct builtin_description *, int,
1121 enum rs6000_builtins,
1122 enum rs6000_builtins);
1123 static void spe_init_builtins (void);
1124 static rtx spe_expand_builtin (tree, rtx, bool *);
1125 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1126 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1127 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1128 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1129 static rs6000_stack_t *rs6000_stack_info (void);
1130 static void debug_stack_info (rs6000_stack_t *);
1132 static rtx altivec_expand_builtin (tree, rtx, bool *);
1133 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1134 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1135 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1136 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1137 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1138 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1139 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1140 static rtx altivec_expand_vec_set_builtin (tree);
1141 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1142 static int get_element_number (tree, tree);
1143 static void rs6000_option_override (void);
1144 static void rs6000_option_init_struct (struct gcc_options *);
1145 static void rs6000_option_default_params (void);
1146 static bool rs6000_handle_option (size_t, const char *, int);
1147 static int rs6000_loop_align_max_skip (rtx);
1148 static void rs6000_parse_tls_size_option (void);
1149 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
1150 static int first_altivec_reg_to_save (void);
1151 static unsigned int compute_vrsave_mask (void);
1152 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1153 static void is_altivec_return_reg (rtx, void *);
1154 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1155 int easy_vector_constant (rtx, enum machine_mode);
1156 static rtx rs6000_dwarf_register_span (rtx);
1157 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1158 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1159 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1160 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1161 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1162 static rtx rs6000_delegitimize_address (rtx);
1163 static rtx rs6000_tls_get_addr (void);
1164 static rtx rs6000_got_sym (void);
1165 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1166 static const char *rs6000_get_some_local_dynamic_name (void);
1167 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1168 static rtx rs6000_complex_function_value (enum machine_mode);
1169 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1170 enum machine_mode, const_tree);
1171 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1172 HOST_WIDE_INT, int);
1173 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1176 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1179 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1180 const_tree, HOST_WIDE_INT,
1182 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1183 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1184 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1186 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1188 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1189 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1190 enum machine_mode, tree,
1192 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1194 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1196 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1198 static void macho_branch_islands (void);
1199 static int no_previous_def (tree function_name);
1200 static tree get_prev_label (tree function_name);
1201 static void rs6000_darwin_file_start (void);
1204 static tree rs6000_build_builtin_va_list (void);
1205 static void rs6000_va_start (tree, rtx);
1206 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1207 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1208 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1209 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1210 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1211 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1213 static tree rs6000_stack_protect_fail (void);
1215 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1218 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1221 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1223 = rs6000_legitimize_reload_address;
1225 static bool rs6000_mode_dependent_address_p (const_rtx);
1226 static bool rs6000_mode_dependent_address (const_rtx);
1227 static bool rs6000_debug_mode_dependent_address (const_rtx);
1228 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1229 = rs6000_mode_dependent_address;
1231 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1232 enum machine_mode, rtx);
1233 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1236 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1237 enum machine_mode, rtx)
1238 = rs6000_secondary_reload_class;
1240 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1241 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1243 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1244 = rs6000_preferred_reload_class;
1246 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1249 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1253 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1255 = rs6000_secondary_memory_needed;
1257 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1260 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1264 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1267 = rs6000_cannot_change_mode_class;
1269 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1271 struct secondary_reload_info *);
1273 static const reg_class_t *rs6000_ira_cover_classes (void);
1275 const int INSN_NOT_AVAILABLE = -1;
1276 static enum machine_mode rs6000_eh_return_filter_mode (void);
1277 static bool rs6000_can_eliminate (const int, const int);
1278 static void rs6000_trampoline_init (rtx, tree, rtx);
1280 /* Hash table stuff for keeping track of TOC entries. */
1282 struct GTY(()) toc_hash_struct
1284 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1285 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1287 enum machine_mode key_mode;
1291 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1293 /* Hash table to keep track of the argument types for builtin functions. */
1295 struct GTY(()) builtin_hash_struct
1298 enum machine_mode mode[4]; /* return value + 3 arguments. */
1299 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1302 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1304 /* Default register names. */
1305 char rs6000_reg_names[][8] =
1307 "0", "1", "2", "3", "4", "5", "6", "7",
1308 "8", "9", "10", "11", "12", "13", "14", "15",
1309 "16", "17", "18", "19", "20", "21", "22", "23",
1310 "24", "25", "26", "27", "28", "29", "30", "31",
1311 "0", "1", "2", "3", "4", "5", "6", "7",
1312 "8", "9", "10", "11", "12", "13", "14", "15",
1313 "16", "17", "18", "19", "20", "21", "22", "23",
1314 "24", "25", "26", "27", "28", "29", "30", "31",
1315 "mq", "lr", "ctr","ap",
1316 "0", "1", "2", "3", "4", "5", "6", "7",
1318 /* AltiVec registers. */
1319 "0", "1", "2", "3", "4", "5", "6", "7",
1320 "8", "9", "10", "11", "12", "13", "14", "15",
1321 "16", "17", "18", "19", "20", "21", "22", "23",
1322 "24", "25", "26", "27", "28", "29", "30", "31",
1324 /* SPE registers. */
1325 "spe_acc", "spefscr",
1326 /* Soft frame pointer. */
1330 #ifdef TARGET_REGNAMES
1331 static const char alt_reg_names[][8] =
1333 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1334 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1335 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1336 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1337 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1338 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1339 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1340 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1341 "mq", "lr", "ctr", "ap",
1342 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1344 /* AltiVec registers. */
1345 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1346 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1347 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1348 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1350 /* SPE registers. */
1351 "spe_acc", "spefscr",
1352 /* Soft frame pointer. */
1357 /* Table of valid machine attributes. */
1359 static const struct attribute_spec rs6000_attribute_table[] =
1361 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1362 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
1363 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1364 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
1365 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1366 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
1367 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1368 SUBTARGET_ATTRIBUTE_TABLE,
1370 { NULL, 0, 0, false, false, false, NULL }
1373 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1374 static const struct default_options rs6000_option_optimization_table[] =
1376 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1377 { OPT_LEVELS_NONE, 0, NULL, 0 }
1380 #ifndef MASK_STRICT_ALIGN
1381 #define MASK_STRICT_ALIGN 0
1383 #ifndef TARGET_PROFILE_KERNEL
1384 #define TARGET_PROFILE_KERNEL 0
1387 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1388 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1390 /* Initialize the GCC target structure. */
1391 #undef TARGET_ATTRIBUTE_TABLE
1392 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1393 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1394 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1395 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1396 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1398 #undef TARGET_ASM_ALIGNED_DI_OP
1399 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1401 /* Default unaligned ops are only provided for ELF. Find the ops needed
1402 for non-ELF systems. */
1403 #ifndef OBJECT_FORMAT_ELF
1405 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1407 #undef TARGET_ASM_UNALIGNED_HI_OP
1408 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1409 #undef TARGET_ASM_UNALIGNED_SI_OP
1410 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1411 #undef TARGET_ASM_UNALIGNED_DI_OP
1412 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1415 #undef TARGET_ASM_UNALIGNED_HI_OP
1416 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1417 #undef TARGET_ASM_UNALIGNED_SI_OP
1418 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1419 #undef TARGET_ASM_UNALIGNED_DI_OP
1420 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1421 #undef TARGET_ASM_ALIGNED_DI_OP
1422 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1426 /* This hook deals with fixups for relocatable code and DI-mode objects
1428 #undef TARGET_ASM_INTEGER
1429 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1431 #ifdef HAVE_GAS_HIDDEN
1432 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1433 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1436 #undef TARGET_HAVE_TLS
1437 #define TARGET_HAVE_TLS HAVE_AS_TLS
1439 #undef TARGET_CANNOT_FORCE_CONST_MEM
1440 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1442 #undef TARGET_DELEGITIMIZE_ADDRESS
1443 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1445 #undef TARGET_ASM_FUNCTION_PROLOGUE
1446 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1447 #undef TARGET_ASM_FUNCTION_EPILOGUE
1448 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1450 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1451 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1453 #undef TARGET_LEGITIMIZE_ADDRESS
1454 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1456 #undef TARGET_SCHED_VARIABLE_ISSUE
1457 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1459 #undef TARGET_SCHED_ISSUE_RATE
1460 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1461 #undef TARGET_SCHED_ADJUST_COST
1462 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1463 #undef TARGET_SCHED_ADJUST_PRIORITY
1464 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1465 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1466 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1467 #undef TARGET_SCHED_INIT
1468 #define TARGET_SCHED_INIT rs6000_sched_init
1469 #undef TARGET_SCHED_FINISH
1470 #define TARGET_SCHED_FINISH rs6000_sched_finish
1471 #undef TARGET_SCHED_REORDER
1472 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1473 #undef TARGET_SCHED_REORDER2
1474 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1476 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1477 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1479 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1480 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1482 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1483 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1484 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1485 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1486 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1487 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1488 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1489 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1491 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1492 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1493 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1494 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1495 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1496 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1497 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1498 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1499 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1500 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1501 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1502 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1503 rs6000_builtin_support_vector_misalignment
1504 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1505 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1506 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1507 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1508 rs6000_builtin_vectorization_cost
1509 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1510 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1511 rs6000_preferred_simd_mode
1513 #undef TARGET_INIT_BUILTINS
1514 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1515 #undef TARGET_BUILTIN_DECL
1516 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1518 #undef TARGET_EXPAND_BUILTIN
1519 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1521 #undef TARGET_MANGLE_TYPE
1522 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1524 #undef TARGET_INIT_LIBFUNCS
1525 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1528 #undef TARGET_BINDS_LOCAL_P
1529 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1532 #undef TARGET_MS_BITFIELD_LAYOUT_P
1533 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1535 #undef TARGET_ASM_OUTPUT_MI_THUNK
1536 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1538 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1539 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1541 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1542 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1544 #undef TARGET_INVALID_WITHIN_DOLOOP
1545 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1547 #undef TARGET_REGISTER_MOVE_COST
1548 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1549 #undef TARGET_MEMORY_MOVE_COST
1550 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1551 #undef TARGET_RTX_COSTS
1552 #define TARGET_RTX_COSTS rs6000_rtx_costs
1553 #undef TARGET_ADDRESS_COST
1554 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1556 #undef TARGET_DWARF_REGISTER_SPAN
1557 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1559 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1560 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1562 /* On rs6000, function arguments are promoted, as are function return
1564 #undef TARGET_PROMOTE_FUNCTION_MODE
1565 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1567 #undef TARGET_RETURN_IN_MEMORY
1568 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1570 #undef TARGET_SETUP_INCOMING_VARARGS
1571 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1573 /* Always strict argument naming on rs6000. */
1574 #undef TARGET_STRICT_ARGUMENT_NAMING
1575 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1576 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1577 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1578 #undef TARGET_SPLIT_COMPLEX_ARG
1579 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1580 #undef TARGET_MUST_PASS_IN_STACK
1581 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1582 #undef TARGET_PASS_BY_REFERENCE
1583 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1584 #undef TARGET_ARG_PARTIAL_BYTES
1585 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1586 #undef TARGET_FUNCTION_ARG_ADVANCE
1587 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1588 #undef TARGET_FUNCTION_ARG
1589 #define TARGET_FUNCTION_ARG rs6000_function_arg
1591 #undef TARGET_BUILD_BUILTIN_VA_LIST
1592 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1594 #undef TARGET_EXPAND_BUILTIN_VA_START
1595 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1597 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1598 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1600 #undef TARGET_EH_RETURN_FILTER_MODE
1601 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1603 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1604 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1606 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1607 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1609 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1610 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1612 #undef TARGET_HANDLE_OPTION
1613 #define TARGET_HANDLE_OPTION rs6000_handle_option
1615 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1616 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1618 #undef TARGET_OPTION_OVERRIDE
1619 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1621 #undef TARGET_OPTION_INIT_STRUCT
1622 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1624 #undef TARGET_OPTION_DEFAULT_PARAMS
1625 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1627 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1628 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1630 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1631 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1632 rs6000_builtin_vectorized_function
1634 #undef TARGET_DEFAULT_TARGET_FLAGS
1635 #define TARGET_DEFAULT_TARGET_FLAGS \
1638 #undef TARGET_STACK_PROTECT_FAIL
1639 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1641 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1642 The PowerPC architecture requires only weak consistency among
1643 processors--that is, memory accesses between processors need not be
1644 sequentially consistent and memory accesses among processors can occur
1645 in any order. The ability to order memory accesses weakly provides
1646 opportunities for more efficient use of the system bus. Unless a
1647 dependency exists, the 604e allows read operations to precede store
1649 #undef TARGET_RELAXED_ORDERING
1650 #define TARGET_RELAXED_ORDERING true
1653 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1654 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1657 /* Use a 32-bit anchor range. This leads to sequences like:
1659 addis tmp,anchor,high
1662 where tmp itself acts as an anchor, and can be shared between
1663 accesses to the same 64k page. */
1664 #undef TARGET_MIN_ANCHOR_OFFSET
1665 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1666 #undef TARGET_MAX_ANCHOR_OFFSET
1667 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1668 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1669 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1671 #undef TARGET_BUILTIN_RECIPROCAL
1672 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1674 #undef TARGET_EXPAND_TO_RTL_HOOK
1675 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1677 #undef TARGET_INSTANTIATE_DECLS
1678 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1680 #undef TARGET_SECONDARY_RELOAD
1681 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1683 #undef TARGET_IRA_COVER_CLASSES
1684 #define TARGET_IRA_COVER_CLASSES rs6000_ira_cover_classes
1686 #undef TARGET_LEGITIMATE_ADDRESS_P
1687 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1689 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1690 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1692 #undef TARGET_CAN_ELIMINATE
1693 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1695 #undef TARGET_TRAMPOLINE_INIT
1696 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1698 #undef TARGET_FUNCTION_VALUE
1699 #define TARGET_FUNCTION_VALUE rs6000_function_value
1701 struct gcc_target targetm = TARGET_INITIALIZER;
1703 /* Return number of consecutive hard regs needed starting at reg REGNO
1704 to hold something of mode MODE.
1705 This is ordinarily the length in words of a value of mode MODE
1706 but can be less for certain modes in special long registers.
1708 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1709 scalar instructions. The upper 32 bits are only available to the
1712 POWER and PowerPC GPRs hold 32 bits worth;
1713 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1716 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1718 unsigned HOST_WIDE_INT reg_size;
1720 if (FP_REGNO_P (regno))
1721 reg_size = (VECTOR_MEM_VSX_P (mode)
1722 ? UNITS_PER_VSX_WORD
1723 : UNITS_PER_FP_WORD);
1725 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1726 reg_size = UNITS_PER_SPE_WORD;
1728 else if (ALTIVEC_REGNO_P (regno))
1729 reg_size = UNITS_PER_ALTIVEC_WORD;
1731 /* The value returned for SCmode in the E500 double case is 2 for
1732 ABI compatibility; storing an SCmode value in a single register
1733 would require function_arg and rs6000_spe_function_arg to handle
1734 SCmode so as to pass the value correctly in a pair of
1736 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1737 && !DECIMAL_FLOAT_MODE_P (mode))
1738 reg_size = UNITS_PER_FP_WORD;
1741 reg_size = UNITS_PER_WORD;
1743 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1746 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1749 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1751 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1753 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1754 implementations. Don't allow an item to be split between a FP register
1755 and an Altivec register. */
1756 if (VECTOR_MEM_VSX_P (mode))
1758 if (FP_REGNO_P (regno))
1759 return FP_REGNO_P (last_regno);
1761 if (ALTIVEC_REGNO_P (regno))
1762 return ALTIVEC_REGNO_P (last_regno);
1765 /* The GPRs can hold any mode, but values bigger than one register
1766 cannot go past R31. */
1767 if (INT_REGNO_P (regno))
1768 return INT_REGNO_P (last_regno);
1770 /* The float registers (except for VSX vector modes) can only hold floating
1771 modes and DImode. This excludes the 32-bit decimal float mode for
1773 if (FP_REGNO_P (regno))
1775 if (SCALAR_FLOAT_MODE_P (mode)
1776 && (mode != TDmode || (regno % 2) == 0)
1777 && FP_REGNO_P (last_regno))
1780 if (GET_MODE_CLASS (mode) == MODE_INT
1781 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1784 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1785 && PAIRED_VECTOR_MODE (mode))
1791 /* The CR register can only hold CC modes. */
1792 if (CR_REGNO_P (regno))
1793 return GET_MODE_CLASS (mode) == MODE_CC;
1795 if (CA_REGNO_P (regno))
1796 return mode == BImode;
1798 /* AltiVec only in AldyVec registers. */
1799 if (ALTIVEC_REGNO_P (regno))
1800 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1802 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1803 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1806 /* We cannot put TImode anywhere except general register and it must be able
1807 to fit within the register set. In the future, allow TImode in the
1808 Altivec or VSX registers. */
1810 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1813 /* Print interesting facts about registers. */
1815 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1819 for (r = first_regno; r <= last_regno; ++r)
1821 const char *comma = "";
1824 if (first_regno == last_regno)
1825 fprintf (stderr, "%s:\t", reg_name);
1827 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1830 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1831 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1835 fprintf (stderr, ",\n\t");
1840 if (rs6000_hard_regno_nregs[m][r] > 1)
1841 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
1842 rs6000_hard_regno_nregs[m][r]);
1844 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
1849 if (call_used_regs[r])
1853 fprintf (stderr, ",\n\t");
1858 len += fprintf (stderr, "%s%s", comma, "call-used");
1866 fprintf (stderr, ",\n\t");
1871 len += fprintf (stderr, "%s%s", comma, "fixed");
1877 fprintf (stderr, ",\n\t");
1881 fprintf (stderr, "%sregno = %d\n", comma, r);
1885 /* Print various interesting information with -mdebug=reg. */
1887 rs6000_debug_reg_global (void)
1889 const char *nl = (const char *)0;
1891 char costly_num[20];
1893 const char *costly_str;
1894 const char *nop_str;
1896 /* Map enum rs6000_vector to string. */
1897 static const char *rs6000_debug_vector_unit[] = {
1906 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
1907 LAST_VIRTUAL_REGISTER);
1908 rs6000_debug_reg_print (0, 31, "gr");
1909 rs6000_debug_reg_print (32, 63, "fp");
1910 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
1913 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
1914 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
1915 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
1916 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
1917 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
1918 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
1919 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
1920 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
1921 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
1925 "d reg_class = %s\n"
1926 "f reg_class = %s\n"
1927 "v reg_class = %s\n"
1928 "wa reg_class = %s\n"
1929 "wd reg_class = %s\n"
1930 "wf reg_class = %s\n"
1931 "ws reg_class = %s\n\n",
1932 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
1933 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
1934 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
1935 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
1936 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
1937 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
1938 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
1940 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1941 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
1944 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
1946 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
1947 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
1953 if (rs6000_recip_control)
1955 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
1957 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1958 if (rs6000_recip_bits[m])
1961 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
1963 (RS6000_RECIP_AUTO_RE_P (m)
1965 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
1966 (RS6000_RECIP_AUTO_RSQRTE_P (m)
1968 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
1971 fputs ("\n", stderr);
1974 switch (rs6000_sched_costly_dep)
1976 case max_dep_latency:
1977 costly_str = "max_dep_latency";
1981 costly_str = "no_dep_costly";
1984 case all_deps_costly:
1985 costly_str = "all_deps_costly";
1988 case true_store_to_load_dep_costly:
1989 costly_str = "true_store_to_load_dep_costly";
1992 case store_to_load_dep_costly:
1993 costly_str = "store_to_load_dep_costly";
1997 costly_str = costly_num;
1998 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2002 switch (rs6000_sched_insert_nops)
2004 case sched_finish_regroup_exact:
2005 nop_str = "sched_finish_regroup_exact";
2008 case sched_finish_pad_groups:
2009 nop_str = "sched_finish_pad_groups";
2012 case sched_finish_none:
2013 nop_str = "sched_finish_none";
2018 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2023 "always_hint = %s\n"
2024 "align_branch_targets = %s\n"
2025 "sched_restricted_insns_priority = %d\n"
2026 "sched_costly_dep = %s\n"
2027 "sched_insert_nops = %s\n\n",
2028 rs6000_always_hint ? "true" : "false",
2029 rs6000_align_branch_targets ? "true" : "false",
2030 (int)rs6000_sched_restricted_insns_priority,
2031 costly_str, nop_str);
2034 /* Initialize the various global tables that are based on register size. */
2036 rs6000_init_hard_regno_mode_ok (void)
2042 /* Precalculate REGNO_REG_CLASS. */
2043 rs6000_regno_regclass[0] = GENERAL_REGS;
2044 for (r = 1; r < 32; ++r)
2045 rs6000_regno_regclass[r] = BASE_REGS;
2047 for (r = 32; r < 64; ++r)
2048 rs6000_regno_regclass[r] = FLOAT_REGS;
2050 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2051 rs6000_regno_regclass[r] = NO_REGS;
2053 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2054 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2056 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2057 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2058 rs6000_regno_regclass[r] = CR_REGS;
2060 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2061 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2062 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2063 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2064 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2065 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2066 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2067 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2068 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2069 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2071 /* Precalculate vector information, this must be set up before the
2072 rs6000_hard_regno_nregs_internal below. */
2073 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2075 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2076 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2077 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2080 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2081 rs6000_constraints[c] = NO_REGS;
2083 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2084 believes it can use native alignment or still uses 128-bit alignment. */
2085 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2096 /* V2DF mode, VSX only. */
2099 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2100 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2101 rs6000_vector_align[V2DFmode] = align64;
2104 /* V4SF mode, either VSX or Altivec. */
2107 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2108 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2109 rs6000_vector_align[V4SFmode] = align32;
2111 else if (TARGET_ALTIVEC)
2113 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2114 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2115 rs6000_vector_align[V4SFmode] = align32;
2118 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2122 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2123 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2124 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2125 rs6000_vector_align[V4SImode] = align32;
2126 rs6000_vector_align[V8HImode] = align32;
2127 rs6000_vector_align[V16QImode] = align32;
2131 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2132 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2133 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2137 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2138 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2139 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2143 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2144 Altivec doesn't have 64-bit support. */
2147 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2148 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2149 rs6000_vector_align[V2DImode] = align64;
2152 /* DFmode, see if we want to use the VSX unit. */
2153 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2155 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2156 rs6000_vector_mem[DFmode]
2157 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2158 rs6000_vector_align[DFmode] = align64;
2161 /* TODO add SPE and paired floating point vector support. */
2163 /* Register class constaints for the constraints that depend on compile
2165 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2166 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2168 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2169 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2173 /* At present, we just use VSX_REGS, but we have different constraints
2174 based on the use, in case we want to fine tune the default register
2175 class used. wa = any VSX register, wf = register class to use for
2176 V4SF, wd = register class to use for V2DF, and ws = register classs to
2177 use for DF scalars. */
2178 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2179 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2180 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2181 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2187 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2189 /* Set up the reload helper functions. */
2190 if (TARGET_VSX || TARGET_ALTIVEC)
2194 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2195 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2196 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2197 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2198 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2199 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2200 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2201 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2202 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2203 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2204 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2205 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2209 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2210 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2211 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2212 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2213 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2214 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2215 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2216 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2217 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2218 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2219 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2220 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2224 /* Precalculate HARD_REGNO_NREGS. */
2225 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2226 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2227 rs6000_hard_regno_nregs[m][r]
2228 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2230 /* Precalculate HARD_REGNO_MODE_OK. */
2231 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2232 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2233 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2234 rs6000_hard_regno_mode_ok_p[m][r] = true;
2236 /* Precalculate CLASS_MAX_NREGS sizes. */
2237 for (c = 0; c < LIM_REG_CLASSES; ++c)
2241 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2242 reg_size = UNITS_PER_VSX_WORD;
2244 else if (c == ALTIVEC_REGS)
2245 reg_size = UNITS_PER_ALTIVEC_WORD;
2247 else if (c == FLOAT_REGS)
2248 reg_size = UNITS_PER_FP_WORD;
2251 reg_size = UNITS_PER_WORD;
2253 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2254 rs6000_class_max_nregs[m][c]
2255 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2258 if (TARGET_E500_DOUBLE)
2259 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2261 /* Calculate which modes to automatically generate code to use a the
2262 reciprocal divide and square root instructions. In the future, possibly
2263 automatically generate the instructions even if the user did not specify
2264 -mrecip. The older machines double precision reciprocal sqrt estimate is
2265 not accurate enough. */
2266 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2268 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2270 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2271 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2272 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2273 if (VECTOR_UNIT_VSX_P (V2DFmode))
2274 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2276 if (TARGET_FRSQRTES)
2277 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2279 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2280 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2281 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2282 if (VECTOR_UNIT_VSX_P (V2DFmode))
2283 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2285 if (rs6000_recip_control)
2287 if (!TARGET_FUSED_MADD)
2288 warning (0, "-mrecip requires -mfused-madd");
2289 if (!flag_finite_math_only)
2290 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2291 if (flag_trapping_math)
2292 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2293 if (!flag_reciprocal_math)
2294 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2295 if (TARGET_FUSED_MADD && flag_finite_math_only && !flag_trapping_math
2296 && flag_reciprocal_math)
2298 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2299 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2300 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2302 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2303 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2304 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2306 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2307 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2308 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2310 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2311 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2312 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2314 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2315 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2316 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2318 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2319 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2320 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2322 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2323 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2324 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2326 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2327 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2328 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2332 if (TARGET_DEBUG_REG)
2333 rs6000_debug_reg_global ();
2335 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2337 "SImode variable mult cost = %d\n"
2338 "SImode constant mult cost = %d\n"
2339 "SImode short constant mult cost = %d\n"
2340 "DImode multipliciation cost = %d\n"
2341 "SImode division cost = %d\n"
2342 "DImode division cost = %d\n"
2343 "Simple fp operation cost = %d\n"
2344 "DFmode multiplication cost = %d\n"
2345 "SFmode division cost = %d\n"
2346 "DFmode division cost = %d\n"
2347 "cache line size = %d\n"
2348 "l1 cache size = %d\n"
2349 "l2 cache size = %d\n"
2350 "simultaneous prefetches = %d\n"
2353 rs6000_cost->mulsi_const,
2354 rs6000_cost->mulsi_const9,
2362 rs6000_cost->cache_line_size,
2363 rs6000_cost->l1_cache_size,
2364 rs6000_cost->l2_cache_size,
2365 rs6000_cost->simultaneous_prefetches);
2369 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2372 darwin_rs6000_override_options (void)
2374 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2376 rs6000_altivec_abi = 1;
2377 TARGET_ALTIVEC_VRSAVE = 1;
2379 if (DEFAULT_ABI == ABI_DARWIN
2381 darwin_one_byte_bool = 1;
2383 if (TARGET_64BIT && ! TARGET_POWERPC64)
2385 target_flags |= MASK_POWERPC64;
2386 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2390 rs6000_default_long_calls = 1;
2391 target_flags |= MASK_SOFT_FLOAT;
2394 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2396 if (!flag_mkernel && !flag_apple_kext
2398 && ! (target_flags_explicit & MASK_ALTIVEC))
2399 target_flags |= MASK_ALTIVEC;
2401 /* Unless the user (not the configurer) has explicitly overridden
2402 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2403 G4 unless targetting the kernel. */
2406 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2407 && ! (target_flags_explicit & MASK_ALTIVEC)
2408 && ! rs6000_select[1].string)
2410 target_flags |= MASK_ALTIVEC;
2415 /* If not otherwise specified by a target, make 'long double' equivalent to
2418 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2419 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2422 /* Override command line options. Mostly we process the processor
2423 type and sometimes adjust other TARGET_ options. */
2426 rs6000_option_override_internal (const char *default_cpu)
2429 struct rs6000_cpu_select *ptr;
2432 /* Simplifications for entries below. */
2435 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
2436 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
2439 /* This table occasionally claims that a processor does not support
2440 a particular feature even though it does, but the feature is slower
2441 than the alternative. Thus, it shouldn't be relied on as a
2442 complete description of the processor's support.
2444 Please keep this list in order, and don't forget to update the
2445 documentation in invoke.texi when adding a new processor or
2449 const char *const name; /* Canonical processor name. */
2450 const enum processor_type processor; /* Processor type enum value. */
2451 const int target_enable; /* Target flags to enable. */
2452 } const processor_target_table[]
2453 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2454 {"403", PROCESSOR_PPC403,
2455 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
2456 {"405", PROCESSOR_PPC405,
2457 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2458 {"405fp", PROCESSOR_PPC405,
2459 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2460 {"440", PROCESSOR_PPC440,
2461 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2462 {"440fp", PROCESSOR_PPC440,
2463 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2464 {"464", PROCESSOR_PPC440,
2465 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
2466 {"464fp", PROCESSOR_PPC440,
2467 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2468 {"476", PROCESSOR_PPC476,
2469 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
2470 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2471 {"476fp", PROCESSOR_PPC476,
2472 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
2473 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
2474 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
2475 {"601", PROCESSOR_PPC601,
2476 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
2477 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2478 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2479 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2480 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2481 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2482 {"620", PROCESSOR_PPC620,
2483 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2484 {"630", PROCESSOR_PPC630,
2485 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2486 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2487 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
2488 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2489 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2490 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2491 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2492 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2493 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2495 /* 8548 has a dummy entry for now. */
2496 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
2498 {"a2", PROCESSOR_PPCA2,
2499 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
2500 | MASK_CMPB | MASK_NO_UPDATE },
2501 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2502 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
2503 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
2505 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
2506 | MASK_PPC_GFXOPT | MASK_ISEL},
2507 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2508 {"970", PROCESSOR_POWER4,
2509 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2510 {"cell", PROCESSOR_CELL,
2511 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2512 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
2513 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
2514 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
2515 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
2516 {"G5", PROCESSOR_POWER4,
2517 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
2518 {"titan", PROCESSOR_TITAN,
2519 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
2520 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2521 {"power2", PROCESSOR_POWER,
2522 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2523 {"power3", PROCESSOR_PPC630,
2524 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2525 {"power4", PROCESSOR_POWER4,
2526 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2528 {"power5", PROCESSOR_POWER5,
2529 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2530 | MASK_MFCRF | MASK_POPCNTB},
2531 {"power5+", PROCESSOR_POWER5,
2532 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2533 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
2534 {"power6", PROCESSOR_POWER6,
2535 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2536 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2537 | MASK_RECIP_PRECISION},
2538 {"power6x", PROCESSOR_POWER6,
2539 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
2540 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
2541 | MASK_MFPGPR | MASK_RECIP_PRECISION},
2542 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
2543 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
2544 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
2545 | MASK_VSX | MASK_RECIP_PRECISION},
2546 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
2547 {"powerpc64", PROCESSOR_POWERPC64,
2548 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
2549 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2550 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2551 {"rios2", PROCESSOR_RIOS2,
2552 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
2553 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2554 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
2555 {"rs64", PROCESSOR_RS64A,
2556 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
2559 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
2561 /* Some OSs don't support saving the high part of 64-bit registers on
2562 context switch. Other OSs don't support saving Altivec registers.
2563 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
2564 settings; if the user wants either, the user must explicitly specify
2565 them and we won't interfere with the user's specification. */
2568 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
2569 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
2570 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
2571 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
2572 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
2573 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
2574 | MASK_RECIP_PRECISION)
2577 /* Masks for instructions set at various powerpc ISAs. */
2579 ISA_2_1_MASKS = MASK_MFCRF,
2580 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB | MASK_FPRND),
2582 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2583 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2584 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2585 masks by server and embedded. */
2586 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2587 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2588 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2590 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2591 altivec is a win so enable it. */
2592 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2593 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2597 /* Numerous experiment shows that IRA based loop pressure
2598 calculation works better for RTL loop invariant motion on targets
2599 with enough (>= 32) registers. It is an expensive optimization.
2600 So it is on only for peak performance. */
2602 flag_ira_loop_pressure = 1;
2604 /* Set the pointer size. */
2607 rs6000_pmode = (int)DImode;
2608 rs6000_pointer_size = 64;
2612 rs6000_pmode = (int)SImode;
2613 rs6000_pointer_size = 32;
2616 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2617 #ifdef OS_MISSING_POWERPC64
2618 if (OS_MISSING_POWERPC64)
2619 set_masks &= ~MASK_POWERPC64;
2621 #ifdef OS_MISSING_ALTIVEC
2622 if (OS_MISSING_ALTIVEC)
2623 set_masks &= ~MASK_ALTIVEC;
2626 /* Don't override by the processor default if given explicitly. */
2627 set_masks &= ~target_flags_explicit;
2629 /* Identify the processor type. */
2630 rs6000_select[0].string = default_cpu;
2631 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2633 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2635 ptr = &rs6000_select[i];
2636 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2638 for (j = 0; j < ptt_size; j++)
2639 if (! strcmp (ptr->string, processor_target_table[j].name))
2641 if (ptr->set_tune_p)
2642 rs6000_cpu = processor_target_table[j].processor;
2644 if (ptr->set_arch_p)
2646 target_flags &= ~set_masks;
2647 target_flags |= (processor_target_table[j].target_enable
2654 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2658 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2659 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2662 error ("AltiVec not supported in this target");
2664 error ("Spe not supported in this target");
2667 /* Disable Cell microcode if we are optimizing for the Cell
2668 and not optimizing for size. */
2669 if (rs6000_gen_cell_microcode == -1)
2670 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2673 /* If we are optimizing big endian systems for space and it's OK to
2674 use instructions that would be microcoded on the Cell, use the
2675 load/store multiple and string instructions. */
2676 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2677 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2679 /* Don't allow -mmultiple or -mstring on little endian systems
2680 unless the cpu is a 750, because the hardware doesn't support the
2681 instructions used in little endian mode, and causes an alignment
2682 trap. The 750 does not cause an alignment trap (except when the
2683 target is unaligned). */
2685 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2687 if (TARGET_MULTIPLE)
2689 target_flags &= ~MASK_MULTIPLE;
2690 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2691 warning (0, "-mmultiple is not supported on little endian systems");
2696 target_flags &= ~MASK_STRING;
2697 if ((target_flags_explicit & MASK_STRING) != 0)
2698 warning (0, "-mstring is not supported on little endian systems");
2702 /* Add some warnings for VSX. */
2705 const char *msg = NULL;
2706 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2707 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2709 if (target_flags_explicit & MASK_VSX)
2710 msg = N_("-mvsx requires hardware floating point");
2712 target_flags &= ~ MASK_VSX;
2714 else if (TARGET_PAIRED_FLOAT)
2715 msg = N_("-mvsx and -mpaired are incompatible");
2716 /* The hardware will allow VSX and little endian, but until we make sure
2717 things like vector select, etc. work don't allow VSX on little endian
2718 systems at this point. */
2719 else if (!BYTES_BIG_ENDIAN)
2720 msg = N_("-mvsx used with little endian code");
2721 else if (TARGET_AVOID_XFORM > 0)
2722 msg = N_("-mvsx needs indexed addressing");
2723 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2725 if (target_flags_explicit & MASK_VSX)
2726 msg = N_("-mvsx and -mno-altivec are incompatible");
2728 msg = N_("-mno-altivec disables vsx");
2734 target_flags &= ~ MASK_VSX;
2735 target_flags_explicit |= MASK_VSX;
2739 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2740 unless the user explicitly used the -mno-<option> to disable the code. */
2742 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2743 else if (TARGET_POPCNTD)
2744 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2745 else if (TARGET_DFP)
2746 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2747 else if (TARGET_CMPB)
2748 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2749 else if (TARGET_POPCNTB || TARGET_FPRND)
2750 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2751 else if (TARGET_ALTIVEC)
2752 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2754 /* E500mc does "better" if we inline more aggressively. Respect the
2755 user's opinion, though. */
2756 if (rs6000_block_move_inline_limit == 0
2757 && (rs6000_cpu == PROCESSOR_PPCE500MC
2758 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2759 rs6000_block_move_inline_limit = 128;
2761 /* store_one_arg depends on expand_block_move to handle at least the
2762 size of reg_parm_stack_space. */
2763 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2764 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2766 /* Set debug flags */
2767 if (rs6000_debug_name)
2769 if (! strcmp (rs6000_debug_name, "all"))
2770 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2771 = rs6000_debug_addr = rs6000_debug_cost = 1;
2772 else if (! strcmp (rs6000_debug_name, "stack"))
2773 rs6000_debug_stack = 1;
2774 else if (! strcmp (rs6000_debug_name, "arg"))
2775 rs6000_debug_arg = 1;
2776 else if (! strcmp (rs6000_debug_name, "reg"))
2777 rs6000_debug_reg = 1;
2778 else if (! strcmp (rs6000_debug_name, "addr"))
2779 rs6000_debug_addr = 1;
2780 else if (! strcmp (rs6000_debug_name, "cost"))
2781 rs6000_debug_cost = 1;
2783 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2785 /* If the appropriate debug option is enabled, replace the target hooks
2786 with debug versions that call the real version and then prints
2787 debugging information. */
2788 if (TARGET_DEBUG_COST)
2790 targetm.rtx_costs = rs6000_debug_rtx_costs;
2791 targetm.address_cost = rs6000_debug_address_cost;
2792 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2795 if (TARGET_DEBUG_ADDR)
2797 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2798 targetm.legitimize_address = rs6000_debug_legitimize_address;
2799 rs6000_secondary_reload_class_ptr
2800 = rs6000_debug_secondary_reload_class;
2801 rs6000_secondary_memory_needed_ptr
2802 = rs6000_debug_secondary_memory_needed;
2803 rs6000_cannot_change_mode_class_ptr
2804 = rs6000_debug_cannot_change_mode_class;
2805 rs6000_preferred_reload_class_ptr
2806 = rs6000_debug_preferred_reload_class;
2807 rs6000_legitimize_reload_address_ptr
2808 = rs6000_debug_legitimize_reload_address;
2809 rs6000_mode_dependent_address_ptr
2810 = rs6000_debug_mode_dependent_address;
2814 if (rs6000_traceback_name)
2816 if (! strncmp (rs6000_traceback_name, "full", 4))
2817 rs6000_traceback = traceback_full;
2818 else if (! strncmp (rs6000_traceback_name, "part", 4))
2819 rs6000_traceback = traceback_part;
2820 else if (! strncmp (rs6000_traceback_name, "no", 2))
2821 rs6000_traceback = traceback_none;
2823 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2824 rs6000_traceback_name);
2827 if (rs6000_veclibabi_name)
2829 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2830 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2832 error ("unknown vectorization library ABI type (%s) for "
2833 "-mveclibabi= switch", rs6000_veclibabi_name);
2836 if (!rs6000_explicit_options.long_double)
2837 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2839 #ifndef POWERPC_LINUX
2840 if (!rs6000_explicit_options.ieee)
2841 rs6000_ieeequad = 1;
2844 /* Enable Altivec ABI for AIX -maltivec. */
2845 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2846 rs6000_altivec_abi = 1;
2848 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2849 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2850 be explicitly overridden in either case. */
2853 if (!rs6000_explicit_options.altivec_abi
2854 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2855 rs6000_altivec_abi = 1;
2857 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2858 if (!rs6000_explicit_options.vrsave)
2859 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2862 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2863 So far, the only darwin64 targets are also MACH-O. */
2865 && DEFAULT_ABI == ABI_DARWIN
2868 rs6000_darwin64_abi = 1;
2869 /* Default to natural alignment, for better performance. */
2870 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2873 /* Place FP constants in the constant pool instead of TOC
2874 if section anchors enabled. */
2875 if (flag_section_anchors)
2876 TARGET_NO_FP_IN_TOC = 1;
2878 /* Handle -mtls-size option. */
2879 rs6000_parse_tls_size_option ();
2881 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2882 SUBTARGET_OVERRIDE_OPTIONS;
2884 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2885 SUBSUBTARGET_OVERRIDE_OPTIONS;
2887 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2888 SUB3TARGET_OVERRIDE_OPTIONS;
2891 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2892 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2894 /* The e500 and e500mc do not have string instructions, and we set
2895 MASK_STRING above when optimizing for size. */
2896 if ((target_flags & MASK_STRING) != 0)
2897 target_flags = target_flags & ~MASK_STRING;
2899 else if (rs6000_select[1].string != NULL)
2901 /* For the powerpc-eabispe configuration, we set all these by
2902 default, so let's unset them if we manually set another
2903 CPU that is not the E500. */
2904 if (!rs6000_explicit_options.spe_abi)
2906 if (!rs6000_explicit_options.spe)
2908 if (!rs6000_explicit_options.float_gprs)
2909 rs6000_float_gprs = 0;
2910 if (!(target_flags_explicit & MASK_ISEL))
2911 target_flags &= ~MASK_ISEL;
2914 /* Detect invalid option combinations with E500. */
2917 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2918 && rs6000_cpu != PROCESSOR_POWER5
2919 && rs6000_cpu != PROCESSOR_POWER6
2920 && rs6000_cpu != PROCESSOR_POWER7
2921 && rs6000_cpu != PROCESSOR_PPCA2
2922 && rs6000_cpu != PROCESSOR_CELL);
2923 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2924 || rs6000_cpu == PROCESSOR_POWER5
2925 || rs6000_cpu == PROCESSOR_POWER7);
2926 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2927 || rs6000_cpu == PROCESSOR_POWER5
2928 || rs6000_cpu == PROCESSOR_POWER6
2929 || rs6000_cpu == PROCESSOR_POWER7
2930 || rs6000_cpu == PROCESSOR_PPCE500MC
2931 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2933 /* Allow debug switches to override the above settings. */
2934 if (TARGET_ALWAYS_HINT > 0)
2935 rs6000_always_hint = TARGET_ALWAYS_HINT;
2937 if (TARGET_SCHED_GROUPS > 0)
2938 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2940 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2941 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2943 rs6000_sched_restricted_insns_priority
2944 = (rs6000_sched_groups ? 1 : 0);
2946 /* Handle -msched-costly-dep option. */
2947 rs6000_sched_costly_dep
2948 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2950 if (rs6000_sched_costly_dep_str)
2952 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2953 rs6000_sched_costly_dep = no_dep_costly;
2954 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2955 rs6000_sched_costly_dep = all_deps_costly;
2956 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2957 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2958 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2959 rs6000_sched_costly_dep = store_to_load_dep_costly;
2961 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2962 atoi (rs6000_sched_costly_dep_str));
2965 /* Handle -minsert-sched-nops option. */
2966 rs6000_sched_insert_nops
2967 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2969 if (rs6000_sched_insert_nops_str)
2971 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2972 rs6000_sched_insert_nops = sched_finish_none;
2973 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2974 rs6000_sched_insert_nops = sched_finish_pad_groups;
2975 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2976 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2978 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2979 atoi (rs6000_sched_insert_nops_str));
2982 #ifdef TARGET_REGNAMES
2983 /* If the user desires alternate register names, copy in the
2984 alternate names now. */
2985 if (TARGET_REGNAMES)
2986 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2989 /* Set aix_struct_return last, after the ABI is determined.
2990 If -maix-struct-return or -msvr4-struct-return was explicitly
2991 used, don't override with the ABI default. */
2992 if (!rs6000_explicit_options.aix_struct_ret)
2993 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2996 /* IBM XL compiler defaults to unsigned bitfields. */
2997 if (TARGET_XL_COMPAT)
2998 flag_signed_bitfields = 0;
3001 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3002 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3005 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3007 /* We can only guarantee the availability of DI pseudo-ops when
3008 assembling for 64-bit targets. */
3011 targetm.asm_out.aligned_op.di = NULL;
3012 targetm.asm_out.unaligned_op.di = NULL;
3015 /* Set branch target alignment, if not optimizing for size. */
3018 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3019 aligned 8byte to avoid misprediction by the branch predictor. */
3020 if (rs6000_cpu == PROCESSOR_TITAN
3021 || rs6000_cpu == PROCESSOR_CELL)
3023 if (align_functions <= 0)
3024 align_functions = 8;
3025 if (align_jumps <= 0)
3027 if (align_loops <= 0)
3030 if (rs6000_align_branch_targets)
3032 if (align_functions <= 0)
3033 align_functions = 16;
3034 if (align_jumps <= 0)
3036 if (align_loops <= 0)
3038 can_override_loop_align = 1;
3042 if (align_jumps_max_skip <= 0)
3043 align_jumps_max_skip = 15;
3044 if (align_loops_max_skip <= 0)
3045 align_loops_max_skip = 15;
3048 /* Arrange to save and restore machine status around nested functions. */
3049 init_machine_status = rs6000_init_machine_status;
3051 /* We should always be splitting complex arguments, but we can't break
3052 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3053 if (DEFAULT_ABI != ABI_AIX)
3054 targetm.calls.split_complex_arg = NULL;
3056 /* Initialize rs6000_cost with the appropriate target costs. */
3058 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3062 case PROCESSOR_RIOS1:
3063 rs6000_cost = &rios1_cost;
3066 case PROCESSOR_RIOS2:
3067 rs6000_cost = &rios2_cost;
3070 case PROCESSOR_RS64A:
3071 rs6000_cost = &rs64a_cost;
3074 case PROCESSOR_MPCCORE:
3075 rs6000_cost = &mpccore_cost;
3078 case PROCESSOR_PPC403:
3079 rs6000_cost = &ppc403_cost;
3082 case PROCESSOR_PPC405:
3083 rs6000_cost = &ppc405_cost;
3086 case PROCESSOR_PPC440:
3087 rs6000_cost = &ppc440_cost;
3090 case PROCESSOR_PPC476:
3091 rs6000_cost = &ppc476_cost;
3094 case PROCESSOR_PPC601:
3095 rs6000_cost = &ppc601_cost;
3098 case PROCESSOR_PPC603:
3099 rs6000_cost = &ppc603_cost;
3102 case PROCESSOR_PPC604:
3103 rs6000_cost = &ppc604_cost;
3106 case PROCESSOR_PPC604e:
3107 rs6000_cost = &ppc604e_cost;
3110 case PROCESSOR_PPC620:
3111 rs6000_cost = &ppc620_cost;
3114 case PROCESSOR_PPC630:
3115 rs6000_cost = &ppc630_cost;
3118 case PROCESSOR_CELL:
3119 rs6000_cost = &ppccell_cost;
3122 case PROCESSOR_PPC750:
3123 case PROCESSOR_PPC7400:
3124 rs6000_cost = &ppc750_cost;
3127 case PROCESSOR_PPC7450:
3128 rs6000_cost = &ppc7450_cost;
3131 case PROCESSOR_PPC8540:
3132 rs6000_cost = &ppc8540_cost;
3135 case PROCESSOR_PPCE300C2:
3136 case PROCESSOR_PPCE300C3:
3137 rs6000_cost = &ppce300c2c3_cost;
3140 case PROCESSOR_PPCE500MC:
3141 rs6000_cost = &ppce500mc_cost;
3144 case PROCESSOR_PPCE500MC64:
3145 rs6000_cost = &ppce500mc64_cost;
3148 case PROCESSOR_TITAN:
3149 rs6000_cost = &titan_cost;
3152 case PROCESSOR_POWER4:
3153 case PROCESSOR_POWER5:
3154 rs6000_cost = &power4_cost;
3157 case PROCESSOR_POWER6:
3158 rs6000_cost = &power6_cost;
3161 case PROCESSOR_POWER7:
3162 rs6000_cost = &power7_cost;
3165 case PROCESSOR_PPCA2:
3166 rs6000_cost = &ppca2_cost;
3173 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3174 rs6000_cost->simultaneous_prefetches,
3175 global_options.x_param_values,
3176 global_options_set.x_param_values);
3177 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3178 global_options.x_param_values,
3179 global_options_set.x_param_values);
3180 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3181 rs6000_cost->cache_line_size,
3182 global_options.x_param_values,
3183 global_options_set.x_param_values);
3184 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3185 global_options.x_param_values,
3186 global_options_set.x_param_values);
3188 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3189 can be optimized to ap = __builtin_next_arg (0). */
3190 if (DEFAULT_ABI != ABI_V4)
3191 targetm.expand_builtin_va_start = NULL;
3193 /* Set up single/double float flags.
3194 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3195 then set both flags. */
3196 if (TARGET_HARD_FLOAT && TARGET_FPRS
3197 && rs6000_single_float == 0 && rs6000_double_float == 0)
3198 rs6000_single_float = rs6000_double_float = 1;
3200 /* Reset single and double FP flags if target is E500. */
3203 rs6000_single_float = rs6000_double_float = 0;
3204 if (TARGET_E500_SINGLE)
3205 rs6000_single_float = 1;
3206 if (TARGET_E500_DOUBLE)
3207 rs6000_single_float = rs6000_double_float = 1;
3210 /* If not explicitly specified via option, decide whether to generate indexed
3211 load/store instructions. */
3212 if (TARGET_AVOID_XFORM == -1)
3213 /* Avoid indexed addressing when targeting Power6 in order to avoid
3214 the DERAT mispredict penalty. */
3215 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3217 /* Set the -mrecip options. */
3218 if (rs6000_recip_name)
3220 char *p = ASTRDUP (rs6000_recip_name);
3222 unsigned int mask, i;
3225 while ((q = strtok (p, ",")) != NULL)
3236 if (!strcmp (q, "default"))
3237 mask = ((TARGET_RECIP_PRECISION)
3238 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3241 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3242 if (!strcmp (q, recip_options[i].string))
3244 mask = recip_options[i].mask;
3248 if (i == ARRAY_SIZE (recip_options))
3250 error ("Unknown option for -mrecip=%s", q);
3257 rs6000_recip_control &= ~mask;
3259 rs6000_recip_control |= mask;
3263 rs6000_init_hard_regno_mode_ok ();
3266 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3267 define the target cpu type. */
3270 rs6000_option_override (void)
3272 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT);
3275 /* Implement targetm.vectorize.builtin_mask_for_load. */
3277 rs6000_builtin_mask_for_load (void)
3279 if (TARGET_ALTIVEC || TARGET_VSX)
3280 return altivec_builtin_mask_for_load;
3285 /* Implement LOOP_ALIGN. */
3287 rs6000_loop_align (rtx label)
3292 /* Don't override loop alignment if -falign-loops was specified. */
3293 if (!can_override_loop_align)
3294 return align_loops_log;
3296 bb = BLOCK_FOR_INSN (label);
3297 ninsns = num_loop_insns(bb->loop_father);
3299 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3300 if (ninsns > 4 && ninsns <= 8
3301 && (rs6000_cpu == PROCESSOR_POWER4
3302 || rs6000_cpu == PROCESSOR_POWER5
3303 || rs6000_cpu == PROCESSOR_POWER6
3304 || rs6000_cpu == PROCESSOR_POWER7))
3307 return align_loops_log;
3310 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3312 rs6000_loop_align_max_skip (rtx label)
3314 return (1 << rs6000_loop_align (label)) - 1;
3317 /* Implement targetm.vectorize.builtin_conversion.
3318 Returns a decl of a function that implements conversion of an integer vector
3319 into a floating-point vector, or vice-versa. DEST_TYPE is the
3320 destination type and SRC_TYPE the source type of the conversion.
3321 Return NULL_TREE if it is not available. */
3323 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3325 enum tree_code code = (enum tree_code) tcode;
3329 case FIX_TRUNC_EXPR:
3330 switch (TYPE_MODE (dest_type))
3333 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3336 return TYPE_UNSIGNED (dest_type)
3337 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3338 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3341 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3344 return TYPE_UNSIGNED (dest_type)
3345 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3346 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3353 switch (TYPE_MODE (src_type))
3356 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3359 return TYPE_UNSIGNED (src_type)
3360 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3361 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3364 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3367 return TYPE_UNSIGNED (src_type)
3368 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3369 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3380 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3382 rs6000_builtin_mul_widen_even (tree type)
3384 if (!TARGET_ALTIVEC)
3387 switch (TYPE_MODE (type))
3390 return TYPE_UNSIGNED (type)
3391 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3392 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3395 return TYPE_UNSIGNED (type)
3396 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3397 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3403 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3405 rs6000_builtin_mul_widen_odd (tree type)
3407 if (!TARGET_ALTIVEC)
3410 switch (TYPE_MODE (type))
3413 return TYPE_UNSIGNED (type)
3414 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3415 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3418 return TYPE_UNSIGNED (type)
3419 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3420 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3427 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3428 after applying N number of iterations. This routine does not determine
3429 how may iterations are required to reach desired alignment. */
3432 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3439 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3442 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3452 /* Assuming that all other types are naturally aligned. CHECKME! */
3457 /* Return true if the vector misalignment factor is supported by the
3460 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3467 /* Return if movmisalign pattern is not supported for this mode. */
3468 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3471 if (misalignment == -1)
3473 /* Misalignment factor is unknown at compile time but we know
3474 it's word aligned. */
3475 if (rs6000_vector_alignment_reachable (type, is_packed))
3477 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3479 if (element_size == 64 || element_size == 32)
3486 /* VSX supports word-aligned vector. */
3487 if (misalignment % 4 == 0)
3493 /* Implement targetm.vectorize.builtin_vec_perm. */
3495 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3497 tree inner_type = TREE_TYPE (type);
3498 bool uns_p = TYPE_UNSIGNED (inner_type);
3501 *mask_element_type = unsigned_char_type_node;
3503 switch (TYPE_MODE (type))
3507 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3508 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3513 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3514 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3519 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3520 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3524 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3528 if (!TARGET_ALLOW_DF_PERMUTE)
3531 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3535 if (!TARGET_ALLOW_DF_PERMUTE)
3539 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3540 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3552 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3554 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3555 tree vectype, int misalign)
3559 switch (type_of_cost)
3569 case cond_branch_not_taken:
3573 case cond_branch_taken:
3576 case unaligned_load:
3577 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3579 elements = TYPE_VECTOR_SUBPARTS (vectype);
3581 /* Double word aligned. */
3589 /* Double word aligned. */
3593 /* Unknown misalignment. */
3606 /* Misaligned loads are not supported. */
3611 case unaligned_store:
3612 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3614 elements = TYPE_VECTOR_SUBPARTS (vectype);
3616 /* Double word aligned. */
3624 /* Double word aligned. */
3628 /* Unknown misalignment. */
3641 /* Misaligned stores are not supported. */
3651 /* Implement targetm.vectorize.preferred_simd_mode. */
3653 static enum machine_mode
3654 rs6000_preferred_simd_mode (enum machine_mode mode)
3663 if (TARGET_ALTIVEC || TARGET_VSX)
3687 if (TARGET_PAIRED_FLOAT
3693 /* Handle generic options of the form -mfoo=yes/no.
3694 NAME is the option name.
3695 VALUE is the option value.
3696 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3697 whether the option value is 'yes' or 'no' respectively. */
3699 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3703 else if (!strcmp (value, "yes"))
3705 else if (!strcmp (value, "no"))
3708 error ("unknown -m%s= option specified: '%s'", name, value);
3711 /* Validate and record the size specified with the -mtls-size option. */
3714 rs6000_parse_tls_size_option (void)
3716 if (rs6000_tls_size_string == 0)
3718 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3719 rs6000_tls_size = 16;
3720 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3721 rs6000_tls_size = 32;
3722 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3723 rs6000_tls_size = 64;
3725 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3728 /* Implement TARGET_OPTION_INIT_STRUCT. */
3731 rs6000_option_init_struct (struct gcc_options *opts)
3733 if (DEFAULT_ABI == ABI_DARWIN)
3734 /* The Darwin libraries never set errno, so we might as well
3735 avoid calling them when that's the only reason we would. */
3736 opts->x_flag_errno_math = 0;
3738 /* Enable section anchors by default. */
3740 opts->x_flag_section_anchors = 1;
3743 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3746 rs6000_option_default_params (void)
3748 /* Double growth factor to counter reduced min jump length. */
3749 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3752 static enum fpu_type_t
3753 rs6000_parse_fpu_option (const char *option)
3755 if (!strcmp("none", option)) return FPU_NONE;
3756 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3757 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3758 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3759 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3760 error("unknown value %s for -mfpu", option);
3765 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3766 library with vectorized intrinsics. */
3769 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3772 const char *suffix = NULL;
3773 tree fntype, new_fndecl, bdecl = NULL_TREE;
3776 enum machine_mode el_mode, in_mode;
3779 /* Libmass is suitable for unsafe math only as it does not correctly support
3780 parts of IEEE with the required precision such as denormals. Only support
3781 it if we have VSX to use the simd d2 or f4 functions.
3782 XXX: Add variable length support. */
3783 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3786 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3787 n = TYPE_VECTOR_SUBPARTS (type_out);
3788 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3789 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3790 if (el_mode != in_mode
3794 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3796 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3799 case BUILT_IN_ATAN2:
3800 case BUILT_IN_HYPOT:
3806 case BUILT_IN_ACOSH:
3808 case BUILT_IN_ASINH:
3810 case BUILT_IN_ATANH:
3818 case BUILT_IN_EXPM1:
3819 case BUILT_IN_LGAMMA:
3820 case BUILT_IN_LOG10:
3821 case BUILT_IN_LOG1P:
3829 bdecl = implicit_built_in_decls[fn];
3830 suffix = "d2"; /* pow -> powd2 */
3831 if (el_mode != DFmode
3836 case BUILT_IN_ATAN2F:
3837 case BUILT_IN_HYPOTF:
3842 case BUILT_IN_ACOSF:
3843 case BUILT_IN_ACOSHF:
3844 case BUILT_IN_ASINF:
3845 case BUILT_IN_ASINHF:
3846 case BUILT_IN_ATANF:
3847 case BUILT_IN_ATANHF:
3848 case BUILT_IN_CBRTF:
3850 case BUILT_IN_COSHF:
3852 case BUILT_IN_ERFCF:
3853 case BUILT_IN_EXP2F:
3855 case BUILT_IN_EXPM1F:
3856 case BUILT_IN_LGAMMAF:
3857 case BUILT_IN_LOG10F:
3858 case BUILT_IN_LOG1PF:
3859 case BUILT_IN_LOG2F:
3862 case BUILT_IN_SINHF:
3863 case BUILT_IN_SQRTF:
3865 case BUILT_IN_TANHF:
3866 bdecl = implicit_built_in_decls[fn];
3867 suffix = "4"; /* powf -> powf4 */
3868 if (el_mode != SFmode
3880 gcc_assert (suffix != NULL);
3881 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3882 strcpy (name, bname + sizeof ("__builtin_") - 1);
3883 strcat (name, suffix);
3886 fntype = build_function_type_list (type_out, type_in, NULL);
3887 else if (n_args == 2)
3888 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3892 /* Build a function declaration for the vectorized function. */
3893 new_fndecl = build_decl (BUILTINS_LOCATION,
3894 FUNCTION_DECL, get_identifier (name), fntype);
3895 TREE_PUBLIC (new_fndecl) = 1;
3896 DECL_EXTERNAL (new_fndecl) = 1;
3897 DECL_IS_NOVOPS (new_fndecl) = 1;
3898 TREE_READONLY (new_fndecl) = 1;
3903 /* Returns a function decl for a vectorized version of the builtin function
3904 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3905 if it is not available. */
3908 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3911 enum machine_mode in_mode, out_mode;
3914 if (TREE_CODE (type_out) != VECTOR_TYPE
3915 || TREE_CODE (type_in) != VECTOR_TYPE
3916 || !TARGET_VECTORIZE_BUILTINS)
3919 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3920 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3921 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3922 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3924 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3926 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3929 case BUILT_IN_COPYSIGN:
3930 if (VECTOR_UNIT_VSX_P (V2DFmode)
3931 && out_mode == DFmode && out_n == 2
3932 && in_mode == DFmode && in_n == 2)
3933 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3935 case BUILT_IN_COPYSIGNF:
3936 if (out_mode != SFmode || out_n != 4
3937 || in_mode != SFmode || in_n != 4)
3939 if (VECTOR_UNIT_VSX_P (V4SFmode))
3940 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3941 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3942 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3945 if (VECTOR_UNIT_VSX_P (V2DFmode)
3946 && out_mode == DFmode && out_n == 2
3947 && in_mode == DFmode && in_n == 2)
3948 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3950 case BUILT_IN_SQRTF:
3951 if (VECTOR_UNIT_VSX_P (V4SFmode)
3952 && out_mode == SFmode && out_n == 4
3953 && in_mode == SFmode && in_n == 4)
3954 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3957 if (VECTOR_UNIT_VSX_P (V2DFmode)
3958 && out_mode == DFmode && out_n == 2
3959 && in_mode == DFmode && in_n == 2)
3960 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3962 case BUILT_IN_CEILF:
3963 if (out_mode != SFmode || out_n != 4
3964 || in_mode != SFmode || in_n != 4)
3966 if (VECTOR_UNIT_VSX_P (V4SFmode))
3967 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3968 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3969 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3971 case BUILT_IN_FLOOR:
3972 if (VECTOR_UNIT_VSX_P (V2DFmode)
3973 && out_mode == DFmode && out_n == 2
3974 && in_mode == DFmode && in_n == 2)
3975 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3977 case BUILT_IN_FLOORF:
3978 if (out_mode != SFmode || out_n != 4
3979 || in_mode != SFmode || in_n != 4)
3981 if (VECTOR_UNIT_VSX_P (V4SFmode))
3982 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3983 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3984 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3987 if (VECTOR_UNIT_VSX_P (V2DFmode)
3988 && out_mode == DFmode && out_n == 2
3989 && in_mode == DFmode && in_n == 2)
3990 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3993 if (VECTOR_UNIT_VSX_P (V4SFmode)
3994 && out_mode == SFmode && out_n == 4
3995 && in_mode == SFmode && in_n == 4)
3996 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
3997 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
3998 && out_mode == SFmode && out_n == 4
3999 && in_mode == SFmode && in_n == 4)
4000 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4002 case BUILT_IN_TRUNC:
4003 if (VECTOR_UNIT_VSX_P (V2DFmode)
4004 && out_mode == DFmode && out_n == 2
4005 && in_mode == DFmode && in_n == 2)
4006 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4008 case BUILT_IN_TRUNCF:
4009 if (out_mode != SFmode || out_n != 4
4010 || in_mode != SFmode || in_n != 4)
4012 if (VECTOR_UNIT_VSX_P (V4SFmode))
4013 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4014 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4015 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4017 case BUILT_IN_NEARBYINT:
4018 if (VECTOR_UNIT_VSX_P (V2DFmode)
4019 && flag_unsafe_math_optimizations
4020 && out_mode == DFmode && out_n == 2
4021 && in_mode == DFmode && in_n == 2)
4022 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4024 case BUILT_IN_NEARBYINTF:
4025 if (VECTOR_UNIT_VSX_P (V4SFmode)
4026 && flag_unsafe_math_optimizations
4027 && out_mode == SFmode && out_n == 4
4028 && in_mode == SFmode && in_n == 4)
4029 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4032 if (VECTOR_UNIT_VSX_P (V2DFmode)
4033 && !flag_trapping_math
4034 && out_mode == DFmode && out_n == 2
4035 && in_mode == DFmode && in_n == 2)
4036 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4038 case BUILT_IN_RINTF:
4039 if (VECTOR_UNIT_VSX_P (V4SFmode)
4040 && !flag_trapping_math
4041 && out_mode == SFmode && out_n == 4
4042 && in_mode == SFmode && in_n == 4)
4043 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4050 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4052 enum rs6000_builtins fn
4053 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4056 case RS6000_BUILTIN_RSQRTF:
4057 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4058 && out_mode == SFmode && out_n == 4
4059 && in_mode == SFmode && in_n == 4)
4060 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4062 case RS6000_BUILTIN_RSQRT:
4063 if (VECTOR_UNIT_VSX_P (V2DFmode)
4064 && out_mode == DFmode && out_n == 2
4065 && in_mode == DFmode && in_n == 2)
4066 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4068 case RS6000_BUILTIN_RECIPF:
4069 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4070 && out_mode == SFmode && out_n == 4
4071 && in_mode == SFmode && in_n == 4)
4072 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4074 case RS6000_BUILTIN_RECIP:
4075 if (VECTOR_UNIT_VSX_P (V2DFmode)
4076 && out_mode == DFmode && out_n == 2
4077 && in_mode == DFmode && in_n == 2)
4078 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4085 /* Generate calls to libmass if appropriate. */
4086 if (rs6000_veclib_handler)
4087 return rs6000_veclib_handler (fndecl, type_out, type_in);
4093 /* Implement TARGET_HANDLE_OPTION. */
4096 rs6000_handle_option (size_t code, const char *arg, int value)
4098 enum fpu_type_t fpu_type = FPU_NONE;
4104 target_flags &= ~(MASK_POWER | MASK_POWER2
4105 | MASK_MULTIPLE | MASK_STRING);
4106 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4107 | MASK_MULTIPLE | MASK_STRING);
4109 case OPT_mno_powerpc:
4110 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4111 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4112 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4113 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4116 target_flags &= ~MASK_MINIMAL_TOC;
4117 TARGET_NO_FP_IN_TOC = 0;
4118 TARGET_NO_SUM_IN_TOC = 0;
4119 target_flags_explicit |= MASK_MINIMAL_TOC;
4120 #ifdef TARGET_USES_SYSV4_OPT
4121 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4122 just the same as -mminimal-toc. */
4123 target_flags |= MASK_MINIMAL_TOC;
4124 target_flags_explicit |= MASK_MINIMAL_TOC;
4128 #ifdef TARGET_USES_SYSV4_OPT
4130 /* Make -mtoc behave like -mminimal-toc. */
4131 target_flags |= MASK_MINIMAL_TOC;
4132 target_flags_explicit |= MASK_MINIMAL_TOC;
4136 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4138 if (strcmp (arg, "small") == 0)
4139 cmodel = CMODEL_SMALL;
4140 else if (strcmp (arg, "medium") == 0)
4141 cmodel = CMODEL_MEDIUM;
4142 else if (strcmp (arg, "large") == 0)
4143 cmodel = CMODEL_LARGE;
4146 error ("invalid option for -mcmodel: '%s'", arg);
4149 rs6000_explicit_options.cmodel = true;
4152 #ifdef TARGET_USES_AIX64_OPT
4157 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4158 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4159 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4162 #ifdef TARGET_USES_AIX64_OPT
4167 target_flags &= ~MASK_POWERPC64;
4168 target_flags_explicit |= MASK_POWERPC64;
4171 case OPT_minsert_sched_nops_:
4172 rs6000_sched_insert_nops_str = arg;
4175 case OPT_mminimal_toc:
4178 TARGET_NO_FP_IN_TOC = 0;
4179 TARGET_NO_SUM_IN_TOC = 0;
4186 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4187 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4194 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4195 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4199 case OPT_mpowerpc_gpopt:
4200 case OPT_mpowerpc_gfxopt:
4203 target_flags |= MASK_POWERPC;
4204 target_flags_explicit |= MASK_POWERPC;
4208 case OPT_maix_struct_return:
4209 case OPT_msvr4_struct_return:
4210 rs6000_explicit_options.aix_struct_ret = true;
4214 rs6000_explicit_options.vrsave = true;
4215 TARGET_ALTIVEC_VRSAVE = value;
4219 rs6000_explicit_options.vrsave = true;
4220 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4224 target_flags_explicit |= MASK_ISEL;
4226 rs6000_parse_yes_no_option ("isel", arg, &isel);
4228 target_flags |= MASK_ISEL;
4230 target_flags &= ~MASK_ISEL;
4234 rs6000_explicit_options.spe = true;
4239 rs6000_explicit_options.spe = true;
4240 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4244 rs6000_debug_name = arg;
4247 #ifdef TARGET_USES_SYSV4_OPT
4249 rs6000_abi_name = arg;
4253 rs6000_sdata_name = arg;
4256 case OPT_mtls_size_:
4257 rs6000_tls_size_string = arg;
4260 case OPT_mrelocatable:
4263 target_flags |= MASK_MINIMAL_TOC;
4264 target_flags_explicit |= MASK_MINIMAL_TOC;
4265 TARGET_NO_FP_IN_TOC = 1;
4269 case OPT_mrelocatable_lib:
4272 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4273 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4274 TARGET_NO_FP_IN_TOC = 1;
4278 target_flags &= ~MASK_RELOCATABLE;
4279 target_flags_explicit |= MASK_RELOCATABLE;
4285 if (!strcmp (arg, "altivec"))
4287 rs6000_explicit_options.altivec_abi = true;
4288 rs6000_altivec_abi = 1;
4290 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4293 else if (! strcmp (arg, "no-altivec"))
4295 rs6000_explicit_options.altivec_abi = true;
4296 rs6000_altivec_abi = 0;
4298 else if (! strcmp (arg, "spe"))
4300 rs6000_explicit_options.spe_abi = true;
4302 rs6000_altivec_abi = 0;
4303 if (!TARGET_SPE_ABI)
4304 error ("not configured for ABI: '%s'", arg);
4306 else if (! strcmp (arg, "no-spe"))
4308 rs6000_explicit_options.spe_abi = true;
4312 /* These are here for testing during development only, do not
4313 document in the manual please. */
4314 else if (! strcmp (arg, "d64"))
4316 rs6000_darwin64_abi = 1;
4317 warning (0, "Using darwin64 ABI");
4319 else if (! strcmp (arg, "d32"))
4321 rs6000_darwin64_abi = 0;
4322 warning (0, "Using old darwin ABI");
4325 else if (! strcmp (arg, "ibmlongdouble"))
4327 rs6000_explicit_options.ieee = true;
4328 rs6000_ieeequad = 0;
4329 warning (0, "Using IBM extended precision long double");
4331 else if (! strcmp (arg, "ieeelongdouble"))
4333 rs6000_explicit_options.ieee = true;
4334 rs6000_ieeequad = 1;
4335 warning (0, "Using IEEE extended precision long double");
4340 error ("unknown ABI specified: '%s'", arg);
4346 rs6000_select[1].string = arg;
4350 rs6000_select[2].string = arg;
4353 case OPT_mtraceback_:
4354 rs6000_traceback_name = arg;
4357 case OPT_mfloat_gprs_:
4358 rs6000_explicit_options.float_gprs = true;
4359 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4360 rs6000_float_gprs = 1;
4361 else if (! strcmp (arg, "double"))
4362 rs6000_float_gprs = 2;
4363 else if (! strcmp (arg, "no"))
4364 rs6000_float_gprs = 0;
4367 error ("invalid option for -mfloat-gprs: '%s'", arg);
4372 case OPT_mlong_double_:
4373 rs6000_explicit_options.long_double = true;
4374 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4375 if (value != 64 && value != 128)
4377 error ("Unknown switch -mlong-double-%s", arg);
4378 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4382 rs6000_long_double_type_size = value;
4385 case OPT_msched_costly_dep_:
4386 rs6000_sched_costly_dep_str = arg;
4390 rs6000_explicit_options.alignment = true;
4391 if (! strcmp (arg, "power"))
4393 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4394 some C library functions, so warn about it. The flag may be
4395 useful for performance studies from time to time though, so
4396 don't disable it entirely. */
4397 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4398 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4399 " it is incompatible with the installed C and C++ libraries");
4400 rs6000_alignment_flags = MASK_ALIGN_POWER;
4402 else if (! strcmp (arg, "natural"))
4403 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4406 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4411 case OPT_msingle_float:
4412 if (!TARGET_SINGLE_FPU)
4413 warning (0, "-msingle-float option equivalent to -mhard-float");
4414 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4415 rs6000_double_float = 0;
4416 target_flags &= ~MASK_SOFT_FLOAT;
4417 target_flags_explicit |= MASK_SOFT_FLOAT;
4420 case OPT_mdouble_float:
4421 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4422 rs6000_single_float = 1;
4423 target_flags &= ~MASK_SOFT_FLOAT;
4424 target_flags_explicit |= MASK_SOFT_FLOAT;
4427 case OPT_msimple_fpu:
4428 if (!TARGET_SINGLE_FPU)
4429 warning (0, "-msimple-fpu option ignored");
4432 case OPT_mhard_float:
4433 /* -mhard_float implies -msingle-float and -mdouble-float. */
4434 rs6000_single_float = rs6000_double_float = 1;
4437 case OPT_msoft_float:
4438 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4439 rs6000_single_float = rs6000_double_float = 0;
4443 fpu_type = rs6000_parse_fpu_option(arg);
4444 if (fpu_type != FPU_NONE)
4445 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4447 target_flags &= ~MASK_SOFT_FLOAT;
4448 target_flags_explicit |= MASK_SOFT_FLOAT;
4449 rs6000_xilinx_fpu = 1;
4450 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4451 rs6000_single_float = 1;
4452 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4453 rs6000_single_float = rs6000_double_float = 1;
4454 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4455 rs6000_simple_fpu = 1;
4459 /* -mfpu=none is equivalent to -msoft-float */
4460 target_flags |= MASK_SOFT_FLOAT;
4461 target_flags_explicit |= MASK_SOFT_FLOAT;
4462 rs6000_single_float = rs6000_double_float = 0;
4466 rs6000_recip_name = (value) ? "default" : "none";
4470 rs6000_recip_name = arg;
4476 /* Do anything needed at the start of the asm file. */
4479 rs6000_file_start (void)
4483 const char *start = buffer;
4484 struct rs6000_cpu_select *ptr;
4485 const char *default_cpu = TARGET_CPU_DEFAULT;
4486 FILE *file = asm_out_file;
4488 default_file_start ();
4490 #ifdef TARGET_BI_ARCH
4491 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4495 if (flag_verbose_asm)
4497 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4498 rs6000_select[0].string = default_cpu;
4500 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4502 ptr = &rs6000_select[i];
4503 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4505 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4510 if (PPC405_ERRATUM77)
4512 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4516 #ifdef USING_ELFOS_H
4517 switch (rs6000_sdata)
4519 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4520 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4521 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4522 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4525 if (rs6000_sdata && g_switch_value)
4527 fprintf (file, "%s -G %d", start,
4537 #ifdef HAVE_AS_GNU_ATTRIBUTE
4538 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4540 fprintf (file, "\t.gnu_attribute 4, %d\n",
4541 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4542 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4544 fprintf (file, "\t.gnu_attribute 8, %d\n",
4545 (TARGET_ALTIVEC_ABI ? 2
4546 : TARGET_SPE_ABI ? 3
4548 fprintf (file, "\t.gnu_attribute 12, %d\n",
4549 aix_struct_return ? 2 : 1);
4554 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4556 switch_to_section (toc_section);
4557 switch_to_section (text_section);
4562 /* Return nonzero if this function is known to have a null epilogue. */
4565 direct_return (void)
4567 if (reload_completed)
4569 rs6000_stack_t *info = rs6000_stack_info ();
4571 if (info->first_gp_reg_save == 32
4572 && info->first_fp_reg_save == 64
4573 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4574 && ! info->lr_save_p
4575 && ! info->cr_save_p
4576 && info->vrsave_mask == 0
4584 /* Return the number of instructions it takes to form a constant in an
4585 integer register. */
4588 num_insns_constant_wide (HOST_WIDE_INT value)
4590 /* signed constant loadable with {cal|addi} */
4591 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4594 /* constant loadable with {cau|addis} */
4595 else if ((value & 0xffff) == 0
4596 && (value >> 31 == -1 || value >> 31 == 0))
4599 #if HOST_BITS_PER_WIDE_INT == 64
4600 else if (TARGET_POWERPC64)
4602 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4603 HOST_WIDE_INT high = value >> 31;
4605 if (high == 0 || high == -1)
4611 return num_insns_constant_wide (high) + 1;
4613 return num_insns_constant_wide (low) + 1;
4615 return (num_insns_constant_wide (high)
4616 + num_insns_constant_wide (low) + 1);
4625 num_insns_constant (rtx op, enum machine_mode mode)
4627 HOST_WIDE_INT low, high;
4629 switch (GET_CODE (op))
4632 #if HOST_BITS_PER_WIDE_INT == 64
4633 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4634 && mask64_operand (op, mode))
4638 return num_insns_constant_wide (INTVAL (op));
4641 if (mode == SFmode || mode == SDmode)
4646 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4647 if (DECIMAL_FLOAT_MODE_P (mode))
4648 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4650 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4651 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4654 if (mode == VOIDmode || mode == DImode)
4656 high = CONST_DOUBLE_HIGH (op);
4657 low = CONST_DOUBLE_LOW (op);
4664 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4665 if (DECIMAL_FLOAT_MODE_P (mode))
4666 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4668 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4669 high = l[WORDS_BIG_ENDIAN == 0];
4670 low = l[WORDS_BIG_ENDIAN != 0];
4674 return (num_insns_constant_wide (low)
4675 + num_insns_constant_wide (high));
4678 if ((high == 0 && low >= 0)
4679 || (high == -1 && low < 0))
4680 return num_insns_constant_wide (low);
4682 else if (mask64_operand (op, mode))
4686 return num_insns_constant_wide (high) + 1;
4689 return (num_insns_constant_wide (high)
4690 + num_insns_constant_wide (low) + 1);
4698 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4699 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4700 corresponding element of the vector, but for V4SFmode and V2SFmode,
4701 the corresponding "float" is interpreted as an SImode integer. */
4704 const_vector_elt_as_int (rtx op, unsigned int elt)
4706 rtx tmp = CONST_VECTOR_ELT (op, elt);
4707 if (GET_MODE (op) == V4SFmode
4708 || GET_MODE (op) == V2SFmode)
4709 tmp = gen_lowpart (SImode, tmp);
4710 return INTVAL (tmp);
4713 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4714 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4715 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4716 all items are set to the same value and contain COPIES replicas of the
4717 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4718 operand and the others are set to the value of the operand's msb. */
4721 vspltis_constant (rtx op, unsigned step, unsigned copies)
4723 enum machine_mode mode = GET_MODE (op);
4724 enum machine_mode inner = GET_MODE_INNER (mode);
4727 unsigned nunits = GET_MODE_NUNITS (mode);
4728 unsigned bitsize = GET_MODE_BITSIZE (inner);
4729 unsigned mask = GET_MODE_MASK (inner);
4731 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4732 HOST_WIDE_INT splat_val = val;
4733 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4735 /* Construct the value to be splatted, if possible. If not, return 0. */
4736 for (i = 2; i <= copies; i *= 2)
4738 HOST_WIDE_INT small_val;
4740 small_val = splat_val >> bitsize;
4742 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4744 splat_val = small_val;
4747 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4748 if (EASY_VECTOR_15 (splat_val))
4751 /* Also check if we can splat, and then add the result to itself. Do so if
4752 the value is positive, of if the splat instruction is using OP's mode;
4753 for splat_val < 0, the splat and the add should use the same mode. */
4754 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4755 && (splat_val >= 0 || (step == 1 && copies == 1)))
4758 /* Also check if are loading up the most significant bit which can be done by
4759 loading up -1 and shifting the value left by -1. */
4760 else if (EASY_VECTOR_MSB (splat_val, inner))
4766 /* Check if VAL is present in every STEP-th element, and the
4767 other elements are filled with its most significant bit. */
4768 for (i = 0; i < nunits - 1; ++i)
4770 HOST_WIDE_INT desired_val;
4771 if (((i + 1) & (step - 1)) == 0)
4774 desired_val = msb_val;
4776 if (desired_val != const_vector_elt_as_int (op, i))
4784 /* Return true if OP is of the given MODE and can be synthesized
4785 with a vspltisb, vspltish or vspltisw. */
4788 easy_altivec_constant (rtx op, enum machine_mode mode)
4790 unsigned step, copies;
4792 if (mode == VOIDmode)
4793 mode = GET_MODE (op);
4794 else if (mode != GET_MODE (op))
4797 /* Start with a vspltisw. */
4798 step = GET_MODE_NUNITS (mode) / 4;
4801 if (vspltis_constant (op, step, copies))
4804 /* Then try with a vspltish. */
4810 if (vspltis_constant (op, step, copies))
4813 /* And finally a vspltisb. */
4819 if (vspltis_constant (op, step, copies))
4825 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4826 result is OP. Abort if it is not possible. */
4829 gen_easy_altivec_constant (rtx op)
4831 enum machine_mode mode = GET_MODE (op);
4832 int nunits = GET_MODE_NUNITS (mode);
4833 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4834 unsigned step = nunits / 4;
4835 unsigned copies = 1;
4837 /* Start with a vspltisw. */
4838 if (vspltis_constant (op, step, copies))
4839 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4841 /* Then try with a vspltish. */
4847 if (vspltis_constant (op, step, copies))
4848 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4850 /* And finally a vspltisb. */
4856 if (vspltis_constant (op, step, copies))
4857 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4863 output_vec_const_move (rtx *operands)
4866 enum machine_mode mode;
4871 mode = GET_MODE (dest);
4873 if (TARGET_VSX && zero_constant (vec, mode))
4874 return "xxlxor %x0,%x0,%x0";
4879 if (zero_constant (vec, mode))
4880 return "vxor %0,%0,%0";
4882 splat_vec = gen_easy_altivec_constant (vec);
4883 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4884 operands[1] = XEXP (splat_vec, 0);
4885 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4888 switch (GET_MODE (splat_vec))
4891 return "vspltisw %0,%1";
4894 return "vspltish %0,%1";
4897 return "vspltisb %0,%1";
4904 gcc_assert (TARGET_SPE);
4906 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4907 pattern of V1DI, V4HI, and V2SF.
4909 FIXME: We should probably return # and add post reload
4910 splitters for these, but this way is so easy ;-). */
4911 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4912 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4913 operands[1] = CONST_VECTOR_ELT (vec, 0);
4914 operands[2] = CONST_VECTOR_ELT (vec, 1);
4916 return "li %0,%1\n\tevmergelo %0,%0,%0";
4918 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4921 /* Initialize TARGET of vector PAIRED to VALS. */
4924 paired_expand_vector_init (rtx target, rtx vals)
4926 enum machine_mode mode = GET_MODE (target);
4927 int n_elts = GET_MODE_NUNITS (mode);
4929 rtx x, new_rtx, tmp, constant_op, op1, op2;
4932 for (i = 0; i < n_elts; ++i)
4934 x = XVECEXP (vals, 0, i);
4935 if (!CONSTANT_P (x))
4940 /* Load from constant pool. */
4941 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4947 /* The vector is initialized only with non-constants. */
4948 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4949 XVECEXP (vals, 0, 1));
4951 emit_move_insn (target, new_rtx);
4955 /* One field is non-constant and the other one is a constant. Load the
4956 constant from the constant pool and use ps_merge instruction to
4957 construct the whole vector. */
4958 op1 = XVECEXP (vals, 0, 0);
4959 op2 = XVECEXP (vals, 0, 1);
4961 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4963 tmp = gen_reg_rtx (GET_MODE (constant_op));
4964 emit_move_insn (tmp, constant_op);
4966 if (CONSTANT_P (op1))
4967 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4969 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4971 emit_move_insn (target, new_rtx);
4975 paired_expand_vector_move (rtx operands[])
4977 rtx op0 = operands[0], op1 = operands[1];
4979 emit_move_insn (op0, op1);
4982 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4983 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4984 operands for the relation operation COND. This is a recursive
4988 paired_emit_vector_compare (enum rtx_code rcode,
4989 rtx dest, rtx op0, rtx op1,
4990 rtx cc_op0, rtx cc_op1)
4992 rtx tmp = gen_reg_rtx (V2SFmode);
4995 gcc_assert (TARGET_PAIRED_FLOAT);
4996 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5002 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5006 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5007 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5011 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5014 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5017 tmp1 = gen_reg_rtx (V2SFmode);
5018 max = gen_reg_rtx (V2SFmode);
5019 min = gen_reg_rtx (V2SFmode);
5020 gen_reg_rtx (V2SFmode);
5022 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5023 emit_insn (gen_selv2sf4
5024 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5025 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5026 emit_insn (gen_selv2sf4
5027 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5028 emit_insn (gen_subv2sf3 (tmp1, min, max));
5029 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5032 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5035 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5038 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5041 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5044 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5053 /* Emit vector conditional expression.
5054 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5055 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5058 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5059 rtx cond, rtx cc_op0, rtx cc_op1)
5061 enum rtx_code rcode = GET_CODE (cond);
5063 if (!TARGET_PAIRED_FLOAT)
5066 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5071 /* Initialize vector TARGET to VALS. */
5074 rs6000_expand_vector_init (rtx target, rtx vals)
5076 enum machine_mode mode = GET_MODE (target);
5077 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5078 int n_elts = GET_MODE_NUNITS (mode);
5079 int n_var = 0, one_var = -1;
5080 bool all_same = true, all_const_zero = true;
5084 for (i = 0; i < n_elts; ++i)
5086 x = XVECEXP (vals, 0, i);
5087 if (!CONSTANT_P (x))
5088 ++n_var, one_var = i;
5089 else if (x != CONST0_RTX (inner_mode))
5090 all_const_zero = false;
5092 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5098 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5099 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5100 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5102 /* Zero register. */
5103 emit_insn (gen_rtx_SET (VOIDmode, target,
5104 gen_rtx_XOR (mode, target, target)));
5107 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5109 /* Splat immediate. */
5110 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5115 /* Load from constant pool. */
5116 emit_move_insn (target, const_vec);
5121 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5122 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5126 rtx element = XVECEXP (vals, 0, 0);
5127 if (mode == V2DFmode)
5128 emit_insn (gen_vsx_splat_v2df (target, element));
5130 emit_insn (gen_vsx_splat_v2di (target, element));
5134 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5135 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5136 if (mode == V2DFmode)
5137 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5139 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5144 /* With single precision floating point on VSX, know that internally single
5145 precision is actually represented as a double, and either make 2 V2DF
5146 vectors, and convert these vectors to single precision, or do one
5147 conversion, and splat the result to the other elements. */
5148 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5152 rtx freg = gen_reg_rtx (V4SFmode);
5153 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5155 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5156 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5160 rtx dbl_even = gen_reg_rtx (V2DFmode);
5161 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5162 rtx flt_even = gen_reg_rtx (V4SFmode);
5163 rtx flt_odd = gen_reg_rtx (V4SFmode);
5165 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5166 copy_to_reg (XVECEXP (vals, 0, 0)),
5167 copy_to_reg (XVECEXP (vals, 0, 1))));
5168 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5169 copy_to_reg (XVECEXP (vals, 0, 2)),
5170 copy_to_reg (XVECEXP (vals, 0, 3))));
5171 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5172 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5173 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5178 /* Store value to stack temp. Load vector element. Splat. However, splat
5179 of 64-bit items is not supported on Altivec. */
5180 if (all_same && GET_MODE_SIZE (mode) <= 4)
5182 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5183 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5184 XVECEXP (vals, 0, 0));
5185 x = gen_rtx_UNSPEC (VOIDmode,
5186 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5187 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5189 gen_rtx_SET (VOIDmode,
5192 x = gen_rtx_VEC_SELECT (inner_mode, target,
5193 gen_rtx_PARALLEL (VOIDmode,
5194 gen_rtvec (1, const0_rtx)));
5195 emit_insn (gen_rtx_SET (VOIDmode, target,
5196 gen_rtx_VEC_DUPLICATE (mode, x)));
5200 /* One field is non-constant. Load constant then overwrite
5204 rtx copy = copy_rtx (vals);
5206 /* Load constant part of vector, substitute neighboring value for
5208 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5209 rs6000_expand_vector_init (target, copy);
5211 /* Insert variable. */
5212 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5216 /* Construct the vector in memory one field at a time
5217 and load the whole vector. */
5218 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5219 for (i = 0; i < n_elts; i++)
5220 emit_move_insn (adjust_address_nv (mem, inner_mode,
5221 i * GET_MODE_SIZE (inner_mode)),
5222 XVECEXP (vals, 0, i));
5223 emit_move_insn (target, mem);
5226 /* Set field ELT of TARGET to VAL. */
5229 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5231 enum machine_mode mode = GET_MODE (target);
5232 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5233 rtx reg = gen_reg_rtx (mode);
5235 int width = GET_MODE_SIZE (inner_mode);
5238 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5240 rtx (*set_func) (rtx, rtx, rtx, rtx)
5241 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5242 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5246 /* Load single variable value. */
5247 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5248 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5249 x = gen_rtx_UNSPEC (VOIDmode,
5250 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5251 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5253 gen_rtx_SET (VOIDmode,
5257 /* Linear sequence. */
5258 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5259 for (i = 0; i < 16; ++i)
5260 XVECEXP (mask, 0, i) = GEN_INT (i);
5262 /* Set permute mask to insert element into target. */
5263 for (i = 0; i < width; ++i)
5264 XVECEXP (mask, 0, elt*width + i)
5265 = GEN_INT (i + 0x10);
5266 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5267 x = gen_rtx_UNSPEC (mode,
5268 gen_rtvec (3, target, reg,
5269 force_reg (V16QImode, x)),
5271 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5274 /* Extract field ELT from VEC into TARGET. */
5277 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5279 enum machine_mode mode = GET_MODE (vec);
5280 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5283 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5285 rtx (*extract_func) (rtx, rtx, rtx)
5286 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5287 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5291 /* Allocate mode-sized buffer. */
5292 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5294 /* Add offset to field within buffer matching vector element. */
5295 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5297 /* Store single field into mode-sized buffer. */
5298 x = gen_rtx_UNSPEC (VOIDmode,
5299 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5300 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5302 gen_rtx_SET (VOIDmode,
5305 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5308 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5309 implement ANDing by the mask IN. */
5311 build_mask64_2_operands (rtx in, rtx *out)
5313 #if HOST_BITS_PER_WIDE_INT >= 64
5314 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5317 gcc_assert (GET_CODE (in) == CONST_INT);
5322 /* Assume c initially something like 0x00fff000000fffff. The idea
5323 is to rotate the word so that the middle ^^^^^^ group of zeros
5324 is at the MS end and can be cleared with an rldicl mask. We then
5325 rotate back and clear off the MS ^^ group of zeros with a
5327 c = ~c; /* c == 0xff000ffffff00000 */
5328 lsb = c & -c; /* lsb == 0x0000000000100000 */
5329 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5330 c = ~c; /* c == 0x00fff000000fffff */
5331 c &= -lsb; /* c == 0x00fff00000000000 */
5332 lsb = c & -c; /* lsb == 0x0000100000000000 */
5333 c = ~c; /* c == 0xff000fffffffffff */
5334 c &= -lsb; /* c == 0xff00000000000000 */
5336 while ((lsb >>= 1) != 0)
5337 shift++; /* shift == 44 on exit from loop */
5338 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5339 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5340 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5344 /* Assume c initially something like 0xff000f0000000000. The idea
5345 is to rotate the word so that the ^^^ middle group of zeros
5346 is at the LS end and can be cleared with an rldicr mask. We then
5347 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5349 lsb = c & -c; /* lsb == 0x0000010000000000 */
5350 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5351 c = ~c; /* c == 0x00fff0ffffffffff */
5352 c &= -lsb; /* c == 0x00fff00000000000 */
5353 lsb = c & -c; /* lsb == 0x0000100000000000 */
5354 c = ~c; /* c == 0xff000fffffffffff */
5355 c &= -lsb; /* c == 0xff00000000000000 */
5357 while ((lsb >>= 1) != 0)
5358 shift++; /* shift == 44 on exit from loop */
5359 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5360 m1 >>= shift; /* m1 == 0x0000000000000fff */
5361 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5364 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5365 masks will be all 1's. We are guaranteed more than one transition. */
5366 out[0] = GEN_INT (64 - shift);
5367 out[1] = GEN_INT (m1);
5368 out[2] = GEN_INT (shift);
5369 out[3] = GEN_INT (m2);
5377 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5380 invalid_e500_subreg (rtx op, enum machine_mode mode)
5382 if (TARGET_E500_DOUBLE)
5384 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5385 subreg:TI and reg:TF. Decimal float modes are like integer
5386 modes (only low part of each register used) for this
5388 if (GET_CODE (op) == SUBREG
5389 && (mode == SImode || mode == DImode || mode == TImode
5390 || mode == DDmode || mode == TDmode)
5391 && REG_P (SUBREG_REG (op))
5392 && (GET_MODE (SUBREG_REG (op)) == DFmode
5393 || GET_MODE (SUBREG_REG (op)) == TFmode))
5396 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5398 if (GET_CODE (op) == SUBREG
5399 && (mode == DFmode || mode == TFmode)
5400 && REG_P (SUBREG_REG (op))
5401 && (GET_MODE (SUBREG_REG (op)) == DImode
5402 || GET_MODE (SUBREG_REG (op)) == TImode
5403 || GET_MODE (SUBREG_REG (op)) == DDmode
5404 || GET_MODE (SUBREG_REG (op)) == TDmode))
5409 && GET_CODE (op) == SUBREG
5411 && REG_P (SUBREG_REG (op))
5412 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5418 /* AIX increases natural record alignment to doubleword if the first
5419 field is an FP double while the FP fields remain word aligned. */
5422 rs6000_special_round_type_align (tree type, unsigned int computed,
5423 unsigned int specified)
5425 unsigned int align = MAX (computed, specified);
5426 tree field = TYPE_FIELDS (type);
5428 /* Skip all non field decls */
5429 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5430 field = DECL_CHAIN (field);
5432 if (field != NULL && field != type)
5434 type = TREE_TYPE (field);
5435 while (TREE_CODE (type) == ARRAY_TYPE)
5436 type = TREE_TYPE (type);
5438 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5439 align = MAX (align, 64);
5445 /* Darwin increases record alignment to the natural alignment of
5449 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5450 unsigned int specified)
5452 unsigned int align = MAX (computed, specified);
5454 if (TYPE_PACKED (type))
5457 /* Find the first field, looking down into aggregates. */
5459 tree field = TYPE_FIELDS (type);
5460 /* Skip all non field decls */
5461 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5462 field = DECL_CHAIN (field);
5465 /* A packed field does not contribute any extra alignment. */
5466 if (DECL_PACKED (field))
5468 type = TREE_TYPE (field);
5469 while (TREE_CODE (type) == ARRAY_TYPE)
5470 type = TREE_TYPE (type);
5471 } while (AGGREGATE_TYPE_P (type));
5473 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5474 align = MAX (align, TYPE_ALIGN (type));
5479 /* Return 1 for an operand in small memory on V.4/eabi. */
5482 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5483 enum machine_mode mode ATTRIBUTE_UNUSED)
5488 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5491 if (DEFAULT_ABI != ABI_V4)
5494 /* Vector and float memory instructions have a limited offset on the
5495 SPE, so using a vector or float variable directly as an operand is
5498 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5501 if (GET_CODE (op) == SYMBOL_REF)
5504 else if (GET_CODE (op) != CONST
5505 || GET_CODE (XEXP (op, 0)) != PLUS
5506 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5507 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5512 rtx sum = XEXP (op, 0);
5513 HOST_WIDE_INT summand;
5515 /* We have to be careful here, because it is the referenced address
5516 that must be 32k from _SDA_BASE_, not just the symbol. */
5517 summand = INTVAL (XEXP (sum, 1));
5518 if (summand < 0 || summand > g_switch_value)
5521 sym_ref = XEXP (sum, 0);
5524 return SYMBOL_REF_SMALL_P (sym_ref);
5530 /* Return true if either operand is a general purpose register. */
5533 gpr_or_gpr_p (rtx op0, rtx op1)
5535 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5536 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5540 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5543 reg_offset_addressing_ok_p (enum machine_mode mode)
5553 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5554 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5562 /* Paired vector modes. Only reg+reg addressing is valid. */
5563 if (TARGET_PAIRED_FLOAT)
5575 virtual_stack_registers_memory_p (rtx op)
5579 if (GET_CODE (op) == REG)
5580 regnum = REGNO (op);
5582 else if (GET_CODE (op) == PLUS
5583 && GET_CODE (XEXP (op, 0)) == REG
5584 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5585 regnum = REGNO (XEXP (op, 0));
5590 return (regnum >= FIRST_VIRTUAL_REGISTER
5591 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5595 constant_pool_expr_p (rtx op)
5599 split_const (op, &base, &offset);
5600 return (GET_CODE (base) == SYMBOL_REF
5601 && CONSTANT_POOL_ADDRESS_P (base)
5602 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5605 static rtx tocrel_base, tocrel_offset;
5608 toc_relative_expr_p (rtx op)
5610 if (GET_CODE (op) != CONST)
5613 split_const (op, &tocrel_base, &tocrel_offset);
5614 return (GET_CODE (tocrel_base) == UNSPEC
5615 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5619 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5622 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5623 && GET_CODE (XEXP (x, 0)) == REG
5624 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5625 || ((TARGET_MINIMAL_TOC
5626 || TARGET_CMODEL != CMODEL_SMALL)
5627 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5628 && toc_relative_expr_p (XEXP (x, 1)));
5632 legitimate_small_data_p (enum machine_mode mode, rtx x)
5634 return (DEFAULT_ABI == ABI_V4
5635 && !flag_pic && !TARGET_TOC
5636 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5637 && small_data_operand (x, mode));
5640 /* SPE offset addressing is limited to 5-bits worth of double words. */
5641 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5644 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5646 unsigned HOST_WIDE_INT offset, extra;
5648 if (GET_CODE (x) != PLUS)
5650 if (GET_CODE (XEXP (x, 0)) != REG)
5652 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5654 if (!reg_offset_addressing_ok_p (mode))
5655 return virtual_stack_registers_memory_p (x);
5656 if (legitimate_constant_pool_address_p (x, strict))
5658 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5661 offset = INTVAL (XEXP (x, 1));
5669 /* SPE vector modes. */
5670 return SPE_CONST_OFFSET_OK (offset);
5673 if (TARGET_E500_DOUBLE)
5674 return SPE_CONST_OFFSET_OK (offset);
5676 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5678 if (VECTOR_MEM_VSX_P (DFmode))
5683 /* On e500v2, we may have:
5685 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5687 Which gets addressed with evldd instructions. */
5688 if (TARGET_E500_DOUBLE)
5689 return SPE_CONST_OFFSET_OK (offset);
5691 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5693 else if (offset & 3)
5698 if (TARGET_E500_DOUBLE)
5699 return (SPE_CONST_OFFSET_OK (offset)
5700 && SPE_CONST_OFFSET_OK (offset + 8));
5704 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5706 else if (offset & 3)
5717 return (offset < 0x10000) && (offset + extra < 0x10000);
5721 legitimate_indexed_address_p (rtx x, int strict)
5725 if (GET_CODE (x) != PLUS)
5731 /* Recognize the rtl generated by reload which we know will later be
5732 replaced with proper base and index regs. */
5734 && reload_in_progress
5735 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5739 return (REG_P (op0) && REG_P (op1)
5740 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5741 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5742 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5743 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5747 avoiding_indexed_address_p (enum machine_mode mode)
5749 /* Avoid indexed addressing for modes that have non-indexed
5750 load/store instruction forms. */
5751 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5755 legitimate_indirect_address_p (rtx x, int strict)
5757 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5761 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5763 if (!TARGET_MACHO || !flag_pic
5764 || mode != SImode || GET_CODE (x) != MEM)
5768 if (GET_CODE (x) != LO_SUM)
5770 if (GET_CODE (XEXP (x, 0)) != REG)
5772 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5776 return CONSTANT_P (x);
5780 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5782 if (GET_CODE (x) != LO_SUM)
5784 if (GET_CODE (XEXP (x, 0)) != REG)
5786 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5788 /* Restrict addressing for DI because of our SUBREG hackery. */
5789 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5790 || mode == DDmode || mode == TDmode
5795 if (TARGET_ELF || TARGET_MACHO)
5797 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5801 if (GET_MODE_NUNITS (mode) != 1)
5803 if (GET_MODE_BITSIZE (mode) > 64
5804 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5805 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5806 && (mode == DFmode || mode == DDmode))))
5809 return CONSTANT_P (x);
5816 /* Try machine-dependent ways of modifying an illegitimate address
5817 to be legitimate. If we find one, return the new, valid address.
5818 This is used from only one place: `memory_address' in explow.c.
5820 OLDX is the address as it was before break_out_memory_refs was
5821 called. In some cases it is useful to look at this to decide what
5824 It is always safe for this function to do nothing. It exists to
5825 recognize opportunities to optimize the output.
5827 On RS/6000, first check for the sum of a register with a constant
5828 integer that is out of range. If so, generate code to add the
5829 constant with the low-order 16 bits masked to the register and force
5830 this result into another register (this can be done with `cau').
5831 Then generate an address of REG+(CONST&0xffff), allowing for the
5832 possibility of bit 16 being a one.
5834 Then check for the sum of a register and something not constant, try to
5835 load the other things into a register and return the sum. */
5838 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5839 enum machine_mode mode)
5841 unsigned int extra = 0;
5843 if (!reg_offset_addressing_ok_p (mode))
5845 if (virtual_stack_registers_memory_p (x))
5848 /* In theory we should not be seeing addresses of the form reg+0,
5849 but just in case it is generated, optimize it away. */
5850 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5851 return force_reg (Pmode, XEXP (x, 0));
5853 /* Make sure both operands are registers. */
5854 else if (GET_CODE (x) == PLUS)
5855 return gen_rtx_PLUS (Pmode,
5856 force_reg (Pmode, XEXP (x, 0)),
5857 force_reg (Pmode, XEXP (x, 1)));
5859 return force_reg (Pmode, x);
5861 if (GET_CODE (x) == SYMBOL_REF)
5863 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5865 return rs6000_legitimize_tls_address (x, model);
5875 if (!TARGET_POWERPC64)
5883 extra = TARGET_POWERPC64 ? 8 : 12;
5889 if (GET_CODE (x) == PLUS
5890 && GET_CODE (XEXP (x, 0)) == REG
5891 && GET_CODE (XEXP (x, 1)) == CONST_INT
5892 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5894 && !((TARGET_POWERPC64
5895 && (mode == DImode || mode == TImode)
5896 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5897 || SPE_VECTOR_MODE (mode)
5898 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5899 || mode == DImode || mode == DDmode
5900 || mode == TDmode))))
5902 HOST_WIDE_INT high_int, low_int;
5904 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5905 if (low_int >= 0x8000 - extra)
5907 high_int = INTVAL (XEXP (x, 1)) - low_int;
5908 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5909 GEN_INT (high_int)), 0);
5910 return plus_constant (sum, low_int);
5912 else if (GET_CODE (x) == PLUS
5913 && GET_CODE (XEXP (x, 0)) == REG
5914 && GET_CODE (XEXP (x, 1)) != CONST_INT
5915 && GET_MODE_NUNITS (mode) == 1
5916 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5918 || ((mode != DImode && mode != DFmode && mode != DDmode)
5919 || (TARGET_E500_DOUBLE && mode != DDmode)))
5920 && (TARGET_POWERPC64 || mode != DImode)
5921 && !avoiding_indexed_address_p (mode)
5926 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5927 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5929 else if (SPE_VECTOR_MODE (mode)
5930 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5931 || mode == DDmode || mode == TDmode
5932 || mode == DImode)))
5936 /* We accept [reg + reg] and [reg + OFFSET]. */
5938 if (GET_CODE (x) == PLUS)
5940 rtx op1 = XEXP (x, 0);
5941 rtx op2 = XEXP (x, 1);
5944 op1 = force_reg (Pmode, op1);
5946 if (GET_CODE (op2) != REG
5947 && (GET_CODE (op2) != CONST_INT
5948 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5949 || (GET_MODE_SIZE (mode) > 8
5950 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5951 op2 = force_reg (Pmode, op2);
5953 /* We can't always do [reg + reg] for these, because [reg +
5954 reg + offset] is not a legitimate addressing mode. */
5955 y = gen_rtx_PLUS (Pmode, op1, op2);
5957 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5958 return force_reg (Pmode, y);
5963 return force_reg (Pmode, x);
5969 && GET_CODE (x) != CONST_INT
5970 && GET_CODE (x) != CONST_DOUBLE
5972 && GET_MODE_NUNITS (mode) == 1
5973 && (GET_MODE_BITSIZE (mode) <= 32
5974 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5975 && (mode == DFmode || mode == DDmode))))
5977 rtx reg = gen_reg_rtx (Pmode);
5978 emit_insn (gen_elf_high (reg, x));
5979 return gen_rtx_LO_SUM (Pmode, reg, x);
5981 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5984 && ! MACHO_DYNAMIC_NO_PIC_P
5986 && GET_CODE (x) != CONST_INT
5987 && GET_CODE (x) != CONST_DOUBLE
5989 && GET_MODE_NUNITS (mode) == 1
5990 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5991 || (mode != DFmode && mode != DDmode))
5995 rtx reg = gen_reg_rtx (Pmode);
5996 emit_insn (gen_macho_high (reg, x));
5997 return gen_rtx_LO_SUM (Pmode, reg, x);
6000 && GET_CODE (x) == SYMBOL_REF
6001 && constant_pool_expr_p (x)
6002 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6004 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6005 return create_TOC_reference (x, reg);
6011 /* Debug version of rs6000_legitimize_address. */
6013 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6019 ret = rs6000_legitimize_address (x, oldx, mode);
6020 insns = get_insns ();
6026 "\nrs6000_legitimize_address: mode %s, old code %s, "
6027 "new code %s, modified\n",
6028 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6029 GET_RTX_NAME (GET_CODE (ret)));
6031 fprintf (stderr, "Original address:\n");
6034 fprintf (stderr, "oldx:\n");
6037 fprintf (stderr, "New address:\n");
6042 fprintf (stderr, "Insns added:\n");
6043 debug_rtx_list (insns, 20);
6049 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6050 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6061 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6062 We need to emit DTP-relative relocations. */
6065 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6070 fputs ("\t.long\t", file);
6073 fputs (DOUBLE_INT_ASM_OP, file);
6078 output_addr_const (file, x);
6079 fputs ("@dtprel+0x8000", file);
6082 /* In the name of slightly smaller debug output, and to cater to
6083 general assembler lossage, recognize various UNSPEC sequences
6084 and turn them back into a direct symbol reference. */
6087 rs6000_delegitimize_address (rtx orig_x)
6091 orig_x = delegitimize_mem_from_attrs (orig_x);
6096 if ((GET_CODE (x) == PLUS
6097 || GET_CODE (x) == LO_SUM)
6098 && GET_CODE (XEXP (x, 0)) == REG
6099 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6100 || TARGET_MINIMAL_TOC
6101 || TARGET_CMODEL != CMODEL_SMALL)
6102 && GET_CODE (XEXP (x, 1)) == CONST)
6104 y = XEXP (XEXP (x, 1), 0);
6105 if (GET_CODE (y) == UNSPEC
6106 && XINT (y, 1) == UNSPEC_TOCREL)
6108 y = XVECEXP (y, 0, 0);
6109 if (!MEM_P (orig_x))
6112 return replace_equiv_address_nv (orig_x, y);
6117 && GET_CODE (orig_x) == LO_SUM
6118 && GET_CODE (XEXP (x, 1)) == CONST)
6120 y = XEXP (XEXP (x, 1), 0);
6121 if (GET_CODE (y) == UNSPEC
6122 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6123 return XVECEXP (y, 0, 0);
6129 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6131 static GTY(()) rtx rs6000_tls_symbol;
6133 rs6000_tls_get_addr (void)
6135 if (!rs6000_tls_symbol)
6136 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6138 return rs6000_tls_symbol;
6141 /* Construct the SYMBOL_REF for TLS GOT references. */
6143 static GTY(()) rtx rs6000_got_symbol;
6145 rs6000_got_sym (void)
6147 if (!rs6000_got_symbol)
6149 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6150 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6151 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6154 return rs6000_got_symbol;
6157 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6158 this (thread-local) address. */
6161 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6165 dest = gen_reg_rtx (Pmode);
6166 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6172 tlsreg = gen_rtx_REG (Pmode, 13);
6173 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6177 tlsreg = gen_rtx_REG (Pmode, 2);
6178 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6182 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6186 tmp = gen_reg_rtx (Pmode);
6189 tlsreg = gen_rtx_REG (Pmode, 13);
6190 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6194 tlsreg = gen_rtx_REG (Pmode, 2);
6195 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6199 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6201 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6206 rtx r3, got, tga, tmp1, tmp2, call_insn;
6208 /* We currently use relocations like @got@tlsgd for tls, which
6209 means the linker will handle allocation of tls entries, placing
6210 them in the .got section. So use a pointer to the .got section,
6211 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6212 or to secondary GOT sections used by 32-bit -fPIC. */
6214 got = gen_rtx_REG (Pmode, 2);
6218 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6221 rtx gsym = rs6000_got_sym ();
6222 got = gen_reg_rtx (Pmode);
6224 rs6000_emit_move (got, gsym, Pmode);
6229 tmp1 = gen_reg_rtx (Pmode);
6230 tmp2 = gen_reg_rtx (Pmode);
6231 mem = gen_const_mem (Pmode, tmp1);
6232 lab = gen_label_rtx ();
6233 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6234 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6235 emit_move_insn (tmp2, mem);
6236 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6237 set_unique_reg_note (last, REG_EQUAL, gsym);
6242 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6244 r3 = gen_rtx_REG (Pmode, 3);
6245 tga = rs6000_tls_get_addr ();
6246 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6248 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6249 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6250 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6251 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6252 else if (DEFAULT_ABI == ABI_V4)
6253 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6256 call_insn = last_call_insn ();
6257 PATTERN (call_insn) = insn;
6258 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6259 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6260 pic_offset_table_rtx);
6262 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6264 r3 = gen_rtx_REG (Pmode, 3);
6265 tga = rs6000_tls_get_addr ();
6266 tmp1 = gen_reg_rtx (Pmode);
6267 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6269 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6270 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6271 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6272 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6273 else if (DEFAULT_ABI == ABI_V4)
6274 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6277 call_insn = last_call_insn ();
6278 PATTERN (call_insn) = insn;
6279 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6280 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6281 pic_offset_table_rtx);
6283 if (rs6000_tls_size == 16)
6286 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6288 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6290 else if (rs6000_tls_size == 32)
6292 tmp2 = gen_reg_rtx (Pmode);
6294 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6296 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6299 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6301 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6305 tmp2 = gen_reg_rtx (Pmode);
6307 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6309 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6311 insn = gen_rtx_SET (Pmode, dest,
6312 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6318 /* IE, or 64-bit offset LE. */
6319 tmp2 = gen_reg_rtx (Pmode);
6321 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6323 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6326 insn = gen_tls_tls_64 (dest, tmp2, addr);
6328 insn = gen_tls_tls_32 (dest, tmp2, addr);
6336 /* Return 1 if X contains a thread-local symbol. */
6339 rs6000_tls_referenced_p (rtx x)
6341 if (! TARGET_HAVE_TLS)
6344 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6347 /* Return 1 if *X is a thread-local symbol. This is the same as
6348 rs6000_tls_symbol_ref except for the type of the unused argument. */
6351 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6353 return RS6000_SYMBOL_REF_TLS_P (*x);
6356 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6357 replace the input X, or the original X if no replacement is called for.
6358 The output parameter *WIN is 1 if the calling macro should goto WIN,
6361 For RS/6000, we wish to handle large displacements off a base
6362 register by splitting the addend across an addiu/addis and the mem insn.
6363 This cuts number of extra insns needed from 3 to 1.
6365 On Darwin, we use this to generate code for floating point constants.
6366 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6367 The Darwin code is inside #if TARGET_MACHO because only then are the
6368 machopic_* functions defined. */
6370 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6371 int opnum, int type,
6372 int ind_levels ATTRIBUTE_UNUSED, int *win)
6374 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6376 /* We must recognize output that we have already generated ourselves. */
6377 if (GET_CODE (x) == PLUS
6378 && GET_CODE (XEXP (x, 0)) == PLUS
6379 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6380 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6381 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6383 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6384 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6385 opnum, (enum reload_type)type);
6390 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6391 if (GET_CODE (x) == LO_SUM
6392 && GET_CODE (XEXP (x, 0)) == HIGH)
6394 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6395 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6396 opnum, (enum reload_type)type);
6402 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6403 && GET_CODE (x) == LO_SUM
6404 && GET_CODE (XEXP (x, 0)) == PLUS
6405 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6406 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6407 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6408 && machopic_operand_p (XEXP (x, 1)))
6410 /* Result of previous invocation of this function on Darwin
6411 floating point constant. */
6412 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6413 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6414 opnum, (enum reload_type)type);
6420 if (TARGET_CMODEL != CMODEL_SMALL
6421 && GET_CODE (x) == LO_SUM
6422 && GET_CODE (XEXP (x, 0)) == PLUS
6423 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6424 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6425 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6426 && GET_CODE (XEXP (x, 1)) == CONST
6427 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6428 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6429 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6431 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6432 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6433 opnum, (enum reload_type) type);
6438 /* Force ld/std non-word aligned offset into base register by wrapping
6440 if (GET_CODE (x) == PLUS
6441 && GET_CODE (XEXP (x, 0)) == REG
6442 && REGNO (XEXP (x, 0)) < 32
6443 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6444 && GET_CODE (XEXP (x, 1)) == CONST_INT
6446 && (INTVAL (XEXP (x, 1)) & 3) != 0
6447 && VECTOR_MEM_NONE_P (mode)
6448 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6449 && TARGET_POWERPC64)
6451 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6452 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6453 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6454 opnum, (enum reload_type) type);
6459 if (GET_CODE (x) == PLUS
6460 && GET_CODE (XEXP (x, 0)) == REG
6461 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6462 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6463 && GET_CODE (XEXP (x, 1)) == CONST_INT
6465 && !SPE_VECTOR_MODE (mode)
6466 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6467 || mode == DDmode || mode == TDmode
6469 && VECTOR_MEM_NONE_P (mode))
6471 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6472 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6474 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6476 /* Check for 32-bit overflow. */
6477 if (high + low != val)
6483 /* Reload the high part into a base reg; leave the low part
6484 in the mem directly. */
6486 x = gen_rtx_PLUS (GET_MODE (x),
6487 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6491 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6492 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6493 opnum, (enum reload_type)type);
6498 if (GET_CODE (x) == SYMBOL_REF
6500 && VECTOR_MEM_NONE_P (mode)
6501 && !SPE_VECTOR_MODE (mode)
6503 && DEFAULT_ABI == ABI_DARWIN
6504 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6506 && DEFAULT_ABI == ABI_V4
6509 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6510 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6514 && (mode != DImode || TARGET_POWERPC64)
6515 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6516 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6521 rtx offset = machopic_gen_offset (x);
6522 x = gen_rtx_LO_SUM (GET_MODE (x),
6523 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6524 gen_rtx_HIGH (Pmode, offset)), offset);
6528 x = gen_rtx_LO_SUM (GET_MODE (x),
6529 gen_rtx_HIGH (Pmode, x), x);
6531 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6532 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6533 opnum, (enum reload_type)type);
6538 /* Reload an offset address wrapped by an AND that represents the
6539 masking of the lower bits. Strip the outer AND and let reload
6540 convert the offset address into an indirect address. For VSX,
6541 force reload to create the address with an AND in a separate
6542 register, because we can't guarantee an altivec register will
6544 if (VECTOR_MEM_ALTIVEC_P (mode)
6545 && GET_CODE (x) == AND
6546 && GET_CODE (XEXP (x, 0)) == PLUS
6547 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6548 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6549 && GET_CODE (XEXP (x, 1)) == CONST_INT
6550 && INTVAL (XEXP (x, 1)) == -16)
6559 && GET_CODE (x) == SYMBOL_REF
6560 && constant_pool_expr_p (x)
6561 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6563 x = create_TOC_reference (x, NULL_RTX);
6564 if (TARGET_CMODEL != CMODEL_SMALL)
6565 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6566 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6567 opnum, (enum reload_type) type);
6575 /* Debug version of rs6000_legitimize_reload_address. */
6577 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6578 int opnum, int type,
6579 int ind_levels, int *win)
6581 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6584 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6585 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6586 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6590 fprintf (stderr, "Same address returned\n");
6592 fprintf (stderr, "NULL returned\n");
6595 fprintf (stderr, "New address:\n");
6602 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6603 that is a valid memory address for an instruction.
6604 The MODE argument is the machine mode for the MEM expression
6605 that wants to use this address.
6607 On the RS/6000, there are four valid address: a SYMBOL_REF that
6608 refers to a constant pool entry of an address (or the sum of it
6609 plus a constant), a short (16-bit signed) constant plus a register,
6610 the sum of two registers, or a register indirect, possibly with an
6611 auto-increment. For DFmode, DDmode and DImode with a constant plus
6612 register, we must ensure that both words are addressable or PowerPC64
6613 with offset word aligned.
6615 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6616 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6617 because adjacent memory cells are accessed by adding word-sized offsets
6618 during assembly output. */
6620 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6622 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6624 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6625 if (VECTOR_MEM_ALTIVEC_P (mode)
6626 && GET_CODE (x) == AND
6627 && GET_CODE (XEXP (x, 1)) == CONST_INT
6628 && INTVAL (XEXP (x, 1)) == -16)
6631 if (RS6000_SYMBOL_REF_TLS_P (x))
6633 if (legitimate_indirect_address_p (x, reg_ok_strict))
6635 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6636 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6637 && !SPE_VECTOR_MODE (mode)
6640 /* Restrict addressing for DI because of our SUBREG hackery. */
6641 && !(TARGET_E500_DOUBLE
6642 && (mode == DFmode || mode == DDmode || mode == DImode))
6644 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6646 if (virtual_stack_registers_memory_p (x))
6648 if (reg_offset_p && legitimate_small_data_p (mode, x))
6650 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6652 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6655 && GET_CODE (x) == PLUS
6656 && GET_CODE (XEXP (x, 0)) == REG
6657 && (XEXP (x, 0) == virtual_stack_vars_rtx
6658 || XEXP (x, 0) == arg_pointer_rtx)
6659 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6661 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6666 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6668 || (mode != DFmode && mode != DDmode)
6669 || (TARGET_E500_DOUBLE && mode != DDmode))
6670 && (TARGET_POWERPC64 || mode != DImode)
6671 && !avoiding_indexed_address_p (mode)
6672 && legitimate_indexed_address_p (x, reg_ok_strict))
6674 if (GET_CODE (x) == PRE_MODIFY
6678 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6680 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6681 && (TARGET_POWERPC64 || mode != DImode)
6682 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6683 && !SPE_VECTOR_MODE (mode)
6684 /* Restrict addressing for DI because of our SUBREG hackery. */
6685 && !(TARGET_E500_DOUBLE
6686 && (mode == DFmode || mode == DDmode || mode == DImode))
6688 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6689 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6690 || (!avoiding_indexed_address_p (mode)
6691 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6692 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6694 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6699 /* Debug version of rs6000_legitimate_address_p. */
6701 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6704 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6706 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6707 "strict = %d, code = %s\n",
6708 ret ? "true" : "false",
6709 GET_MODE_NAME (mode),
6711 GET_RTX_NAME (GET_CODE (x)));
6717 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6720 rs6000_mode_dependent_address_p (const_rtx addr)
6722 return rs6000_mode_dependent_address_ptr (addr);
6725 /* Go to LABEL if ADDR (a legitimate address expression)
6726 has an effect that depends on the machine mode it is used for.
6728 On the RS/6000 this is true of all integral offsets (since AltiVec
6729 and VSX modes don't allow them) or is a pre-increment or decrement.
6731 ??? Except that due to conceptual problems in offsettable_address_p
6732 we can't really report the problems of integral offsets. So leave
6733 this assuming that the adjustable offset must be valid for the
6734 sub-words of a TFmode operand, which is what we had before. */
6737 rs6000_mode_dependent_address (const_rtx addr)
6739 switch (GET_CODE (addr))
6742 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6743 is considered a legitimate address before reload, so there
6744 are no offset restrictions in that case. Note that this
6745 condition is safe in strict mode because any address involving
6746 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6747 been rejected as illegitimate. */
6748 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6749 && XEXP (addr, 0) != arg_pointer_rtx
6750 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6752 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6753 return val + 12 + 0x8000 >= 0x10000;
6758 /* Anything in the constant pool is sufficiently aligned that
6759 all bytes have the same high part address. */
6760 return !legitimate_constant_pool_address_p (addr, false);
6762 /* Auto-increment cases are now treated generically in recog.c. */
6764 return TARGET_UPDATE;
6766 /* AND is only allowed in Altivec loads. */
6777 /* Debug version of rs6000_mode_dependent_address. */
6779 rs6000_debug_mode_dependent_address (const_rtx addr)
6781 bool ret = rs6000_mode_dependent_address (addr);
6783 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6784 ret ? "true" : "false");
6790 /* Implement FIND_BASE_TERM. */
6793 rs6000_find_base_term (rtx op)
6797 split_const (op, &base, &offset);
6798 if (GET_CODE (base) == UNSPEC)
6799 switch (XINT (base, 1))
6802 case UNSPEC_MACHOPIC_OFFSET:
6803 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6804 for aliasing purposes. */
6805 return XVECEXP (base, 0, 0);
6811 /* More elaborate version of recog's offsettable_memref_p predicate
6812 that works around the ??? note of rs6000_mode_dependent_address.
6813 In particular it accepts
6815 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6817 in 32-bit mode, that the recog predicate rejects. */
6820 rs6000_offsettable_memref_p (rtx op)
6825 /* First mimic offsettable_memref_p. */
6826 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6829 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6830 the latter predicate knows nothing about the mode of the memory
6831 reference and, therefore, assumes that it is the largest supported
6832 mode (TFmode). As a consequence, legitimate offsettable memory
6833 references are rejected. rs6000_legitimate_offset_address_p contains
6834 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6835 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6838 /* Change register usage conditional on target flags. */
6840 rs6000_conditional_register_usage (void)
6844 /* Set MQ register fixed (already call_used) if not POWER
6845 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6850 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6852 fixed_regs[13] = call_used_regs[13]
6853 = call_really_used_regs[13] = 1;
6855 /* Conditionally disable FPRs. */
6856 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6857 for (i = 32; i < 64; i++)
6858 fixed_regs[i] = call_used_regs[i]
6859 = call_really_used_regs[i] = 1;
6861 /* The TOC register is not killed across calls in a way that is
6862 visible to the compiler. */
6863 if (DEFAULT_ABI == ABI_AIX)
6864 call_really_used_regs[2] = 0;
6866 if (DEFAULT_ABI == ABI_V4
6867 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6869 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6871 if (DEFAULT_ABI == ABI_V4
6872 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6874 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6875 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6876 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6878 if (DEFAULT_ABI == ABI_DARWIN
6879 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6880 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6881 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6882 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6884 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6885 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6886 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6890 global_regs[SPEFSCR_REGNO] = 1;
6891 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6892 registers in prologues and epilogues. We no longer use r14
6893 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6894 pool for link-compatibility with older versions of GCC. Once
6895 "old" code has died out, we can return r14 to the allocation
6898 = call_used_regs[14]
6899 = call_really_used_regs[14] = 1;
6902 if (!TARGET_ALTIVEC && !TARGET_VSX)
6904 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6905 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6906 call_really_used_regs[VRSAVE_REGNO] = 1;
6909 if (TARGET_ALTIVEC || TARGET_VSX)
6910 global_regs[VSCR_REGNO] = 1;
6912 if (TARGET_ALTIVEC_ABI)
6914 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6915 call_used_regs[i] = call_really_used_regs[i] = 1;
6917 /* AIX reserves VR20:31 in non-extended ABI mode. */
6919 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6920 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6924 /* Try to output insns to set TARGET equal to the constant C if it can
6925 be done in less than N insns. Do all computations in MODE.
6926 Returns the place where the output has been placed if it can be
6927 done and the insns have been emitted. If it would take more than N
6928 insns, zero is returned and no insns and emitted. */
6931 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6932 rtx source, int n ATTRIBUTE_UNUSED)
6934 rtx result, insn, set;
6935 HOST_WIDE_INT c0, c1;
6942 dest = gen_reg_rtx (mode);
6943 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6947 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6949 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6950 GEN_INT (INTVAL (source)
6951 & (~ (HOST_WIDE_INT) 0xffff))));
6952 emit_insn (gen_rtx_SET (VOIDmode, dest,
6953 gen_rtx_IOR (SImode, copy_rtx (result),
6954 GEN_INT (INTVAL (source) & 0xffff))));
6959 switch (GET_CODE (source))
6962 c0 = INTVAL (source);
6967 #if HOST_BITS_PER_WIDE_INT >= 64
6968 c0 = CONST_DOUBLE_LOW (source);
6971 c0 = CONST_DOUBLE_LOW (source);
6972 c1 = CONST_DOUBLE_HIGH (source);
6980 result = rs6000_emit_set_long_const (dest, c0, c1);
6987 insn = get_last_insn ();
6988 set = single_set (insn);
6989 if (! CONSTANT_P (SET_SRC (set)))
6990 set_unique_reg_note (insn, REG_EQUAL, source);
6995 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6996 fall back to a straight forward decomposition. We do this to avoid
6997 exponential run times encountered when looking for longer sequences
6998 with rs6000_emit_set_const. */
7000 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7002 if (!TARGET_POWERPC64)
7004 rtx operand1, operand2;
7006 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7008 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7010 emit_move_insn (operand1, GEN_INT (c1));
7011 emit_move_insn (operand2, GEN_INT (c2));
7015 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7018 ud2 = (c1 & 0xffff0000) >> 16;
7019 #if HOST_BITS_PER_WIDE_INT >= 64
7023 ud4 = (c2 & 0xffff0000) >> 16;
7025 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7026 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7029 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7031 emit_move_insn (dest, GEN_INT (ud1));
7034 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7035 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7038 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7041 emit_move_insn (dest, GEN_INT (ud2 << 16));
7043 emit_move_insn (copy_rtx (dest),
7044 gen_rtx_IOR (DImode, copy_rtx (dest),
7047 else if (ud3 == 0 && ud4 == 0)
7049 gcc_assert (ud2 & 0x8000);
7050 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7053 emit_move_insn (copy_rtx (dest),
7054 gen_rtx_IOR (DImode, copy_rtx (dest),
7056 emit_move_insn (copy_rtx (dest),
7057 gen_rtx_ZERO_EXTEND (DImode,
7058 gen_lowpart (SImode,
7061 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7062 || (ud4 == 0 && ! (ud3 & 0x8000)))
7065 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7068 emit_move_insn (dest, GEN_INT (ud3 << 16));
7071 emit_move_insn (copy_rtx (dest),
7072 gen_rtx_IOR (DImode, copy_rtx (dest),
7074 emit_move_insn (copy_rtx (dest),
7075 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7078 emit_move_insn (copy_rtx (dest),
7079 gen_rtx_IOR (DImode, copy_rtx (dest),
7085 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7088 emit_move_insn (dest, GEN_INT (ud4 << 16));
7091 emit_move_insn (copy_rtx (dest),
7092 gen_rtx_IOR (DImode, copy_rtx (dest),
7095 emit_move_insn (copy_rtx (dest),
7096 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7099 emit_move_insn (copy_rtx (dest),
7100 gen_rtx_IOR (DImode, copy_rtx (dest),
7101 GEN_INT (ud2 << 16)));
7103 emit_move_insn (copy_rtx (dest),
7104 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7110 /* Helper for the following. Get rid of [r+r] memory refs
7111 in cases where it won't work (TImode, TFmode, TDmode). */
7114 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7116 if (reload_in_progress)
7119 if (GET_CODE (operands[0]) == MEM
7120 && GET_CODE (XEXP (operands[0], 0)) != REG
7121 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7123 = replace_equiv_address (operands[0],
7124 copy_addr_to_reg (XEXP (operands[0], 0)));
7126 if (GET_CODE (operands[1]) == MEM
7127 && GET_CODE (XEXP (operands[1], 0)) != REG
7128 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7130 = replace_equiv_address (operands[1],
7131 copy_addr_to_reg (XEXP (operands[1], 0)));
7134 /* Return true if memory accesses to DECL are known to never straddle
7138 offsettable_ok_by_alignment (tree decl)
7140 unsigned HOST_WIDE_INT dsize, dalign;
7142 /* Presume any compiler generated symbol_ref is suitably aligned. */
7146 if (TREE_CODE (decl) != VAR_DECL
7147 && TREE_CODE (decl) != PARM_DECL
7148 && TREE_CODE (decl) != RESULT_DECL
7149 && TREE_CODE (decl) != FIELD_DECL)
7152 if (!DECL_SIZE_UNIT (decl))
7155 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7158 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7164 dalign = DECL_ALIGN_UNIT (decl);
7165 return dalign >= dsize;
7168 /* Emit a move from SOURCE to DEST in mode MODE. */
7170 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7174 operands[1] = source;
7176 if (TARGET_DEBUG_ADDR)
7179 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7180 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7181 GET_MODE_NAME (mode),
7184 can_create_pseudo_p ());
7186 fprintf (stderr, "source:\n");
7190 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7191 if (GET_CODE (operands[1]) == CONST_DOUBLE
7192 && ! FLOAT_MODE_P (mode)
7193 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7195 /* FIXME. This should never happen. */
7196 /* Since it seems that it does, do the safe thing and convert
7198 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7200 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7201 || FLOAT_MODE_P (mode)
7202 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7203 || CONST_DOUBLE_LOW (operands[1]) < 0)
7204 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7205 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7207 /* Check if GCC is setting up a block move that will end up using FP
7208 registers as temporaries. We must make sure this is acceptable. */
7209 if (GET_CODE (operands[0]) == MEM
7210 && GET_CODE (operands[1]) == MEM
7212 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7213 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7214 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7215 ? 32 : MEM_ALIGN (operands[0])))
7216 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7218 : MEM_ALIGN (operands[1]))))
7219 && ! MEM_VOLATILE_P (operands [0])
7220 && ! MEM_VOLATILE_P (operands [1]))
7222 emit_move_insn (adjust_address (operands[0], SImode, 0),
7223 adjust_address (operands[1], SImode, 0));
7224 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7225 adjust_address (copy_rtx (operands[1]), SImode, 4));
7229 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7230 && !gpc_reg_operand (operands[1], mode))
7231 operands[1] = force_reg (mode, operands[1]);
7233 if (mode == SFmode && ! TARGET_POWERPC
7234 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7235 && GET_CODE (operands[0]) == MEM)
7239 if (reload_in_progress || reload_completed)
7240 regnum = true_regnum (operands[1]);
7241 else if (GET_CODE (operands[1]) == REG)
7242 regnum = REGNO (operands[1]);
7246 /* If operands[1] is a register, on POWER it may have
7247 double-precision data in it, so truncate it to single
7249 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7252 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7253 : gen_reg_rtx (mode));
7254 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7255 operands[1] = newreg;
7259 /* Recognize the case where operand[1] is a reference to thread-local
7260 data and load its address to a register. */
7261 if (rs6000_tls_referenced_p (operands[1]))
7263 enum tls_model model;
7264 rtx tmp = operands[1];
7267 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7269 addend = XEXP (XEXP (tmp, 0), 1);
7270 tmp = XEXP (XEXP (tmp, 0), 0);
7273 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7274 model = SYMBOL_REF_TLS_MODEL (tmp);
7275 gcc_assert (model != 0);
7277 tmp = rs6000_legitimize_tls_address (tmp, model);
7280 tmp = gen_rtx_PLUS (mode, tmp, addend);
7281 tmp = force_operand (tmp, operands[0]);
7286 /* Handle the case where reload calls us with an invalid address. */
7287 if (reload_in_progress && mode == Pmode
7288 && (! general_operand (operands[1], mode)
7289 || ! nonimmediate_operand (operands[0], mode)))
7292 /* 128-bit constant floating-point values on Darwin should really be
7293 loaded as two parts. */
7294 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7295 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7297 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7298 know how to get a DFmode SUBREG of a TFmode. */
7299 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7300 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7301 simplify_gen_subreg (imode, operands[1], mode, 0),
7303 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7304 GET_MODE_SIZE (imode)),
7305 simplify_gen_subreg (imode, operands[1], mode,
7306 GET_MODE_SIZE (imode)),
7311 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7312 cfun->machine->sdmode_stack_slot =
7313 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7315 if (reload_in_progress
7317 && MEM_P (operands[0])
7318 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7319 && REG_P (operands[1]))
7321 if (FP_REGNO_P (REGNO (operands[1])))
7323 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7324 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7325 emit_insn (gen_movsd_store (mem, operands[1]));
7327 else if (INT_REGNO_P (REGNO (operands[1])))
7329 rtx mem = adjust_address_nv (operands[0], mode, 4);
7330 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7331 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7337 if (reload_in_progress
7339 && REG_P (operands[0])
7340 && MEM_P (operands[1])
7341 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7343 if (FP_REGNO_P (REGNO (operands[0])))
7345 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7346 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7347 emit_insn (gen_movsd_load (operands[0], mem));
7349 else if (INT_REGNO_P (REGNO (operands[0])))
7351 rtx mem = adjust_address_nv (operands[1], mode, 4);
7352 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7353 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7360 /* FIXME: In the long term, this switch statement should go away
7361 and be replaced by a sequence of tests based on things like
7367 if (CONSTANT_P (operands[1])
7368 && GET_CODE (operands[1]) != CONST_INT)
7369 operands[1] = force_const_mem (mode, operands[1]);
7374 rs6000_eliminate_indexed_memrefs (operands);
7381 if (CONSTANT_P (operands[1])
7382 && ! easy_fp_constant (operands[1], mode))
7383 operands[1] = force_const_mem (mode, operands[1]);
7396 if (CONSTANT_P (operands[1])
7397 && !easy_vector_constant (operands[1], mode))
7398 operands[1] = force_const_mem (mode, operands[1]);
7403 /* Use default pattern for address of ELF small data */
7406 && DEFAULT_ABI == ABI_V4
7407 && (GET_CODE (operands[1]) == SYMBOL_REF
7408 || GET_CODE (operands[1]) == CONST)
7409 && small_data_operand (operands[1], mode))
7411 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7415 if (DEFAULT_ABI == ABI_V4
7416 && mode == Pmode && mode == SImode
7417 && flag_pic == 1 && got_operand (operands[1], mode))
7419 emit_insn (gen_movsi_got (operands[0], operands[1]));
7423 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7427 && CONSTANT_P (operands[1])
7428 && GET_CODE (operands[1]) != HIGH
7429 && GET_CODE (operands[1]) != CONST_INT)
7431 rtx target = (!can_create_pseudo_p ()
7433 : gen_reg_rtx (mode));
7435 /* If this is a function address on -mcall-aixdesc,
7436 convert it to the address of the descriptor. */
7437 if (DEFAULT_ABI == ABI_AIX
7438 && GET_CODE (operands[1]) == SYMBOL_REF
7439 && XSTR (operands[1], 0)[0] == '.')
7441 const char *name = XSTR (operands[1], 0);
7443 while (*name == '.')
7445 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7446 CONSTANT_POOL_ADDRESS_P (new_ref)
7447 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7448 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7449 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7450 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7451 operands[1] = new_ref;
7454 if (DEFAULT_ABI == ABI_DARWIN)
7457 if (MACHO_DYNAMIC_NO_PIC_P)
7459 /* Take care of any required data indirection. */
7460 operands[1] = rs6000_machopic_legitimize_pic_address (
7461 operands[1], mode, operands[0]);
7462 if (operands[0] != operands[1])
7463 emit_insn (gen_rtx_SET (VOIDmode,
7464 operands[0], operands[1]));
7468 emit_insn (gen_macho_high (target, operands[1]));
7469 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7473 emit_insn (gen_elf_high (target, operands[1]));
7474 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7478 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7479 and we have put it in the TOC, we just need to make a TOC-relative
7482 && GET_CODE (operands[1]) == SYMBOL_REF
7483 && constant_pool_expr_p (operands[1])
7484 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7485 get_pool_mode (operands[1])))
7486 || (TARGET_CMODEL == CMODEL_MEDIUM
7487 && GET_CODE (operands[1]) == SYMBOL_REF
7488 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7489 && SYMBOL_REF_LOCAL_P (operands[1])
7490 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7493 if (TARGET_CMODEL != CMODEL_SMALL)
7495 if (can_create_pseudo_p ())
7496 reg = gen_reg_rtx (Pmode);
7500 operands[1] = create_TOC_reference (operands[1], reg);
7502 else if (mode == Pmode
7503 && CONSTANT_P (operands[1])
7504 && ((GET_CODE (operands[1]) != CONST_INT
7505 && ! easy_fp_constant (operands[1], mode))
7506 || (GET_CODE (operands[1]) == CONST_INT
7507 && (num_insns_constant (operands[1], mode)
7508 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7509 || (GET_CODE (operands[0]) == REG
7510 && FP_REGNO_P (REGNO (operands[0]))))
7511 && GET_CODE (operands[1]) != HIGH
7512 && ! legitimate_constant_pool_address_p (operands[1], false)
7513 && ! toc_relative_expr_p (operands[1])
7514 && (TARGET_CMODEL == CMODEL_SMALL
7515 || can_create_pseudo_p ()
7516 || (REG_P (operands[0])
7517 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7521 /* Darwin uses a special PIC legitimizer. */
7522 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7525 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7527 if (operands[0] != operands[1])
7528 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7533 /* If we are to limit the number of things we put in the TOC and
7534 this is a symbol plus a constant we can add in one insn,
7535 just put the symbol in the TOC and add the constant. Don't do
7536 this if reload is in progress. */
7537 if (GET_CODE (operands[1]) == CONST
7538 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7539 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7540 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7541 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7542 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7543 && ! side_effects_p (operands[0]))
7546 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7547 rtx other = XEXP (XEXP (operands[1], 0), 1);
7549 sym = force_reg (mode, sym);
7550 emit_insn (gen_add3_insn (operands[0], sym, other));
7554 operands[1] = force_const_mem (mode, operands[1]);
7557 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7558 && constant_pool_expr_p (XEXP (operands[1], 0))
7559 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7560 get_pool_constant (XEXP (operands[1], 0)),
7561 get_pool_mode (XEXP (operands[1], 0))))
7565 if (TARGET_CMODEL != CMODEL_SMALL)
7567 if (can_create_pseudo_p ())
7568 reg = gen_reg_rtx (Pmode);
7572 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7573 operands[1] = gen_const_mem (mode, tocref);
7574 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7580 rs6000_eliminate_indexed_memrefs (operands);
7584 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7586 gen_rtx_SET (VOIDmode,
7587 operands[0], operands[1]),
7588 gen_rtx_CLOBBER (VOIDmode,
7589 gen_rtx_SCRATCH (SImode)))));
7595 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7598 /* Above, we may have called force_const_mem which may have returned
7599 an invalid address. If we can, fix this up; otherwise, reload will
7600 have to deal with it. */
7601 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7602 operands[1] = validize_mem (operands[1]);
7605 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7608 /* Nonzero if we can use a floating-point register to pass this arg. */
7609 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7610 (SCALAR_FLOAT_MODE_P (MODE) \
7611 && (CUM)->fregno <= FP_ARG_MAX_REG \
7612 && TARGET_HARD_FLOAT && TARGET_FPRS)
7614 /* Nonzero if we can use an AltiVec register to pass this arg. */
7615 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7616 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7617 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7618 && TARGET_ALTIVEC_ABI \
7621 /* Return a nonzero value to say to return the function value in
7622 memory, just as large structures are always returned. TYPE will be
7623 the data type of the value, and FNTYPE will be the type of the
7624 function doing the returning, or @code{NULL} for libcalls.
7626 The AIX ABI for the RS/6000 specifies that all structures are
7627 returned in memory. The Darwin ABI does the same.
7629 For the Darwin 64 Bit ABI, a function result can be returned in
7630 registers or in memory, depending on the size of the return data
7631 type. If it is returned in registers, the value occupies the same
7632 registers as it would if it were the first and only function
7633 argument. Otherwise, the function places its result in memory at
7634 the location pointed to by GPR3.
7636 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7637 but a draft put them in memory, and GCC used to implement the draft
7638 instead of the final standard. Therefore, aix_struct_return
7639 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7640 compatibility can change DRAFT_V4_STRUCT_RET to override the
7641 default, and -m switches get the final word. See
7642 rs6000_option_override_internal for more details.
7644 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7645 long double support is enabled. These values are returned in memory.
7647 int_size_in_bytes returns -1 for variable size objects, which go in
7648 memory always. The cast to unsigned makes -1 > 8. */
7651 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7653 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7655 && rs6000_darwin64_abi
7656 && TREE_CODE (type) == RECORD_TYPE
7657 && int_size_in_bytes (type) > 0)
7659 CUMULATIVE_ARGS valcum;
7663 valcum.fregno = FP_ARG_MIN_REG;
7664 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7665 /* Do a trial code generation as if this were going to be passed
7666 as an argument; if any part goes in memory, we return NULL. */
7667 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7670 /* Otherwise fall through to more conventional ABI rules. */
7673 if (AGGREGATE_TYPE_P (type)
7674 && (aix_struct_return
7675 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7678 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7679 modes only exist for GCC vector types if -maltivec. */
7680 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7681 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7684 /* Return synthetic vectors in memory. */
7685 if (TREE_CODE (type) == VECTOR_TYPE
7686 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7688 static bool warned_for_return_big_vectors = false;
7689 if (!warned_for_return_big_vectors)
7691 warning (0, "GCC vector returned by reference: "
7692 "non-standard ABI extension with no compatibility guarantee");
7693 warned_for_return_big_vectors = true;
7698 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7704 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7705 for a call to a function whose data type is FNTYPE.
7706 For a library call, FNTYPE is 0.
7708 For incoming args we set the number of arguments in the prototype large
7709 so we never return a PARALLEL. */
7712 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7713 rtx libname ATTRIBUTE_UNUSED, int incoming,
7714 int libcall, int n_named_args)
7716 static CUMULATIVE_ARGS zero_cumulative;
7718 *cum = zero_cumulative;
7720 cum->fregno = FP_ARG_MIN_REG;
7721 cum->vregno = ALTIVEC_ARG_MIN_REG;
7722 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7723 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7724 ? CALL_LIBCALL : CALL_NORMAL);
7725 cum->sysv_gregno = GP_ARG_MIN_REG;
7726 cum->stdarg = stdarg_p (fntype);
7728 cum->nargs_prototype = 0;
7729 if (incoming || cum->prototype)
7730 cum->nargs_prototype = n_named_args;
7732 /* Check for a longcall attribute. */
7733 if ((!fntype && rs6000_default_long_calls)
7735 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7736 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7737 cum->call_cookie |= CALL_LONG;
7739 if (TARGET_DEBUG_ARG)
7741 fprintf (stderr, "\ninit_cumulative_args:");
7744 tree ret_type = TREE_TYPE (fntype);
7745 fprintf (stderr, " ret code = %s,",
7746 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7749 if (cum->call_cookie & CALL_LONG)
7750 fprintf (stderr, " longcall,");
7752 fprintf (stderr, " proto = %d, nargs = %d\n",
7753 cum->prototype, cum->nargs_prototype);
7758 && TARGET_ALTIVEC_ABI
7759 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7761 error ("cannot return value in vector register because"
7762 " altivec instructions are disabled, use -maltivec"
7767 /* Return true if TYPE must be passed on the stack and not in registers. */
7770 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7772 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7773 return must_pass_in_stack_var_size (mode, type);
7775 return must_pass_in_stack_var_size_or_pad (mode, type);
7778 /* If defined, a C expression which determines whether, and in which
7779 direction, to pad out an argument with extra space. The value
7780 should be of type `enum direction': either `upward' to pad above
7781 the argument, `downward' to pad below, or `none' to inhibit
7784 For the AIX ABI structs are always stored left shifted in their
7788 function_arg_padding (enum machine_mode mode, const_tree type)
7790 #ifndef AGGREGATE_PADDING_FIXED
7791 #define AGGREGATE_PADDING_FIXED 0
7793 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7794 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7797 if (!AGGREGATE_PADDING_FIXED)
7799 /* GCC used to pass structures of the same size as integer types as
7800 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7801 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7802 passed padded downward, except that -mstrict-align further
7803 muddied the water in that multi-component structures of 2 and 4
7804 bytes in size were passed padded upward.
7806 The following arranges for best compatibility with previous
7807 versions of gcc, but removes the -mstrict-align dependency. */
7808 if (BYTES_BIG_ENDIAN)
7810 HOST_WIDE_INT size = 0;
7812 if (mode == BLKmode)
7814 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7815 size = int_size_in_bytes (type);
7818 size = GET_MODE_SIZE (mode);
7820 if (size == 1 || size == 2 || size == 4)
7826 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7828 if (type != 0 && AGGREGATE_TYPE_P (type))
7832 /* Fall back to the default. */
7833 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7836 /* If defined, a C expression that gives the alignment boundary, in bits,
7837 of an argument with the specified mode and type. If it is not defined,
7838 PARM_BOUNDARY is used for all arguments.
7840 V.4 wants long longs and doubles to be double word aligned. Just
7841 testing the mode size is a boneheaded way to do this as it means
7842 that other types such as complex int are also double word aligned.
7843 However, we're stuck with this because changing the ABI might break
7844 existing library interfaces.
7846 Doubleword align SPE vectors.
7847 Quadword align Altivec vectors.
7848 Quadword align large synthetic vector types. */
7851 function_arg_boundary (enum machine_mode mode, const_tree type)
7853 if (DEFAULT_ABI == ABI_V4
7854 && (GET_MODE_SIZE (mode) == 8
7855 || (TARGET_HARD_FLOAT
7857 && (mode == TFmode || mode == TDmode))))
7859 else if (SPE_VECTOR_MODE (mode)
7860 || (type && TREE_CODE (type) == VECTOR_TYPE
7861 && int_size_in_bytes (type) >= 8
7862 && int_size_in_bytes (type) < 16))
7864 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7865 || (type && TREE_CODE (type) == VECTOR_TYPE
7866 && int_size_in_bytes (type) >= 16))
7868 else if (TARGET_MACHO
7869 && rs6000_darwin64_abi
7871 && type && TYPE_ALIGN (type) > 64)
7874 return PARM_BOUNDARY;
7877 /* For a function parm of MODE and TYPE, return the starting word in
7878 the parameter area. NWORDS of the parameter area are already used. */
7881 rs6000_parm_start (enum machine_mode mode, const_tree type,
7882 unsigned int nwords)
7885 unsigned int parm_offset;
7887 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7888 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7889 return nwords + (-(parm_offset + nwords) & align);
7892 /* Compute the size (in words) of a function argument. */
7894 static unsigned long
7895 rs6000_arg_size (enum machine_mode mode, const_tree type)
7899 if (mode != BLKmode)
7900 size = GET_MODE_SIZE (mode);
7902 size = int_size_in_bytes (type);
7905 return (size + 3) >> 2;
7907 return (size + 7) >> 3;
7910 /* Use this to flush pending int fields. */
7913 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7914 HOST_WIDE_INT bitpos, int final)
7916 unsigned int startbit, endbit;
7917 int intregs, intoffset;
7918 enum machine_mode mode;
7920 /* Handle the situations where a float is taking up the first half
7921 of the GPR, and the other half is empty (typically due to
7922 alignment restrictions). We can detect this by a 8-byte-aligned
7923 int field, or by seeing that this is the final flush for this
7924 argument. Count the word and continue on. */
7925 if (cum->floats_in_gpr == 1
7926 && (cum->intoffset % 64 == 0
7927 || (cum->intoffset == -1 && final)))
7930 cum->floats_in_gpr = 0;
7933 if (cum->intoffset == -1)
7936 intoffset = cum->intoffset;
7937 cum->intoffset = -1;
7938 cum->floats_in_gpr = 0;
7940 if (intoffset % BITS_PER_WORD != 0)
7942 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7944 if (mode == BLKmode)
7946 /* We couldn't find an appropriate mode, which happens,
7947 e.g., in packed structs when there are 3 bytes to load.
7948 Back intoffset back to the beginning of the word in this
7950 intoffset = intoffset & -BITS_PER_WORD;
7954 startbit = intoffset & -BITS_PER_WORD;
7955 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7956 intregs = (endbit - startbit) / BITS_PER_WORD;
7957 cum->words += intregs;
7958 /* words should be unsigned. */
7959 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7961 int pad = (endbit/BITS_PER_WORD) - cum->words;
7966 /* The darwin64 ABI calls for us to recurse down through structs,
7967 looking for elements passed in registers. Unfortunately, we have
7968 to track int register count here also because of misalignments
7969 in powerpc alignment mode. */
7972 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7974 HOST_WIDE_INT startbitpos)
7978 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7979 if (TREE_CODE (f) == FIELD_DECL)
7981 HOST_WIDE_INT bitpos = startbitpos;
7982 tree ftype = TREE_TYPE (f);
7983 enum machine_mode mode;
7984 if (ftype == error_mark_node)
7986 mode = TYPE_MODE (ftype);
7988 if (DECL_SIZE (f) != 0
7989 && host_integerp (bit_position (f), 1))
7990 bitpos += int_bit_position (f);
7992 /* ??? FIXME: else assume zero offset. */
7994 if (TREE_CODE (ftype) == RECORD_TYPE)
7995 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7996 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
7998 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
7999 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8000 /* Single-precision floats present a special problem for
8001 us, because they are smaller than an 8-byte GPR, and so
8002 the structure-packing rules combined with the standard
8003 varargs behavior mean that we want to pack float/float
8004 and float/int combinations into a single register's
8005 space. This is complicated by the arg advance flushing,
8006 which works on arbitrarily large groups of int-type
8010 if (cum->floats_in_gpr == 1)
8012 /* Two floats in a word; count the word and reset
8015 cum->floats_in_gpr = 0;
8017 else if (bitpos % 64 == 0)
8019 /* A float at the beginning of an 8-byte word;
8020 count it and put off adjusting cum->words until
8021 we see if a arg advance flush is going to do it
8023 cum->floats_in_gpr++;
8027 /* The float is at the end of a word, preceded
8028 by integer fields, so the arg advance flush
8029 just above has already set cum->words and
8030 everything is taken care of. */
8034 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
8036 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8038 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8042 else if (cum->intoffset == -1)
8043 cum->intoffset = bitpos;
8047 /* Check for an item that needs to be considered specially under the darwin 64
8048 bit ABI. These are record types where the mode is BLK or the structure is
8051 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8053 return rs6000_darwin64_abi
8054 && ((mode == BLKmode
8055 && TREE_CODE (type) == RECORD_TYPE
8056 && int_size_in_bytes (type) > 0)
8057 || (type && TREE_CODE (type) == RECORD_TYPE
8058 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8061 /* Update the data in CUM to advance over an argument
8062 of mode MODE and data type TYPE.
8063 (TYPE is null for libcalls where that information may not be available.)
8065 Note that for args passed by reference, function_arg will be called
8066 with MODE and TYPE set to that of the pointer to the arg, not the arg
8070 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8071 const_tree type, bool named, int depth)
8074 /* Only tick off an argument if we're not recursing. */
8076 cum->nargs_prototype--;
8078 if (TARGET_ALTIVEC_ABI
8079 && (ALTIVEC_VECTOR_MODE (mode)
8080 || VSX_VECTOR_MODE (mode)
8081 || (type && TREE_CODE (type) == VECTOR_TYPE
8082 && int_size_in_bytes (type) == 16)))
8086 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8089 if (!TARGET_ALTIVEC)
8090 error ("cannot pass argument in vector register because"
8091 " altivec instructions are disabled, use -maltivec"
8094 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8095 even if it is going to be passed in a vector register.
8096 Darwin does the same for variable-argument functions. */
8097 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8098 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8108 /* Vector parameters must be 16-byte aligned. This places
8109 them at 2 mod 4 in terms of words in 32-bit mode, since
8110 the parameter save area starts at offset 24 from the
8111 stack. In 64-bit mode, they just have to start on an
8112 even word, since the parameter save area is 16-byte
8113 aligned. Space for GPRs is reserved even if the argument
8114 will be passed in memory. */
8116 align = (2 - cum->words) & 3;
8118 align = cum->words & 1;
8119 cum->words += align + rs6000_arg_size (mode, type);
8121 if (TARGET_DEBUG_ARG)
8123 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8125 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8126 cum->nargs_prototype, cum->prototype,
8127 GET_MODE_NAME (mode));
8131 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8133 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8136 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8138 int size = int_size_in_bytes (type);
8139 /* Variable sized types have size == -1 and are
8140 treated as if consisting entirely of ints.
8141 Pad to 16 byte boundary if needed. */
8142 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8143 && (cum->words % 2) != 0)
8145 /* For varargs, we can just go up by the size of the struct. */
8147 cum->words += (size + 7) / 8;
8150 /* It is tempting to say int register count just goes up by
8151 sizeof(type)/8, but this is wrong in a case such as
8152 { int; double; int; } [powerpc alignment]. We have to
8153 grovel through the fields for these too. */
8155 cum->floats_in_gpr = 0;
8156 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8157 rs6000_darwin64_record_arg_advance_flush (cum,
8158 size * BITS_PER_UNIT, 1);
8160 if (TARGET_DEBUG_ARG)
8162 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8163 cum->words, TYPE_ALIGN (type), size);
8165 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8166 cum->nargs_prototype, cum->prototype,
8167 GET_MODE_NAME (mode));
8170 else if (DEFAULT_ABI == ABI_V4)
8172 if (TARGET_HARD_FLOAT && TARGET_FPRS
8173 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8174 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8175 || (mode == TFmode && !TARGET_IEEEQUAD)
8176 || mode == SDmode || mode == DDmode || mode == TDmode))
8178 /* _Decimal128 must use an even/odd register pair. This assumes
8179 that the register number is odd when fregno is odd. */
8180 if (mode == TDmode && (cum->fregno % 2) == 1)
8183 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8184 <= FP_ARG_V4_MAX_REG)
8185 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8188 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8189 if (mode == DFmode || mode == TFmode
8190 || mode == DDmode || mode == TDmode)
8191 cum->words += cum->words & 1;
8192 cum->words += rs6000_arg_size (mode, type);
8197 int n_words = rs6000_arg_size (mode, type);
8198 int gregno = cum->sysv_gregno;
8200 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8201 (r7,r8) or (r9,r10). As does any other 2 word item such
8202 as complex int due to a historical mistake. */
8204 gregno += (1 - gregno) & 1;
8206 /* Multi-reg args are not split between registers and stack. */
8207 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8209 /* Long long and SPE vectors are aligned on the stack.
8210 So are other 2 word items such as complex int due to
8211 a historical mistake. */
8213 cum->words += cum->words & 1;
8214 cum->words += n_words;
8217 /* Note: continuing to accumulate gregno past when we've started
8218 spilling to the stack indicates the fact that we've started
8219 spilling to the stack to expand_builtin_saveregs. */
8220 cum->sysv_gregno = gregno + n_words;
8223 if (TARGET_DEBUG_ARG)
8225 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8226 cum->words, cum->fregno);
8227 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8228 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8229 fprintf (stderr, "mode = %4s, named = %d\n",
8230 GET_MODE_NAME (mode), named);
8235 int n_words = rs6000_arg_size (mode, type);
8236 int start_words = cum->words;
8237 int align_words = rs6000_parm_start (mode, type, start_words);
8239 cum->words = align_words + n_words;
8241 if (SCALAR_FLOAT_MODE_P (mode)
8242 && TARGET_HARD_FLOAT && TARGET_FPRS)
8244 /* _Decimal128 must be passed in an even/odd float register pair.
8245 This assumes that the register number is odd when fregno is
8247 if (mode == TDmode && (cum->fregno % 2) == 1)
8249 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8252 if (TARGET_DEBUG_ARG)
8254 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8255 cum->words, cum->fregno);
8256 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8257 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8258 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8259 named, align_words - start_words, depth);
8265 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8266 const_tree type, bool named)
8268 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8272 spe_build_register_parallel (enum machine_mode mode, int gregno)
8279 r1 = gen_rtx_REG (DImode, gregno);
8280 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8281 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8285 r1 = gen_rtx_REG (DImode, gregno);
8286 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8287 r3 = gen_rtx_REG (DImode, gregno + 2);
8288 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8289 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8292 r1 = gen_rtx_REG (DImode, gregno);
8293 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8294 r3 = gen_rtx_REG (DImode, gregno + 2);
8295 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8296 r5 = gen_rtx_REG (DImode, gregno + 4);
8297 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8298 r7 = gen_rtx_REG (DImode, gregno + 6);
8299 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8300 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8307 /* Determine where to put a SIMD argument on the SPE. */
8309 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8312 int gregno = cum->sysv_gregno;
8314 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8315 are passed and returned in a pair of GPRs for ABI compatibility. */
8316 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8317 || mode == DCmode || mode == TCmode))
8319 int n_words = rs6000_arg_size (mode, type);
8321 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8323 gregno += (1 - gregno) & 1;
8325 /* Multi-reg args are not split between registers and stack. */
8326 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8329 return spe_build_register_parallel (mode, gregno);
8333 int n_words = rs6000_arg_size (mode, type);
8335 /* SPE vectors are put in odd registers. */
8336 if (n_words == 2 && (gregno & 1) == 0)
8339 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8342 enum machine_mode m = SImode;
8344 r1 = gen_rtx_REG (m, gregno);
8345 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8346 r2 = gen_rtx_REG (m, gregno + 1);
8347 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8348 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8355 if (gregno <= GP_ARG_MAX_REG)
8356 return gen_rtx_REG (mode, gregno);
8362 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8363 structure between cum->intoffset and bitpos to integer registers. */
8366 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8367 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8369 enum machine_mode mode;
8371 unsigned int startbit, endbit;
8372 int this_regno, intregs, intoffset;
8375 if (cum->intoffset == -1)
8378 intoffset = cum->intoffset;
8379 cum->intoffset = -1;
8381 /* If this is the trailing part of a word, try to only load that
8382 much into the register. Otherwise load the whole register. Note
8383 that in the latter case we may pick up unwanted bits. It's not a
8384 problem at the moment but may wish to revisit. */
8386 if (intoffset % BITS_PER_WORD != 0)
8388 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8390 if (mode == BLKmode)
8392 /* We couldn't find an appropriate mode, which happens,
8393 e.g., in packed structs when there are 3 bytes to load.
8394 Back intoffset back to the beginning of the word in this
8396 intoffset = intoffset & -BITS_PER_WORD;
8403 startbit = intoffset & -BITS_PER_WORD;
8404 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8405 intregs = (endbit - startbit) / BITS_PER_WORD;
8406 this_regno = cum->words + intoffset / BITS_PER_WORD;
8408 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8411 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8415 intoffset /= BITS_PER_UNIT;
8418 regno = GP_ARG_MIN_REG + this_regno;
8419 reg = gen_rtx_REG (mode, regno);
8421 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8424 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8428 while (intregs > 0);
8431 /* Recursive workhorse for the following. */
8434 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8435 HOST_WIDE_INT startbitpos, rtx rvec[],
8440 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8441 if (TREE_CODE (f) == FIELD_DECL)
8443 HOST_WIDE_INT bitpos = startbitpos;
8444 tree ftype = TREE_TYPE (f);
8445 enum machine_mode mode;
8446 if (ftype == error_mark_node)
8448 mode = TYPE_MODE (ftype);
8450 if (DECL_SIZE (f) != 0
8451 && host_integerp (bit_position (f), 1))
8452 bitpos += int_bit_position (f);
8454 /* ??? FIXME: else assume zero offset. */
8456 if (TREE_CODE (ftype) == RECORD_TYPE)
8457 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8458 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8463 case SCmode: mode = SFmode; break;
8464 case DCmode: mode = DFmode; break;
8465 case TCmode: mode = TFmode; break;
8469 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8471 = gen_rtx_EXPR_LIST (VOIDmode,
8472 gen_rtx_REG (mode, cum->fregno++),
8473 GEN_INT (bitpos / BITS_PER_UNIT));
8474 if (mode == TFmode || mode == TDmode)
8477 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8479 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8481 = gen_rtx_EXPR_LIST (VOIDmode,
8482 gen_rtx_REG (mode, cum->vregno++),
8483 GEN_INT (bitpos / BITS_PER_UNIT));
8485 else if (cum->intoffset == -1)
8486 cum->intoffset = bitpos;
8490 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8491 the register(s) to be used for each field and subfield of a struct
8492 being passed by value, along with the offset of where the
8493 register's value may be found in the block. FP fields go in FP
8494 register, vector fields go in vector registers, and everything
8495 else goes in int registers, packed as in memory.
8497 This code is also used for function return values. RETVAL indicates
8498 whether this is the case.
8500 Much of this is taken from the SPARC V9 port, which has a similar
8501 calling convention. */
8504 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8505 bool named, bool retval)
8507 rtx rvec[FIRST_PSEUDO_REGISTER];
8508 int k = 1, kbase = 1;
8509 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8510 /* This is a copy; modifications are not visible to our caller. */
8511 CUMULATIVE_ARGS copy_cum = *orig_cum;
8512 CUMULATIVE_ARGS *cum = ©_cum;
8514 /* Pad to 16 byte boundary if needed. */
8515 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8516 && (cum->words % 2) != 0)
8523 /* Put entries into rvec[] for individual FP and vector fields, and
8524 for the chunks of memory that go in int regs. Note we start at
8525 element 1; 0 is reserved for an indication of using memory, and
8526 may or may not be filled in below. */
8527 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8528 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8530 /* If any part of the struct went on the stack put all of it there.
8531 This hack is because the generic code for
8532 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8533 parts of the struct are not at the beginning. */
8537 return NULL_RTX; /* doesn't go in registers at all */
8539 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8541 if (k > 1 || cum->use_stack)
8542 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8547 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8550 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8555 rtx rvec[GP_ARG_NUM_REG + 1];
8557 if (align_words >= GP_ARG_NUM_REG)
8560 n_units = rs6000_arg_size (mode, type);
8562 /* Optimize the simple case where the arg fits in one gpr, except in
8563 the case of BLKmode due to assign_parms assuming that registers are
8564 BITS_PER_WORD wide. */
8566 || (n_units == 1 && mode != BLKmode))
8567 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8570 if (align_words + n_units > GP_ARG_NUM_REG)
8571 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8572 using a magic NULL_RTX component.
8573 This is not strictly correct. Only some of the arg belongs in
8574 memory, not all of it. However, the normal scheme using
8575 function_arg_partial_nregs can result in unusual subregs, eg.
8576 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8577 store the whole arg to memory is often more efficient than code
8578 to store pieces, and we know that space is available in the right
8579 place for the whole arg. */
8580 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8585 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8586 rtx off = GEN_INT (i++ * 4);
8587 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8589 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8591 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8594 /* Determine where to put an argument to a function.
8595 Value is zero to push the argument on the stack,
8596 or a hard register in which to store the argument.
8598 MODE is the argument's machine mode.
8599 TYPE is the data type of the argument (as a tree).
8600 This is null for libcalls where that information may
8602 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8603 the preceding args and about the function being called. It is
8604 not modified in this routine.
8605 NAMED is nonzero if this argument is a named parameter
8606 (otherwise it is an extra parameter matching an ellipsis).
8608 On RS/6000 the first eight words of non-FP are normally in registers
8609 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8610 Under V.4, the first 8 FP args are in registers.
8612 If this is floating-point and no prototype is specified, we use
8613 both an FP and integer register (or possibly FP reg and stack). Library
8614 functions (when CALL_LIBCALL is set) always have the proper types for args,
8615 so we can pass the FP value just in one register. emit_library_function
8616 doesn't support PARALLEL anyway.
8618 Note that for args passed by reference, function_arg will be called
8619 with MODE and TYPE set to that of the pointer to the arg, not the arg
8623 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8624 const_tree type, bool named)
8626 enum rs6000_abi abi = DEFAULT_ABI;
8628 /* Return a marker to indicate whether CR1 needs to set or clear the
8629 bit that V.4 uses to say fp args were passed in registers.
8630 Assume that we don't need the marker for software floating point,
8631 or compiler generated library calls. */
8632 if (mode == VOIDmode)
8635 && (cum->call_cookie & CALL_LIBCALL) == 0
8637 || (cum->nargs_prototype < 0
8638 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8640 /* For the SPE, we need to crxor CR6 always. */
8642 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8643 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8644 return GEN_INT (cum->call_cookie
8645 | ((cum->fregno == FP_ARG_MIN_REG)
8646 ? CALL_V4_SET_FP_ARGS
8647 : CALL_V4_CLEAR_FP_ARGS));
8650 return GEN_INT (cum->call_cookie);
8653 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8655 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8656 if (rslt != NULL_RTX)
8658 /* Else fall through to usual handling. */
8661 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8662 if (TARGET_64BIT && ! cum->prototype)
8664 /* Vector parameters get passed in vector register
8665 and also in GPRs or memory, in absence of prototype. */
8668 align_words = (cum->words + 1) & ~1;
8670 if (align_words >= GP_ARG_NUM_REG)
8676 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8678 return gen_rtx_PARALLEL (mode,
8680 gen_rtx_EXPR_LIST (VOIDmode,
8682 gen_rtx_EXPR_LIST (VOIDmode,
8683 gen_rtx_REG (mode, cum->vregno),
8687 return gen_rtx_REG (mode, cum->vregno);
8688 else if (TARGET_ALTIVEC_ABI
8689 && (ALTIVEC_VECTOR_MODE (mode)
8690 || VSX_VECTOR_MODE (mode)
8691 || (type && TREE_CODE (type) == VECTOR_TYPE
8692 && int_size_in_bytes (type) == 16)))
8694 if (named || abi == ABI_V4)
8698 /* Vector parameters to varargs functions under AIX or Darwin
8699 get passed in memory and possibly also in GPRs. */
8700 int align, align_words, n_words;
8701 enum machine_mode part_mode;
8703 /* Vector parameters must be 16-byte aligned. This places them at
8704 2 mod 4 in terms of words in 32-bit mode, since the parameter
8705 save area starts at offset 24 from the stack. In 64-bit mode,
8706 they just have to start on an even word, since the parameter
8707 save area is 16-byte aligned. */
8709 align = (2 - cum->words) & 3;
8711 align = cum->words & 1;
8712 align_words = cum->words + align;
8714 /* Out of registers? Memory, then. */
8715 if (align_words >= GP_ARG_NUM_REG)
8718 if (TARGET_32BIT && TARGET_POWERPC64)
8719 return rs6000_mixed_function_arg (mode, type, align_words);
8721 /* The vector value goes in GPRs. Only the part of the
8722 value in GPRs is reported here. */
8724 n_words = rs6000_arg_size (mode, type);
8725 if (align_words + n_words > GP_ARG_NUM_REG)
8726 /* Fortunately, there are only two possibilities, the value
8727 is either wholly in GPRs or half in GPRs and half not. */
8730 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8733 else if (TARGET_SPE_ABI && TARGET_SPE
8734 && (SPE_VECTOR_MODE (mode)
8735 || (TARGET_E500_DOUBLE && (mode == DFmode
8738 || mode == TCmode))))
8739 return rs6000_spe_function_arg (cum, mode, type);
8741 else if (abi == ABI_V4)
8743 if (TARGET_HARD_FLOAT && TARGET_FPRS
8744 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8745 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8746 || (mode == TFmode && !TARGET_IEEEQUAD)
8747 || mode == SDmode || mode == DDmode || mode == TDmode))
8749 /* _Decimal128 must use an even/odd register pair. This assumes
8750 that the register number is odd when fregno is odd. */
8751 if (mode == TDmode && (cum->fregno % 2) == 1)
8754 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8755 <= FP_ARG_V4_MAX_REG)
8756 return gen_rtx_REG (mode, cum->fregno);
8762 int n_words = rs6000_arg_size (mode, type);
8763 int gregno = cum->sysv_gregno;
8765 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8766 (r7,r8) or (r9,r10). As does any other 2 word item such
8767 as complex int due to a historical mistake. */
8769 gregno += (1 - gregno) & 1;
8771 /* Multi-reg args are not split between registers and stack. */
8772 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8775 if (TARGET_32BIT && TARGET_POWERPC64)
8776 return rs6000_mixed_function_arg (mode, type,
8777 gregno - GP_ARG_MIN_REG);
8778 return gen_rtx_REG (mode, gregno);
8783 int align_words = rs6000_parm_start (mode, type, cum->words);
8785 /* _Decimal128 must be passed in an even/odd float register pair.
8786 This assumes that the register number is odd when fregno is odd. */
8787 if (mode == TDmode && (cum->fregno % 2) == 1)
8790 if (USE_FP_FOR_ARG_P (cum, mode, type))
8792 rtx rvec[GP_ARG_NUM_REG + 1];
8796 enum machine_mode fmode = mode;
8797 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8799 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8801 /* Currently, we only ever need one reg here because complex
8802 doubles are split. */
8803 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8804 && (fmode == TFmode || fmode == TDmode));
8806 /* Long double or _Decimal128 split over regs and memory. */
8807 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8810 /* Do we also need to pass this arg in the parameter save
8813 && (cum->nargs_prototype <= 0
8814 || (DEFAULT_ABI == ABI_AIX
8816 && align_words >= GP_ARG_NUM_REG)));
8818 if (!needs_psave && mode == fmode)
8819 return gen_rtx_REG (fmode, cum->fregno);
8824 /* Describe the part that goes in gprs or the stack.
8825 This piece must come first, before the fprs. */
8826 if (align_words < GP_ARG_NUM_REG)
8828 unsigned long n_words = rs6000_arg_size (mode, type);
8830 if (align_words + n_words > GP_ARG_NUM_REG
8831 || (TARGET_32BIT && TARGET_POWERPC64))
8833 /* If this is partially on the stack, then we only
8834 include the portion actually in registers here. */
8835 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8838 if (align_words + n_words > GP_ARG_NUM_REG)
8839 /* Not all of the arg fits in gprs. Say that it
8840 goes in memory too, using a magic NULL_RTX
8841 component. Also see comment in
8842 rs6000_mixed_function_arg for why the normal
8843 function_arg_partial_nregs scheme doesn't work
8845 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8849 r = gen_rtx_REG (rmode,
8850 GP_ARG_MIN_REG + align_words);
8851 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8852 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8854 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8858 /* The whole arg fits in gprs. */
8859 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8860 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8864 /* It's entirely in memory. */
8865 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8868 /* Describe where this piece goes in the fprs. */
8869 r = gen_rtx_REG (fmode, cum->fregno);
8870 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8872 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8874 else if (align_words < GP_ARG_NUM_REG)
8876 if (TARGET_32BIT && TARGET_POWERPC64)
8877 return rs6000_mixed_function_arg (mode, type, align_words);
8879 if (mode == BLKmode)
8882 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8889 /* For an arg passed partly in registers and partly in memory, this is
8890 the number of bytes passed in registers. For args passed entirely in
8891 registers or entirely in memory, zero. When an arg is described by a
8892 PARALLEL, perhaps using more than one register type, this function
8893 returns the number of bytes used by the first element of the PARALLEL. */
8896 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8897 tree type, bool named)
8902 if (DEFAULT_ABI == ABI_V4)
8905 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8906 && cum->nargs_prototype >= 0)
8909 /* In this complicated case we just disable the partial_nregs code. */
8910 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8913 align_words = rs6000_parm_start (mode, type, cum->words);
8915 if (USE_FP_FOR_ARG_P (cum, mode, type))
8917 /* If we are passing this arg in the fixed parameter save area
8918 (gprs or memory) as well as fprs, then this function should
8919 return the number of partial bytes passed in the parameter
8920 save area rather than partial bytes passed in fprs. */
8922 && (cum->nargs_prototype <= 0
8923 || (DEFAULT_ABI == ABI_AIX
8925 && align_words >= GP_ARG_NUM_REG)))
8927 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8928 > FP_ARG_MAX_REG + 1)
8929 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8930 else if (cum->nargs_prototype >= 0)
8934 if (align_words < GP_ARG_NUM_REG
8935 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8936 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8938 if (ret != 0 && TARGET_DEBUG_ARG)
8939 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8944 /* A C expression that indicates when an argument must be passed by
8945 reference. If nonzero for an argument, a copy of that argument is
8946 made in memory and a pointer to the argument is passed instead of
8947 the argument itself. The pointer is passed in whatever way is
8948 appropriate for passing a pointer to that type.
8950 Under V.4, aggregates and long double are passed by reference.
8952 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8953 reference unless the AltiVec vector extension ABI is in force.
8955 As an extension to all ABIs, variable sized types are passed by
8959 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8960 enum machine_mode mode, const_tree type,
8961 bool named ATTRIBUTE_UNUSED)
8963 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8965 if (TARGET_DEBUG_ARG)
8966 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8973 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8975 if (TARGET_DEBUG_ARG)
8976 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8980 if (int_size_in_bytes (type) < 0)
8982 if (TARGET_DEBUG_ARG)
8983 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8987 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8988 modes only exist for GCC vector types if -maltivec. */
8989 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8991 if (TARGET_DEBUG_ARG)
8992 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8996 /* Pass synthetic vectors in memory. */
8997 if (TREE_CODE (type) == VECTOR_TYPE
8998 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9000 static bool warned_for_pass_big_vectors = false;
9001 if (TARGET_DEBUG_ARG)
9002 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9003 if (!warned_for_pass_big_vectors)
9005 warning (0, "GCC vector passed by reference: "
9006 "non-standard ABI extension with no compatibility guarantee");
9007 warned_for_pass_big_vectors = true;
9016 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9019 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9024 for (i = 0; i < nregs; i++)
9026 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9027 if (reload_completed)
9029 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9032 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9033 i * GET_MODE_SIZE (reg_mode));
9036 tem = replace_equiv_address (tem, XEXP (tem, 0));
9040 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9044 /* Perform any needed actions needed for a function that is receiving a
9045 variable number of arguments.
9049 MODE and TYPE are the mode and type of the current parameter.
9051 PRETEND_SIZE is a variable that should be set to the amount of stack
9052 that must be pushed by the prolog to pretend that our caller pushed
9055 Normally, this macro will push all remaining incoming registers on the
9056 stack and set PRETEND_SIZE to the length of the registers pushed. */
9059 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9060 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9063 CUMULATIVE_ARGS next_cum;
9064 int reg_size = TARGET_32BIT ? 4 : 8;
9065 rtx save_area = NULL_RTX, mem;
9066 int first_reg_offset;
9069 /* Skip the last named argument. */
9071 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9073 if (DEFAULT_ABI == ABI_V4)
9075 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9079 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9080 HOST_WIDE_INT offset = 0;
9082 /* Try to optimize the size of the varargs save area.
9083 The ABI requires that ap.reg_save_area is doubleword
9084 aligned, but we don't need to allocate space for all
9085 the bytes, only those to which we actually will save
9087 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9088 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9089 if (TARGET_HARD_FLOAT && TARGET_FPRS
9090 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9091 && cfun->va_list_fpr_size)
9094 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9095 * UNITS_PER_FP_WORD;
9096 if (cfun->va_list_fpr_size
9097 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9098 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9100 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9101 * UNITS_PER_FP_WORD;
9105 offset = -((first_reg_offset * reg_size) & ~7);
9106 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9108 gpr_reg_num = cfun->va_list_gpr_size;
9109 if (reg_size == 4 && (first_reg_offset & 1))
9112 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9115 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9117 - (int) (GP_ARG_NUM_REG * reg_size);
9119 if (gpr_size + fpr_size)
9122 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9123 gcc_assert (GET_CODE (reg_save_area) == MEM);
9124 reg_save_area = XEXP (reg_save_area, 0);
9125 if (GET_CODE (reg_save_area) == PLUS)
9127 gcc_assert (XEXP (reg_save_area, 0)
9128 == virtual_stack_vars_rtx);
9129 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9130 offset += INTVAL (XEXP (reg_save_area, 1));
9133 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9136 cfun->machine->varargs_save_offset = offset;
9137 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9142 first_reg_offset = next_cum.words;
9143 save_area = virtual_incoming_args_rtx;
9145 if (targetm.calls.must_pass_in_stack (mode, type))
9146 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9149 set = get_varargs_alias_set ();
9150 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9151 && cfun->va_list_gpr_size)
9153 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9155 if (va_list_gpr_counter_field)
9157 /* V4 va_list_gpr_size counts number of registers needed. */
9158 if (nregs > cfun->va_list_gpr_size)
9159 nregs = cfun->va_list_gpr_size;
9163 /* char * va_list instead counts number of bytes needed. */
9164 if (nregs > cfun->va_list_gpr_size / reg_size)
9165 nregs = cfun->va_list_gpr_size / reg_size;
9168 mem = gen_rtx_MEM (BLKmode,
9169 plus_constant (save_area,
9170 first_reg_offset * reg_size));
9171 MEM_NOTRAP_P (mem) = 1;
9172 set_mem_alias_set (mem, set);
9173 set_mem_align (mem, BITS_PER_WORD);
9175 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9179 /* Save FP registers if needed. */
9180 if (DEFAULT_ABI == ABI_V4
9181 && TARGET_HARD_FLOAT && TARGET_FPRS
9183 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9184 && cfun->va_list_fpr_size)
9186 int fregno = next_cum.fregno, nregs;
9187 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9188 rtx lab = gen_label_rtx ();
9189 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9190 * UNITS_PER_FP_WORD);
9193 (gen_rtx_SET (VOIDmode,
9195 gen_rtx_IF_THEN_ELSE (VOIDmode,
9196 gen_rtx_NE (VOIDmode, cr1,
9198 gen_rtx_LABEL_REF (VOIDmode, lab),
9202 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9203 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9205 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9207 plus_constant (save_area, off));
9208 MEM_NOTRAP_P (mem) = 1;
9209 set_mem_alias_set (mem, set);
9210 set_mem_align (mem, GET_MODE_ALIGNMENT (
9211 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9212 ? DFmode : SFmode));
9213 emit_move_insn (mem, gen_rtx_REG (
9214 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9215 ? DFmode : SFmode, fregno));
9222 /* Create the va_list data type. */
9225 rs6000_build_builtin_va_list (void)
9227 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9229 /* For AIX, prefer 'char *' because that's what the system
9230 header files like. */
9231 if (DEFAULT_ABI != ABI_V4)
9232 return build_pointer_type (char_type_node);
9234 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9235 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9236 get_identifier ("__va_list_tag"), record);
9238 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9239 unsigned_char_type_node);
9240 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9241 unsigned_char_type_node);
9242 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9244 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9245 get_identifier ("reserved"), short_unsigned_type_node);
9246 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9247 get_identifier ("overflow_arg_area"),
9249 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9250 get_identifier ("reg_save_area"),
9253 va_list_gpr_counter_field = f_gpr;
9254 va_list_fpr_counter_field = f_fpr;
9256 DECL_FIELD_CONTEXT (f_gpr) = record;
9257 DECL_FIELD_CONTEXT (f_fpr) = record;
9258 DECL_FIELD_CONTEXT (f_res) = record;
9259 DECL_FIELD_CONTEXT (f_ovf) = record;
9260 DECL_FIELD_CONTEXT (f_sav) = record;
9262 TYPE_STUB_DECL (record) = type_decl;
9263 TYPE_NAME (record) = type_decl;
9264 TYPE_FIELDS (record) = f_gpr;
9265 DECL_CHAIN (f_gpr) = f_fpr;
9266 DECL_CHAIN (f_fpr) = f_res;
9267 DECL_CHAIN (f_res) = f_ovf;
9268 DECL_CHAIN (f_ovf) = f_sav;
9270 layout_type (record);
9272 /* The correct type is an array type of one element. */
9273 return build_array_type (record, build_index_type (size_zero_node));
9276 /* Implement va_start. */
9279 rs6000_va_start (tree valist, rtx nextarg)
9281 HOST_WIDE_INT words, n_gpr, n_fpr;
9282 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9283 tree gpr, fpr, ovf, sav, t;
9285 /* Only SVR4 needs something special. */
9286 if (DEFAULT_ABI != ABI_V4)
9288 std_expand_builtin_va_start (valist, nextarg);
9292 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9293 f_fpr = DECL_CHAIN (f_gpr);
9294 f_res = DECL_CHAIN (f_fpr);
9295 f_ovf = DECL_CHAIN (f_res);
9296 f_sav = DECL_CHAIN (f_ovf);
9298 valist = build_simple_mem_ref (valist);
9299 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9300 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9302 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9304 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9307 /* Count number of gp and fp argument registers used. */
9308 words = crtl->args.info.words;
9309 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9311 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9314 if (TARGET_DEBUG_ARG)
9315 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9316 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9317 words, n_gpr, n_fpr);
9319 if (cfun->va_list_gpr_size)
9321 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9322 build_int_cst (NULL_TREE, n_gpr));
9323 TREE_SIDE_EFFECTS (t) = 1;
9324 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9327 if (cfun->va_list_fpr_size)
9329 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9330 build_int_cst (NULL_TREE, n_fpr));
9331 TREE_SIDE_EFFECTS (t) = 1;
9332 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9335 /* Find the overflow area. */
9336 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9338 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9339 size_int (words * UNITS_PER_WORD));
9340 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9341 TREE_SIDE_EFFECTS (t) = 1;
9342 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9344 /* If there were no va_arg invocations, don't set up the register
9346 if (!cfun->va_list_gpr_size
9347 && !cfun->va_list_fpr_size
9348 && n_gpr < GP_ARG_NUM_REG
9349 && n_fpr < FP_ARG_V4_MAX_REG)
9352 /* Find the register save area. */
9353 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9354 if (cfun->machine->varargs_save_offset)
9355 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9356 size_int (cfun->machine->varargs_save_offset));
9357 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9358 TREE_SIDE_EFFECTS (t) = 1;
9359 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9362 /* Implement va_arg. */
9365 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9368 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9369 tree gpr, fpr, ovf, sav, reg, t, u;
9370 int size, rsize, n_reg, sav_ofs, sav_scale;
9371 tree lab_false, lab_over, addr;
9373 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9377 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9379 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9380 return build_va_arg_indirect_ref (t);
9383 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9384 earlier version of gcc, with the property that it always applied alignment
9385 adjustments to the va-args (even for zero-sized types). The cheapest way
9386 to deal with this is to replicate the effect of the part of
9387 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9389 We don't need to check for pass-by-reference because of the test above.
9390 We can return a simplifed answer, since we know there's no offset to add. */
9393 && rs6000_darwin64_abi
9394 && integer_zerop (TYPE_SIZE (type)))
9396 unsigned HOST_WIDE_INT align, boundary;
9397 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9398 align = PARM_BOUNDARY / BITS_PER_UNIT;
9399 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9400 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9401 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9402 boundary /= BITS_PER_UNIT;
9403 if (boundary > align)
9406 /* This updates arg ptr by the amount that would be necessary
9407 to align the zero-sized (but not zero-alignment) item. */
9408 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9409 fold_build2 (POINTER_PLUS_EXPR,
9411 valist_tmp, size_int (boundary - 1)));
9412 gimplify_and_add (t, pre_p);
9414 t = fold_convert (sizetype, valist_tmp);
9415 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9416 fold_convert (TREE_TYPE (valist),
9417 fold_build2 (BIT_AND_EXPR, sizetype, t,
9418 size_int (-boundary))));
9419 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9420 gimplify_and_add (t, pre_p);
9422 /* Since it is zero-sized there's no increment for the item itself. */
9423 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9424 return build_va_arg_indirect_ref (valist_tmp);
9427 if (DEFAULT_ABI != ABI_V4)
9429 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9431 tree elem_type = TREE_TYPE (type);
9432 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9433 int elem_size = GET_MODE_SIZE (elem_mode);
9435 if (elem_size < UNITS_PER_WORD)
9437 tree real_part, imag_part;
9438 gimple_seq post = NULL;
9440 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9442 /* Copy the value into a temporary, lest the formal temporary
9443 be reused out from under us. */
9444 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9445 gimple_seq_add_seq (pre_p, post);
9447 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9450 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9454 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9457 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9458 f_fpr = DECL_CHAIN (f_gpr);
9459 f_res = DECL_CHAIN (f_fpr);
9460 f_ovf = DECL_CHAIN (f_res);
9461 f_sav = DECL_CHAIN (f_ovf);
9463 valist = build_va_arg_indirect_ref (valist);
9464 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9465 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9467 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9469 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9472 size = int_size_in_bytes (type);
9473 rsize = (size + 3) / 4;
9476 if (TARGET_HARD_FLOAT && TARGET_FPRS
9477 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9478 || (TARGET_DOUBLE_FLOAT
9479 && (TYPE_MODE (type) == DFmode
9480 || TYPE_MODE (type) == TFmode
9481 || TYPE_MODE (type) == SDmode
9482 || TYPE_MODE (type) == DDmode
9483 || TYPE_MODE (type) == TDmode))))
9485 /* FP args go in FP registers, if present. */
9487 n_reg = (size + 7) / 8;
9488 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9489 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9490 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9495 /* Otherwise into GP registers. */
9504 /* Pull the value out of the saved registers.... */
9507 addr = create_tmp_var (ptr_type_node, "addr");
9509 /* AltiVec vectors never go in registers when -mabi=altivec. */
9510 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9514 lab_false = create_artificial_label (input_location);
9515 lab_over = create_artificial_label (input_location);
9517 /* Long long and SPE vectors are aligned in the registers.
9518 As are any other 2 gpr item such as complex int due to a
9519 historical mistake. */
9521 if (n_reg == 2 && reg == gpr)
9524 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9525 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9526 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9527 unshare_expr (reg), u);
9529 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9530 reg number is 0 for f1, so we want to make it odd. */
9531 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9533 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9534 build_int_cst (TREE_TYPE (reg), 1));
9535 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9538 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9539 t = build2 (GE_EXPR, boolean_type_node, u, t);
9540 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9541 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9542 gimplify_and_add (t, pre_p);
9546 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9548 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9549 build_int_cst (TREE_TYPE (reg), n_reg));
9550 u = fold_convert (sizetype, u);
9551 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9552 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9554 /* _Decimal32 varargs are located in the second word of the 64-bit
9555 FP register for 32-bit binaries. */
9556 if (!TARGET_POWERPC64
9557 && TARGET_HARD_FLOAT && TARGET_FPRS
9558 && TYPE_MODE (type) == SDmode)
9559 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9561 gimplify_assign (addr, t, pre_p);
9563 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9565 stmt = gimple_build_label (lab_false);
9566 gimple_seq_add_stmt (pre_p, stmt);
9568 if ((n_reg == 2 && !regalign) || n_reg > 2)
9570 /* Ensure that we don't find any more args in regs.
9571 Alignment has taken care of for special cases. */
9572 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9576 /* ... otherwise out of the overflow area. */
9578 /* Care for on-stack alignment if needed. */
9582 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9583 t = fold_convert (sizetype, t);
9584 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9586 t = fold_convert (TREE_TYPE (ovf), t);
9588 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9590 gimplify_assign (unshare_expr (addr), t, pre_p);
9592 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9593 gimplify_assign (unshare_expr (ovf), t, pre_p);
9597 stmt = gimple_build_label (lab_over);
9598 gimple_seq_add_stmt (pre_p, stmt);
9601 if (STRICT_ALIGNMENT
9602 && (TYPE_ALIGN (type)
9603 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9605 /* The value (of type complex double, for example) may not be
9606 aligned in memory in the saved registers, so copy via a
9607 temporary. (This is the same code as used for SPARC.) */
9608 tree tmp = create_tmp_var (type, "va_arg_tmp");
9609 tree dest_addr = build_fold_addr_expr (tmp);
9611 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9612 3, dest_addr, addr, size_int (rsize * 4));
9614 gimplify_and_add (copy, pre_p);
9618 addr = fold_convert (ptrtype, addr);
9619 return build_va_arg_indirect_ref (addr);
9625 def_builtin (int mask, const char *name, tree type, int code)
9627 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9630 if (rs6000_builtin_decls[code])
9631 fatal_error ("internal error: builtin function to %s already processed.",
9634 rs6000_builtin_decls[code] = t =
9635 add_builtin_function (name, type, code, BUILT_IN_MD,
9638 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9639 switch (builtin_classify[code])
9644 /* assume builtin can do anything. */
9645 case RS6000_BTC_MISC:
9648 /* const function, function only depends on the inputs. */
9649 case RS6000_BTC_CONST:
9650 TREE_READONLY (t) = 1;
9651 TREE_NOTHROW (t) = 1;
9654 /* pure function, function can read global memory. */
9655 case RS6000_BTC_PURE:
9656 DECL_PURE_P (t) = 1;
9657 TREE_NOTHROW (t) = 1;
9660 /* Function is a math function. If rounding mode is on, then treat
9661 the function as not reading global memory, but it can have
9662 arbitrary side effects. If it is off, then assume the function is
9663 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9664 attribute in builtin-attribute.def that is used for the math
9666 case RS6000_BTC_FP_PURE:
9667 TREE_NOTHROW (t) = 1;
9668 if (flag_rounding_math)
9670 DECL_PURE_P (t) = 1;
9671 DECL_IS_NOVOPS (t) = 1;
9674 TREE_READONLY (t) = 1;
9680 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9682 static const struct builtin_description bdesc_3arg[] =
9684 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9685 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9686 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9687 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9688 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9689 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9690 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9691 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9692 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9693 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9694 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9695 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9696 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9697 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9698 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9699 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9700 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9701 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9702 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9703 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9704 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9705 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9706 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9707 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9708 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9709 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9710 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9711 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9712 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9713 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9714 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9715 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9716 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9717 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9718 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9720 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9721 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9722 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9728 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9732 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9736 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9737 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9738 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9739 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9741 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9742 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9743 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9744 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9746 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9747 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9749 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9750 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9751 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9752 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9753 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9754 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9755 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9756 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9757 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9758 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9760 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9761 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9762 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9763 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9764 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9765 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9766 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9767 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9768 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9769 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9771 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9772 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9773 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9774 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9775 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9776 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9777 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9778 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9779 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9781 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9782 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9783 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9784 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9785 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9786 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9787 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9789 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9790 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9791 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9792 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9793 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9794 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9795 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9796 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9797 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9800 /* DST operations: void foo (void *, const int, const char). */
9802 static const struct builtin_description bdesc_dst[] =
9804 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9805 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9806 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9807 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9809 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9810 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9811 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9815 /* Simple binary operations: VECc = foo (VECa, VECb). */
9817 static struct builtin_description bdesc_2arg[] =
9819 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9820 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9821 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9822 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9823 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9824 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9825 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9826 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9827 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9828 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9829 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9830 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9831 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9832 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9833 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9834 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9835 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9836 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9837 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9838 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9839 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9840 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9841 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9842 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9843 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9844 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9845 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9846 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9847 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9848 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9849 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9850 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9851 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9852 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9853 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9854 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9855 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9856 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9857 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9858 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9859 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9860 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9861 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9862 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9863 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9864 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9865 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9866 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9867 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9868 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9869 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9870 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9871 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9872 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9873 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9874 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9875 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9876 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9877 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9878 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9879 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9880 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9881 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9882 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9883 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9884 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9885 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9886 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9887 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9888 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9889 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9890 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9891 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9892 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9893 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9894 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9895 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9896 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9897 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9898 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9899 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9900 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9901 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9902 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9903 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9904 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9905 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9906 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9907 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9908 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9909 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9910 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9911 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9912 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9913 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9914 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9915 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9916 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9917 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9918 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9919 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9920 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9921 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9922 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9923 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9924 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9925 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9926 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9927 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9928 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9929 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9930 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9931 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9932 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9933 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9934 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9935 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9937 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9938 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9939 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9940 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9941 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9942 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9943 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9944 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9945 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9946 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9947 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9948 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9950 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9951 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9952 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9953 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9954 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9955 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9956 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9957 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9958 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9959 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9960 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9961 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9963 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9964 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9965 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9966 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9967 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9968 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9970 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9971 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9972 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9973 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9974 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9975 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9976 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9977 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9978 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9979 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9980 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9981 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9983 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9984 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9985 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9986 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9987 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9996 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
9997 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
9999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10023 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10024 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10039 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10040 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10042 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10043 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10057 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10058 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10060 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10061 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10075 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10092 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10093 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10096 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10100 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10101 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10102 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10103 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10104 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10105 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10106 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10109 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10110 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10111 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10113 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10114 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10116 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10117 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10118 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10119 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10120 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10121 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10122 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10123 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10124 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10125 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10127 /* Place holder, leave as first spe builtin. */
10128 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10129 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10130 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10131 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10132 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10133 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10134 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10135 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10136 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10137 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10138 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10139 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10140 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10141 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10142 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10143 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10144 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10145 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10146 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10147 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10148 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10149 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10150 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10151 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10152 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10153 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10154 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10155 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10156 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10157 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10158 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10159 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10160 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10161 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10162 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10163 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10164 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10165 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10166 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10167 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10168 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10169 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10170 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10171 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10172 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10173 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10174 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10175 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10176 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10177 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10178 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10179 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10180 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10181 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10182 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10183 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10184 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10185 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10186 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10187 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10188 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10189 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10190 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10191 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10192 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10193 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10194 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10195 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10196 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10197 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10198 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10199 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10200 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10201 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10202 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10203 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10204 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10205 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10206 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10207 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10208 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10209 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10210 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10211 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10212 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10213 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10214 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10215 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10216 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10217 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10218 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10219 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10220 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10221 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10222 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10223 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10224 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10225 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10226 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10227 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10228 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10229 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10230 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10231 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10232 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10233 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10234 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10235 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10236 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10238 /* SPE binary operations expecting a 5-bit unsigned literal. */
10239 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10241 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10242 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10243 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10244 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10245 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10246 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10247 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10248 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10249 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10250 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10251 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10252 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10253 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10254 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10255 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10256 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10257 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10258 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10259 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10260 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10261 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10262 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10263 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10264 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10265 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10266 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10268 /* Place-holder. Leave as last binary SPE builtin. */
10269 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10272 /* AltiVec predicates. */
10274 struct builtin_description_predicates
10276 const unsigned int mask;
10277 const enum insn_code icode;
10278 const char *const name;
10279 const enum rs6000_builtins code;
10282 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10284 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10285 ALTIVEC_BUILTIN_VCMPBFP_P },
10286 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10287 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10288 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10289 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10290 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10291 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10292 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10293 ALTIVEC_BUILTIN_VCMPEQUW_P },
10294 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10295 ALTIVEC_BUILTIN_VCMPGTSW_P },
10296 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10297 ALTIVEC_BUILTIN_VCMPGTUW_P },
10298 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10299 ALTIVEC_BUILTIN_VCMPEQUH_P },
10300 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10301 ALTIVEC_BUILTIN_VCMPGTSH_P },
10302 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10303 ALTIVEC_BUILTIN_VCMPGTUH_P },
10304 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10305 ALTIVEC_BUILTIN_VCMPEQUB_P },
10306 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10307 ALTIVEC_BUILTIN_VCMPGTSB_P },
10308 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10309 ALTIVEC_BUILTIN_VCMPGTUB_P },
10311 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10312 VSX_BUILTIN_XVCMPEQSP_P },
10313 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10314 VSX_BUILTIN_XVCMPGESP_P },
10315 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10316 VSX_BUILTIN_XVCMPGTSP_P },
10317 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10318 VSX_BUILTIN_XVCMPEQDP_P },
10319 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10320 VSX_BUILTIN_XVCMPGEDP_P },
10321 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10322 VSX_BUILTIN_XVCMPGTDP_P },
10324 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10325 ALTIVEC_BUILTIN_VCMPEQ_P },
10326 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10327 ALTIVEC_BUILTIN_VCMPGT_P },
10328 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10329 ALTIVEC_BUILTIN_VCMPGE_P }
10332 /* SPE predicates. */
10333 static struct builtin_description bdesc_spe_predicates[] =
10335 /* Place-holder. Leave as first. */
10336 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10337 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10338 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10339 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10340 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10341 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10342 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10343 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10344 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10345 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10346 /* Place-holder. Leave as last. */
10347 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10350 /* SPE evsel predicates. */
10351 static struct builtin_description bdesc_spe_evsel[] =
10353 /* Place-holder. Leave as first. */
10354 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10355 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10356 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10357 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10358 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10359 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10360 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10361 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10362 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10363 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10364 /* Place-holder. Leave as last. */
10365 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10368 /* PAIRED predicates. */
10369 static const struct builtin_description bdesc_paired_preds[] =
10371 /* Place-holder. Leave as first. */
10372 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10373 /* Place-holder. Leave as last. */
10374 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10377 /* ABS* operations. */
10379 static const struct builtin_description bdesc_abs[] =
10381 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10382 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10383 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10384 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10385 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10386 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10387 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10388 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10389 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10390 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10391 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10394 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10397 static struct builtin_description bdesc_1arg[] =
10399 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10400 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10401 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10402 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10403 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10404 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10405 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10406 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10407 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10408 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10409 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10410 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10411 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10412 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10413 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10414 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10415 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10416 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10418 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10419 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10420 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10421 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10422 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10423 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10424 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10426 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10427 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10428 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10429 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10430 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10431 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10432 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10434 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10435 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10436 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10437 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10438 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10439 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10441 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10442 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10443 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10444 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10445 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10446 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10448 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10449 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10450 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10451 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10453 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10454 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10455 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10456 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10457 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10458 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10459 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10460 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10461 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10463 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10464 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10465 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10466 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10467 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10468 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10469 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10470 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10471 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10473 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10474 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10475 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10476 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10477 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10479 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10480 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10481 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10498 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10500 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10501 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10502 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10504 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10505 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10506 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10507 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10509 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10510 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10511 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10512 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10513 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10514 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10515 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10516 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10517 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10518 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10519 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10520 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10521 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10522 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10523 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10524 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10525 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10526 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10527 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10528 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10529 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10530 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10531 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10532 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10533 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10534 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10535 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10536 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10537 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10538 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10540 /* Place-holder. Leave as last unary SPE builtin. */
10541 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10543 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10544 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10545 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10546 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10547 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10551 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10554 tree arg0 = CALL_EXPR_ARG (exp, 0);
10555 rtx op0 = expand_normal (arg0);
10556 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10557 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10559 if (icode == CODE_FOR_nothing)
10560 /* Builtin not supported on this processor. */
10563 /* If we got invalid arguments bail out before generating bad rtl. */
10564 if (arg0 == error_mark_node)
10567 if (icode == CODE_FOR_altivec_vspltisb
10568 || icode == CODE_FOR_altivec_vspltish
10569 || icode == CODE_FOR_altivec_vspltisw
10570 || icode == CODE_FOR_spe_evsplatfi
10571 || icode == CODE_FOR_spe_evsplati)
10573 /* Only allow 5-bit *signed* literals. */
10574 if (GET_CODE (op0) != CONST_INT
10575 || INTVAL (op0) > 15
10576 || INTVAL (op0) < -16)
10578 error ("argument 1 must be a 5-bit signed literal");
10584 || GET_MODE (target) != tmode
10585 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10586 target = gen_reg_rtx (tmode);
10588 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10589 op0 = copy_to_mode_reg (mode0, op0);
10591 pat = GEN_FCN (icode) (target, op0);
10600 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10602 rtx pat, scratch1, scratch2;
10603 tree arg0 = CALL_EXPR_ARG (exp, 0);
10604 rtx op0 = expand_normal (arg0);
10605 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10606 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10608 /* If we have invalid arguments, bail out before generating bad rtl. */
10609 if (arg0 == error_mark_node)
10613 || GET_MODE (target) != tmode
10614 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10615 target = gen_reg_rtx (tmode);
10617 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10618 op0 = copy_to_mode_reg (mode0, op0);
10620 scratch1 = gen_reg_rtx (mode0);
10621 scratch2 = gen_reg_rtx (mode0);
10623 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10632 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10635 tree arg0 = CALL_EXPR_ARG (exp, 0);
10636 tree arg1 = CALL_EXPR_ARG (exp, 1);
10637 rtx op0 = expand_normal (arg0);
10638 rtx op1 = expand_normal (arg1);
10639 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10640 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10641 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10643 if (icode == CODE_FOR_nothing)
10644 /* Builtin not supported on this processor. */
10647 /* If we got invalid arguments bail out before generating bad rtl. */
10648 if (arg0 == error_mark_node || arg1 == error_mark_node)
10651 if (icode == CODE_FOR_altivec_vcfux
10652 || icode == CODE_FOR_altivec_vcfsx
10653 || icode == CODE_FOR_altivec_vctsxs
10654 || icode == CODE_FOR_altivec_vctuxs
10655 || icode == CODE_FOR_altivec_vspltb
10656 || icode == CODE_FOR_altivec_vsplth
10657 || icode == CODE_FOR_altivec_vspltw
10658 || icode == CODE_FOR_spe_evaddiw
10659 || icode == CODE_FOR_spe_evldd
10660 || icode == CODE_FOR_spe_evldh
10661 || icode == CODE_FOR_spe_evldw
10662 || icode == CODE_FOR_spe_evlhhesplat
10663 || icode == CODE_FOR_spe_evlhhossplat
10664 || icode == CODE_FOR_spe_evlhhousplat
10665 || icode == CODE_FOR_spe_evlwhe
10666 || icode == CODE_FOR_spe_evlwhos
10667 || icode == CODE_FOR_spe_evlwhou
10668 || icode == CODE_FOR_spe_evlwhsplat
10669 || icode == CODE_FOR_spe_evlwwsplat
10670 || icode == CODE_FOR_spe_evrlwi
10671 || icode == CODE_FOR_spe_evslwi
10672 || icode == CODE_FOR_spe_evsrwis
10673 || icode == CODE_FOR_spe_evsubifw
10674 || icode == CODE_FOR_spe_evsrwiu)
10676 /* Only allow 5-bit unsigned literals. */
10678 if (TREE_CODE (arg1) != INTEGER_CST
10679 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10681 error ("argument 2 must be a 5-bit unsigned literal");
10687 || GET_MODE (target) != tmode
10688 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10689 target = gen_reg_rtx (tmode);
10691 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10692 op0 = copy_to_mode_reg (mode0, op0);
10693 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10694 op1 = copy_to_mode_reg (mode1, op1);
10696 pat = GEN_FCN (icode) (target, op0, op1);
10705 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10708 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10709 tree arg0 = CALL_EXPR_ARG (exp, 1);
10710 tree arg1 = CALL_EXPR_ARG (exp, 2);
10711 rtx op0 = expand_normal (arg0);
10712 rtx op1 = expand_normal (arg1);
10713 enum machine_mode tmode = SImode;
10714 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10715 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10718 if (TREE_CODE (cr6_form) != INTEGER_CST)
10720 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10724 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10726 gcc_assert (mode0 == mode1);
10728 /* If we have invalid arguments, bail out before generating bad rtl. */
10729 if (arg0 == error_mark_node || arg1 == error_mark_node)
10733 || GET_MODE (target) != tmode
10734 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10735 target = gen_reg_rtx (tmode);
10737 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10738 op0 = copy_to_mode_reg (mode0, op0);
10739 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10740 op1 = copy_to_mode_reg (mode1, op1);
10742 scratch = gen_reg_rtx (mode0);
10744 pat = GEN_FCN (icode) (scratch, op0, op1);
10749 /* The vec_any* and vec_all* predicates use the same opcodes for two
10750 different operations, but the bits in CR6 will be different
10751 depending on what information we want. So we have to play tricks
10752 with CR6 to get the right bits out.
10754 If you think this is disgusting, look at the specs for the
10755 AltiVec predicates. */
10757 switch (cr6_form_int)
10760 emit_insn (gen_cr6_test_for_zero (target));
10763 emit_insn (gen_cr6_test_for_zero_reverse (target));
10766 emit_insn (gen_cr6_test_for_lt (target));
10769 emit_insn (gen_cr6_test_for_lt_reverse (target));
10772 error ("argument 1 of __builtin_altivec_predicate is out of range");
10780 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10783 tree arg0 = CALL_EXPR_ARG (exp, 0);
10784 tree arg1 = CALL_EXPR_ARG (exp, 1);
10785 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10786 enum machine_mode mode0 = Pmode;
10787 enum machine_mode mode1 = Pmode;
10788 rtx op0 = expand_normal (arg0);
10789 rtx op1 = expand_normal (arg1);
10791 if (icode == CODE_FOR_nothing)
10792 /* Builtin not supported on this processor. */
10795 /* If we got invalid arguments bail out before generating bad rtl. */
10796 if (arg0 == error_mark_node || arg1 == error_mark_node)
10800 || GET_MODE (target) != tmode
10801 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10802 target = gen_reg_rtx (tmode);
10804 op1 = copy_to_mode_reg (mode1, op1);
10806 if (op0 == const0_rtx)
10808 addr = gen_rtx_MEM (tmode, op1);
10812 op0 = copy_to_mode_reg (mode0, op0);
10813 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10816 pat = GEN_FCN (icode) (target, addr);
10826 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10829 tree arg0 = CALL_EXPR_ARG (exp, 0);
10830 tree arg1 = CALL_EXPR_ARG (exp, 1);
10831 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10832 enum machine_mode mode0 = Pmode;
10833 enum machine_mode mode1 = Pmode;
10834 rtx op0 = expand_normal (arg0);
10835 rtx op1 = expand_normal (arg1);
10837 if (icode == CODE_FOR_nothing)
10838 /* Builtin not supported on this processor. */
10841 /* If we got invalid arguments bail out before generating bad rtl. */
10842 if (arg0 == error_mark_node || arg1 == error_mark_node)
10846 || GET_MODE (target) != tmode
10847 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10848 target = gen_reg_rtx (tmode);
10850 op1 = copy_to_mode_reg (mode1, op1);
10852 if (op0 == const0_rtx)
10854 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10858 op0 = copy_to_mode_reg (mode0, op0);
10859 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10862 pat = GEN_FCN (icode) (target, addr);
10872 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10874 tree arg0 = CALL_EXPR_ARG (exp, 0);
10875 tree arg1 = CALL_EXPR_ARG (exp, 1);
10876 tree arg2 = CALL_EXPR_ARG (exp, 2);
10877 rtx op0 = expand_normal (arg0);
10878 rtx op1 = expand_normal (arg1);
10879 rtx op2 = expand_normal (arg2);
10881 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10882 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10883 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10885 /* Invalid arguments. Bail before doing anything stoopid! */
10886 if (arg0 == error_mark_node
10887 || arg1 == error_mark_node
10888 || arg2 == error_mark_node)
10891 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10892 op0 = copy_to_mode_reg (mode2, op0);
10893 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10894 op1 = copy_to_mode_reg (mode0, op1);
10895 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10896 op2 = copy_to_mode_reg (mode1, op2);
10898 pat = GEN_FCN (icode) (op1, op2, op0);
10905 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10907 tree arg0 = CALL_EXPR_ARG (exp, 0);
10908 tree arg1 = CALL_EXPR_ARG (exp, 1);
10909 tree arg2 = CALL_EXPR_ARG (exp, 2);
10910 rtx op0 = expand_normal (arg0);
10911 rtx op1 = expand_normal (arg1);
10912 rtx op2 = expand_normal (arg2);
10914 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10915 enum machine_mode mode1 = Pmode;
10916 enum machine_mode mode2 = Pmode;
10918 /* Invalid arguments. Bail before doing anything stoopid! */
10919 if (arg0 == error_mark_node
10920 || arg1 == error_mark_node
10921 || arg2 == error_mark_node)
10924 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10925 op0 = copy_to_mode_reg (tmode, op0);
10927 op2 = copy_to_mode_reg (mode2, op2);
10929 if (op1 == const0_rtx)
10931 addr = gen_rtx_MEM (tmode, op2);
10935 op1 = copy_to_mode_reg (mode1, op1);
10936 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10939 pat = GEN_FCN (icode) (addr, op0);
10946 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10948 tree arg0 = CALL_EXPR_ARG (exp, 0);
10949 tree arg1 = CALL_EXPR_ARG (exp, 1);
10950 tree arg2 = CALL_EXPR_ARG (exp, 2);
10951 rtx op0 = expand_normal (arg0);
10952 rtx op1 = expand_normal (arg1);
10953 rtx op2 = expand_normal (arg2);
10955 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10956 enum machine_mode mode1 = Pmode;
10957 enum machine_mode mode2 = Pmode;
10959 /* Invalid arguments. Bail before doing anything stoopid! */
10960 if (arg0 == error_mark_node
10961 || arg1 == error_mark_node
10962 || arg2 == error_mark_node)
10965 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10966 op0 = copy_to_mode_reg (tmode, op0);
10968 op2 = copy_to_mode_reg (mode2, op2);
10970 if (op1 == const0_rtx)
10972 addr = gen_rtx_MEM (tmode, op2);
10976 op1 = copy_to_mode_reg (mode1, op1);
10977 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10980 pat = GEN_FCN (icode) (addr, op0);
10987 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10990 tree arg0 = CALL_EXPR_ARG (exp, 0);
10991 tree arg1 = CALL_EXPR_ARG (exp, 1);
10992 tree arg2 = CALL_EXPR_ARG (exp, 2);
10993 rtx op0 = expand_normal (arg0);
10994 rtx op1 = expand_normal (arg1);
10995 rtx op2 = expand_normal (arg2);
10996 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10997 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10998 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10999 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11001 if (icode == CODE_FOR_nothing)
11002 /* Builtin not supported on this processor. */
11005 /* If we got invalid arguments bail out before generating bad rtl. */
11006 if (arg0 == error_mark_node
11007 || arg1 == error_mark_node
11008 || arg2 == error_mark_node)
11011 /* Check and prepare argument depending on the instruction code.
11013 Note that a switch statement instead of the sequence of tests
11014 would be incorrect as many of the CODE_FOR values could be
11015 CODE_FOR_nothing and that would yield multiple alternatives
11016 with identical values. We'd never reach here at runtime in
11018 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11019 || icode == CODE_FOR_altivec_vsldoi_v4si
11020 || icode == CODE_FOR_altivec_vsldoi_v8hi
11021 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11023 /* Only allow 4-bit unsigned literals. */
11025 if (TREE_CODE (arg2) != INTEGER_CST
11026 || TREE_INT_CST_LOW (arg2) & ~0xf)
11028 error ("argument 3 must be a 4-bit unsigned literal");
11032 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11033 || icode == CODE_FOR_vsx_xxpermdi_v2di
11034 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11035 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11036 || icode == CODE_FOR_vsx_xxsldwi_v4si
11037 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11038 || icode == CODE_FOR_vsx_xxsldwi_v2di
11039 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11041 /* Only allow 2-bit unsigned literals. */
11043 if (TREE_CODE (arg2) != INTEGER_CST
11044 || TREE_INT_CST_LOW (arg2) & ~0x3)
11046 error ("argument 3 must be a 2-bit unsigned literal");
11050 else if (icode == CODE_FOR_vsx_set_v2df
11051 || icode == CODE_FOR_vsx_set_v2di)
11053 /* Only allow 1-bit unsigned literals. */
11055 if (TREE_CODE (arg2) != INTEGER_CST
11056 || TREE_INT_CST_LOW (arg2) & ~0x1)
11058 error ("argument 3 must be a 1-bit unsigned literal");
11064 || GET_MODE (target) != tmode
11065 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11066 target = gen_reg_rtx (tmode);
11068 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11069 op0 = copy_to_mode_reg (mode0, op0);
11070 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11071 op1 = copy_to_mode_reg (mode1, op1);
11072 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11073 op2 = copy_to_mode_reg (mode2, op2);
11075 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11076 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11078 pat = GEN_FCN (icode) (target, op0, op1, op2);
11086 /* Expand the lvx builtins. */
11088 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11090 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11091 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11093 enum machine_mode tmode, mode0;
11095 enum insn_code icode;
11099 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11100 icode = CODE_FOR_vector_load_v16qi;
11102 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11103 icode = CODE_FOR_vector_load_v8hi;
11105 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11106 icode = CODE_FOR_vector_load_v4si;
11108 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11109 icode = CODE_FOR_vector_load_v4sf;
11112 *expandedp = false;
11118 arg0 = CALL_EXPR_ARG (exp, 0);
11119 op0 = expand_normal (arg0);
11120 tmode = insn_data[icode].operand[0].mode;
11121 mode0 = insn_data[icode].operand[1].mode;
11124 || GET_MODE (target) != tmode
11125 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11126 target = gen_reg_rtx (tmode);
11128 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11129 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11131 pat = GEN_FCN (icode) (target, op0);
11138 /* Expand the stvx builtins. */
11140 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11143 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11144 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11146 enum machine_mode mode0, mode1;
11148 enum insn_code icode;
11152 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11153 icode = CODE_FOR_vector_store_v16qi;
11155 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11156 icode = CODE_FOR_vector_store_v8hi;
11158 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11159 icode = CODE_FOR_vector_store_v4si;
11161 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11162 icode = CODE_FOR_vector_store_v4sf;
11165 *expandedp = false;
11169 arg0 = CALL_EXPR_ARG (exp, 0);
11170 arg1 = CALL_EXPR_ARG (exp, 1);
11171 op0 = expand_normal (arg0);
11172 op1 = expand_normal (arg1);
11173 mode0 = insn_data[icode].operand[0].mode;
11174 mode1 = insn_data[icode].operand[1].mode;
11176 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11177 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11178 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11179 op1 = copy_to_mode_reg (mode1, op1);
11181 pat = GEN_FCN (icode) (op0, op1);
11189 /* Expand the dst builtins. */
11191 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11194 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11195 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11196 tree arg0, arg1, arg2;
11197 enum machine_mode mode0, mode1;
11198 rtx pat, op0, op1, op2;
11199 const struct builtin_description *d;
11202 *expandedp = false;
11204 /* Handle DST variants. */
11206 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11207 if (d->code == fcode)
11209 arg0 = CALL_EXPR_ARG (exp, 0);
11210 arg1 = CALL_EXPR_ARG (exp, 1);
11211 arg2 = CALL_EXPR_ARG (exp, 2);
11212 op0 = expand_normal (arg0);
11213 op1 = expand_normal (arg1);
11214 op2 = expand_normal (arg2);
11215 mode0 = insn_data[d->icode].operand[0].mode;
11216 mode1 = insn_data[d->icode].operand[1].mode;
11218 /* Invalid arguments, bail out before generating bad rtl. */
11219 if (arg0 == error_mark_node
11220 || arg1 == error_mark_node
11221 || arg2 == error_mark_node)
11226 if (TREE_CODE (arg2) != INTEGER_CST
11227 || TREE_INT_CST_LOW (arg2) & ~0x3)
11229 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11233 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11234 op0 = copy_to_mode_reg (Pmode, op0);
11235 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11236 op1 = copy_to_mode_reg (mode1, op1);
11238 pat = GEN_FCN (d->icode) (op0, op1, op2);
11248 /* Expand vec_init builtin. */
11250 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11252 enum machine_mode tmode = TYPE_MODE (type);
11253 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11254 int i, n_elt = GET_MODE_NUNITS (tmode);
11255 rtvec v = rtvec_alloc (n_elt);
11257 gcc_assert (VECTOR_MODE_P (tmode));
11258 gcc_assert (n_elt == call_expr_nargs (exp));
11260 for (i = 0; i < n_elt; ++i)
11262 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11263 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11266 if (!target || !register_operand (target, tmode))
11267 target = gen_reg_rtx (tmode);
11269 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11273 /* Return the integer constant in ARG. Constrain it to be in the range
11274 of the subparts of VEC_TYPE; issue an error if not. */
11277 get_element_number (tree vec_type, tree arg)
11279 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11281 if (!host_integerp (arg, 1)
11282 || (elt = tree_low_cst (arg, 1), elt > max))
11284 error ("selector must be an integer constant in the range 0..%wi", max);
11291 /* Expand vec_set builtin. */
11293 altivec_expand_vec_set_builtin (tree exp)
11295 enum machine_mode tmode, mode1;
11296 tree arg0, arg1, arg2;
11300 arg0 = CALL_EXPR_ARG (exp, 0);
11301 arg1 = CALL_EXPR_ARG (exp, 1);
11302 arg2 = CALL_EXPR_ARG (exp, 2);
11304 tmode = TYPE_MODE (TREE_TYPE (arg0));
11305 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11306 gcc_assert (VECTOR_MODE_P (tmode));
11308 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11309 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11310 elt = get_element_number (TREE_TYPE (arg0), arg2);
11312 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11313 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11315 op0 = force_reg (tmode, op0);
11316 op1 = force_reg (mode1, op1);
11318 rs6000_expand_vector_set (op0, op1, elt);
11323 /* Expand vec_ext builtin. */
11325 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11327 enum machine_mode tmode, mode0;
11332 arg0 = CALL_EXPR_ARG (exp, 0);
11333 arg1 = CALL_EXPR_ARG (exp, 1);
11335 op0 = expand_normal (arg0);
11336 elt = get_element_number (TREE_TYPE (arg0), arg1);
11338 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11339 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11340 gcc_assert (VECTOR_MODE_P (mode0));
11342 op0 = force_reg (mode0, op0);
11344 if (optimize || !target || !register_operand (target, tmode))
11345 target = gen_reg_rtx (tmode);
11347 rs6000_expand_vector_extract (target, op0, elt);
11352 /* Expand the builtin in EXP and store the result in TARGET. Store
11353 true in *EXPANDEDP if we found a builtin to expand. */
11355 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11357 const struct builtin_description *d;
11358 const struct builtin_description_predicates *dp;
11360 enum insn_code icode;
11361 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11364 enum machine_mode tmode, mode0;
11365 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11367 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11368 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11369 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11370 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11373 error ("unresolved overload for Altivec builtin %qF", fndecl);
11377 target = altivec_expand_ld_builtin (exp, target, expandedp);
11381 target = altivec_expand_st_builtin (exp, target, expandedp);
11385 target = altivec_expand_dst_builtin (exp, target, expandedp);
11393 case ALTIVEC_BUILTIN_STVX:
11394 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11395 case ALTIVEC_BUILTIN_STVEBX:
11396 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11397 case ALTIVEC_BUILTIN_STVEHX:
11398 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11399 case ALTIVEC_BUILTIN_STVEWX:
11400 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11401 case ALTIVEC_BUILTIN_STVXL:
11402 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11404 case ALTIVEC_BUILTIN_STVLX:
11405 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11406 case ALTIVEC_BUILTIN_STVLXL:
11407 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11408 case ALTIVEC_BUILTIN_STVRX:
11409 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11410 case ALTIVEC_BUILTIN_STVRXL:
11411 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11413 case ALTIVEC_BUILTIN_MFVSCR:
11414 icode = CODE_FOR_altivec_mfvscr;
11415 tmode = insn_data[icode].operand[0].mode;
11418 || GET_MODE (target) != tmode
11419 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11420 target = gen_reg_rtx (tmode);
11422 pat = GEN_FCN (icode) (target);
11428 case ALTIVEC_BUILTIN_MTVSCR:
11429 icode = CODE_FOR_altivec_mtvscr;
11430 arg0 = CALL_EXPR_ARG (exp, 0);
11431 op0 = expand_normal (arg0);
11432 mode0 = insn_data[icode].operand[0].mode;
11434 /* If we got invalid arguments bail out before generating bad rtl. */
11435 if (arg0 == error_mark_node)
11438 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11439 op0 = copy_to_mode_reg (mode0, op0);
11441 pat = GEN_FCN (icode) (op0);
11446 case ALTIVEC_BUILTIN_DSSALL:
11447 emit_insn (gen_altivec_dssall ());
11450 case ALTIVEC_BUILTIN_DSS:
11451 icode = CODE_FOR_altivec_dss;
11452 arg0 = CALL_EXPR_ARG (exp, 0);
11454 op0 = expand_normal (arg0);
11455 mode0 = insn_data[icode].operand[0].mode;
11457 /* If we got invalid arguments bail out before generating bad rtl. */
11458 if (arg0 == error_mark_node)
11461 if (TREE_CODE (arg0) != INTEGER_CST
11462 || TREE_INT_CST_LOW (arg0) & ~0x3)
11464 error ("argument to dss must be a 2-bit unsigned literal");
11468 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11469 op0 = copy_to_mode_reg (mode0, op0);
11471 emit_insn (gen_altivec_dss (op0));
11474 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11475 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11476 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11477 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11478 case VSX_BUILTIN_VEC_INIT_V2DF:
11479 case VSX_BUILTIN_VEC_INIT_V2DI:
11480 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11482 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11483 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11484 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11485 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11486 case VSX_BUILTIN_VEC_SET_V2DF:
11487 case VSX_BUILTIN_VEC_SET_V2DI:
11488 return altivec_expand_vec_set_builtin (exp);
11490 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11491 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11492 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11493 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11494 case VSX_BUILTIN_VEC_EXT_V2DF:
11495 case VSX_BUILTIN_VEC_EXT_V2DI:
11496 return altivec_expand_vec_ext_builtin (exp, target);
11500 /* Fall through. */
11503 /* Expand abs* operations. */
11505 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11506 if (d->code == fcode)
11507 return altivec_expand_abs_builtin (d->icode, exp, target);
11509 /* Expand the AltiVec predicates. */
11510 dp = bdesc_altivec_preds;
11511 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11512 if (dp->code == fcode)
11513 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11515 /* LV* are funky. We initialized them differently. */
11518 case ALTIVEC_BUILTIN_LVSL:
11519 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11520 exp, target, false);
11521 case ALTIVEC_BUILTIN_LVSR:
11522 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11523 exp, target, false);
11524 case ALTIVEC_BUILTIN_LVEBX:
11525 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11526 exp, target, false);
11527 case ALTIVEC_BUILTIN_LVEHX:
11528 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11529 exp, target, false);
11530 case ALTIVEC_BUILTIN_LVEWX:
11531 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11532 exp, target, false);
11533 case ALTIVEC_BUILTIN_LVXL:
11534 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11535 exp, target, false);
11536 case ALTIVEC_BUILTIN_LVX:
11537 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11538 exp, target, false);
11539 case ALTIVEC_BUILTIN_LVLX:
11540 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11541 exp, target, true);
11542 case ALTIVEC_BUILTIN_LVLXL:
11543 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11544 exp, target, true);
11545 case ALTIVEC_BUILTIN_LVRX:
11546 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11547 exp, target, true);
11548 case ALTIVEC_BUILTIN_LVRXL:
11549 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11550 exp, target, true);
11553 /* Fall through. */
11556 *expandedp = false;
11560 /* Expand the builtin in EXP and store the result in TARGET. Store
11561 true in *EXPANDEDP if we found a builtin to expand. */
11563 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11565 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11566 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11567 const struct builtin_description *d;
11574 case PAIRED_BUILTIN_STX:
11575 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11576 case PAIRED_BUILTIN_LX:
11577 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11580 /* Fall through. */
11583 /* Expand the paired predicates. */
11584 d = bdesc_paired_preds;
11585 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11586 if (d->code == fcode)
11587 return paired_expand_predicate_builtin (d->icode, exp, target);
11589 *expandedp = false;
11593 /* Binops that need to be initialized manually, but can be expanded
11594 automagically by rs6000_expand_binop_builtin. */
11595 static struct builtin_description bdesc_2arg_spe[] =
11597 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11598 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11599 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11600 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11601 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11602 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11603 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11604 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11605 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11606 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11607 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11608 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11609 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11610 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11611 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11612 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11613 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11614 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11615 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11616 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11617 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11618 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11621 /* Expand the builtin in EXP and store the result in TARGET. Store
11622 true in *EXPANDEDP if we found a builtin to expand.
11624 This expands the SPE builtins that are not simple unary and binary
11627 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11629 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11631 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11632 enum insn_code icode;
11633 enum machine_mode tmode, mode0;
11635 struct builtin_description *d;
11640 /* Syntax check for a 5-bit unsigned immediate. */
11643 case SPE_BUILTIN_EVSTDD:
11644 case SPE_BUILTIN_EVSTDH:
11645 case SPE_BUILTIN_EVSTDW:
11646 case SPE_BUILTIN_EVSTWHE:
11647 case SPE_BUILTIN_EVSTWHO:
11648 case SPE_BUILTIN_EVSTWWE:
11649 case SPE_BUILTIN_EVSTWWO:
11650 arg1 = CALL_EXPR_ARG (exp, 2);
11651 if (TREE_CODE (arg1) != INTEGER_CST
11652 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11654 error ("argument 2 must be a 5-bit unsigned literal");
11662 /* The evsplat*i instructions are not quite generic. */
11665 case SPE_BUILTIN_EVSPLATFI:
11666 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11668 case SPE_BUILTIN_EVSPLATI:
11669 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11675 d = (struct builtin_description *) bdesc_2arg_spe;
11676 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11677 if (d->code == fcode)
11678 return rs6000_expand_binop_builtin (d->icode, exp, target);
11680 d = (struct builtin_description *) bdesc_spe_predicates;
11681 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11682 if (d->code == fcode)
11683 return spe_expand_predicate_builtin (d->icode, exp, target);
11685 d = (struct builtin_description *) bdesc_spe_evsel;
11686 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11687 if (d->code == fcode)
11688 return spe_expand_evsel_builtin (d->icode, exp, target);
11692 case SPE_BUILTIN_EVSTDDX:
11693 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11694 case SPE_BUILTIN_EVSTDHX:
11695 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11696 case SPE_BUILTIN_EVSTDWX:
11697 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11698 case SPE_BUILTIN_EVSTWHEX:
11699 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11700 case SPE_BUILTIN_EVSTWHOX:
11701 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11702 case SPE_BUILTIN_EVSTWWEX:
11703 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11704 case SPE_BUILTIN_EVSTWWOX:
11705 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11706 case SPE_BUILTIN_EVSTDD:
11707 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11708 case SPE_BUILTIN_EVSTDH:
11709 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11710 case SPE_BUILTIN_EVSTDW:
11711 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11712 case SPE_BUILTIN_EVSTWHE:
11713 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11714 case SPE_BUILTIN_EVSTWHO:
11715 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11716 case SPE_BUILTIN_EVSTWWE:
11717 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11718 case SPE_BUILTIN_EVSTWWO:
11719 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11720 case SPE_BUILTIN_MFSPEFSCR:
11721 icode = CODE_FOR_spe_mfspefscr;
11722 tmode = insn_data[icode].operand[0].mode;
11725 || GET_MODE (target) != tmode
11726 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11727 target = gen_reg_rtx (tmode);
11729 pat = GEN_FCN (icode) (target);
11734 case SPE_BUILTIN_MTSPEFSCR:
11735 icode = CODE_FOR_spe_mtspefscr;
11736 arg0 = CALL_EXPR_ARG (exp, 0);
11737 op0 = expand_normal (arg0);
11738 mode0 = insn_data[icode].operand[0].mode;
11740 if (arg0 == error_mark_node)
11743 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11744 op0 = copy_to_mode_reg (mode0, op0);
11746 pat = GEN_FCN (icode) (op0);
11754 *expandedp = false;
11759 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11761 rtx pat, scratch, tmp;
11762 tree form = CALL_EXPR_ARG (exp, 0);
11763 tree arg0 = CALL_EXPR_ARG (exp, 1);
11764 tree arg1 = CALL_EXPR_ARG (exp, 2);
11765 rtx op0 = expand_normal (arg0);
11766 rtx op1 = expand_normal (arg1);
11767 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11768 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11770 enum rtx_code code;
11772 if (TREE_CODE (form) != INTEGER_CST)
11774 error ("argument 1 of __builtin_paired_predicate must be a constant");
11778 form_int = TREE_INT_CST_LOW (form);
11780 gcc_assert (mode0 == mode1);
11782 if (arg0 == error_mark_node || arg1 == error_mark_node)
11786 || GET_MODE (target) != SImode
11787 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11788 target = gen_reg_rtx (SImode);
11789 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11790 op0 = copy_to_mode_reg (mode0, op0);
11791 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11792 op1 = copy_to_mode_reg (mode1, op1);
11794 scratch = gen_reg_rtx (CCFPmode);
11796 pat = GEN_FCN (icode) (scratch, op0, op1);
11818 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11821 error ("argument 1 of __builtin_paired_predicate is out of range");
11825 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11826 emit_move_insn (target, tmp);
11831 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11833 rtx pat, scratch, tmp;
11834 tree form = CALL_EXPR_ARG (exp, 0);
11835 tree arg0 = CALL_EXPR_ARG (exp, 1);
11836 tree arg1 = CALL_EXPR_ARG (exp, 2);
11837 rtx op0 = expand_normal (arg0);
11838 rtx op1 = expand_normal (arg1);
11839 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11840 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11842 enum rtx_code code;
11844 if (TREE_CODE (form) != INTEGER_CST)
11846 error ("argument 1 of __builtin_spe_predicate must be a constant");
11850 form_int = TREE_INT_CST_LOW (form);
11852 gcc_assert (mode0 == mode1);
11854 if (arg0 == error_mark_node || arg1 == error_mark_node)
11858 || GET_MODE (target) != SImode
11859 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11860 target = gen_reg_rtx (SImode);
11862 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11863 op0 = copy_to_mode_reg (mode0, op0);
11864 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11865 op1 = copy_to_mode_reg (mode1, op1);
11867 scratch = gen_reg_rtx (CCmode);
11869 pat = GEN_FCN (icode) (scratch, op0, op1);
11874 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11875 _lower_. We use one compare, but look in different bits of the
11876 CR for each variant.
11878 There are 2 elements in each SPE simd type (upper/lower). The CR
11879 bits are set as follows:
11881 BIT0 | BIT 1 | BIT 2 | BIT 3
11882 U | L | (U | L) | (U & L)
11884 So, for an "all" relationship, BIT 3 would be set.
11885 For an "any" relationship, BIT 2 would be set. Etc.
11887 Following traditional nomenclature, these bits map to:
11889 BIT0 | BIT 1 | BIT 2 | BIT 3
11892 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11897 /* All variant. OV bit. */
11899 /* We need to get to the OV bit, which is the ORDERED bit. We
11900 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11901 that's ugly and will make validate_condition_mode die.
11902 So let's just use another pattern. */
11903 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11905 /* Any variant. EQ bit. */
11909 /* Upper variant. LT bit. */
11913 /* Lower variant. GT bit. */
11918 error ("argument 1 of __builtin_spe_predicate is out of range");
11922 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11923 emit_move_insn (target, tmp);
11928 /* The evsel builtins look like this:
11930 e = __builtin_spe_evsel_OP (a, b, c, d);
11932 and work like this:
11934 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11935 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11939 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11942 tree arg0 = CALL_EXPR_ARG (exp, 0);
11943 tree arg1 = CALL_EXPR_ARG (exp, 1);
11944 tree arg2 = CALL_EXPR_ARG (exp, 2);
11945 tree arg3 = CALL_EXPR_ARG (exp, 3);
11946 rtx op0 = expand_normal (arg0);
11947 rtx op1 = expand_normal (arg1);
11948 rtx op2 = expand_normal (arg2);
11949 rtx op3 = expand_normal (arg3);
11950 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11951 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11953 gcc_assert (mode0 == mode1);
11955 if (arg0 == error_mark_node || arg1 == error_mark_node
11956 || arg2 == error_mark_node || arg3 == error_mark_node)
11960 || GET_MODE (target) != mode0
11961 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11962 target = gen_reg_rtx (mode0);
11964 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11965 op0 = copy_to_mode_reg (mode0, op0);
11966 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11967 op1 = copy_to_mode_reg (mode0, op1);
11968 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11969 op2 = copy_to_mode_reg (mode0, op2);
11970 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11971 op3 = copy_to_mode_reg (mode0, op3);
11973 /* Generate the compare. */
11974 scratch = gen_reg_rtx (CCmode);
11975 pat = GEN_FCN (icode) (scratch, op0, op1);
11980 if (mode0 == V2SImode)
11981 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11983 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11988 /* Expand an expression EXP that calls a built-in function,
11989 with result going to TARGET if that's convenient
11990 (and in mode MODE if that's convenient).
11991 SUBTARGET may be used as the target for computing one of EXP's operands.
11992 IGNORE is nonzero if the value is to be ignored. */
11995 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11996 enum machine_mode mode ATTRIBUTE_UNUSED,
11997 int ignore ATTRIBUTE_UNUSED)
11999 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12000 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12001 const struct builtin_description *d;
12008 case RS6000_BUILTIN_RECIP:
12009 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12011 case RS6000_BUILTIN_RECIPF:
12012 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12014 case RS6000_BUILTIN_RSQRTF:
12015 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12017 case RS6000_BUILTIN_RSQRT:
12018 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12020 case RS6000_BUILTIN_BSWAP_HI:
12021 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12023 case POWER7_BUILTIN_BPERMD:
12024 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12025 ? CODE_FOR_bpermd_di
12026 : CODE_FOR_bpermd_si), exp, target);
12028 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12029 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12031 int icode = (int) CODE_FOR_altivec_lvsr;
12032 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12033 enum machine_mode mode = insn_data[icode].operand[1].mode;
12037 gcc_assert (TARGET_ALTIVEC);
12039 arg = CALL_EXPR_ARG (exp, 0);
12040 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12041 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12042 addr = memory_address (mode, op);
12043 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12047 /* For the load case need to negate the address. */
12048 op = gen_reg_rtx (GET_MODE (addr));
12049 emit_insn (gen_rtx_SET (VOIDmode, op,
12050 gen_rtx_NEG (GET_MODE (addr), addr)));
12052 op = gen_rtx_MEM (mode, op);
12055 || GET_MODE (target) != tmode
12056 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12057 target = gen_reg_rtx (tmode);
12059 /*pat = gen_altivec_lvsr (target, op);*/
12060 pat = GEN_FCN (icode) (target, op);
12068 case ALTIVEC_BUILTIN_VCFUX:
12069 case ALTIVEC_BUILTIN_VCFSX:
12070 case ALTIVEC_BUILTIN_VCTUXS:
12071 case ALTIVEC_BUILTIN_VCTSXS:
12072 /* FIXME: There's got to be a nicer way to handle this case than
12073 constructing a new CALL_EXPR. */
12074 if (call_expr_nargs (exp) == 1)
12076 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12077 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12085 if (TARGET_ALTIVEC)
12087 ret = altivec_expand_builtin (exp, target, &success);
12094 ret = spe_expand_builtin (exp, target, &success);
12099 if (TARGET_PAIRED_FLOAT)
12101 ret = paired_expand_builtin (exp, target, &success);
12107 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12109 /* Handle simple unary operations. */
12110 d = (struct builtin_description *) bdesc_1arg;
12111 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12112 if (d->code == fcode)
12113 return rs6000_expand_unop_builtin (d->icode, exp, target);
12115 /* Handle simple binary operations. */
12116 d = (struct builtin_description *) bdesc_2arg;
12117 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12118 if (d->code == fcode)
12119 return rs6000_expand_binop_builtin (d->icode, exp, target);
12121 /* Handle simple ternary operations. */
12123 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12124 if (d->code == fcode)
12125 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12127 gcc_unreachable ();
12131 rs6000_init_builtins (void)
12136 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12137 V2SF_type_node = build_vector_type (float_type_node, 2);
12138 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12139 V2DF_type_node = build_vector_type (double_type_node, 2);
12140 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12141 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12142 V4SF_type_node = build_vector_type (float_type_node, 4);
12143 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12144 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12146 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12147 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12148 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12149 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12151 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12152 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12153 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12154 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12156 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12157 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12158 'vector unsigned short'. */
12160 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12161 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12162 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12163 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12164 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12166 long_integer_type_internal_node = long_integer_type_node;
12167 long_unsigned_type_internal_node = long_unsigned_type_node;
12168 intQI_type_internal_node = intQI_type_node;
12169 uintQI_type_internal_node = unsigned_intQI_type_node;
12170 intHI_type_internal_node = intHI_type_node;
12171 uintHI_type_internal_node = unsigned_intHI_type_node;
12172 intSI_type_internal_node = intSI_type_node;
12173 uintSI_type_internal_node = unsigned_intSI_type_node;
12174 intDI_type_internal_node = intDI_type_node;
12175 uintDI_type_internal_node = unsigned_intDI_type_node;
12176 float_type_internal_node = float_type_node;
12177 double_type_internal_node = float_type_node;
12178 void_type_internal_node = void_type_node;
12180 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12182 builtin_mode_to_type[QImode][0] = integer_type_node;
12183 builtin_mode_to_type[HImode][0] = integer_type_node;
12184 builtin_mode_to_type[SImode][0] = intSI_type_node;
12185 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12186 builtin_mode_to_type[DImode][0] = intDI_type_node;
12187 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12188 builtin_mode_to_type[SFmode][0] = float_type_node;
12189 builtin_mode_to_type[DFmode][0] = double_type_node;
12190 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12191 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12192 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12193 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12194 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12195 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12196 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12197 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12198 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12199 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12200 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12201 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12202 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12204 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12205 get_identifier ("__bool char"),
12206 bool_char_type_node);
12207 TYPE_NAME (bool_char_type_node) = tdecl;
12208 (*lang_hooks.decls.pushdecl) (tdecl);
12209 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12210 get_identifier ("__bool short"),
12211 bool_short_type_node);
12212 TYPE_NAME (bool_short_type_node) = tdecl;
12213 (*lang_hooks.decls.pushdecl) (tdecl);
12214 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12215 get_identifier ("__bool int"),
12216 bool_int_type_node);
12217 TYPE_NAME (bool_int_type_node) = tdecl;
12218 (*lang_hooks.decls.pushdecl) (tdecl);
12219 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12221 TYPE_NAME (pixel_type_node) = tdecl;
12222 (*lang_hooks.decls.pushdecl) (tdecl);
12224 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12225 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12226 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12227 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12228 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12230 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12231 get_identifier ("__vector unsigned char"),
12232 unsigned_V16QI_type_node);
12233 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12234 (*lang_hooks.decls.pushdecl) (tdecl);
12235 tdecl = build_decl (BUILTINS_LOCATION,
12236 TYPE_DECL, get_identifier ("__vector signed char"),
12238 TYPE_NAME (V16QI_type_node) = tdecl;
12239 (*lang_hooks.decls.pushdecl) (tdecl);
12240 tdecl = build_decl (BUILTINS_LOCATION,
12241 TYPE_DECL, get_identifier ("__vector __bool char"),
12242 bool_V16QI_type_node);
12243 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12244 (*lang_hooks.decls.pushdecl) (tdecl);
12246 tdecl = build_decl (BUILTINS_LOCATION,
12247 TYPE_DECL, get_identifier ("__vector unsigned short"),
12248 unsigned_V8HI_type_node);
12249 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12250 (*lang_hooks.decls.pushdecl) (tdecl);
12251 tdecl = build_decl (BUILTINS_LOCATION,
12252 TYPE_DECL, get_identifier ("__vector signed short"),
12254 TYPE_NAME (V8HI_type_node) = tdecl;
12255 (*lang_hooks.decls.pushdecl) (tdecl);
12256 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12257 get_identifier ("__vector __bool short"),
12258 bool_V8HI_type_node);
12259 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12260 (*lang_hooks.decls.pushdecl) (tdecl);
12262 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12263 get_identifier ("__vector unsigned int"),
12264 unsigned_V4SI_type_node);
12265 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12266 (*lang_hooks.decls.pushdecl) (tdecl);
12267 tdecl = build_decl (BUILTINS_LOCATION,
12268 TYPE_DECL, get_identifier ("__vector signed int"),
12270 TYPE_NAME (V4SI_type_node) = tdecl;
12271 (*lang_hooks.decls.pushdecl) (tdecl);
12272 tdecl = build_decl (BUILTINS_LOCATION,
12273 TYPE_DECL, get_identifier ("__vector __bool int"),
12274 bool_V4SI_type_node);
12275 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12276 (*lang_hooks.decls.pushdecl) (tdecl);
12278 tdecl = build_decl (BUILTINS_LOCATION,
12279 TYPE_DECL, get_identifier ("__vector float"),
12281 TYPE_NAME (V4SF_type_node) = tdecl;
12282 (*lang_hooks.decls.pushdecl) (tdecl);
12283 tdecl = build_decl (BUILTINS_LOCATION,
12284 TYPE_DECL, get_identifier ("__vector __pixel"),
12285 pixel_V8HI_type_node);
12286 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12287 (*lang_hooks.decls.pushdecl) (tdecl);
12291 tdecl = build_decl (BUILTINS_LOCATION,
12292 TYPE_DECL, get_identifier ("__vector double"),
12294 TYPE_NAME (V2DF_type_node) = tdecl;
12295 (*lang_hooks.decls.pushdecl) (tdecl);
12297 tdecl = build_decl (BUILTINS_LOCATION,
12298 TYPE_DECL, get_identifier ("__vector long"),
12300 TYPE_NAME (V2DI_type_node) = tdecl;
12301 (*lang_hooks.decls.pushdecl) (tdecl);
12303 tdecl = build_decl (BUILTINS_LOCATION,
12304 TYPE_DECL, get_identifier ("__vector unsigned long"),
12305 unsigned_V2DI_type_node);
12306 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12307 (*lang_hooks.decls.pushdecl) (tdecl);
12309 tdecl = build_decl (BUILTINS_LOCATION,
12310 TYPE_DECL, get_identifier ("__vector __bool long"),
12311 bool_V2DI_type_node);
12312 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12313 (*lang_hooks.decls.pushdecl) (tdecl);
12316 if (TARGET_PAIRED_FLOAT)
12317 paired_init_builtins ();
12319 spe_init_builtins ();
12320 if (TARGET_ALTIVEC)
12321 altivec_init_builtins ();
12322 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12323 rs6000_common_init_builtins ();
12326 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12327 RS6000_BUILTIN_RECIP,
12328 "__builtin_recipdiv");
12329 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12330 RS6000_BUILTIN_RECIP);
12334 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12335 RS6000_BUILTIN_RECIPF,
12336 "__builtin_recipdivf");
12337 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12338 RS6000_BUILTIN_RECIPF);
12340 if (TARGET_FRSQRTE)
12342 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12343 RS6000_BUILTIN_RSQRT,
12344 "__builtin_rsqrt");
12345 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12346 RS6000_BUILTIN_RSQRT);
12348 if (TARGET_FRSQRTES)
12350 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12351 RS6000_BUILTIN_RSQRTF,
12352 "__builtin_rsqrtf");
12353 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12354 RS6000_BUILTIN_RSQRTF);
12356 if (TARGET_POPCNTD)
12358 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12359 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12360 POWER7_BUILTIN_BPERMD,
12361 "__builtin_bpermd");
12362 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12363 POWER7_BUILTIN_BPERMD);
12365 if (TARGET_POWERPC)
12367 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12368 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12369 unsigned_intHI_type_node,
12371 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12372 RS6000_BUILTIN_BSWAP_HI);
12376 /* AIX libm provides clog as __clog. */
12377 if (built_in_decls [BUILT_IN_CLOG])
12378 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12381 #ifdef SUBTARGET_INIT_BUILTINS
12382 SUBTARGET_INIT_BUILTINS;
12386 /* Returns the rs6000 builtin decl for CODE. */
12389 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12391 if (code >= RS6000_BUILTIN_COUNT)
12392 return error_mark_node;
12394 return rs6000_builtin_decls[code];
12397 /* Search through a set of builtins and enable the mask bits.
12398 DESC is an array of builtins.
12399 SIZE is the total number of builtins.
12400 START is the builtin enum at which to start.
12401 END is the builtin enum at which to end. */
12403 enable_mask_for_builtins (struct builtin_description *desc, int size,
12404 enum rs6000_builtins start,
12405 enum rs6000_builtins end)
12409 for (i = 0; i < size; ++i)
12410 if (desc[i].code == start)
12416 for (; i < size; ++i)
12418 /* Flip all the bits on. */
12419 desc[i].mask = target_flags;
12420 if (desc[i].code == end)
12426 spe_init_builtins (void)
12428 tree endlink = void_list_node;
12429 tree puint_type_node = build_pointer_type (unsigned_type_node);
12430 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12431 struct builtin_description *d;
12434 tree v2si_ftype_4_v2si
12435 = build_function_type
12436 (opaque_V2SI_type_node,
12437 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12438 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12439 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12440 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12443 tree v2sf_ftype_4_v2sf
12444 = build_function_type
12445 (opaque_V2SF_type_node,
12446 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12447 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12448 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12449 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12452 tree int_ftype_int_v2si_v2si
12453 = build_function_type
12454 (integer_type_node,
12455 tree_cons (NULL_TREE, integer_type_node,
12456 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12457 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12460 tree int_ftype_int_v2sf_v2sf
12461 = build_function_type
12462 (integer_type_node,
12463 tree_cons (NULL_TREE, integer_type_node,
12464 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12465 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12468 tree void_ftype_v2si_puint_int
12469 = build_function_type (void_type_node,
12470 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12471 tree_cons (NULL_TREE, puint_type_node,
12472 tree_cons (NULL_TREE,
12476 tree void_ftype_v2si_puint_char
12477 = build_function_type (void_type_node,
12478 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12479 tree_cons (NULL_TREE, puint_type_node,
12480 tree_cons (NULL_TREE,
12484 tree void_ftype_v2si_pv2si_int
12485 = build_function_type (void_type_node,
12486 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12487 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12488 tree_cons (NULL_TREE,
12492 tree void_ftype_v2si_pv2si_char
12493 = build_function_type (void_type_node,
12494 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12495 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12496 tree_cons (NULL_TREE,
12500 tree void_ftype_int
12501 = build_function_type (void_type_node,
12502 tree_cons (NULL_TREE, integer_type_node, endlink));
12504 tree int_ftype_void
12505 = build_function_type (integer_type_node, endlink);
12507 tree v2si_ftype_pv2si_int
12508 = build_function_type (opaque_V2SI_type_node,
12509 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12510 tree_cons (NULL_TREE, integer_type_node,
12513 tree v2si_ftype_puint_int
12514 = build_function_type (opaque_V2SI_type_node,
12515 tree_cons (NULL_TREE, puint_type_node,
12516 tree_cons (NULL_TREE, integer_type_node,
12519 tree v2si_ftype_pushort_int
12520 = build_function_type (opaque_V2SI_type_node,
12521 tree_cons (NULL_TREE, pushort_type_node,
12522 tree_cons (NULL_TREE, integer_type_node,
12525 tree v2si_ftype_signed_char
12526 = build_function_type (opaque_V2SI_type_node,
12527 tree_cons (NULL_TREE, signed_char_type_node,
12530 /* The initialization of the simple binary and unary builtins is
12531 done in rs6000_common_init_builtins, but we have to enable the
12532 mask bits here manually because we have run out of `target_flags'
12533 bits. We really need to redesign this mask business. */
12535 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12536 ARRAY_SIZE (bdesc_2arg),
12537 SPE_BUILTIN_EVADDW,
12538 SPE_BUILTIN_EVXOR);
12539 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12540 ARRAY_SIZE (bdesc_1arg),
12542 SPE_BUILTIN_EVSUBFUSIAAW);
12543 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12544 ARRAY_SIZE (bdesc_spe_predicates),
12545 SPE_BUILTIN_EVCMPEQ,
12546 SPE_BUILTIN_EVFSTSTLT);
12547 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12548 ARRAY_SIZE (bdesc_spe_evsel),
12549 SPE_BUILTIN_EVSEL_CMPGTS,
12550 SPE_BUILTIN_EVSEL_FSTSTEQ);
12552 (*lang_hooks.decls.pushdecl)
12553 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12554 get_identifier ("__ev64_opaque__"),
12555 opaque_V2SI_type_node));
12557 /* Initialize irregular SPE builtins. */
12559 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12560 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12561 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12562 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12563 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12564 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12565 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12566 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12567 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12568 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12569 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12570 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12571 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12572 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12573 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12574 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12575 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12576 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12579 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12580 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12581 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12582 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12583 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12584 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12585 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12586 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12587 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12588 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12589 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12590 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12591 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12592 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12593 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12594 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12595 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12596 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12597 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12598 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12599 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12600 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12603 d = (struct builtin_description *) bdesc_spe_predicates;
12604 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12608 switch (insn_data[d->icode].operand[1].mode)
12611 type = int_ftype_int_v2si_v2si;
12614 type = int_ftype_int_v2sf_v2sf;
12617 gcc_unreachable ();
12620 def_builtin (d->mask, d->name, type, d->code);
12623 /* Evsel predicates. */
12624 d = (struct builtin_description *) bdesc_spe_evsel;
12625 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12629 switch (insn_data[d->icode].operand[1].mode)
12632 type = v2si_ftype_4_v2si;
12635 type = v2sf_ftype_4_v2sf;
12638 gcc_unreachable ();
12641 def_builtin (d->mask, d->name, type, d->code);
12646 paired_init_builtins (void)
12648 const struct builtin_description *d;
12650 tree endlink = void_list_node;
12652 tree int_ftype_int_v2sf_v2sf
12653 = build_function_type
12654 (integer_type_node,
12655 tree_cons (NULL_TREE, integer_type_node,
12656 tree_cons (NULL_TREE, V2SF_type_node,
12657 tree_cons (NULL_TREE, V2SF_type_node,
12659 tree pcfloat_type_node =
12660 build_pointer_type (build_qualified_type
12661 (float_type_node, TYPE_QUAL_CONST));
12663 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12664 long_integer_type_node,
12667 tree void_ftype_v2sf_long_pcfloat =
12668 build_function_type_list (void_type_node,
12670 long_integer_type_node,
12675 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12676 PAIRED_BUILTIN_LX);
12679 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12680 PAIRED_BUILTIN_STX);
12683 d = bdesc_paired_preds;
12684 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12688 switch (insn_data[d->icode].operand[1].mode)
12691 type = int_ftype_int_v2sf_v2sf;
12694 gcc_unreachable ();
12697 def_builtin (d->mask, d->name, type, d->code);
12702 altivec_init_builtins (void)
12704 const struct builtin_description *d;
12705 const struct builtin_description_predicates *dp;
12709 tree pfloat_type_node = build_pointer_type (float_type_node);
12710 tree pint_type_node = build_pointer_type (integer_type_node);
12711 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12712 tree pchar_type_node = build_pointer_type (char_type_node);
12714 tree pvoid_type_node = build_pointer_type (void_type_node);
12716 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12717 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12718 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12719 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12721 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12723 tree int_ftype_opaque
12724 = build_function_type_list (integer_type_node,
12725 opaque_V4SI_type_node, NULL_TREE);
12726 tree opaque_ftype_opaque
12727 = build_function_type (integer_type_node,
12729 tree opaque_ftype_opaque_int
12730 = build_function_type_list (opaque_V4SI_type_node,
12731 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12732 tree opaque_ftype_opaque_opaque_int
12733 = build_function_type_list (opaque_V4SI_type_node,
12734 opaque_V4SI_type_node, opaque_V4SI_type_node,
12735 integer_type_node, NULL_TREE);
12736 tree int_ftype_int_opaque_opaque
12737 = build_function_type_list (integer_type_node,
12738 integer_type_node, opaque_V4SI_type_node,
12739 opaque_V4SI_type_node, NULL_TREE);
12740 tree int_ftype_int_v4si_v4si
12741 = build_function_type_list (integer_type_node,
12742 integer_type_node, V4SI_type_node,
12743 V4SI_type_node, NULL_TREE);
12744 tree v4sf_ftype_pcfloat
12745 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12746 tree void_ftype_pfloat_v4sf
12747 = build_function_type_list (void_type_node,
12748 pfloat_type_node, V4SF_type_node, NULL_TREE);
12749 tree v4si_ftype_pcint
12750 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12751 tree void_ftype_pint_v4si
12752 = build_function_type_list (void_type_node,
12753 pint_type_node, V4SI_type_node, NULL_TREE);
12754 tree v8hi_ftype_pcshort
12755 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12756 tree void_ftype_pshort_v8hi
12757 = build_function_type_list (void_type_node,
12758 pshort_type_node, V8HI_type_node, NULL_TREE);
12759 tree v16qi_ftype_pcchar
12760 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12761 tree void_ftype_pchar_v16qi
12762 = build_function_type_list (void_type_node,
12763 pchar_type_node, V16QI_type_node, NULL_TREE);
12764 tree void_ftype_v4si
12765 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12766 tree v8hi_ftype_void
12767 = build_function_type (V8HI_type_node, void_list_node);
12768 tree void_ftype_void
12769 = build_function_type (void_type_node, void_list_node);
12770 tree void_ftype_int
12771 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12773 tree opaque_ftype_long_pcvoid
12774 = build_function_type_list (opaque_V4SI_type_node,
12775 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12776 tree v16qi_ftype_long_pcvoid
12777 = build_function_type_list (V16QI_type_node,
12778 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12779 tree v8hi_ftype_long_pcvoid
12780 = build_function_type_list (V8HI_type_node,
12781 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12782 tree v4si_ftype_long_pcvoid
12783 = build_function_type_list (V4SI_type_node,
12784 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12786 tree void_ftype_opaque_long_pvoid
12787 = build_function_type_list (void_type_node,
12788 opaque_V4SI_type_node, long_integer_type_node,
12789 pvoid_type_node, NULL_TREE);
12790 tree void_ftype_v4si_long_pvoid
12791 = build_function_type_list (void_type_node,
12792 V4SI_type_node, long_integer_type_node,
12793 pvoid_type_node, NULL_TREE);
12794 tree void_ftype_v16qi_long_pvoid
12795 = build_function_type_list (void_type_node,
12796 V16QI_type_node, long_integer_type_node,
12797 pvoid_type_node, NULL_TREE);
12798 tree void_ftype_v8hi_long_pvoid
12799 = build_function_type_list (void_type_node,
12800 V8HI_type_node, long_integer_type_node,
12801 pvoid_type_node, NULL_TREE);
12802 tree int_ftype_int_v8hi_v8hi
12803 = build_function_type_list (integer_type_node,
12804 integer_type_node, V8HI_type_node,
12805 V8HI_type_node, NULL_TREE);
12806 tree int_ftype_int_v16qi_v16qi
12807 = build_function_type_list (integer_type_node,
12808 integer_type_node, V16QI_type_node,
12809 V16QI_type_node, NULL_TREE);
12810 tree int_ftype_int_v4sf_v4sf
12811 = build_function_type_list (integer_type_node,
12812 integer_type_node, V4SF_type_node,
12813 V4SF_type_node, NULL_TREE);
12814 tree int_ftype_int_v2df_v2df
12815 = build_function_type_list (integer_type_node,
12816 integer_type_node, V2DF_type_node,
12817 V2DF_type_node, NULL_TREE);
12818 tree v4si_ftype_v4si
12819 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12820 tree v8hi_ftype_v8hi
12821 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12822 tree v16qi_ftype_v16qi
12823 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12824 tree v4sf_ftype_v4sf
12825 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12826 tree v2df_ftype_v2df
12827 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12828 tree void_ftype_pcvoid_int_int
12829 = build_function_type_list (void_type_node,
12830 pcvoid_type_node, integer_type_node,
12831 integer_type_node, NULL_TREE);
12833 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12834 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12835 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12836 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12837 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12838 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12839 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12840 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12841 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12842 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12843 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12844 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12845 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12846 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12847 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12848 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12849 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12850 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12851 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12852 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12853 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12854 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12855 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12856 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12857 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12858 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12859 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12860 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12861 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12862 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12863 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12864 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12865 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12866 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12867 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12868 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12869 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12870 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12871 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12872 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12873 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12874 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12875 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12876 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12877 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12878 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12880 if (rs6000_cpu == PROCESSOR_CELL)
12882 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12883 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12884 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12885 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12887 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12888 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12889 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12890 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12892 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12893 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12894 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12895 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12897 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12898 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12899 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12900 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12902 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12903 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12904 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12906 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12907 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12908 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12909 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12910 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12911 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12912 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12913 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12914 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12915 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12916 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12917 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12919 /* Add the DST variants. */
12921 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12922 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12924 /* Initialize the predicates. */
12925 dp = bdesc_altivec_preds;
12926 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12928 enum machine_mode mode1;
12930 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12931 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12932 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12933 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12938 mode1 = insn_data[dp->icode].operand[1].mode;
12943 type = int_ftype_int_opaque_opaque;
12946 type = int_ftype_int_v4si_v4si;
12949 type = int_ftype_int_v8hi_v8hi;
12952 type = int_ftype_int_v16qi_v16qi;
12955 type = int_ftype_int_v4sf_v4sf;
12958 type = int_ftype_int_v2df_v2df;
12961 gcc_unreachable ();
12964 def_builtin (dp->mask, dp->name, type, dp->code);
12967 /* Initialize the abs* operators. */
12969 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12971 enum machine_mode mode0;
12974 mode0 = insn_data[d->icode].operand[0].mode;
12979 type = v4si_ftype_v4si;
12982 type = v8hi_ftype_v8hi;
12985 type = v16qi_ftype_v16qi;
12988 type = v4sf_ftype_v4sf;
12991 type = v2df_ftype_v2df;
12994 gcc_unreachable ();
12997 def_builtin (d->mask, d->name, type, d->code);
13000 if (TARGET_ALTIVEC)
13004 /* Initialize target builtin that implements
13005 targetm.vectorize.builtin_mask_for_load. */
13007 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13008 v16qi_ftype_long_pcvoid,
13009 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13010 BUILT_IN_MD, NULL, NULL_TREE);
13011 TREE_READONLY (decl) = 1;
13012 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13013 altivec_builtin_mask_for_load = decl;
13016 /* Access to the vec_init patterns. */
13017 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13018 integer_type_node, integer_type_node,
13019 integer_type_node, NULL_TREE);
13020 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13021 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13023 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13024 short_integer_type_node,
13025 short_integer_type_node,
13026 short_integer_type_node,
13027 short_integer_type_node,
13028 short_integer_type_node,
13029 short_integer_type_node,
13030 short_integer_type_node, NULL_TREE);
13031 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13032 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13034 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13035 char_type_node, char_type_node,
13036 char_type_node, char_type_node,
13037 char_type_node, char_type_node,
13038 char_type_node, char_type_node,
13039 char_type_node, char_type_node,
13040 char_type_node, char_type_node,
13041 char_type_node, char_type_node,
13042 char_type_node, NULL_TREE);
13043 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13044 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13046 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13047 float_type_node, float_type_node,
13048 float_type_node, NULL_TREE);
13049 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13050 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13054 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13055 double_type_node, NULL_TREE);
13056 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13057 VSX_BUILTIN_VEC_INIT_V2DF);
13059 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13060 intDI_type_node, NULL_TREE);
13061 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13062 VSX_BUILTIN_VEC_INIT_V2DI);
13065 /* Access to the vec_set patterns. */
13066 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13068 integer_type_node, NULL_TREE);
13069 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13070 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13072 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13074 integer_type_node, NULL_TREE);
13075 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13076 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13078 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13080 integer_type_node, NULL_TREE);
13081 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13082 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13084 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13086 integer_type_node, NULL_TREE);
13087 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13088 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13092 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13094 integer_type_node, NULL_TREE);
13095 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13096 VSX_BUILTIN_VEC_SET_V2DF);
13098 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13100 integer_type_node, NULL_TREE);
13101 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13102 VSX_BUILTIN_VEC_SET_V2DI);
13105 /* Access to the vec_extract patterns. */
13106 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13107 integer_type_node, NULL_TREE);
13108 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13109 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13111 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13112 integer_type_node, NULL_TREE);
13113 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13114 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13116 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13117 integer_type_node, NULL_TREE);
13118 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13119 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13121 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13122 integer_type_node, NULL_TREE);
13123 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13124 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13128 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13129 integer_type_node, NULL_TREE);
13130 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13131 VSX_BUILTIN_VEC_EXT_V2DF);
13133 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13134 integer_type_node, NULL_TREE);
13135 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13136 VSX_BUILTIN_VEC_EXT_V2DI);
13140 /* Hash function for builtin functions with up to 3 arguments and a return
13143 builtin_hash_function (const void *hash_entry)
13147 const struct builtin_hash_struct *bh =
13148 (const struct builtin_hash_struct *) hash_entry;
13150 for (i = 0; i < 4; i++)
13152 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13153 ret = (ret * 2) + bh->uns_p[i];
13159 /* Compare builtin hash entries H1 and H2 for equivalence. */
13161 builtin_hash_eq (const void *h1, const void *h2)
13163 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13164 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13166 return ((p1->mode[0] == p2->mode[0])
13167 && (p1->mode[1] == p2->mode[1])
13168 && (p1->mode[2] == p2->mode[2])
13169 && (p1->mode[3] == p2->mode[3])
13170 && (p1->uns_p[0] == p2->uns_p[0])
13171 && (p1->uns_p[1] == p2->uns_p[1])
13172 && (p1->uns_p[2] == p2->uns_p[2])
13173 && (p1->uns_p[3] == p2->uns_p[3]));
13176 /* Map types for builtin functions with an explicit return type and up to 3
13177 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13178 of the argument. */
13180 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13181 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13182 enum rs6000_builtins builtin, const char *name)
13184 struct builtin_hash_struct h;
13185 struct builtin_hash_struct *h2;
13189 tree ret_type = NULL_TREE;
13190 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13193 /* Create builtin_hash_table. */
13194 if (builtin_hash_table == NULL)
13195 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13196 builtin_hash_eq, NULL);
13198 h.type = NULL_TREE;
13199 h.mode[0] = mode_ret;
13200 h.mode[1] = mode_arg0;
13201 h.mode[2] = mode_arg1;
13202 h.mode[3] = mode_arg2;
13208 /* If the builtin is a type that produces unsigned results or takes unsigned
13209 arguments, and it is returned as a decl for the vectorizer (such as
13210 widening multiplies, permute), make sure the arguments and return value
13211 are type correct. */
13214 /* unsigned 2 argument functions. */
13215 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13216 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13217 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13218 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13224 /* unsigned 3 argument functions. */
13225 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13226 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13227 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13228 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13229 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13230 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13231 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13232 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13233 case VSX_BUILTIN_VPERM_16QI_UNS:
13234 case VSX_BUILTIN_VPERM_8HI_UNS:
13235 case VSX_BUILTIN_VPERM_4SI_UNS:
13236 case VSX_BUILTIN_VPERM_2DI_UNS:
13237 case VSX_BUILTIN_XXSEL_16QI_UNS:
13238 case VSX_BUILTIN_XXSEL_8HI_UNS:
13239 case VSX_BUILTIN_XXSEL_4SI_UNS:
13240 case VSX_BUILTIN_XXSEL_2DI_UNS:
13247 /* signed permute functions with unsigned char mask. */
13248 case ALTIVEC_BUILTIN_VPERM_16QI:
13249 case ALTIVEC_BUILTIN_VPERM_8HI:
13250 case ALTIVEC_BUILTIN_VPERM_4SI:
13251 case ALTIVEC_BUILTIN_VPERM_4SF:
13252 case ALTIVEC_BUILTIN_VPERM_2DI:
13253 case ALTIVEC_BUILTIN_VPERM_2DF:
13254 case VSX_BUILTIN_VPERM_16QI:
13255 case VSX_BUILTIN_VPERM_8HI:
13256 case VSX_BUILTIN_VPERM_4SI:
13257 case VSX_BUILTIN_VPERM_4SF:
13258 case VSX_BUILTIN_VPERM_2DI:
13259 case VSX_BUILTIN_VPERM_2DF:
13263 /* unsigned args, signed return. */
13264 case VSX_BUILTIN_XVCVUXDDP_UNS:
13265 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13269 /* signed args, unsigned return. */
13270 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13271 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13279 /* Figure out how many args are present. */
13280 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13284 fatal_error ("internal error: builtin function %s had no type", name);
13286 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13287 if (!ret_type && h.uns_p[0])
13288 ret_type = builtin_mode_to_type[h.mode[0]][0];
13291 fatal_error ("internal error: builtin function %s had an unexpected "
13292 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13294 for (i = 0; i < num_args; i++)
13296 int m = (int) h.mode[i+1];
13297 int uns_p = h.uns_p[i+1];
13299 arg_type[i] = builtin_mode_to_type[m][uns_p];
13300 if (!arg_type[i] && uns_p)
13301 arg_type[i] = builtin_mode_to_type[m][0];
13304 fatal_error ("internal error: builtin function %s, argument %d "
13305 "had unexpected argument type %s", name, i,
13306 GET_MODE_NAME (m));
13309 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13310 if (*found == NULL)
13312 h2 = ggc_alloc_builtin_hash_struct ();
13314 *found = (void *)h2;
13315 args = void_list_node;
13317 for (i = num_args - 1; i >= 0; i--)
13318 args = tree_cons (NULL_TREE, arg_type[i], args);
13320 h2->type = build_function_type (ret_type, args);
13323 return ((struct builtin_hash_struct *)(*found))->type;
13327 rs6000_common_init_builtins (void)
13329 const struct builtin_description *d;
13332 tree opaque_ftype_opaque = NULL_TREE;
13333 tree opaque_ftype_opaque_opaque = NULL_TREE;
13334 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13335 tree v2si_ftype_qi = NULL_TREE;
13336 tree v2si_ftype_v2si_qi = NULL_TREE;
13337 tree v2si_ftype_int_qi = NULL_TREE;
13339 if (!TARGET_PAIRED_FLOAT)
13341 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13342 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13345 /* Add the ternary operators. */
13347 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13350 int mask = d->mask;
13352 if ((mask != 0 && (mask & target_flags) == 0)
13353 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13356 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13357 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13358 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13359 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13361 if (! (type = opaque_ftype_opaque_opaque_opaque))
13362 type = opaque_ftype_opaque_opaque_opaque
13363 = build_function_type_list (opaque_V4SI_type_node,
13364 opaque_V4SI_type_node,
13365 opaque_V4SI_type_node,
13366 opaque_V4SI_type_node,
13371 enum insn_code icode = d->icode;
13372 if (d->name == 0 || icode == CODE_FOR_nothing)
13375 type = builtin_function_type (insn_data[icode].operand[0].mode,
13376 insn_data[icode].operand[1].mode,
13377 insn_data[icode].operand[2].mode,
13378 insn_data[icode].operand[3].mode,
13382 def_builtin (d->mask, d->name, type, d->code);
13385 /* Add the binary operators. */
13387 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13389 enum machine_mode mode0, mode1, mode2;
13391 int mask = d->mask;
13393 if ((mask != 0 && (mask & target_flags) == 0)
13394 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13397 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13398 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13399 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13400 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13402 if (! (type = opaque_ftype_opaque_opaque))
13403 type = opaque_ftype_opaque_opaque
13404 = build_function_type_list (opaque_V4SI_type_node,
13405 opaque_V4SI_type_node,
13406 opaque_V4SI_type_node,
13411 enum insn_code icode = d->icode;
13412 if (d->name == 0 || icode == CODE_FOR_nothing)
13415 mode0 = insn_data[icode].operand[0].mode;
13416 mode1 = insn_data[icode].operand[1].mode;
13417 mode2 = insn_data[icode].operand[2].mode;
13419 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13421 if (! (type = v2si_ftype_v2si_qi))
13422 type = v2si_ftype_v2si_qi
13423 = build_function_type_list (opaque_V2SI_type_node,
13424 opaque_V2SI_type_node,
13429 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13430 && mode2 == QImode)
13432 if (! (type = v2si_ftype_int_qi))
13433 type = v2si_ftype_int_qi
13434 = build_function_type_list (opaque_V2SI_type_node,
13441 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13445 def_builtin (d->mask, d->name, type, d->code);
13448 /* Add the simple unary operators. */
13449 d = (struct builtin_description *) bdesc_1arg;
13450 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13452 enum machine_mode mode0, mode1;
13454 int mask = d->mask;
13456 if ((mask != 0 && (mask & target_flags) == 0)
13457 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13460 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13461 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13462 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13463 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13465 if (! (type = opaque_ftype_opaque))
13466 type = opaque_ftype_opaque
13467 = build_function_type_list (opaque_V4SI_type_node,
13468 opaque_V4SI_type_node,
13473 enum insn_code icode = d->icode;
13474 if (d->name == 0 || icode == CODE_FOR_nothing)
13477 mode0 = insn_data[icode].operand[0].mode;
13478 mode1 = insn_data[icode].operand[1].mode;
13480 if (mode0 == V2SImode && mode1 == QImode)
13482 if (! (type = v2si_ftype_qi))
13483 type = v2si_ftype_qi
13484 = build_function_type_list (opaque_V2SI_type_node,
13490 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13494 def_builtin (d->mask, d->name, type, d->code);
13499 rs6000_init_libfuncs (void)
13501 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13502 && !TARGET_POWER2 && !TARGET_POWERPC)
13504 /* AIX library routines for float->int conversion. */
13505 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13506 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13507 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13508 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13511 if (!TARGET_IEEEQUAD)
13512 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13513 if (!TARGET_XL_COMPAT)
13515 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13516 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13517 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13518 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13520 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13522 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13523 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13524 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13525 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13526 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13527 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13528 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13530 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13531 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13532 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13533 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13534 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13535 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13536 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13537 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13540 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13541 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13545 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13546 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13547 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13548 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13552 /* 32-bit SVR4 quad floating point routines. */
13554 set_optab_libfunc (add_optab, TFmode, "_q_add");
13555 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13556 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13557 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13558 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13559 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13560 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13562 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13563 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13564 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13565 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13566 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13567 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13569 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13570 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13571 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13572 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13573 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13574 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13575 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13576 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13581 /* Expand a block clear operation, and return 1 if successful. Return 0
13582 if we should let the compiler generate normal code.
13584 operands[0] is the destination
13585 operands[1] is the length
13586 operands[3] is the alignment */
13589 expand_block_clear (rtx operands[])
13591 rtx orig_dest = operands[0];
13592 rtx bytes_rtx = operands[1];
13593 rtx align_rtx = operands[3];
13594 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13595 HOST_WIDE_INT align;
13596 HOST_WIDE_INT bytes;
13601 /* If this is not a fixed size move, just call memcpy */
13605 /* This must be a fixed size alignment */
13606 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13607 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13609 /* Anything to clear? */
13610 bytes = INTVAL (bytes_rtx);
13614 /* Use the builtin memset after a point, to avoid huge code bloat.
13615 When optimize_size, avoid any significant code bloat; calling
13616 memset is about 4 instructions, so allow for one instruction to
13617 load zero and three to do clearing. */
13618 if (TARGET_ALTIVEC && align >= 128)
13620 else if (TARGET_POWERPC64 && align >= 32)
13622 else if (TARGET_SPE && align >= 64)
13627 if (optimize_size && bytes > 3 * clear_step)
13629 if (! optimize_size && bytes > 8 * clear_step)
13632 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13634 enum machine_mode mode = BLKmode;
13637 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13642 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13647 else if (bytes >= 8 && TARGET_POWERPC64
13648 /* 64-bit loads and stores require word-aligned
13650 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13655 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13656 { /* move 4 bytes */
13660 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13661 { /* move 2 bytes */
13665 else /* move 1 byte at a time */
13671 dest = adjust_address (orig_dest, mode, offset);
13673 emit_move_insn (dest, CONST0_RTX (mode));
13680 /* Expand a block move operation, and return 1 if successful. Return 0
13681 if we should let the compiler generate normal code.
13683 operands[0] is the destination
13684 operands[1] is the source
13685 operands[2] is the length
13686 operands[3] is the alignment */
13688 #define MAX_MOVE_REG 4
13691 expand_block_move (rtx operands[])
13693 rtx orig_dest = operands[0];
13694 rtx orig_src = operands[1];
13695 rtx bytes_rtx = operands[2];
13696 rtx align_rtx = operands[3];
13697 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13702 rtx stores[MAX_MOVE_REG];
13705 /* If this is not a fixed size move, just call memcpy */
13709 /* This must be a fixed size alignment */
13710 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13711 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13713 /* Anything to move? */
13714 bytes = INTVAL (bytes_rtx);
13718 if (bytes > rs6000_block_move_inline_limit)
13721 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13724 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13725 rtx (*mov) (rtx, rtx);
13727 enum machine_mode mode = BLKmode;
13730 /* Altivec first, since it will be faster than a string move
13731 when it applies, and usually not significantly larger. */
13732 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13736 gen_func.mov = gen_movv4si;
13738 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13742 gen_func.mov = gen_movv2si;
13744 else if (TARGET_STRING
13745 && bytes > 24 /* move up to 32 bytes at a time */
13751 && ! fixed_regs[10]
13752 && ! fixed_regs[11]
13753 && ! fixed_regs[12])
13755 move_bytes = (bytes > 32) ? 32 : bytes;
13756 gen_func.movmemsi = gen_movmemsi_8reg;
13758 else if (TARGET_STRING
13759 && bytes > 16 /* move up to 24 bytes at a time */
13765 && ! fixed_regs[10])
13767 move_bytes = (bytes > 24) ? 24 : bytes;
13768 gen_func.movmemsi = gen_movmemsi_6reg;
13770 else if (TARGET_STRING
13771 && bytes > 8 /* move up to 16 bytes at a time */
13775 && ! fixed_regs[8])
13777 move_bytes = (bytes > 16) ? 16 : bytes;
13778 gen_func.movmemsi = gen_movmemsi_4reg;
13780 else if (bytes >= 8 && TARGET_POWERPC64
13781 /* 64-bit loads and stores require word-aligned
13783 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13787 gen_func.mov = gen_movdi;
13789 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13790 { /* move up to 8 bytes at a time */
13791 move_bytes = (bytes > 8) ? 8 : bytes;
13792 gen_func.movmemsi = gen_movmemsi_2reg;
13794 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13795 { /* move 4 bytes */
13798 gen_func.mov = gen_movsi;
13800 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13801 { /* move 2 bytes */
13804 gen_func.mov = gen_movhi;
13806 else if (TARGET_STRING && bytes > 1)
13807 { /* move up to 4 bytes at a time */
13808 move_bytes = (bytes > 4) ? 4 : bytes;
13809 gen_func.movmemsi = gen_movmemsi_1reg;
13811 else /* move 1 byte at a time */
13815 gen_func.mov = gen_movqi;
13818 src = adjust_address (orig_src, mode, offset);
13819 dest = adjust_address (orig_dest, mode, offset);
13821 if (mode != BLKmode)
13823 rtx tmp_reg = gen_reg_rtx (mode);
13825 emit_insn ((*gen_func.mov) (tmp_reg, src));
13826 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13829 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13832 for (i = 0; i < num_reg; i++)
13833 emit_insn (stores[i]);
13837 if (mode == BLKmode)
13839 /* Move the address into scratch registers. The movmemsi
13840 patterns require zero offset. */
13841 if (!REG_P (XEXP (src, 0)))
13843 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13844 src = replace_equiv_address (src, src_reg);
13846 set_mem_size (src, GEN_INT (move_bytes));
13848 if (!REG_P (XEXP (dest, 0)))
13850 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13851 dest = replace_equiv_address (dest, dest_reg);
13853 set_mem_size (dest, GEN_INT (move_bytes));
13855 emit_insn ((*gen_func.movmemsi) (dest, src,
13856 GEN_INT (move_bytes & 31),
13865 /* Return a string to perform a load_multiple operation.
13866 operands[0] is the vector.
13867 operands[1] is the source address.
13868 operands[2] is the first destination register. */
13871 rs6000_output_load_multiple (rtx operands[3])
13873 /* We have to handle the case where the pseudo used to contain the address
13874 is assigned to one of the output registers. */
13876 int words = XVECLEN (operands[0], 0);
13879 if (XVECLEN (operands[0], 0) == 1)
13880 return "{l|lwz} %2,0(%1)";
13882 for (i = 0; i < words; i++)
13883 if (refers_to_regno_p (REGNO (operands[2]) + i,
13884 REGNO (operands[2]) + i + 1, operands[1], 0))
13888 xop[0] = GEN_INT (4 * (words-1));
13889 xop[1] = operands[1];
13890 xop[2] = operands[2];
13891 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13896 xop[0] = GEN_INT (4 * (words-1));
13897 xop[1] = operands[1];
13898 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13899 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);
13904 for (j = 0; j < words; j++)
13907 xop[0] = GEN_INT (j * 4);
13908 xop[1] = operands[1];
13909 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13910 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13912 xop[0] = GEN_INT (i * 4);
13913 xop[1] = operands[1];
13914 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13919 return "{lsi|lswi} %2,%1,%N0";
13923 /* A validation routine: say whether CODE, a condition code, and MODE
13924 match. The other alternatives either don't make sense or should
13925 never be generated. */
13928 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13930 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13931 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13932 && GET_MODE_CLASS (mode) == MODE_CC);
13934 /* These don't make sense. */
13935 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13936 || mode != CCUNSmode);
13938 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13939 || mode == CCUNSmode);
13941 gcc_assert (mode == CCFPmode
13942 || (code != ORDERED && code != UNORDERED
13943 && code != UNEQ && code != LTGT
13944 && code != UNGT && code != UNLT
13945 && code != UNGE && code != UNLE));
13947 /* These should never be generated except for
13948 flag_finite_math_only. */
13949 gcc_assert (mode != CCFPmode
13950 || flag_finite_math_only
13951 || (code != LE && code != GE
13952 && code != UNEQ && code != LTGT
13953 && code != UNGT && code != UNLT));
13955 /* These are invalid; the information is not there. */
13956 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13960 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13961 mask required to convert the result of a rotate insn into a shift
13962 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13965 includes_lshift_p (rtx shiftop, rtx andop)
13967 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13969 shift_mask <<= INTVAL (shiftop);
13971 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13974 /* Similar, but for right shift. */
13977 includes_rshift_p (rtx shiftop, rtx andop)
13979 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13981 shift_mask >>= INTVAL (shiftop);
13983 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13986 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13987 to perform a left shift. It must have exactly SHIFTOP least
13988 significant 0's, then one or more 1's, then zero or more 0's. */
13991 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13993 if (GET_CODE (andop) == CONST_INT)
13995 HOST_WIDE_INT c, lsb, shift_mask;
13997 c = INTVAL (andop);
13998 if (c == 0 || c == ~0)
14002 shift_mask <<= INTVAL (shiftop);
14004 /* Find the least significant one bit. */
14007 /* It must coincide with the LSB of the shift mask. */
14008 if (-lsb != shift_mask)
14011 /* Invert to look for the next transition (if any). */
14014 /* Remove the low group of ones (originally low group of zeros). */
14017 /* Again find the lsb, and check we have all 1's above. */
14021 else if (GET_CODE (andop) == CONST_DOUBLE
14022 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14024 HOST_WIDE_INT low, high, lsb;
14025 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14027 low = CONST_DOUBLE_LOW (andop);
14028 if (HOST_BITS_PER_WIDE_INT < 64)
14029 high = CONST_DOUBLE_HIGH (andop);
14031 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14032 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14035 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14037 shift_mask_high = ~0;
14038 if (INTVAL (shiftop) > 32)
14039 shift_mask_high <<= INTVAL (shiftop) - 32;
14041 lsb = high & -high;
14043 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14049 lsb = high & -high;
14050 return high == -lsb;
14053 shift_mask_low = ~0;
14054 shift_mask_low <<= INTVAL (shiftop);
14058 if (-lsb != shift_mask_low)
14061 if (HOST_BITS_PER_WIDE_INT < 64)
14066 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14068 lsb = high & -high;
14069 return high == -lsb;
14073 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14079 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14080 to perform a left shift. It must have SHIFTOP or more least
14081 significant 0's, with the remainder of the word 1's. */
14084 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14086 if (GET_CODE (andop) == CONST_INT)
14088 HOST_WIDE_INT c, lsb, shift_mask;
14091 shift_mask <<= INTVAL (shiftop);
14092 c = INTVAL (andop);
14094 /* Find the least significant one bit. */
14097 /* It must be covered by the shift mask.
14098 This test also rejects c == 0. */
14099 if ((lsb & shift_mask) == 0)
14102 /* Check we have all 1's above the transition, and reject all 1's. */
14103 return c == -lsb && lsb != 1;
14105 else if (GET_CODE (andop) == CONST_DOUBLE
14106 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14108 HOST_WIDE_INT low, lsb, shift_mask_low;
14110 low = CONST_DOUBLE_LOW (andop);
14112 if (HOST_BITS_PER_WIDE_INT < 64)
14114 HOST_WIDE_INT high, shift_mask_high;
14116 high = CONST_DOUBLE_HIGH (andop);
14120 shift_mask_high = ~0;
14121 if (INTVAL (shiftop) > 32)
14122 shift_mask_high <<= INTVAL (shiftop) - 32;
14124 lsb = high & -high;
14126 if ((lsb & shift_mask_high) == 0)
14129 return high == -lsb;
14135 shift_mask_low = ~0;
14136 shift_mask_low <<= INTVAL (shiftop);
14140 if ((lsb & shift_mask_low) == 0)
14143 return low == -lsb && lsb != 1;
14149 /* Return 1 if operands will generate a valid arguments to rlwimi
14150 instruction for insert with right shift in 64-bit mode. The mask may
14151 not start on the first bit or stop on the last bit because wrap-around
14152 effects of instruction do not correspond to semantics of RTL insn. */
14155 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14157 if (INTVAL (startop) > 32
14158 && INTVAL (startop) < 64
14159 && INTVAL (sizeop) > 1
14160 && INTVAL (sizeop) + INTVAL (startop) < 64
14161 && INTVAL (shiftop) > 0
14162 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14163 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14169 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14170 for lfq and stfq insns iff the registers are hard registers. */
14173 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14175 /* We might have been passed a SUBREG. */
14176 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14179 /* We might have been passed non floating point registers. */
14180 if (!FP_REGNO_P (REGNO (reg1))
14181 || !FP_REGNO_P (REGNO (reg2)))
14184 return (REGNO (reg1) == REGNO (reg2) - 1);
14187 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14188 addr1 and addr2 must be in consecutive memory locations
14189 (addr2 == addr1 + 8). */
14192 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14195 unsigned int reg1, reg2;
14196 int offset1, offset2;
14198 /* The mems cannot be volatile. */
14199 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14202 addr1 = XEXP (mem1, 0);
14203 addr2 = XEXP (mem2, 0);
14205 /* Extract an offset (if used) from the first addr. */
14206 if (GET_CODE (addr1) == PLUS)
14208 /* If not a REG, return zero. */
14209 if (GET_CODE (XEXP (addr1, 0)) != REG)
14213 reg1 = REGNO (XEXP (addr1, 0));
14214 /* The offset must be constant! */
14215 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14217 offset1 = INTVAL (XEXP (addr1, 1));
14220 else if (GET_CODE (addr1) != REG)
14224 reg1 = REGNO (addr1);
14225 /* This was a simple (mem (reg)) expression. Offset is 0. */
14229 /* And now for the second addr. */
14230 if (GET_CODE (addr2) == PLUS)
14232 /* If not a REG, return zero. */
14233 if (GET_CODE (XEXP (addr2, 0)) != REG)
14237 reg2 = REGNO (XEXP (addr2, 0));
14238 /* The offset must be constant. */
14239 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14241 offset2 = INTVAL (XEXP (addr2, 1));
14244 else if (GET_CODE (addr2) != REG)
14248 reg2 = REGNO (addr2);
14249 /* This was a simple (mem (reg)) expression. Offset is 0. */
14253 /* Both of these must have the same base register. */
14257 /* The offset for the second addr must be 8 more than the first addr. */
14258 if (offset2 != offset1 + 8)
14261 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14268 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14270 static bool eliminated = false;
14273 if (mode != SDmode)
14274 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14277 rtx mem = cfun->machine->sdmode_stack_slot;
14278 gcc_assert (mem != NULL_RTX);
14282 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14283 cfun->machine->sdmode_stack_slot = mem;
14289 if (TARGET_DEBUG_ADDR)
14291 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14292 GET_MODE_NAME (mode));
14294 fprintf (stderr, "\tNULL_RTX\n");
14303 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14305 /* Don't walk into types. */
14306 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14308 *walk_subtrees = 0;
14312 switch (TREE_CODE (*tp))
14321 case VIEW_CONVERT_EXPR:
14322 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14332 enum reload_reg_type {
14334 VECTOR_REGISTER_TYPE,
14335 OTHER_REGISTER_TYPE
14338 static enum reload_reg_type
14339 rs6000_reload_register_type (enum reg_class rclass)
14345 return GPR_REGISTER_TYPE;
14350 return VECTOR_REGISTER_TYPE;
14353 return OTHER_REGISTER_TYPE;
14357 /* Inform reload about cases where moving X with a mode MODE to a register in
14358 RCLASS requires an extra scratch or immediate register. Return the class
14359 needed for the immediate register.
14361 For VSX and Altivec, we may need a register to convert sp+offset into
14365 rs6000_secondary_reload (bool in_p,
14367 reg_class_t rclass_i,
14368 enum machine_mode mode,
14369 secondary_reload_info *sri)
14371 enum reg_class rclass = (enum reg_class) rclass_i;
14372 reg_class_t ret = ALL_REGS;
14373 enum insn_code icode;
14374 bool default_p = false;
14376 sri->icode = CODE_FOR_nothing;
14378 /* Convert vector loads and stores into gprs to use an additional base
14380 icode = rs6000_vector_reload[mode][in_p != false];
14381 if (icode != CODE_FOR_nothing)
14384 sri->icode = CODE_FOR_nothing;
14385 sri->extra_cost = 0;
14387 if (GET_CODE (x) == MEM)
14389 rtx addr = XEXP (x, 0);
14391 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14392 an extra register in that case, but it would need an extra
14393 register if the addressing is reg+reg or (reg+reg)&(-16). */
14394 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14396 if (!legitimate_indirect_address_p (addr, false)
14397 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14399 sri->icode = icode;
14400 /* account for splitting the loads, and converting the
14401 address from reg+reg to reg. */
14402 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14403 + ((GET_CODE (addr) == AND) ? 1 : 0));
14406 /* Loads to and stores from vector registers can only do reg+reg
14407 addressing. Altivec registers can also do (reg+reg)&(-16). */
14408 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14409 || rclass == FLOAT_REGS || rclass == NO_REGS)
14411 if (!VECTOR_MEM_ALTIVEC_P (mode)
14412 && GET_CODE (addr) == AND
14413 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14414 && INTVAL (XEXP (addr, 1)) == -16
14415 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14416 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14418 sri->icode = icode;
14419 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14422 else if (!legitimate_indirect_address_p (addr, false)
14423 && (rclass == NO_REGS
14424 || !legitimate_indexed_address_p (addr, false)))
14426 sri->icode = icode;
14427 sri->extra_cost = 1;
14430 icode = CODE_FOR_nothing;
14432 /* Any other loads, including to pseudo registers which haven't been
14433 assigned to a register yet, default to require a scratch
14437 sri->icode = icode;
14438 sri->extra_cost = 2;
14441 else if (REG_P (x))
14443 int regno = true_regnum (x);
14445 icode = CODE_FOR_nothing;
14446 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14450 enum reg_class xclass = REGNO_REG_CLASS (regno);
14451 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14452 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14454 /* If memory is needed, use default_secondary_reload to create the
14456 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14469 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14471 gcc_assert (ret != ALL_REGS);
14473 if (TARGET_DEBUG_ADDR)
14476 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14478 reg_class_names[ret],
14479 in_p ? "true" : "false",
14480 reg_class_names[rclass],
14481 GET_MODE_NAME (mode));
14484 fprintf (stderr, ", default secondary reload");
14486 if (sri->icode != CODE_FOR_nothing)
14487 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14488 insn_data[sri->icode].name, sri->extra_cost);
14490 fprintf (stderr, "\n");
14498 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14499 to SP+reg addressing. */
14502 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14504 int regno = true_regnum (reg);
14505 enum machine_mode mode = GET_MODE (reg);
14506 enum reg_class rclass;
14508 rtx and_op2 = NULL_RTX;
14511 rtx scratch_or_premodify = scratch;
14515 if (TARGET_DEBUG_ADDR)
14517 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14518 store_p ? "store" : "load");
14519 fprintf (stderr, "reg:\n");
14521 fprintf (stderr, "mem:\n");
14523 fprintf (stderr, "scratch:\n");
14524 debug_rtx (scratch);
14527 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14528 gcc_assert (GET_CODE (mem) == MEM);
14529 rclass = REGNO_REG_CLASS (regno);
14530 addr = XEXP (mem, 0);
14534 /* GPRs can handle reg + small constant, all other addresses need to use
14535 the scratch register. */
14538 if (GET_CODE (addr) == AND)
14540 and_op2 = XEXP (addr, 1);
14541 addr = XEXP (addr, 0);
14544 if (GET_CODE (addr) == PRE_MODIFY)
14546 scratch_or_premodify = XEXP (addr, 0);
14547 gcc_assert (REG_P (scratch_or_premodify));
14548 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14549 addr = XEXP (addr, 1);
14552 if (GET_CODE (addr) == PLUS
14553 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14554 || and_op2 != NULL_RTX))
14556 addr_op1 = XEXP (addr, 0);
14557 addr_op2 = XEXP (addr, 1);
14558 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14560 if (!REG_P (addr_op2)
14561 && (GET_CODE (addr_op2) != CONST_INT
14562 || !satisfies_constraint_I (addr_op2)))
14564 if (TARGET_DEBUG_ADDR)
14567 "\nMove plus addr to register %s, mode = %s: ",
14568 rs6000_reg_names[REGNO (scratch)],
14569 GET_MODE_NAME (mode));
14570 debug_rtx (addr_op2);
14572 rs6000_emit_move (scratch, addr_op2, Pmode);
14573 addr_op2 = scratch;
14576 emit_insn (gen_rtx_SET (VOIDmode,
14577 scratch_or_premodify,
14578 gen_rtx_PLUS (Pmode,
14582 addr = scratch_or_premodify;
14583 scratch_or_premodify = scratch;
14585 else if (!legitimate_indirect_address_p (addr, false)
14586 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14588 if (TARGET_DEBUG_ADDR)
14590 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14591 rs6000_reg_names[REGNO (scratch_or_premodify)],
14592 GET_MODE_NAME (mode));
14595 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14596 addr = scratch_or_premodify;
14597 scratch_or_premodify = scratch;
14601 /* Float/Altivec registers can only handle reg+reg addressing. Move
14602 other addresses into a scratch register. */
14607 /* With float regs, we need to handle the AND ourselves, since we can't
14608 use the Altivec instruction with an implicit AND -16. Allow scalar
14609 loads to float registers to use reg+offset even if VSX. */
14610 if (GET_CODE (addr) == AND
14611 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14612 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14613 || INTVAL (XEXP (addr, 1)) != -16
14614 || !VECTOR_MEM_ALTIVEC_P (mode)))
14616 and_op2 = XEXP (addr, 1);
14617 addr = XEXP (addr, 0);
14620 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14621 as the address later. */
14622 if (GET_CODE (addr) == PRE_MODIFY
14623 && (!VECTOR_MEM_VSX_P (mode)
14624 || and_op2 != NULL_RTX
14625 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14627 scratch_or_premodify = XEXP (addr, 0);
14628 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14630 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14631 addr = XEXP (addr, 1);
14634 if (legitimate_indirect_address_p (addr, false) /* reg */
14635 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14636 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14637 || (GET_CODE (addr) == AND /* Altivec memory */
14638 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14639 && INTVAL (XEXP (addr, 1)) == -16
14640 && VECTOR_MEM_ALTIVEC_P (mode))
14641 || (rclass == FLOAT_REGS /* legacy float mem */
14642 && GET_MODE_SIZE (mode) == 8
14643 && and_op2 == NULL_RTX
14644 && scratch_or_premodify == scratch
14645 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14648 else if (GET_CODE (addr) == PLUS)
14650 addr_op1 = XEXP (addr, 0);
14651 addr_op2 = XEXP (addr, 1);
14652 gcc_assert (REG_P (addr_op1));
14654 if (TARGET_DEBUG_ADDR)
14656 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14657 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14658 debug_rtx (addr_op2);
14660 rs6000_emit_move (scratch, addr_op2, Pmode);
14661 emit_insn (gen_rtx_SET (VOIDmode,
14662 scratch_or_premodify,
14663 gen_rtx_PLUS (Pmode,
14666 addr = scratch_or_premodify;
14667 scratch_or_premodify = scratch;
14670 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14671 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14673 if (TARGET_DEBUG_ADDR)
14675 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14676 rs6000_reg_names[REGNO (scratch_or_premodify)],
14677 GET_MODE_NAME (mode));
14681 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14682 addr = scratch_or_premodify;
14683 scratch_or_premodify = scratch;
14687 gcc_unreachable ();
14692 gcc_unreachable ();
14695 /* If the original address involved a pre-modify that we couldn't use the VSX
14696 memory instruction with update, and we haven't taken care of already,
14697 store the address in the pre-modify register and use that as the
14699 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14701 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14702 addr = scratch_or_premodify;
14705 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14706 memory instruction, recreate the AND now, including the clobber which is
14707 generated by the general ANDSI3/ANDDI3 patterns for the
14708 andi. instruction. */
14709 if (and_op2 != NULL_RTX)
14711 if (! legitimate_indirect_address_p (addr, false))
14713 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14717 if (TARGET_DEBUG_ADDR)
14719 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14720 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14721 debug_rtx (and_op2);
14724 and_rtx = gen_rtx_SET (VOIDmode,
14726 gen_rtx_AND (Pmode,
14730 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14731 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14732 gen_rtvec (2, and_rtx, cc_clobber)));
14736 /* Adjust the address if it changed. */
14737 if (addr != XEXP (mem, 0))
14739 mem = change_address (mem, mode, addr);
14740 if (TARGET_DEBUG_ADDR)
14741 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14744 /* Now create the move. */
14746 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14748 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14753 /* Target hook to return the cover classes for Integrated Register Allocator.
14754 Cover classes is a set of non-intersected register classes covering all hard
14755 registers used for register allocation purpose. Any move between two
14756 registers of a cover class should be cheaper than load or store of the
14757 registers. The value is array of register classes with LIM_REG_CLASSES used
14760 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14761 account for the Altivec and Floating registers being subsets of the VSX
14762 register set under VSX, but distinct register sets on pre-VSX machines. */
14764 static const reg_class_t *
14765 rs6000_ira_cover_classes (void)
14767 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14768 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14770 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14773 /* Allocate a 64-bit stack slot to be used for copying SDmode
14774 values through if this function has any SDmode references. */
14777 rs6000_alloc_sdmode_stack_slot (void)
14781 gimple_stmt_iterator gsi;
14783 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14786 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14788 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14791 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14792 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14798 /* Check for any SDmode parameters of the function. */
14799 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14801 if (TREE_TYPE (t) == error_mark_node)
14804 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14805 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14807 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14808 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14816 rs6000_instantiate_decls (void)
14818 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14819 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14822 /* Given an rtx X being reloaded into a reg required to be
14823 in class CLASS, return the class of reg to actually use.
14824 In general this is just CLASS; but on some machines
14825 in some cases it is preferable to use a more restrictive class.
14827 On the RS/6000, we have to return NO_REGS when we want to reload a
14828 floating-point CONST_DOUBLE to force it to be copied to memory.
14830 We also don't want to reload integer values into floating-point
14831 registers if we can at all help it. In fact, this can
14832 cause reload to die, if it tries to generate a reload of CTR
14833 into a FP register and discovers it doesn't have the memory location
14836 ??? Would it be a good idea to have reload do the converse, that is
14837 try to reload floating modes into FP registers if possible?
14840 static enum reg_class
14841 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14843 enum machine_mode mode = GET_MODE (x);
14845 if (VECTOR_UNIT_VSX_P (mode)
14846 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14849 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14850 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14851 && easy_vector_constant (x, mode))
14852 return ALTIVEC_REGS;
14854 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14857 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14858 return GENERAL_REGS;
14860 /* For VSX, prefer the traditional registers for 64-bit values because we can
14861 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14862 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14863 prefer Altivec loads.. */
14864 if (rclass == VSX_REGS)
14866 if (GET_MODE_SIZE (mode) <= 8)
14869 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14870 return ALTIVEC_REGS;
14878 /* Debug version of rs6000_preferred_reload_class. */
14879 static enum reg_class
14880 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14882 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14885 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14887 reg_class_names[ret], reg_class_names[rclass],
14888 GET_MODE_NAME (GET_MODE (x)));
14894 /* If we are copying between FP or AltiVec registers and anything else, we need
14895 a memory location. The exception is when we are targeting ppc64 and the
14896 move to/from fpr to gpr instructions are available. Also, under VSX, you
14897 can copy vector registers from the FP register set to the Altivec register
14898 set and vice versa. */
14901 rs6000_secondary_memory_needed (enum reg_class class1,
14902 enum reg_class class2,
14903 enum machine_mode mode)
14905 if (class1 == class2)
14908 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14909 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14910 between these classes. But we need memory for other things that can go in
14911 FLOAT_REGS like SFmode. */
14913 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14914 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14915 || class1 == FLOAT_REGS))
14916 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14917 && class2 != FLOAT_REGS);
14919 if (class1 == VSX_REGS || class2 == VSX_REGS)
14922 if (class1 == FLOAT_REGS
14923 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14924 || ((mode != DFmode)
14925 && (mode != DDmode)
14926 && (mode != DImode))))
14929 if (class2 == FLOAT_REGS
14930 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14931 || ((mode != DFmode)
14932 && (mode != DDmode)
14933 && (mode != DImode))))
14936 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14942 /* Debug version of rs6000_secondary_memory_needed. */
14944 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14945 enum reg_class class2,
14946 enum machine_mode mode)
14948 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14951 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14952 "class2 = %s, mode = %s\n",
14953 ret ? "true" : "false", reg_class_names[class1],
14954 reg_class_names[class2], GET_MODE_NAME (mode));
14959 /* Return the register class of a scratch register needed to copy IN into
14960 or out of a register in RCLASS in MODE. If it can be done directly,
14961 NO_REGS is returned. */
14963 static enum reg_class
14964 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14969 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14971 && MACHOPIC_INDIRECT
14975 /* We cannot copy a symbolic operand directly into anything
14976 other than BASE_REGS for TARGET_ELF. So indicate that a
14977 register from BASE_REGS is needed as an intermediate
14980 On Darwin, pic addresses require a load from memory, which
14981 needs a base register. */
14982 if (rclass != BASE_REGS
14983 && (GET_CODE (in) == SYMBOL_REF
14984 || GET_CODE (in) == HIGH
14985 || GET_CODE (in) == LABEL_REF
14986 || GET_CODE (in) == CONST))
14990 if (GET_CODE (in) == REG)
14992 regno = REGNO (in);
14993 if (regno >= FIRST_PSEUDO_REGISTER)
14995 regno = true_regnum (in);
14996 if (regno >= FIRST_PSEUDO_REGISTER)
15000 else if (GET_CODE (in) == SUBREG)
15002 regno = true_regnum (in);
15003 if (regno >= FIRST_PSEUDO_REGISTER)
15009 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15011 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15012 || (regno >= 0 && INT_REGNO_P (regno)))
15015 /* Constants, memory, and FP registers can go into FP registers. */
15016 if ((regno == -1 || FP_REGNO_P (regno))
15017 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15018 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15020 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15023 && (regno == -1 || VSX_REGNO_P (regno))
15024 && VSX_REG_CLASS_P (rclass))
15027 /* Memory, and AltiVec registers can go into AltiVec registers. */
15028 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15029 && rclass == ALTIVEC_REGS)
15032 /* We can copy among the CR registers. */
15033 if ((rclass == CR_REGS || rclass == CR0_REGS)
15034 && regno >= 0 && CR_REGNO_P (regno))
15037 /* Otherwise, we need GENERAL_REGS. */
15038 return GENERAL_REGS;
15041 /* Debug version of rs6000_secondary_reload_class. */
15042 static enum reg_class
15043 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15044 enum machine_mode mode, rtx in)
15046 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15048 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15049 "mode = %s, input rtx:\n",
15050 reg_class_names[ret], reg_class_names[rclass],
15051 GET_MODE_NAME (mode));
15057 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15060 rs6000_cannot_change_mode_class (enum machine_mode from,
15061 enum machine_mode to,
15062 enum reg_class rclass)
15064 unsigned from_size = GET_MODE_SIZE (from);
15065 unsigned to_size = GET_MODE_SIZE (to);
15067 if (from_size != to_size)
15069 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15070 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15071 && reg_classes_intersect_p (xclass, rclass));
15074 if (TARGET_E500_DOUBLE
15075 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15076 || (((to) == TFmode) + ((from) == TFmode)) == 1
15077 || (((to) == DDmode) + ((from) == DDmode)) == 1
15078 || (((to) == TDmode) + ((from) == TDmode)) == 1
15079 || (((to) == DImode) + ((from) == DImode)) == 1))
15082 /* Since the VSX register set includes traditional floating point registers
15083 and altivec registers, just check for the size being different instead of
15084 trying to check whether the modes are vector modes. Otherwise it won't
15085 allow say DF and DI to change classes. */
15086 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15087 return (from_size != 8 && from_size != 16);
15089 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15090 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15093 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15094 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15100 /* Debug version of rs6000_cannot_change_mode_class. */
15102 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15103 enum machine_mode to,
15104 enum reg_class rclass)
15106 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15109 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15110 "to = %s, rclass = %s\n",
15111 ret ? "true" : "false",
15112 GET_MODE_NAME (from), GET_MODE_NAME (to),
15113 reg_class_names[rclass]);
15118 /* Given a comparison operation, return the bit number in CCR to test. We
15119 know this is a valid comparison.
15121 SCC_P is 1 if this is for an scc. That means that %D will have been
15122 used instead of %C, so the bits will be in different places.
15124 Return -1 if OP isn't a valid comparison for some reason. */
15127 ccr_bit (rtx op, int scc_p)
15129 enum rtx_code code = GET_CODE (op);
15130 enum machine_mode cc_mode;
15135 if (!COMPARISON_P (op))
15138 reg = XEXP (op, 0);
15140 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15142 cc_mode = GET_MODE (reg);
15143 cc_regnum = REGNO (reg);
15144 base_bit = 4 * (cc_regnum - CR0_REGNO);
15146 validate_condition_mode (code, cc_mode);
15148 /* When generating a sCOND operation, only positive conditions are
15151 || code == EQ || code == GT || code == LT || code == UNORDERED
15152 || code == GTU || code == LTU);
15157 return scc_p ? base_bit + 3 : base_bit + 2;
15159 return base_bit + 2;
15160 case GT: case GTU: case UNLE:
15161 return base_bit + 1;
15162 case LT: case LTU: case UNGE:
15164 case ORDERED: case UNORDERED:
15165 return base_bit + 3;
15168 /* If scc, we will have done a cror to put the bit in the
15169 unordered position. So test that bit. For integer, this is ! LT
15170 unless this is an scc insn. */
15171 return scc_p ? base_bit + 3 : base_bit;
15174 return scc_p ? base_bit + 3 : base_bit + 1;
15177 gcc_unreachable ();
15181 /* Return the GOT register. */
15184 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15186 /* The second flow pass currently (June 1999) can't update
15187 regs_ever_live without disturbing other parts of the compiler, so
15188 update it here to make the prolog/epilogue code happy. */
15189 if (!can_create_pseudo_p ()
15190 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15191 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15193 crtl->uses_pic_offset_table = 1;
15195 return pic_offset_table_rtx;
15198 static rs6000_stack_t stack_info;
15200 /* Function to init struct machine_function.
15201 This will be called, via a pointer variable,
15202 from push_function_context. */
15204 static struct machine_function *
15205 rs6000_init_machine_status (void)
15207 stack_info.reload_completed = 0;
15208 return ggc_alloc_cleared_machine_function ();
15211 /* These macros test for integers and extract the low-order bits. */
15213 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15214 && GET_MODE (X) == VOIDmode)
15216 #define INT_LOWPART(X) \
15217 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15220 extract_MB (rtx op)
15223 unsigned long val = INT_LOWPART (op);
15225 /* If the high bit is zero, the value is the first 1 bit we find
15227 if ((val & 0x80000000) == 0)
15229 gcc_assert (val & 0xffffffff);
15232 while (((val <<= 1) & 0x80000000) == 0)
15237 /* If the high bit is set and the low bit is not, or the mask is all
15238 1's, the value is zero. */
15239 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15242 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15245 while (((val >>= 1) & 1) != 0)
15252 extract_ME (rtx op)
15255 unsigned long val = INT_LOWPART (op);
15257 /* If the low bit is zero, the value is the first 1 bit we find from
15259 if ((val & 1) == 0)
15261 gcc_assert (val & 0xffffffff);
15264 while (((val >>= 1) & 1) == 0)
15270 /* If the low bit is set and the high bit is not, or the mask is all
15271 1's, the value is 31. */
15272 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15275 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15278 while (((val <<= 1) & 0x80000000) != 0)
15284 /* Locate some local-dynamic symbol still in use by this function
15285 so that we can print its name in some tls_ld pattern. */
15287 static const char *
15288 rs6000_get_some_local_dynamic_name (void)
15292 if (cfun->machine->some_ld_name)
15293 return cfun->machine->some_ld_name;
15295 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15297 && for_each_rtx (&PATTERN (insn),
15298 rs6000_get_some_local_dynamic_name_1, 0))
15299 return cfun->machine->some_ld_name;
15301 gcc_unreachable ();
15304 /* Helper function for rs6000_get_some_local_dynamic_name. */
15307 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15311 if (GET_CODE (x) == SYMBOL_REF)
15313 const char *str = XSTR (x, 0);
15314 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15316 cfun->machine->some_ld_name = str;
15324 /* Write out a function code label. */
15327 rs6000_output_function_entry (FILE *file, const char *fname)
15329 if (fname[0] != '.')
15331 switch (DEFAULT_ABI)
15334 gcc_unreachable ();
15340 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15349 RS6000_OUTPUT_BASENAME (file, fname);
15352 /* Print an operand. Recognize special options, documented below. */
15355 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15356 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15358 #define SMALL_DATA_RELOC "sda21"
15359 #define SMALL_DATA_REG 0
15363 print_operand (FILE *file, rtx x, int code)
15367 unsigned HOST_WIDE_INT uval;
15372 /* Write out an instruction after the call which may be replaced
15373 with glue code by the loader. This depends on the AIX version. */
15374 asm_fprintf (file, RS6000_CALL_GLUE);
15377 /* %a is output_address. */
15380 /* If X is a constant integer whose low-order 5 bits are zero,
15381 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15382 in the AIX assembler where "sri" with a zero shift count
15383 writes a trash instruction. */
15384 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15391 /* If constant, low-order 16 bits of constant, unsigned.
15392 Otherwise, write normally. */
15394 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15396 print_operand (file, x, 0);
15400 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15401 for 64-bit mask direction. */
15402 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15405 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15409 /* X is a CR register. Print the number of the GT bit of the CR. */
15410 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15411 output_operand_lossage ("invalid %%c value");
15413 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15417 /* Like 'J' but get to the GT bit only. */
15418 gcc_assert (GET_CODE (x) == REG);
15420 /* Bit 1 is GT bit. */
15421 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15423 /* Add one for shift count in rlinm for scc. */
15424 fprintf (file, "%d", i + 1);
15428 /* X is a CR register. Print the number of the EQ bit of the CR */
15429 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15430 output_operand_lossage ("invalid %%E value");
15432 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15436 /* X is a CR register. Print the shift count needed to move it
15437 to the high-order four bits. */
15438 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15439 output_operand_lossage ("invalid %%f value");
15441 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15445 /* Similar, but print the count for the rotate in the opposite
15447 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15448 output_operand_lossage ("invalid %%F value");
15450 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15454 /* X is a constant integer. If it is negative, print "m",
15455 otherwise print "z". This is to make an aze or ame insn. */
15456 if (GET_CODE (x) != CONST_INT)
15457 output_operand_lossage ("invalid %%G value");
15458 else if (INTVAL (x) >= 0)
15465 /* If constant, output low-order five bits. Otherwise, write
15468 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15470 print_operand (file, x, 0);
15474 /* If constant, output low-order six bits. Otherwise, write
15477 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15479 print_operand (file, x, 0);
15483 /* Print `i' if this is a constant, else nothing. */
15489 /* Write the bit number in CCR for jump. */
15490 i = ccr_bit (x, 0);
15492 output_operand_lossage ("invalid %%j code");
15494 fprintf (file, "%d", i);
15498 /* Similar, but add one for shift count in rlinm for scc and pass
15499 scc flag to `ccr_bit'. */
15500 i = ccr_bit (x, 1);
15502 output_operand_lossage ("invalid %%J code");
15504 /* If we want bit 31, write a shift count of zero, not 32. */
15505 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15509 /* X must be a constant. Write the 1's complement of the
15512 output_operand_lossage ("invalid %%k value");
15514 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15518 /* X must be a symbolic constant on ELF. Write an
15519 expression suitable for an 'addi' that adds in the low 16
15520 bits of the MEM. */
15521 if (GET_CODE (x) == CONST)
15523 if (GET_CODE (XEXP (x, 0)) != PLUS
15524 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15525 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15526 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15527 output_operand_lossage ("invalid %%K value");
15529 print_operand_address (file, x);
15530 fputs ("@l", file);
15533 /* %l is output_asm_label. */
15536 /* Write second word of DImode or DFmode reference. Works on register
15537 or non-indexed memory only. */
15538 if (GET_CODE (x) == REG)
15539 fputs (reg_names[REGNO (x) + 1], file);
15540 else if (GET_CODE (x) == MEM)
15542 /* Handle possible auto-increment. Since it is pre-increment and
15543 we have already done it, we can just use an offset of word. */
15544 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15545 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15546 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15548 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15549 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15552 output_address (XEXP (adjust_address_nv (x, SImode,
15556 if (small_data_operand (x, GET_MODE (x)))
15557 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15558 reg_names[SMALL_DATA_REG]);
15563 /* MB value for a mask operand. */
15564 if (! mask_operand (x, SImode))
15565 output_operand_lossage ("invalid %%m value");
15567 fprintf (file, "%d", extract_MB (x));
15571 /* ME value for a mask operand. */
15572 if (! mask_operand (x, SImode))
15573 output_operand_lossage ("invalid %%M value");
15575 fprintf (file, "%d", extract_ME (x));
15578 /* %n outputs the negative of its operand. */
15581 /* Write the number of elements in the vector times 4. */
15582 if (GET_CODE (x) != PARALLEL)
15583 output_operand_lossage ("invalid %%N value");
15585 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15589 /* Similar, but subtract 1 first. */
15590 if (GET_CODE (x) != PARALLEL)
15591 output_operand_lossage ("invalid %%O value");
15593 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15597 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15599 || INT_LOWPART (x) < 0
15600 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15601 output_operand_lossage ("invalid %%p value");
15603 fprintf (file, "%d", i);
15607 /* The operand must be an indirect memory reference. The result
15608 is the register name. */
15609 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15610 || REGNO (XEXP (x, 0)) >= 32)
15611 output_operand_lossage ("invalid %%P value");
15613 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15617 /* This outputs the logical code corresponding to a boolean
15618 expression. The expression may have one or both operands
15619 negated (if one, only the first one). For condition register
15620 logical operations, it will also treat the negated
15621 CR codes as NOTs, but not handle NOTs of them. */
15623 const char *const *t = 0;
15625 enum rtx_code code = GET_CODE (x);
15626 static const char * const tbl[3][3] = {
15627 { "and", "andc", "nor" },
15628 { "or", "orc", "nand" },
15629 { "xor", "eqv", "xor" } };
15633 else if (code == IOR)
15635 else if (code == XOR)
15638 output_operand_lossage ("invalid %%q value");
15640 if (GET_CODE (XEXP (x, 0)) != NOT)
15644 if (GET_CODE (XEXP (x, 1)) == NOT)
15662 /* X is a CR register. Print the mask for `mtcrf'. */
15663 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15664 output_operand_lossage ("invalid %%R value");
15666 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15670 /* Low 5 bits of 32 - value */
15672 output_operand_lossage ("invalid %%s value");
15674 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15678 /* PowerPC64 mask position. All 0's is excluded.
15679 CONST_INT 32-bit mask is considered sign-extended so any
15680 transition must occur within the CONST_INT, not on the boundary. */
15681 if (! mask64_operand (x, DImode))
15682 output_operand_lossage ("invalid %%S value");
15684 uval = INT_LOWPART (x);
15686 if (uval & 1) /* Clear Left */
15688 #if HOST_BITS_PER_WIDE_INT > 64
15689 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15693 else /* Clear Right */
15696 #if HOST_BITS_PER_WIDE_INT > 64
15697 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15703 gcc_assert (i >= 0);
15704 fprintf (file, "%d", i);
15708 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15709 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15711 /* Bit 3 is OV bit. */
15712 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15714 /* If we want bit 31, write a shift count of zero, not 32. */
15715 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15719 /* Print the symbolic name of a branch target register. */
15720 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15721 && REGNO (x) != CTR_REGNO))
15722 output_operand_lossage ("invalid %%T value");
15723 else if (REGNO (x) == LR_REGNO)
15724 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15726 fputs ("ctr", file);
15730 /* High-order 16 bits of constant for use in unsigned operand. */
15732 output_operand_lossage ("invalid %%u value");
15734 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15735 (INT_LOWPART (x) >> 16) & 0xffff);
15739 /* High-order 16 bits of constant for use in signed operand. */
15741 output_operand_lossage ("invalid %%v value");
15743 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15744 (INT_LOWPART (x) >> 16) & 0xffff);
15748 /* Print `u' if this has an auto-increment or auto-decrement. */
15749 if (GET_CODE (x) == MEM
15750 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15751 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15752 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15757 /* Print the trap code for this operand. */
15758 switch (GET_CODE (x))
15761 fputs ("eq", file); /* 4 */
15764 fputs ("ne", file); /* 24 */
15767 fputs ("lt", file); /* 16 */
15770 fputs ("le", file); /* 20 */
15773 fputs ("gt", file); /* 8 */
15776 fputs ("ge", file); /* 12 */
15779 fputs ("llt", file); /* 2 */
15782 fputs ("lle", file); /* 6 */
15785 fputs ("lgt", file); /* 1 */
15788 fputs ("lge", file); /* 5 */
15791 gcc_unreachable ();
15796 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15799 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15800 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15802 print_operand (file, x, 0);
15806 /* MB value for a PowerPC64 rldic operand. */
15807 val = (GET_CODE (x) == CONST_INT
15808 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15813 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15814 if ((val <<= 1) < 0)
15817 #if HOST_BITS_PER_WIDE_INT == 32
15818 if (GET_CODE (x) == CONST_INT && i >= 0)
15819 i += 32; /* zero-extend high-part was all 0's */
15820 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15822 val = CONST_DOUBLE_LOW (x);
15828 for ( ; i < 64; i++)
15829 if ((val <<= 1) < 0)
15834 fprintf (file, "%d", i + 1);
15838 /* X is a FPR or Altivec register used in a VSX context. */
15839 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15840 output_operand_lossage ("invalid %%x value");
15843 int reg = REGNO (x);
15844 int vsx_reg = (FP_REGNO_P (reg)
15846 : reg - FIRST_ALTIVEC_REGNO + 32);
15848 #ifdef TARGET_REGNAMES
15849 if (TARGET_REGNAMES)
15850 fprintf (file, "%%vs%d", vsx_reg);
15853 fprintf (file, "%d", vsx_reg);
15858 if (GET_CODE (x) == MEM
15859 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15860 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15861 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15866 /* Like 'L', for third word of TImode */
15867 if (GET_CODE (x) == REG)
15868 fputs (reg_names[REGNO (x) + 2], file);
15869 else if (GET_CODE (x) == MEM)
15871 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15872 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15873 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15874 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15875 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15877 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15878 if (small_data_operand (x, GET_MODE (x)))
15879 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15880 reg_names[SMALL_DATA_REG]);
15885 /* X is a SYMBOL_REF. Write out the name preceded by a
15886 period and without any trailing data in brackets. Used for function
15887 names. If we are configured for System V (or the embedded ABI) on
15888 the PowerPC, do not emit the period, since those systems do not use
15889 TOCs and the like. */
15890 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15892 /* Mark the decl as referenced so that cgraph will output the
15894 if (SYMBOL_REF_DECL (x))
15895 mark_decl_referenced (SYMBOL_REF_DECL (x));
15897 /* For macho, check to see if we need a stub. */
15900 const char *name = XSTR (x, 0);
15902 if (darwin_emit_branch_islands
15903 && MACHOPIC_INDIRECT
15904 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15905 name = machopic_indirection_name (x, /*stub_p=*/true);
15907 assemble_name (file, name);
15909 else if (!DOT_SYMBOLS)
15910 assemble_name (file, XSTR (x, 0));
15912 rs6000_output_function_entry (file, XSTR (x, 0));
15916 /* Like 'L', for last word of TImode. */
15917 if (GET_CODE (x) == REG)
15918 fputs (reg_names[REGNO (x) + 3], file);
15919 else if (GET_CODE (x) == MEM)
15921 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15922 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15923 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15924 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15925 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15927 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15928 if (small_data_operand (x, GET_MODE (x)))
15929 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15930 reg_names[SMALL_DATA_REG]);
15934 /* Print AltiVec or SPE memory operand. */
15939 gcc_assert (GET_CODE (x) == MEM);
15943 /* Ugly hack because %y is overloaded. */
15944 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15945 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15946 || GET_MODE (x) == TFmode
15947 || GET_MODE (x) == TImode))
15949 /* Handle [reg]. */
15950 if (GET_CODE (tmp) == REG)
15952 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15955 /* Handle [reg+UIMM]. */
15956 else if (GET_CODE (tmp) == PLUS &&
15957 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15961 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15963 x = INTVAL (XEXP (tmp, 1));
15964 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15968 /* Fall through. Must be [reg+reg]. */
15970 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15971 && GET_CODE (tmp) == AND
15972 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15973 && INTVAL (XEXP (tmp, 1)) == -16)
15974 tmp = XEXP (tmp, 0);
15975 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15976 && GET_CODE (tmp) == PRE_MODIFY)
15977 tmp = XEXP (tmp, 1);
15978 if (GET_CODE (tmp) == REG)
15979 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15982 if (!GET_CODE (tmp) == PLUS
15983 || !REG_P (XEXP (tmp, 0))
15984 || !REG_P (XEXP (tmp, 1)))
15986 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15990 if (REGNO (XEXP (tmp, 0)) == 0)
15991 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15992 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15994 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15995 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16001 if (GET_CODE (x) == REG)
16002 fprintf (file, "%s", reg_names[REGNO (x)]);
16003 else if (GET_CODE (x) == MEM)
16005 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16006 know the width from the mode. */
16007 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16008 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16009 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16010 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16011 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16012 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16013 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16014 output_address (XEXP (XEXP (x, 0), 1));
16016 output_address (XEXP (x, 0));
16019 output_addr_const (file, x);
16023 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16027 output_operand_lossage ("invalid %%xn code");
16031 /* Print the address of an operand. */
16034 print_operand_address (FILE *file, rtx x)
16036 if (GET_CODE (x) == REG)
16037 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16038 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16039 || GET_CODE (x) == LABEL_REF)
16041 output_addr_const (file, x);
16042 if (small_data_operand (x, GET_MODE (x)))
16043 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16044 reg_names[SMALL_DATA_REG]);
16046 gcc_assert (!TARGET_TOC);
16048 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16050 gcc_assert (REG_P (XEXP (x, 0)));
16051 if (REGNO (XEXP (x, 0)) == 0)
16052 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16053 reg_names[ REGNO (XEXP (x, 0)) ]);
16055 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16056 reg_names[ REGNO (XEXP (x, 1)) ]);
16058 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16059 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16060 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16062 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16063 && CONSTANT_P (XEXP (x, 1)))
16065 fprintf (file, "lo16(");
16066 output_addr_const (file, XEXP (x, 1));
16067 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16070 else if (legitimate_constant_pool_address_p (x, true))
16072 /* This hack along with a corresponding hack in
16073 rs6000_output_addr_const_extra arranges to output addends
16074 where the assembler expects to find them. eg.
16076 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16077 without this hack would be output as "x@toc+8@l(9)". We
16078 want "x+8@toc@l(9)". */
16079 output_addr_const (file, tocrel_base);
16080 if (GET_CODE (x) == LO_SUM)
16081 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16083 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16086 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16087 && CONSTANT_P (XEXP (x, 1)))
16089 output_addr_const (file, XEXP (x, 1));
16090 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16094 gcc_unreachable ();
16097 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16100 rs6000_output_addr_const_extra (FILE *file, rtx x)
16102 if (GET_CODE (x) == UNSPEC)
16103 switch (XINT (x, 1))
16105 case UNSPEC_TOCREL:
16106 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16107 output_addr_const (file, XVECEXP (x, 0, 0));
16108 if (x == tocrel_base && tocrel_offset != const0_rtx)
16110 if (INTVAL (tocrel_offset) >= 0)
16111 fprintf (file, "+");
16112 output_addr_const (file, tocrel_offset);
16114 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16117 assemble_name (file, toc_label_name);
16119 else if (TARGET_ELF)
16120 fputs ("@toc", file);
16124 case UNSPEC_MACHOPIC_OFFSET:
16125 output_addr_const (file, XVECEXP (x, 0, 0));
16127 machopic_output_function_base_name (file);
16134 /* Target hook for assembling integer objects. The PowerPC version has
16135 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16136 is defined. It also needs to handle DI-mode objects on 64-bit
16140 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16142 #ifdef RELOCATABLE_NEEDS_FIXUP
16143 /* Special handling for SI values. */
16144 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16146 static int recurse = 0;
16148 /* For -mrelocatable, we mark all addresses that need to be fixed up
16149 in the .fixup section. */
16150 if (TARGET_RELOCATABLE
16151 && in_section != toc_section
16152 && in_section != text_section
16153 && !unlikely_text_section_p (in_section)
16155 && GET_CODE (x) != CONST_INT
16156 && GET_CODE (x) != CONST_DOUBLE
16162 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16164 ASM_OUTPUT_LABEL (asm_out_file, buf);
16165 fprintf (asm_out_file, "\t.long\t(");
16166 output_addr_const (asm_out_file, x);
16167 fprintf (asm_out_file, ")@fixup\n");
16168 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16169 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16170 fprintf (asm_out_file, "\t.long\t");
16171 assemble_name (asm_out_file, buf);
16172 fprintf (asm_out_file, "\n\t.previous\n");
16176 /* Remove initial .'s to turn a -mcall-aixdesc function
16177 address into the address of the descriptor, not the function
16179 else if (GET_CODE (x) == SYMBOL_REF
16180 && XSTR (x, 0)[0] == '.'
16181 && DEFAULT_ABI == ABI_AIX)
16183 const char *name = XSTR (x, 0);
16184 while (*name == '.')
16187 fprintf (asm_out_file, "\t.long\t%s\n", name);
16191 #endif /* RELOCATABLE_NEEDS_FIXUP */
16192 return default_assemble_integer (x, size, aligned_p);
16195 #ifdef HAVE_GAS_HIDDEN
16196 /* Emit an assembler directive to set symbol visibility for DECL to
16197 VISIBILITY_TYPE. */
16200 rs6000_assemble_visibility (tree decl, int vis)
16202 /* Functions need to have their entry point symbol visibility set as
16203 well as their descriptor symbol visibility. */
16204 if (DEFAULT_ABI == ABI_AIX
16206 && TREE_CODE (decl) == FUNCTION_DECL)
16208 static const char * const visibility_types[] = {
16209 NULL, "internal", "hidden", "protected"
16212 const char *name, *type;
16214 name = ((* targetm.strip_name_encoding)
16215 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16216 type = visibility_types[vis];
16218 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16219 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16222 default_assemble_visibility (decl, vis);
16227 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16229 /* Reversal of FP compares takes care -- an ordered compare
16230 becomes an unordered compare and vice versa. */
16231 if (mode == CCFPmode
16232 && (!flag_finite_math_only
16233 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16234 || code == UNEQ || code == LTGT))
16235 return reverse_condition_maybe_unordered (code);
16237 return reverse_condition (code);
16240 /* Generate a compare for CODE. Return a brand-new rtx that
16241 represents the result of the compare. */
16244 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16246 enum machine_mode comp_mode;
16247 rtx compare_result;
16248 enum rtx_code code = GET_CODE (cmp);
16249 rtx op0 = XEXP (cmp, 0);
16250 rtx op1 = XEXP (cmp, 1);
16252 if (FLOAT_MODE_P (mode))
16253 comp_mode = CCFPmode;
16254 else if (code == GTU || code == LTU
16255 || code == GEU || code == LEU)
16256 comp_mode = CCUNSmode;
16257 else if ((code == EQ || code == NE)
16258 && GET_CODE (op0) == SUBREG
16259 && GET_CODE (op1) == SUBREG
16260 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16261 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16262 /* These are unsigned values, perhaps there will be a later
16263 ordering compare that can be shared with this one.
16264 Unfortunately we cannot detect the signedness of the operands
16265 for non-subregs. */
16266 comp_mode = CCUNSmode;
16268 comp_mode = CCmode;
16270 /* First, the compare. */
16271 compare_result = gen_reg_rtx (comp_mode);
16273 /* E500 FP compare instructions on the GPRs. Yuck! */
16274 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16275 && FLOAT_MODE_P (mode))
16277 rtx cmp, or_result, compare_result2;
16278 enum machine_mode op_mode = GET_MODE (op0);
16280 if (op_mode == VOIDmode)
16281 op_mode = GET_MODE (op1);
16283 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16284 This explains the following mess. */
16288 case EQ: case UNEQ: case NE: case LTGT:
16292 cmp = (flag_finite_math_only && !flag_trapping_math)
16293 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16294 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16298 cmp = (flag_finite_math_only && !flag_trapping_math)
16299 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16300 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16304 cmp = (flag_finite_math_only && !flag_trapping_math)
16305 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16306 : gen_cmptfeq_gpr (compare_result, op0, op1);
16310 gcc_unreachable ();
16314 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16318 cmp = (flag_finite_math_only && !flag_trapping_math)
16319 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16320 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16324 cmp = (flag_finite_math_only && !flag_trapping_math)
16325 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16326 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16330 cmp = (flag_finite_math_only && !flag_trapping_math)
16331 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16332 : gen_cmptfgt_gpr (compare_result, op0, op1);
16336 gcc_unreachable ();
16340 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16344 cmp = (flag_finite_math_only && !flag_trapping_math)
16345 ? gen_tstsflt_gpr (compare_result, op0, op1)
16346 : gen_cmpsflt_gpr (compare_result, op0, op1);
16350 cmp = (flag_finite_math_only && !flag_trapping_math)
16351 ? gen_tstdflt_gpr (compare_result, op0, op1)
16352 : gen_cmpdflt_gpr (compare_result, op0, op1);
16356 cmp = (flag_finite_math_only && !flag_trapping_math)
16357 ? gen_tsttflt_gpr (compare_result, op0, op1)
16358 : gen_cmptflt_gpr (compare_result, op0, op1);
16362 gcc_unreachable ();
16366 gcc_unreachable ();
16369 /* Synthesize LE and GE from LT/GT || EQ. */
16370 if (code == LE || code == GE || code == LEU || code == GEU)
16376 case LE: code = LT; break;
16377 case GE: code = GT; break;
16378 case LEU: code = LT; break;
16379 case GEU: code = GT; break;
16380 default: gcc_unreachable ();
16383 compare_result2 = gen_reg_rtx (CCFPmode);
16389 cmp = (flag_finite_math_only && !flag_trapping_math)
16390 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16391 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16395 cmp = (flag_finite_math_only && !flag_trapping_math)
16396 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16397 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16401 cmp = (flag_finite_math_only && !flag_trapping_math)
16402 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16403 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16407 gcc_unreachable ();
16411 /* OR them together. */
16412 or_result = gen_reg_rtx (CCFPmode);
16413 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16415 compare_result = or_result;
16420 if (code == NE || code == LTGT)
16430 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16431 CLOBBERs to match cmptf_internal2 pattern. */
16432 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16433 && GET_MODE (op0) == TFmode
16434 && !TARGET_IEEEQUAD
16435 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16436 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16438 gen_rtx_SET (VOIDmode,
16440 gen_rtx_COMPARE (comp_mode, op0, op1)),
16441 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16442 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16443 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16444 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16445 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16446 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16447 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16448 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16449 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16450 else if (GET_CODE (op1) == UNSPEC
16451 && XINT (op1, 1) == UNSPEC_SP_TEST)
16453 rtx op1b = XVECEXP (op1, 0, 0);
16454 comp_mode = CCEQmode;
16455 compare_result = gen_reg_rtx (CCEQmode);
16457 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16459 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16462 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16463 gen_rtx_COMPARE (comp_mode, op0, op1)));
16466 /* Some kinds of FP comparisons need an OR operation;
16467 under flag_finite_math_only we don't bother. */
16468 if (FLOAT_MODE_P (mode)
16469 && !flag_finite_math_only
16470 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16471 && (code == LE || code == GE
16472 || code == UNEQ || code == LTGT
16473 || code == UNGT || code == UNLT))
16475 enum rtx_code or1, or2;
16476 rtx or1_rtx, or2_rtx, compare2_rtx;
16477 rtx or_result = gen_reg_rtx (CCEQmode);
16481 case LE: or1 = LT; or2 = EQ; break;
16482 case GE: or1 = GT; or2 = EQ; break;
16483 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16484 case LTGT: or1 = LT; or2 = GT; break;
16485 case UNGT: or1 = UNORDERED; or2 = GT; break;
16486 case UNLT: or1 = UNORDERED; or2 = LT; break;
16487 default: gcc_unreachable ();
16489 validate_condition_mode (or1, comp_mode);
16490 validate_condition_mode (or2, comp_mode);
16491 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16492 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16493 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16494 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16496 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16498 compare_result = or_result;
16502 validate_condition_mode (code, GET_MODE (compare_result));
16504 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16508 /* Emit the RTL for an sISEL pattern. */
16511 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16513 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16517 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16520 enum machine_mode op_mode;
16521 enum rtx_code cond_code;
16522 rtx result = operands[0];
16524 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16526 rs6000_emit_sISEL (mode, operands);
16530 condition_rtx = rs6000_generate_compare (operands[1], mode);
16531 cond_code = GET_CODE (condition_rtx);
16533 if (FLOAT_MODE_P (mode)
16534 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16538 PUT_MODE (condition_rtx, SImode);
16539 t = XEXP (condition_rtx, 0);
16541 gcc_assert (cond_code == NE || cond_code == EQ);
16543 if (cond_code == NE)
16544 emit_insn (gen_e500_flip_gt_bit (t, t));
16546 emit_insn (gen_move_from_CR_gt_bit (result, t));
16550 if (cond_code == NE
16551 || cond_code == GE || cond_code == LE
16552 || cond_code == GEU || cond_code == LEU
16553 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16555 rtx not_result = gen_reg_rtx (CCEQmode);
16556 rtx not_op, rev_cond_rtx;
16557 enum machine_mode cc_mode;
16559 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16561 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16562 SImode, XEXP (condition_rtx, 0), const0_rtx);
16563 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16564 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16565 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16568 op_mode = GET_MODE (XEXP (operands[1], 0));
16569 if (op_mode == VOIDmode)
16570 op_mode = GET_MODE (XEXP (operands[1], 1));
16572 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16574 PUT_MODE (condition_rtx, DImode);
16575 convert_move (result, condition_rtx, 0);
16579 PUT_MODE (condition_rtx, SImode);
16580 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16584 /* Emit a branch of kind CODE to location LOC. */
16587 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16589 rtx condition_rtx, loc_ref;
16591 condition_rtx = rs6000_generate_compare (operands[0], mode);
16592 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16593 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16594 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16595 loc_ref, pc_rtx)));
16598 /* Return the string to output a conditional branch to LABEL, which is
16599 the operand number of the label, or -1 if the branch is really a
16600 conditional return.
16602 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16603 condition code register and its mode specifies what kind of
16604 comparison we made.
16606 REVERSED is nonzero if we should reverse the sense of the comparison.
16608 INSN is the insn. */
16611 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16613 static char string[64];
16614 enum rtx_code code = GET_CODE (op);
16615 rtx cc_reg = XEXP (op, 0);
16616 enum machine_mode mode = GET_MODE (cc_reg);
16617 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16618 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16619 int really_reversed = reversed ^ need_longbranch;
16625 validate_condition_mode (code, mode);
16627 /* Work out which way this really branches. We could use
16628 reverse_condition_maybe_unordered here always but this
16629 makes the resulting assembler clearer. */
16630 if (really_reversed)
16632 /* Reversal of FP compares takes care -- an ordered compare
16633 becomes an unordered compare and vice versa. */
16634 if (mode == CCFPmode)
16635 code = reverse_condition_maybe_unordered (code);
16637 code = reverse_condition (code);
16640 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16642 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16647 /* Opposite of GT. */
16656 gcc_unreachable ();
16662 /* Not all of these are actually distinct opcodes, but
16663 we distinguish them for clarity of the resulting assembler. */
16664 case NE: case LTGT:
16665 ccode = "ne"; break;
16666 case EQ: case UNEQ:
16667 ccode = "eq"; break;
16669 ccode = "ge"; break;
16670 case GT: case GTU: case UNGT:
16671 ccode = "gt"; break;
16673 ccode = "le"; break;
16674 case LT: case LTU: case UNLT:
16675 ccode = "lt"; break;
16676 case UNORDERED: ccode = "un"; break;
16677 case ORDERED: ccode = "nu"; break;
16678 case UNGE: ccode = "nl"; break;
16679 case UNLE: ccode = "ng"; break;
16681 gcc_unreachable ();
16684 /* Maybe we have a guess as to how likely the branch is.
16685 The old mnemonics don't have a way to specify this information. */
16687 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16688 if (note != NULL_RTX)
16690 /* PROB is the difference from 50%. */
16691 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16693 /* Only hint for highly probable/improbable branches on newer
16694 cpus as static prediction overrides processor dynamic
16695 prediction. For older cpus we may as well always hint, but
16696 assume not taken for branches that are very close to 50% as a
16697 mispredicted taken branch is more expensive than a
16698 mispredicted not-taken branch. */
16699 if (rs6000_always_hint
16700 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16701 && br_prob_note_reliable_p (note)))
16703 if (abs (prob) > REG_BR_PROB_BASE / 20
16704 && ((prob > 0) ^ need_longbranch))
16712 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16714 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16716 /* We need to escape any '%' characters in the reg_names string.
16717 Assume they'd only be the first character.... */
16718 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16720 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16724 /* If the branch distance was too far, we may have to use an
16725 unconditional branch to go the distance. */
16726 if (need_longbranch)
16727 s += sprintf (s, ",$+8\n\tb %s", label);
16729 s += sprintf (s, ",%s", label);
16735 /* Return the string to flip the GT bit on a CR. */
16737 output_e500_flip_gt_bit (rtx dst, rtx src)
16739 static char string[64];
16742 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16743 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16746 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16747 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16749 sprintf (string, "crnot %d,%d", a, b);
16753 /* Return insn for VSX or Altivec comparisons. */
16756 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16759 enum machine_mode mode = GET_MODE (op0);
16767 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16773 mask = gen_reg_rtx (mode);
16774 emit_insn (gen_rtx_SET (VOIDmode,
16776 gen_rtx_fmt_ee (code, mode, op0, op1)));
16783 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16784 DMODE is expected destination mode. This is a recursive function. */
16787 rs6000_emit_vector_compare (enum rtx_code rcode,
16789 enum machine_mode dmode)
16792 bool swap_operands = false;
16793 bool try_again = false;
16795 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16796 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16798 /* See if the comparison works as is. */
16799 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16807 swap_operands = true;
16812 swap_operands = true;
16820 /* Invert condition and try again.
16821 e.g., A != B becomes ~(A==B). */
16823 enum rtx_code rev_code;
16824 enum insn_code nor_code;
16827 rev_code = reverse_condition_maybe_unordered (rcode);
16828 if (rev_code == UNKNOWN)
16831 nor_code = optab_handler (one_cmpl_optab, dmode);
16832 if (nor_code == CODE_FOR_nothing)
16835 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16839 mask = gen_reg_rtx (dmode);
16840 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16848 /* Try GT/GTU/LT/LTU OR EQ */
16851 enum insn_code ior_code;
16852 enum rtx_code new_code;
16873 gcc_unreachable ();
16876 ior_code = optab_handler (ior_optab, dmode);
16877 if (ior_code == CODE_FOR_nothing)
16880 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16884 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16888 mask = gen_reg_rtx (dmode);
16889 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16907 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16912 /* You only get two chances. */
16916 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16917 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16918 operands for the relation operation COND. */
16921 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16922 rtx cond, rtx cc_op0, rtx cc_op1)
16924 enum machine_mode dest_mode = GET_MODE (dest);
16925 enum rtx_code rcode = GET_CODE (cond);
16926 enum machine_mode cc_mode = CCmode;
16930 bool invert_move = false;
16932 if (VECTOR_UNIT_NONE_P (dest_mode))
16937 /* Swap operands if we can, and fall back to doing the operation as
16938 specified, and doing a NOR to invert the test. */
16944 /* Invert condition and try again.
16945 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16946 invert_move = true;
16947 rcode = reverse_condition_maybe_unordered (rcode);
16948 if (rcode == UNKNOWN)
16952 /* Mark unsigned tests with CCUNSmode. */
16957 cc_mode = CCUNSmode;
16964 /* Get the vector mask for the given relational operations. */
16965 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16973 op_true = op_false;
16977 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16978 emit_insn (gen_rtx_SET (VOIDmode,
16980 gen_rtx_IF_THEN_ELSE (dest_mode,
16987 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16988 operands of the last comparison is nonzero/true, FALSE_COND if it
16989 is zero/false. Return 0 if the hardware has no such operation. */
16992 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16994 enum rtx_code code = GET_CODE (op);
16995 rtx op0 = XEXP (op, 0);
16996 rtx op1 = XEXP (op, 1);
16997 REAL_VALUE_TYPE c1;
16998 enum machine_mode compare_mode = GET_MODE (op0);
16999 enum machine_mode result_mode = GET_MODE (dest);
17001 bool is_against_zero;
17003 /* These modes should always match. */
17004 if (GET_MODE (op1) != compare_mode
17005 /* In the isel case however, we can use a compare immediate, so
17006 op1 may be a small constant. */
17007 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17009 if (GET_MODE (true_cond) != result_mode)
17011 if (GET_MODE (false_cond) != result_mode)
17014 /* First, work out if the hardware can do this at all, or
17015 if it's too slow.... */
17016 if (!FLOAT_MODE_P (compare_mode))
17019 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17022 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17023 && SCALAR_FLOAT_MODE_P (compare_mode))
17026 is_against_zero = op1 == CONST0_RTX (compare_mode);
17028 /* A floating-point subtract might overflow, underflow, or produce
17029 an inexact result, thus changing the floating-point flags, so it
17030 can't be generated if we care about that. It's safe if one side
17031 of the construct is zero, since then no subtract will be
17033 if (SCALAR_FLOAT_MODE_P (compare_mode)
17034 && flag_trapping_math && ! is_against_zero)
17037 /* Eliminate half of the comparisons by switching operands, this
17038 makes the remaining code simpler. */
17039 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17040 || code == LTGT || code == LT || code == UNLE)
17042 code = reverse_condition_maybe_unordered (code);
17044 true_cond = false_cond;
17048 /* UNEQ and LTGT take four instructions for a comparison with zero,
17049 it'll probably be faster to use a branch here too. */
17050 if (code == UNEQ && HONOR_NANS (compare_mode))
17053 if (GET_CODE (op1) == CONST_DOUBLE)
17054 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17056 /* We're going to try to implement comparisons by performing
17057 a subtract, then comparing against zero. Unfortunately,
17058 Inf - Inf is NaN which is not zero, and so if we don't
17059 know that the operand is finite and the comparison
17060 would treat EQ different to UNORDERED, we can't do it. */
17061 if (HONOR_INFINITIES (compare_mode)
17062 && code != GT && code != UNGE
17063 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17064 /* Constructs of the form (a OP b ? a : b) are safe. */
17065 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17066 || (! rtx_equal_p (op0, true_cond)
17067 && ! rtx_equal_p (op1, true_cond))))
17070 /* At this point we know we can use fsel. */
17072 /* Reduce the comparison to a comparison against zero. */
17073 if (! is_against_zero)
17075 temp = gen_reg_rtx (compare_mode);
17076 emit_insn (gen_rtx_SET (VOIDmode, temp,
17077 gen_rtx_MINUS (compare_mode, op0, op1)));
17079 op1 = CONST0_RTX (compare_mode);
17082 /* If we don't care about NaNs we can reduce some of the comparisons
17083 down to faster ones. */
17084 if (! HONOR_NANS (compare_mode))
17090 true_cond = false_cond;
17103 /* Now, reduce everything down to a GE. */
17110 temp = gen_reg_rtx (compare_mode);
17111 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17116 temp = gen_reg_rtx (compare_mode);
17117 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17122 temp = gen_reg_rtx (compare_mode);
17123 emit_insn (gen_rtx_SET (VOIDmode, temp,
17124 gen_rtx_NEG (compare_mode,
17125 gen_rtx_ABS (compare_mode, op0))));
17130 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17131 temp = gen_reg_rtx (result_mode);
17132 emit_insn (gen_rtx_SET (VOIDmode, temp,
17133 gen_rtx_IF_THEN_ELSE (result_mode,
17134 gen_rtx_GE (VOIDmode,
17136 true_cond, false_cond)));
17137 false_cond = true_cond;
17140 temp = gen_reg_rtx (compare_mode);
17141 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17146 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17147 temp = gen_reg_rtx (result_mode);
17148 emit_insn (gen_rtx_SET (VOIDmode, temp,
17149 gen_rtx_IF_THEN_ELSE (result_mode,
17150 gen_rtx_GE (VOIDmode,
17152 true_cond, false_cond)));
17153 true_cond = false_cond;
17156 temp = gen_reg_rtx (compare_mode);
17157 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17162 gcc_unreachable ();
17165 emit_insn (gen_rtx_SET (VOIDmode, dest,
17166 gen_rtx_IF_THEN_ELSE (result_mode,
17167 gen_rtx_GE (VOIDmode,
17169 true_cond, false_cond)));
17173 /* Same as above, but for ints (isel). */
17176 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17178 rtx condition_rtx, cr;
17179 enum machine_mode mode = GET_MODE (dest);
17180 enum rtx_code cond_code;
17181 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17184 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17187 /* We still have to do the compare, because isel doesn't do a
17188 compare, it just looks at the CRx bits set by a previous compare
17190 condition_rtx = rs6000_generate_compare (op, mode);
17191 cond_code = GET_CODE (condition_rtx);
17192 cr = XEXP (condition_rtx, 0);
17193 signedp = GET_MODE (cr) == CCmode;
17195 isel_func = (mode == SImode
17196 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17197 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17201 case LT: case GT: case LTU: case GTU: case EQ:
17202 /* isel handles these directly. */
17206 /* We need to swap the sense of the comparison. */
17209 true_cond = false_cond;
17211 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17216 false_cond = force_reg (mode, false_cond);
17217 if (true_cond != const0_rtx)
17218 true_cond = force_reg (mode, true_cond);
17220 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17226 output_isel (rtx *operands)
17228 enum rtx_code code;
17230 code = GET_CODE (operands[1]);
17232 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17234 gcc_assert (GET_CODE (operands[2]) == REG
17235 && GET_CODE (operands[3]) == REG);
17236 PUT_CODE (operands[1], reverse_condition (code));
17237 return "isel %0,%3,%2,%j1";
17240 return "isel %0,%2,%3,%j1";
17244 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17246 enum machine_mode mode = GET_MODE (op0);
17250 /* VSX/altivec have direct min/max insns. */
17251 if ((code == SMAX || code == SMIN)
17252 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17253 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17255 emit_insn (gen_rtx_SET (VOIDmode,
17257 gen_rtx_fmt_ee (code, mode, op0, op1)));
17261 if (code == SMAX || code == SMIN)
17266 if (code == SMAX || code == UMAX)
17267 target = emit_conditional_move (dest, c, op0, op1, mode,
17268 op0, op1, mode, 0);
17270 target = emit_conditional_move (dest, c, op0, op1, mode,
17271 op1, op0, mode, 0);
17272 gcc_assert (target);
17273 if (target != dest)
17274 emit_move_insn (dest, target);
17277 /* Emit instructions to perform a load-reserved/store-conditional operation.
17278 The operation performed is an atomic
17279 (set M (CODE:MODE M OP))
17280 If not NULL, BEFORE is atomically set to M before the operation, and
17281 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17282 If SYNC_P then a memory barrier is emitted before the operation.
17283 Either OP or M may be wrapped in a NOT operation. */
17286 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17287 rtx m, rtx op, rtx before_param, rtx after_param,
17290 enum machine_mode used_mode;
17291 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17294 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17295 rtx shift = NULL_RTX;
17298 emit_insn (gen_lwsync ());
17302 /* If this is smaller than SImode, we'll have to use SImode with
17304 if (mode == QImode || mode == HImode)
17308 if (MEM_ALIGN (used_m) >= 32)
17311 if (BYTES_BIG_ENDIAN)
17312 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17314 shift = GEN_INT (ishift);
17315 used_m = change_address (used_m, SImode, 0);
17319 rtx addrSI, aligned_addr;
17320 int shift_mask = mode == QImode ? 0x18 : 0x10;
17322 addrSI = gen_lowpart_common (SImode,
17323 force_reg (Pmode, XEXP (used_m, 0)));
17324 addrSI = force_reg (SImode, addrSI);
17325 shift = gen_reg_rtx (SImode);
17327 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17328 GEN_INT (shift_mask)));
17329 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17331 aligned_addr = expand_binop (Pmode, and_optab,
17333 GEN_INT (-4), NULL_RTX,
17334 1, OPTAB_LIB_WIDEN);
17335 used_m = change_address (used_m, SImode, aligned_addr);
17336 set_mem_align (used_m, 32);
17338 /* It's safe to keep the old alias set of USED_M, because
17339 the operation is atomic and only affects the original
17343 if (GET_CODE (op) == NOT)
17345 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17346 oldop = gen_rtx_NOT (SImode, oldop);
17349 oldop = lowpart_subreg (SImode, op, mode);
17355 newop = expand_binop (SImode, and_optab,
17356 oldop, GEN_INT (imask), NULL_RTX,
17357 1, OPTAB_LIB_WIDEN);
17358 emit_insn (gen_ashlsi3 (newop, newop, shift));
17361 case NOT: /* NAND */
17362 newop = expand_binop (SImode, ior_optab,
17363 oldop, GEN_INT (~imask), NULL_RTX,
17364 1, OPTAB_LIB_WIDEN);
17365 emit_insn (gen_rotlsi3 (newop, newop, shift));
17369 newop = expand_binop (SImode, ior_optab,
17370 oldop, GEN_INT (~imask), NULL_RTX,
17371 1, OPTAB_LIB_WIDEN);
17372 emit_insn (gen_rotlsi3 (newop, newop, shift));
17380 newop = expand_binop (SImode, and_optab,
17381 oldop, GEN_INT (imask), NULL_RTX,
17382 1, OPTAB_LIB_WIDEN);
17383 emit_insn (gen_ashlsi3 (newop, newop, shift));
17385 mask = gen_reg_rtx (SImode);
17386 emit_move_insn (mask, GEN_INT (imask));
17387 emit_insn (gen_ashlsi3 (mask, mask, shift));
17390 newop = gen_rtx_PLUS (SImode, m, newop);
17392 newop = gen_rtx_MINUS (SImode, m, newop);
17393 newop = gen_rtx_AND (SImode, newop, mask);
17394 newop = gen_rtx_IOR (SImode, newop,
17395 gen_rtx_AND (SImode,
17396 gen_rtx_NOT (SImode, mask),
17402 gcc_unreachable ();
17406 used_mode = SImode;
17407 before = gen_reg_rtx (used_mode);
17408 after = gen_reg_rtx (used_mode);
17413 before = before_param;
17414 after = after_param;
17416 if (before == NULL_RTX)
17417 before = gen_reg_rtx (used_mode);
17418 if (after == NULL_RTX)
17419 after = gen_reg_rtx (used_mode);
17422 if ((code == PLUS || code == MINUS)
17423 && used_mode != mode)
17424 the_op = op; /* Computed above. */
17425 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17426 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17427 else if (code == NOT)
17428 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17429 gen_rtx_NOT (used_mode, m),
17430 gen_rtx_NOT (used_mode, op));
17432 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17434 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17435 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17436 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17437 gen_rtx_UNSPEC (used_mode,
17438 gen_rtvec (1, the_op),
17440 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17442 if ((code == PLUS || code == MINUS) && used_mode != mode)
17443 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17444 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17446 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17447 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17449 /* Shift and mask the return values properly. */
17450 if (used_mode != mode && before_param)
17452 emit_insn (gen_lshrsi3 (before, before, shift));
17453 convert_move (before_param, before, 1);
17456 if (used_mode != mode && after_param)
17458 emit_insn (gen_lshrsi3 (after, after, shift));
17459 convert_move (after_param, after, 1);
17462 /* The previous sequence will end with a branch that's dependent on
17463 the conditional store, so placing an isync will ensure that no
17464 other instructions (especially, no load or store instructions)
17465 can start before the atomic operation completes. */
17467 emit_insn (gen_isync ());
17470 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17471 COND is true. Mark the jump as unlikely to be taken. */
17474 emit_unlikely_jump (rtx cond, rtx label)
17476 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17479 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17480 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17481 add_reg_note (x, REG_BR_PROB, very_unlikely);
17484 /* A subroutine of the atomic operation splitters. Emit a load-locked
17485 instruction in MODE. */
17488 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17490 rtx (*fn) (rtx, rtx) = NULL;
17491 if (mode == SImode)
17492 fn = gen_load_locked_si;
17493 else if (mode == DImode)
17494 fn = gen_load_locked_di;
17495 emit_insn (fn (reg, mem));
17498 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17499 instruction in MODE. */
17502 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17504 rtx (*fn) (rtx, rtx, rtx) = NULL;
17505 if (mode == SImode)
17506 fn = gen_store_conditional_si;
17507 else if (mode == DImode)
17508 fn = gen_store_conditional_di;
17510 /* Emit sync before stwcx. to address PPC405 Erratum. */
17511 if (PPC405_ERRATUM77)
17512 emit_insn (gen_memory_barrier ());
17514 emit_insn (fn (res, mem, val));
17517 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17518 to perform. MEM is the memory on which to operate. VAL is the second
17519 operand of the binary operator. BEFORE and AFTER are optional locations to
17520 return the value of MEM either before of after the operation. SCRATCH is
17521 a scratch register. */
17524 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17525 rtx before, rtx after, rtx scratch)
17527 enum machine_mode mode = GET_MODE (mem);
17528 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17530 emit_insn (gen_lwsync ());
17532 label = gen_label_rtx ();
17533 emit_label (label);
17534 label = gen_rtx_LABEL_REF (VOIDmode, label);
17536 if (before == NULL_RTX)
17538 emit_load_locked (mode, before, mem);
17541 x = gen_rtx_IOR (mode,
17542 gen_rtx_NOT (mode, before),
17543 gen_rtx_NOT (mode, val));
17544 else if (code == AND)
17545 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17547 x = gen_rtx_fmt_ee (code, mode, before, val);
17549 if (after != NULL_RTX)
17550 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17551 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17553 emit_store_conditional (mode, cond, mem, scratch);
17555 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17556 emit_unlikely_jump (x, label);
17558 emit_insn (gen_isync ());
17561 /* Expand an atomic compare and swap operation. MEM is the memory on which
17562 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17563 value to be stored. SCRATCH is a scratch GPR. */
17566 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17569 enum machine_mode mode = GET_MODE (mem);
17570 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17572 emit_insn (gen_lwsync ());
17574 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17575 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17576 emit_label (XEXP (label1, 0));
17578 emit_load_locked (mode, retval, mem);
17580 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17581 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17583 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17584 emit_unlikely_jump (x, label2);
17586 emit_move_insn (scratch, newval);
17587 emit_store_conditional (mode, cond, mem, scratch);
17589 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17590 emit_unlikely_jump (x, label1);
17592 emit_insn (gen_isync ());
17593 emit_label (XEXP (label2, 0));
17596 /* Expand an atomic test and set operation. MEM is the memory on which
17597 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17600 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17602 enum machine_mode mode = GET_MODE (mem);
17603 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17605 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17606 emit_label (XEXP (label, 0));
17608 emit_load_locked (mode, retval, mem);
17609 emit_move_insn (scratch, val);
17610 emit_store_conditional (mode, cond, mem, scratch);
17612 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17613 emit_unlikely_jump (x, label);
17615 emit_insn (gen_isync ());
17619 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17621 enum machine_mode mode = GET_MODE (mem);
17622 rtx addrSI, align, wdst, shift, mask;
17623 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17624 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17626 /* Shift amount for subword relative to aligned word. */
17627 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17628 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17629 shift = gen_reg_rtx (SImode);
17630 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17631 GEN_INT (shift_mask)));
17632 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17634 /* Shift and mask old value into position within word. */
17635 oldval = convert_modes (SImode, mode, oldval, 1);
17636 oldval = expand_binop (SImode, and_optab,
17637 oldval, GEN_INT (imask), NULL_RTX,
17638 1, OPTAB_LIB_WIDEN);
17639 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17641 /* Shift and mask new value into position within word. */
17642 newval = convert_modes (SImode, mode, newval, 1);
17643 newval = expand_binop (SImode, and_optab,
17644 newval, GEN_INT (imask), NULL_RTX,
17645 1, OPTAB_LIB_WIDEN);
17646 emit_insn (gen_ashlsi3 (newval, newval, shift));
17648 /* Mask for insertion. */
17649 mask = gen_reg_rtx (SImode);
17650 emit_move_insn (mask, GEN_INT (imask));
17651 emit_insn (gen_ashlsi3 (mask, mask, shift));
17653 /* Address of aligned word containing subword. */
17654 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17655 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17656 mem = change_address (mem, SImode, align);
17657 set_mem_align (mem, 32);
17658 MEM_VOLATILE_P (mem) = 1;
17660 wdst = gen_reg_rtx (SImode);
17661 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17662 oldval, newval, mem));
17664 /* Shift the result back. */
17665 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17667 emit_move_insn (dst, gen_lowpart (mode, wdst));
17671 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17672 rtx oldval, rtx newval, rtx mem,
17675 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17677 emit_insn (gen_lwsync ());
17678 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17679 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17680 emit_label (XEXP (label1, 0));
17682 emit_load_locked (SImode, scratch, mem);
17684 /* Mask subword within loaded value for comparison with oldval.
17685 Use UNSPEC_AND to avoid clobber.*/
17686 emit_insn (gen_rtx_SET (SImode, dest,
17687 gen_rtx_UNSPEC (SImode,
17688 gen_rtvec (2, scratch, mask),
17691 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17692 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17694 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17695 emit_unlikely_jump (x, label2);
17697 /* Clear subword within loaded value for insertion of new value. */
17698 emit_insn (gen_rtx_SET (SImode, scratch,
17699 gen_rtx_AND (SImode,
17700 gen_rtx_NOT (SImode, mask), scratch)));
17701 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17702 emit_store_conditional (SImode, cond, mem, scratch);
17704 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17705 emit_unlikely_jump (x, label1);
17707 emit_insn (gen_isync ());
17708 emit_label (XEXP (label2, 0));
17712 /* Emit instructions to move SRC to DST. Called by splitters for
17713 multi-register moves. It will emit at most one instruction for
17714 each register that is accessed; that is, it won't emit li/lis pairs
17715 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17719 rs6000_split_multireg_move (rtx dst, rtx src)
17721 /* The register number of the first register being moved. */
17723 /* The mode that is to be moved. */
17724 enum machine_mode mode;
17725 /* The mode that the move is being done in, and its size. */
17726 enum machine_mode reg_mode;
17728 /* The number of registers that will be moved. */
17731 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17732 mode = GET_MODE (dst);
17733 nregs = hard_regno_nregs[reg][mode];
17734 if (FP_REGNO_P (reg))
17735 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17736 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17737 else if (ALTIVEC_REGNO_P (reg))
17738 reg_mode = V16QImode;
17739 else if (TARGET_E500_DOUBLE && mode == TFmode)
17742 reg_mode = word_mode;
17743 reg_mode_size = GET_MODE_SIZE (reg_mode);
17745 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17747 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17749 /* Move register range backwards, if we might have destructive
17752 for (i = nregs - 1; i >= 0; i--)
17753 emit_insn (gen_rtx_SET (VOIDmode,
17754 simplify_gen_subreg (reg_mode, dst, mode,
17755 i * reg_mode_size),
17756 simplify_gen_subreg (reg_mode, src, mode,
17757 i * reg_mode_size)));
17763 bool used_update = false;
17764 rtx restore_basereg = NULL_RTX;
17766 if (MEM_P (src) && INT_REGNO_P (reg))
17770 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17771 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17774 breg = XEXP (XEXP (src, 0), 0);
17775 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17776 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17777 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17778 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17779 src = replace_equiv_address (src, breg);
17781 else if (! rs6000_offsettable_memref_p (src))
17783 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17785 rtx basereg = XEXP (XEXP (src, 0), 0);
17788 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17789 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17790 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17791 used_update = true;
17794 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17795 XEXP (XEXP (src, 0), 1)));
17796 src = replace_equiv_address (src, basereg);
17800 rtx basereg = gen_rtx_REG (Pmode, reg);
17801 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17802 src = replace_equiv_address (src, basereg);
17806 breg = XEXP (src, 0);
17807 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17808 breg = XEXP (breg, 0);
17810 /* If the base register we are using to address memory is
17811 also a destination reg, then change that register last. */
17813 && REGNO (breg) >= REGNO (dst)
17814 && REGNO (breg) < REGNO (dst) + nregs)
17815 j = REGNO (breg) - REGNO (dst);
17817 else if (MEM_P (dst) && INT_REGNO_P (reg))
17821 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17822 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17825 breg = XEXP (XEXP (dst, 0), 0);
17826 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17827 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17828 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17830 /* We have to update the breg before doing the store.
17831 Use store with update, if available. */
17835 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17836 emit_insn (TARGET_32BIT
17837 ? (TARGET_POWERPC64
17838 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17839 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17840 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17841 used_update = true;
17844 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17845 dst = replace_equiv_address (dst, breg);
17847 else if (!rs6000_offsettable_memref_p (dst)
17848 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17850 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17852 rtx basereg = XEXP (XEXP (dst, 0), 0);
17855 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17856 emit_insn (gen_rtx_SET (VOIDmode,
17857 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17858 used_update = true;
17861 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17862 XEXP (XEXP (dst, 0), 1)));
17863 dst = replace_equiv_address (dst, basereg);
17867 rtx basereg = XEXP (XEXP (dst, 0), 0);
17868 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17869 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17871 && REG_P (offsetreg)
17872 && REGNO (basereg) != REGNO (offsetreg));
17873 if (REGNO (basereg) == 0)
17875 rtx tmp = offsetreg;
17876 offsetreg = basereg;
17879 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17880 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17881 dst = replace_equiv_address (dst, basereg);
17884 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17885 gcc_assert (rs6000_offsettable_memref_p (dst));
17888 for (i = 0; i < nregs; i++)
17890 /* Calculate index to next subword. */
17895 /* If compiler already emitted move of first word by
17896 store with update, no need to do anything. */
17897 if (j == 0 && used_update)
17900 emit_insn (gen_rtx_SET (VOIDmode,
17901 simplify_gen_subreg (reg_mode, dst, mode,
17902 j * reg_mode_size),
17903 simplify_gen_subreg (reg_mode, src, mode,
17904 j * reg_mode_size)));
17906 if (restore_basereg != NULL_RTX)
17907 emit_insn (restore_basereg);
17912 /* This page contains routines that are used to determine what the
17913 function prologue and epilogue code will do and write them out. */
17915 /* Return the first fixed-point register that is required to be
17916 saved. 32 if none. */
17919 first_reg_to_save (void)
17923 /* Find lowest numbered live register. */
17924 for (first_reg = 13; first_reg <= 31; first_reg++)
17925 if (df_regs_ever_live_p (first_reg)
17926 && (! call_used_regs[first_reg]
17927 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17928 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17929 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17930 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17935 && crtl->uses_pic_offset_table
17936 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17937 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17943 /* Similar, for FP regs. */
17946 first_fp_reg_to_save (void)
17950 /* Find lowest numbered live register. */
17951 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17952 if (df_regs_ever_live_p (first_reg))
17958 /* Similar, for AltiVec regs. */
17961 first_altivec_reg_to_save (void)
17965 /* Stack frame remains as is unless we are in AltiVec ABI. */
17966 if (! TARGET_ALTIVEC_ABI)
17967 return LAST_ALTIVEC_REGNO + 1;
17969 /* On Darwin, the unwind routines are compiled without
17970 TARGET_ALTIVEC, and use save_world to save/restore the
17971 altivec registers when necessary. */
17972 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17973 && ! TARGET_ALTIVEC)
17974 return FIRST_ALTIVEC_REGNO + 20;
17976 /* Find lowest numbered live register. */
17977 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17978 if (df_regs_ever_live_p (i))
17984 /* Return a 32-bit mask of the AltiVec registers we need to set in
17985 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17986 the 32-bit word is 0. */
17988 static unsigned int
17989 compute_vrsave_mask (void)
17991 unsigned int i, mask = 0;
17993 /* On Darwin, the unwind routines are compiled without
17994 TARGET_ALTIVEC, and use save_world to save/restore the
17995 call-saved altivec registers when necessary. */
17996 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17997 && ! TARGET_ALTIVEC)
18000 /* First, find out if we use _any_ altivec registers. */
18001 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18002 if (df_regs_ever_live_p (i))
18003 mask |= ALTIVEC_REG_BIT (i);
18008 /* Next, remove the argument registers from the set. These must
18009 be in the VRSAVE mask set by the caller, so we don't need to add
18010 them in again. More importantly, the mask we compute here is
18011 used to generate CLOBBERs in the set_vrsave insn, and we do not
18012 wish the argument registers to die. */
18013 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18014 mask &= ~ALTIVEC_REG_BIT (i);
18016 /* Similarly, remove the return value from the set. */
18019 diddle_return_value (is_altivec_return_reg, &yes);
18021 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18027 /* For a very restricted set of circumstances, we can cut down the
18028 size of prologues/epilogues by calling our own save/restore-the-world
18032 compute_save_world_info (rs6000_stack_t *info_ptr)
18034 info_ptr->world_save_p = 1;
18035 info_ptr->world_save_p
18036 = (WORLD_SAVE_P (info_ptr)
18037 && DEFAULT_ABI == ABI_DARWIN
18038 && ! (cfun->calls_setjmp && flag_exceptions)
18039 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18040 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18041 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18042 && info_ptr->cr_save_p);
18044 /* This will not work in conjunction with sibcalls. Make sure there
18045 are none. (This check is expensive, but seldom executed.) */
18046 if (WORLD_SAVE_P (info_ptr))
18049 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18050 if ( GET_CODE (insn) == CALL_INSN
18051 && SIBLING_CALL_P (insn))
18053 info_ptr->world_save_p = 0;
18058 if (WORLD_SAVE_P (info_ptr))
18060 /* Even if we're not touching VRsave, make sure there's room on the
18061 stack for it, if it looks like we're calling SAVE_WORLD, which
18062 will attempt to save it. */
18063 info_ptr->vrsave_size = 4;
18065 /* If we are going to save the world, we need to save the link register too. */
18066 info_ptr->lr_save_p = 1;
18068 /* "Save" the VRsave register too if we're saving the world. */
18069 if (info_ptr->vrsave_mask == 0)
18070 info_ptr->vrsave_mask = compute_vrsave_mask ();
18072 /* Because the Darwin register save/restore routines only handle
18073 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18075 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18076 && (info_ptr->first_altivec_reg_save
18077 >= FIRST_SAVED_ALTIVEC_REGNO));
18084 is_altivec_return_reg (rtx reg, void *xyes)
18086 bool *yes = (bool *) xyes;
18087 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18092 /* Determine the strategy for savings/restoring registers. */
18095 SAVRES_MULTIPLE = 0x1,
18096 SAVE_INLINE_FPRS = 0x2,
18097 SAVE_INLINE_GPRS = 0x4,
18098 REST_INLINE_FPRS = 0x8,
18099 REST_INLINE_GPRS = 0x10,
18100 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18101 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18102 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18106 rs6000_savres_strategy (rs6000_stack_t *info,
18107 bool using_static_chain_p)
18111 if (TARGET_MULTIPLE
18112 && !TARGET_POWERPC64
18113 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18114 && info->first_gp_reg_save < 31
18115 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18116 strategy |= SAVRES_MULTIPLE;
18118 if (crtl->calls_eh_return
18119 || cfun->machine->ra_need_lr
18120 || info->total_size > 32767)
18121 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18122 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18124 if (info->first_fp_reg_save == 64
18125 || FP_SAVE_INLINE (info->first_fp_reg_save)
18126 /* The out-of-line FP routines use double-precision stores;
18127 we can't use those routines if we don't have such stores. */
18128 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18129 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18130 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18132 if (info->first_gp_reg_save == 32
18133 || GP_SAVE_INLINE (info->first_gp_reg_save)
18134 || !((strategy & SAVRES_MULTIPLE)
18135 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18136 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18138 /* Don't bother to try to save things out-of-line if r11 is occupied
18139 by the static chain. It would require too much fiddling and the
18140 static chain is rarely used anyway. */
18141 if (using_static_chain_p)
18142 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18144 /* If we are going to use store multiple, then don't even bother
18145 with the out-of-line routines, since the store-multiple
18146 instruction will always be smaller. */
18147 if ((strategy & SAVRES_MULTIPLE))
18148 strategy |= SAVE_INLINE_GPRS;
18150 /* The situation is more complicated with load multiple. We'd
18151 prefer to use the out-of-line routines for restores, since the
18152 "exit" out-of-line routines can handle the restore of LR and the
18153 frame teardown. However if doesn't make sense to use the
18154 out-of-line routine if that is the only reason we'd need to save
18155 LR, and we can't use the "exit" out-of-line gpr restore if we
18156 have saved some fprs; In those cases it is advantageous to use
18157 load multiple when available. */
18158 if ((strategy & SAVRES_MULTIPLE)
18159 && (!info->lr_save_p
18160 || info->first_fp_reg_save != 64))
18161 strategy |= REST_INLINE_GPRS;
18163 /* We can only use load multiple or the out-of-line routines to
18164 restore if we've used store multiple or out-of-line routines
18165 in the prologue, i.e. if we've saved all the registers from
18166 first_gp_reg_save. Otherwise, we risk loading garbage. */
18167 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18168 strategy |= REST_INLINE_GPRS;
18170 /* Saving CR interferes with the exit routines used on the SPE, so
18173 && info->spe_64bit_regs_used
18174 && info->cr_save_p)
18175 strategy |= REST_INLINE_GPRS;
18177 #ifdef POWERPC_LINUX
18180 if (!(strategy & SAVE_INLINE_FPRS))
18181 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18182 else if (!(strategy & SAVE_INLINE_GPRS)
18183 && info->first_fp_reg_save == 64)
18184 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18187 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18188 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18193 /* Calculate the stack information for the current function. This is
18194 complicated by having two separate calling sequences, the AIX calling
18195 sequence and the V.4 calling sequence.
18197 AIX (and Darwin/Mac OS X) stack frames look like:
18199 SP----> +---------------------------------------+
18200 | back chain to caller | 0 0
18201 +---------------------------------------+
18202 | saved CR | 4 8 (8-11)
18203 +---------------------------------------+
18205 +---------------------------------------+
18206 | reserved for compilers | 12 24
18207 +---------------------------------------+
18208 | reserved for binders | 16 32
18209 +---------------------------------------+
18210 | saved TOC pointer | 20 40
18211 +---------------------------------------+
18212 | Parameter save area (P) | 24 48
18213 +---------------------------------------+
18214 | Alloca space (A) | 24+P etc.
18215 +---------------------------------------+
18216 | Local variable space (L) | 24+P+A
18217 +---------------------------------------+
18218 | Float/int conversion temporary (X) | 24+P+A+L
18219 +---------------------------------------+
18220 | Save area for AltiVec registers (W) | 24+P+A+L+X
18221 +---------------------------------------+
18222 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18223 +---------------------------------------+
18224 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18225 +---------------------------------------+
18226 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18227 +---------------------------------------+
18228 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18229 +---------------------------------------+
18230 old SP->| back chain to caller's caller |
18231 +---------------------------------------+
18233 The required alignment for AIX configurations is two words (i.e., 8
18237 V.4 stack frames look like:
18239 SP----> +---------------------------------------+
18240 | back chain to caller | 0
18241 +---------------------------------------+
18242 | caller's saved LR | 4
18243 +---------------------------------------+
18244 | Parameter save area (P) | 8
18245 +---------------------------------------+
18246 | Alloca space (A) | 8+P
18247 +---------------------------------------+
18248 | Varargs save area (V) | 8+P+A
18249 +---------------------------------------+
18250 | Local variable space (L) | 8+P+A+V
18251 +---------------------------------------+
18252 | Float/int conversion temporary (X) | 8+P+A+V+L
18253 +---------------------------------------+
18254 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18255 +---------------------------------------+
18256 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18257 +---------------------------------------+
18258 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18259 +---------------------------------------+
18260 | SPE: area for 64-bit GP registers |
18261 +---------------------------------------+
18262 | SPE alignment padding |
18263 +---------------------------------------+
18264 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18265 +---------------------------------------+
18266 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18267 +---------------------------------------+
18268 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18269 +---------------------------------------+
18270 old SP->| back chain to caller's caller |
18271 +---------------------------------------+
18273 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18274 given. (But note below and in sysv4.h that we require only 8 and
18275 may round up the size of our stack frame anyways. The historical
18276 reason is early versions of powerpc-linux which didn't properly
18277 align the stack at program startup. A happy side-effect is that
18278 -mno-eabi libraries can be used with -meabi programs.)
18280 The EABI configuration defaults to the V.4 layout. However,
18281 the stack alignment requirements may differ. If -mno-eabi is not
18282 given, the required stack alignment is 8 bytes; if -mno-eabi is
18283 given, the required alignment is 16 bytes. (But see V.4 comment
18286 #ifndef ABI_STACK_BOUNDARY
18287 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18290 static rs6000_stack_t *
18291 rs6000_stack_info (void)
18293 #ifdef ENABLE_CHECKING
18294 static rs6000_stack_t info_save;
18296 rs6000_stack_t *info_ptr = &stack_info;
18297 int reg_size = TARGET_32BIT ? 4 : 8;
18301 HOST_WIDE_INT non_fixed_size;
18302 bool using_static_chain_p;
18304 #ifdef ENABLE_CHECKING
18305 memcpy (&info_save, &stack_info, sizeof stack_info);
18307 if (reload_completed && info_ptr->reload_completed)
18311 memset (&stack_info, 0, sizeof (stack_info));
18312 info_ptr->reload_completed = reload_completed;
18316 /* Cache value so we don't rescan instruction chain over and over. */
18317 if (cfun->machine->insn_chain_scanned_p == 0)
18318 cfun->machine->insn_chain_scanned_p
18319 = spe_func_has_64bit_regs_p () + 1;
18320 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18323 /* Select which calling sequence. */
18324 info_ptr->abi = DEFAULT_ABI;
18326 /* Calculate which registers need to be saved & save area size. */
18327 info_ptr->first_gp_reg_save = first_reg_to_save ();
18328 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18329 even if it currently looks like we won't. Reload may need it to
18330 get at a constant; if so, it will have already created a constant
18331 pool entry for it. */
18332 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18333 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18334 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18335 && crtl->uses_const_pool
18336 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18337 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18339 first_gp = info_ptr->first_gp_reg_save;
18341 info_ptr->gp_size = reg_size * (32 - first_gp);
18343 /* For the SPE, we have an additional upper 32-bits on each GPR.
18344 Ideally we should save the entire 64-bits only when the upper
18345 half is used in SIMD instructions. Since we only record
18346 registers live (not the size they are used in), this proves
18347 difficult because we'd have to traverse the instruction chain at
18348 the right time, taking reload into account. This is a real pain,
18349 so we opt to save the GPRs in 64-bits always if but one register
18350 gets used in 64-bits. Otherwise, all the registers in the frame
18351 get saved in 32-bits.
18353 So... since when we save all GPRs (except the SP) in 64-bits, the
18354 traditional GP save area will be empty. */
18355 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18356 info_ptr->gp_size = 0;
18358 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18359 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18361 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18362 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18363 - info_ptr->first_altivec_reg_save);
18365 /* Does this function call anything? */
18366 info_ptr->calls_p = (! current_function_is_leaf
18367 || cfun->machine->ra_needs_full_frame);
18369 /* Determine if we need to save the condition code registers. */
18370 if (df_regs_ever_live_p (CR2_REGNO)
18371 || df_regs_ever_live_p (CR3_REGNO)
18372 || df_regs_ever_live_p (CR4_REGNO))
18374 info_ptr->cr_save_p = 1;
18375 if (DEFAULT_ABI == ABI_V4)
18376 info_ptr->cr_size = reg_size;
18379 /* If the current function calls __builtin_eh_return, then we need
18380 to allocate stack space for registers that will hold data for
18381 the exception handler. */
18382 if (crtl->calls_eh_return)
18385 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18388 /* SPE saves EH registers in 64-bits. */
18389 ehrd_size = i * (TARGET_SPE_ABI
18390 && info_ptr->spe_64bit_regs_used != 0
18391 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18396 /* Determine various sizes. */
18397 info_ptr->reg_size = reg_size;
18398 info_ptr->fixed_size = RS6000_SAVE_AREA;
18399 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18400 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18401 TARGET_ALTIVEC ? 16 : 8);
18402 if (FRAME_GROWS_DOWNWARD)
18403 info_ptr->vars_size
18404 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18405 + info_ptr->parm_size,
18406 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18407 - (info_ptr->fixed_size + info_ptr->vars_size
18408 + info_ptr->parm_size);
18410 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18411 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18413 info_ptr->spe_gp_size = 0;
18415 if (TARGET_ALTIVEC_ABI)
18416 info_ptr->vrsave_mask = compute_vrsave_mask ();
18418 info_ptr->vrsave_mask = 0;
18420 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18421 info_ptr->vrsave_size = 4;
18423 info_ptr->vrsave_size = 0;
18425 compute_save_world_info (info_ptr);
18427 /* Calculate the offsets. */
18428 switch (DEFAULT_ABI)
18432 gcc_unreachable ();
18436 info_ptr->fp_save_offset = - info_ptr->fp_size;
18437 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18439 if (TARGET_ALTIVEC_ABI)
18441 info_ptr->vrsave_save_offset
18442 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18444 /* Align stack so vector save area is on a quadword boundary.
18445 The padding goes above the vectors. */
18446 if (info_ptr->altivec_size != 0)
18447 info_ptr->altivec_padding_size
18448 = info_ptr->vrsave_save_offset & 0xF;
18450 info_ptr->altivec_padding_size = 0;
18452 info_ptr->altivec_save_offset
18453 = info_ptr->vrsave_save_offset
18454 - info_ptr->altivec_padding_size
18455 - info_ptr->altivec_size;
18456 gcc_assert (info_ptr->altivec_size == 0
18457 || info_ptr->altivec_save_offset % 16 == 0);
18459 /* Adjust for AltiVec case. */
18460 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18463 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18464 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18465 info_ptr->lr_save_offset = 2*reg_size;
18469 info_ptr->fp_save_offset = - info_ptr->fp_size;
18470 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18471 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18473 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18475 /* Align stack so SPE GPR save area is aligned on a
18476 double-word boundary. */
18477 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18478 info_ptr->spe_padding_size
18479 = 8 - (-info_ptr->cr_save_offset % 8);
18481 info_ptr->spe_padding_size = 0;
18483 info_ptr->spe_gp_save_offset
18484 = info_ptr->cr_save_offset
18485 - info_ptr->spe_padding_size
18486 - info_ptr->spe_gp_size;
18488 /* Adjust for SPE case. */
18489 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18491 else if (TARGET_ALTIVEC_ABI)
18493 info_ptr->vrsave_save_offset
18494 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18496 /* Align stack so vector save area is on a quadword boundary. */
18497 if (info_ptr->altivec_size != 0)
18498 info_ptr->altivec_padding_size
18499 = 16 - (-info_ptr->vrsave_save_offset % 16);
18501 info_ptr->altivec_padding_size = 0;
18503 info_ptr->altivec_save_offset
18504 = info_ptr->vrsave_save_offset
18505 - info_ptr->altivec_padding_size
18506 - info_ptr->altivec_size;
18508 /* Adjust for AltiVec case. */
18509 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18512 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18513 info_ptr->ehrd_offset -= ehrd_size;
18514 info_ptr->lr_save_offset = reg_size;
18518 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18519 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18520 + info_ptr->gp_size
18521 + info_ptr->altivec_size
18522 + info_ptr->altivec_padding_size
18523 + info_ptr->spe_gp_size
18524 + info_ptr->spe_padding_size
18526 + info_ptr->cr_size
18527 + info_ptr->vrsave_size,
18530 non_fixed_size = (info_ptr->vars_size
18531 + info_ptr->parm_size
18532 + info_ptr->save_size);
18534 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18535 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18537 /* Determine if we need to save the link register. */
18538 if (info_ptr->calls_p
18539 || (DEFAULT_ABI == ABI_AIX
18541 && !TARGET_PROFILE_KERNEL)
18542 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18543 #ifdef TARGET_RELOCATABLE
18544 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18546 || rs6000_ra_ever_killed ())
18547 info_ptr->lr_save_p = 1;
18549 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18550 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18551 && call_used_regs[STATIC_CHAIN_REGNUM]);
18552 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18553 using_static_chain_p);
18555 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18556 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18557 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18558 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18559 info_ptr->lr_save_p = 1;
18561 if (info_ptr->lr_save_p)
18562 df_set_regs_ever_live (LR_REGNO, true);
18564 /* Determine if we need to allocate any stack frame:
18566 For AIX we need to push the stack if a frame pointer is needed
18567 (because the stack might be dynamically adjusted), if we are
18568 debugging, if we make calls, or if the sum of fp_save, gp_save,
18569 and local variables are more than the space needed to save all
18570 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18571 + 18*8 = 288 (GPR13 reserved).
18573 For V.4 we don't have the stack cushion that AIX uses, but assume
18574 that the debugger can handle stackless frames. */
18576 if (info_ptr->calls_p)
18577 info_ptr->push_p = 1;
18579 else if (DEFAULT_ABI == ABI_V4)
18580 info_ptr->push_p = non_fixed_size != 0;
18582 else if (frame_pointer_needed)
18583 info_ptr->push_p = 1;
18585 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18586 info_ptr->push_p = 1;
18589 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18591 /* Zero offsets if we're not saving those registers. */
18592 if (info_ptr->fp_size == 0)
18593 info_ptr->fp_save_offset = 0;
18595 if (info_ptr->gp_size == 0)
18596 info_ptr->gp_save_offset = 0;
18598 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18599 info_ptr->altivec_save_offset = 0;
18601 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18602 info_ptr->vrsave_save_offset = 0;
18604 if (! TARGET_SPE_ABI
18605 || info_ptr->spe_64bit_regs_used == 0
18606 || info_ptr->spe_gp_size == 0)
18607 info_ptr->spe_gp_save_offset = 0;
18609 if (! info_ptr->lr_save_p)
18610 info_ptr->lr_save_offset = 0;
18612 if (! info_ptr->cr_save_p)
18613 info_ptr->cr_save_offset = 0;
18615 #ifdef ENABLE_CHECKING
18616 gcc_assert (!(reload_completed && info_save.reload_completed)
18617 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
18622 /* Return true if the current function uses any GPRs in 64-bit SIMD
18626 spe_func_has_64bit_regs_p (void)
18630 /* Functions that save and restore all the call-saved registers will
18631 need to save/restore the registers in 64-bits. */
18632 if (crtl->calls_eh_return
18633 || cfun->calls_setjmp
18634 || crtl->has_nonlocal_goto)
18637 insns = get_insns ();
18639 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18645 /* FIXME: This should be implemented with attributes...
18647 (set_attr "spe64" "true")....then,
18648 if (get_spe64(insn)) return true;
18650 It's the only reliable way to do the stuff below. */
18652 i = PATTERN (insn);
18653 if (GET_CODE (i) == SET)
18655 enum machine_mode mode = GET_MODE (SET_SRC (i));
18657 if (SPE_VECTOR_MODE (mode))
18659 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18669 debug_stack_info (rs6000_stack_t *info)
18671 const char *abi_string;
18674 info = rs6000_stack_info ();
18676 fprintf (stderr, "\nStack information for function %s:\n",
18677 ((current_function_decl && DECL_NAME (current_function_decl))
18678 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18683 default: abi_string = "Unknown"; break;
18684 case ABI_NONE: abi_string = "NONE"; break;
18685 case ABI_AIX: abi_string = "AIX"; break;
18686 case ABI_DARWIN: abi_string = "Darwin"; break;
18687 case ABI_V4: abi_string = "V.4"; break;
18690 fprintf (stderr, "\tABI = %5s\n", abi_string);
18692 if (TARGET_ALTIVEC_ABI)
18693 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18695 if (TARGET_SPE_ABI)
18696 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18698 if (info->first_gp_reg_save != 32)
18699 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18701 if (info->first_fp_reg_save != 64)
18702 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18704 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18705 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18706 info->first_altivec_reg_save);
18708 if (info->lr_save_p)
18709 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18711 if (info->cr_save_p)
18712 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18714 if (info->vrsave_mask)
18715 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18718 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18721 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18723 if (info->gp_save_offset)
18724 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18726 if (info->fp_save_offset)
18727 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18729 if (info->altivec_save_offset)
18730 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18731 info->altivec_save_offset);
18733 if (info->spe_gp_save_offset)
18734 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18735 info->spe_gp_save_offset);
18737 if (info->vrsave_save_offset)
18738 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18739 info->vrsave_save_offset);
18741 if (info->lr_save_offset)
18742 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18744 if (info->cr_save_offset)
18745 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18747 if (info->varargs_save_offset)
18748 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18750 if (info->total_size)
18751 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18754 if (info->vars_size)
18755 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18758 if (info->parm_size)
18759 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18761 if (info->fixed_size)
18762 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18765 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18767 if (info->spe_gp_size)
18768 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18771 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18773 if (info->altivec_size)
18774 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18776 if (info->vrsave_size)
18777 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18779 if (info->altivec_padding_size)
18780 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18781 info->altivec_padding_size);
18783 if (info->spe_padding_size)
18784 fprintf (stderr, "\tspe_padding_size = %5d\n",
18785 info->spe_padding_size);
18788 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18790 if (info->save_size)
18791 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18793 if (info->reg_size != 4)
18794 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18796 fprintf (stderr, "\n");
18800 rs6000_return_addr (int count, rtx frame)
18802 /* Currently we don't optimize very well between prolog and body
18803 code and for PIC code the code can be actually quite bad, so
18804 don't try to be too clever here. */
18805 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18807 cfun->machine->ra_needs_full_frame = 1;
18814 plus_constant (copy_to_reg
18815 (gen_rtx_MEM (Pmode,
18816 memory_address (Pmode, frame))),
18817 RETURN_ADDRESS_OFFSET)));
18820 cfun->machine->ra_need_lr = 1;
18821 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18824 /* Say whether a function is a candidate for sibcall handling or not.
18825 We do not allow indirect calls to be optimized into sibling calls.
18826 Also, we can't do it if there are any vector parameters; there's
18827 nowhere to put the VRsave code so it works; note that functions with
18828 vector parameters are required to have a prototype, so the argument
18829 type info must be available here. (The tail recursion case can work
18830 with vector parameters, but there's no way to distinguish here.) */
18832 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18837 if (TARGET_ALTIVEC_VRSAVE)
18839 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18840 type; type = TREE_CHAIN (type))
18842 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18846 if (DEFAULT_ABI == ABI_DARWIN
18847 || ((*targetm.binds_local_p) (decl)
18848 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18850 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18852 if (!lookup_attribute ("longcall", attr_list)
18853 || lookup_attribute ("shortcall", attr_list))
18860 /* NULL if INSN insn is valid within a low-overhead loop.
18861 Otherwise return why doloop cannot be applied.
18862 PowerPC uses the COUNT register for branch on table instructions. */
18864 static const char *
18865 rs6000_invalid_within_doloop (const_rtx insn)
18868 return "Function call in the loop.";
18871 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18872 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18873 return "Computed branch in the loop.";
18879 rs6000_ra_ever_killed (void)
18885 if (cfun->is_thunk)
18888 if (cfun->machine->lr_save_state)
18889 return cfun->machine->lr_save_state - 1;
18891 /* regs_ever_live has LR marked as used if any sibcalls are present,
18892 but this should not force saving and restoring in the
18893 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18894 clobbers LR, so that is inappropriate. */
18896 /* Also, the prologue can generate a store into LR that
18897 doesn't really count, like this:
18900 bcl to set PIC register
18904 When we're called from the epilogue, we need to avoid counting
18905 this as a store. */
18907 push_topmost_sequence ();
18908 top = get_insns ();
18909 pop_topmost_sequence ();
18910 reg = gen_rtx_REG (Pmode, LR_REGNO);
18912 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18918 if (!SIBLING_CALL_P (insn))
18921 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18923 else if (set_of (reg, insn) != NULL_RTX
18924 && !prologue_epilogue_contains (insn))
18931 /* Emit instructions needed to load the TOC register.
18932 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18933 a constant pool; or for SVR4 -fpic. */
18936 rs6000_emit_load_toc_table (int fromprolog)
18939 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18941 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18944 rtx lab, tmp1, tmp2, got;
18946 lab = gen_label_rtx ();
18947 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18948 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18950 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18952 got = rs6000_got_sym ();
18953 tmp1 = tmp2 = dest;
18956 tmp1 = gen_reg_rtx (Pmode);
18957 tmp2 = gen_reg_rtx (Pmode);
18959 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18960 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18961 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18962 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18964 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18966 emit_insn (gen_load_toc_v4_pic_si ());
18967 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18969 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18972 rtx temp0 = (fromprolog
18973 ? gen_rtx_REG (Pmode, 0)
18974 : gen_reg_rtx (Pmode));
18980 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18981 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18983 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18984 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18986 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18987 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18988 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18994 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18995 lab = gen_label_rtx ();
18996 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
18997 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18998 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19000 emit_insn (gen_addsi3 (dest, temp0, dest));
19002 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19004 /* This is for AIX code running in non-PIC ELF32. */
19007 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19008 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19010 emit_insn (gen_elf_high (dest, realsym));
19011 emit_insn (gen_elf_low (dest, dest, realsym));
19015 gcc_assert (DEFAULT_ABI == ABI_AIX);
19018 emit_insn (gen_load_toc_aix_si (dest));
19020 emit_insn (gen_load_toc_aix_di (dest));
19024 /* Emit instructions to restore the link register after determining where
19025 its value has been stored. */
19028 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19030 rs6000_stack_t *info = rs6000_stack_info ();
19033 operands[0] = source;
19034 operands[1] = scratch;
19036 if (info->lr_save_p)
19038 rtx frame_rtx = stack_pointer_rtx;
19039 HOST_WIDE_INT sp_offset = 0;
19042 if (frame_pointer_needed
19043 || cfun->calls_alloca
19044 || info->total_size > 32767)
19046 tmp = gen_frame_mem (Pmode, frame_rtx);
19047 emit_move_insn (operands[1], tmp);
19048 frame_rtx = operands[1];
19050 else if (info->push_p)
19051 sp_offset = info->total_size;
19053 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19054 tmp = gen_frame_mem (Pmode, tmp);
19055 emit_move_insn (tmp, operands[0]);
19058 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19060 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19061 state of lr_save_p so any change from here on would be a bug. In
19062 particular, stop rs6000_ra_ever_killed from considering the SET
19063 of lr we may have added just above. */
19064 cfun->machine->lr_save_state = info->lr_save_p + 1;
19067 static GTY(()) alias_set_type set = -1;
19070 get_TOC_alias_set (void)
19073 set = new_alias_set ();
19077 /* This returns nonzero if the current function uses the TOC. This is
19078 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19079 is generated by the ABI_V4 load_toc_* patterns. */
19086 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19089 rtx pat = PATTERN (insn);
19092 if (GET_CODE (pat) == PARALLEL)
19093 for (i = 0; i < XVECLEN (pat, 0); i++)
19095 rtx sub = XVECEXP (pat, 0, i);
19096 if (GET_CODE (sub) == USE)
19098 sub = XEXP (sub, 0);
19099 if (GET_CODE (sub) == UNSPEC
19100 && XINT (sub, 1) == UNSPEC_TOC)
19110 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19112 rtx tocrel, tocreg;
19114 if (TARGET_DEBUG_ADDR)
19116 if (GET_CODE (symbol) == SYMBOL_REF)
19117 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19121 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19122 GET_RTX_NAME (GET_CODE (symbol)));
19123 debug_rtx (symbol);
19127 if (!can_create_pseudo_p ())
19128 df_set_regs_ever_live (TOC_REGISTER, true);
19130 tocrel = gen_rtx_CONST (Pmode,
19131 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19133 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19134 if (TARGET_CMODEL != CMODEL_SMALL)
19136 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19137 if (largetoc_reg != NULL)
19139 emit_move_insn (largetoc_reg, hi);
19142 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19145 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19148 /* Issue assembly directives that create a reference to the given DWARF
19149 FRAME_TABLE_LABEL from the current function section. */
19151 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19153 fprintf (asm_out_file, "\t.ref %s\n",
19154 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19157 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19158 and the change to the stack pointer. */
19161 rs6000_emit_stack_tie (void)
19163 rtx mem = gen_frame_mem (BLKmode,
19164 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19166 emit_insn (gen_stack_tie (mem));
19169 /* Emit the correct code for allocating stack space, as insns.
19170 If COPY_REG, make sure a copy of the old frame is left there.
19171 The generated code may use hard register 0 as a temporary. */
19174 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19177 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19178 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19179 rtx todec = gen_int_mode (-size, Pmode);
19182 if (INTVAL (todec) != -size)
19184 warning (0, "stack frame too large");
19185 emit_insn (gen_trap ());
19189 if (crtl->limit_stack)
19191 if (REG_P (stack_limit_rtx)
19192 && REGNO (stack_limit_rtx) > 1
19193 && REGNO (stack_limit_rtx) <= 31)
19195 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19196 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19199 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19201 && DEFAULT_ABI == ABI_V4)
19203 rtx toload = gen_rtx_CONST (VOIDmode,
19204 gen_rtx_PLUS (Pmode,
19208 emit_insn (gen_elf_high (tmp_reg, toload));
19209 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19210 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19214 warning (0, "stack limit expression is not supported");
19218 emit_move_insn (copy_reg, stack_reg);
19222 /* Need a note here so that try_split doesn't get confused. */
19223 if (get_last_insn () == NULL_RTX)
19224 emit_note (NOTE_INSN_DELETED);
19225 insn = emit_move_insn (tmp_reg, todec);
19226 try_split (PATTERN (insn), insn, 0);
19230 insn = emit_insn (TARGET_32BIT
19231 ? gen_movsi_update_stack (stack_reg, stack_reg,
19233 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19234 todec, stack_reg));
19235 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19236 it now and set the alias set/attributes. The above gen_*_update
19237 calls will generate a PARALLEL with the MEM set being the first
19239 par = PATTERN (insn);
19240 gcc_assert (GET_CODE (par) == PARALLEL);
19241 set = XVECEXP (par, 0, 0);
19242 gcc_assert (GET_CODE (set) == SET);
19243 mem = SET_DEST (set);
19244 gcc_assert (MEM_P (mem));
19245 MEM_NOTRAP_P (mem) = 1;
19246 set_mem_alias_set (mem, get_frame_alias_set ());
19248 RTX_FRAME_RELATED_P (insn) = 1;
19249 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19250 gen_rtx_SET (VOIDmode, stack_reg,
19251 gen_rtx_PLUS (Pmode, stack_reg,
19252 GEN_INT (-size))));
19255 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19257 #if PROBE_INTERVAL > 32768
19258 #error Cannot use indexed addressing mode for stack probing
19261 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19262 inclusive. These are offsets from the current stack pointer. */
19265 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19267 /* See if we have a constant small number of probes to generate. If so,
19268 that's the easy case. */
19269 if (first + size <= 32768)
19273 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19274 it exceeds SIZE. If only one probe is needed, this will not
19275 generate any code. Then probe at FIRST + SIZE. */
19276 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19277 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19279 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19282 /* Otherwise, do the same as above, but in a loop. Note that we must be
19283 extra careful with variables wrapping around because we might be at
19284 the very top (or the very bottom) of the address space and we have
19285 to be able to handle this case properly; in particular, we use an
19286 equality test for the loop condition. */
19289 HOST_WIDE_INT rounded_size;
19290 rtx r12 = gen_rtx_REG (Pmode, 12);
19291 rtx r0 = gen_rtx_REG (Pmode, 0);
19293 /* Sanity check for the addressing mode we're going to use. */
19294 gcc_assert (first <= 32768);
19296 /* Step 1: round SIZE to the previous multiple of the interval. */
19298 rounded_size = size & -PROBE_INTERVAL;
19301 /* Step 2: compute initial and final value of the loop counter. */
19303 /* TEST_ADDR = SP + FIRST. */
19304 emit_insn (gen_rtx_SET (VOIDmode, r12,
19305 plus_constant (stack_pointer_rtx, -first)));
19307 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19308 if (rounded_size > 32768)
19310 emit_move_insn (r0, GEN_INT (-rounded_size));
19311 emit_insn (gen_rtx_SET (VOIDmode, r0,
19312 gen_rtx_PLUS (Pmode, r12, r0)));
19315 emit_insn (gen_rtx_SET (VOIDmode, r0,
19316 plus_constant (r12, -rounded_size)));
19319 /* Step 3: the loop
19321 while (TEST_ADDR != LAST_ADDR)
19323 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19327 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19328 until it is equal to ROUNDED_SIZE. */
19331 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19333 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19336 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19337 that SIZE is equal to ROUNDED_SIZE. */
19339 if (size != rounded_size)
19340 emit_stack_probe (plus_constant (r12, rounded_size - size));
19344 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19345 absolute addresses. */
19348 output_probe_stack_range (rtx reg1, rtx reg2)
19350 static int labelno = 0;
19351 char loop_lab[32], end_lab[32];
19354 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19355 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19357 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19359 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19363 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19365 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19367 fputs ("\tbeq 0,", asm_out_file);
19368 assemble_name_raw (asm_out_file, end_lab);
19369 fputc ('\n', asm_out_file);
19371 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19372 xops[1] = GEN_INT (-PROBE_INTERVAL);
19373 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19375 /* Probe at TEST_ADDR and branch. */
19376 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19377 fprintf (asm_out_file, "\tb ");
19378 assemble_name_raw (asm_out_file, loop_lab);
19379 fputc ('\n', asm_out_file);
19381 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19386 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19387 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19388 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19389 deduce these equivalences by itself so it wasn't necessary to hold
19390 its hand so much. */
19393 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19394 rtx reg2, rtx rreg)
19398 /* copy_rtx will not make unique copies of registers, so we need to
19399 ensure we don't have unwanted sharing here. */
19401 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19404 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19406 real = copy_rtx (PATTERN (insn));
19408 if (reg2 != NULL_RTX)
19409 real = replace_rtx (real, reg2, rreg);
19411 real = replace_rtx (real, reg,
19412 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19413 STACK_POINTER_REGNUM),
19416 /* We expect that 'real' is either a SET or a PARALLEL containing
19417 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19418 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19420 if (GET_CODE (real) == SET)
19424 temp = simplify_rtx (SET_SRC (set));
19426 SET_SRC (set) = temp;
19427 temp = simplify_rtx (SET_DEST (set));
19429 SET_DEST (set) = temp;
19430 if (GET_CODE (SET_DEST (set)) == MEM)
19432 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19434 XEXP (SET_DEST (set), 0) = temp;
19441 gcc_assert (GET_CODE (real) == PARALLEL);
19442 for (i = 0; i < XVECLEN (real, 0); i++)
19443 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19445 rtx set = XVECEXP (real, 0, i);
19447 temp = simplify_rtx (SET_SRC (set));
19449 SET_SRC (set) = temp;
19450 temp = simplify_rtx (SET_DEST (set));
19452 SET_DEST (set) = temp;
19453 if (GET_CODE (SET_DEST (set)) == MEM)
19455 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19457 XEXP (SET_DEST (set), 0) = temp;
19459 RTX_FRAME_RELATED_P (set) = 1;
19463 RTX_FRAME_RELATED_P (insn) = 1;
19464 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19467 /* Returns an insn that has a vrsave set operation with the
19468 appropriate CLOBBERs. */
19471 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19474 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19475 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19478 = gen_rtx_SET (VOIDmode,
19480 gen_rtx_UNSPEC_VOLATILE (SImode,
19481 gen_rtvec (2, reg, vrsave),
19482 UNSPECV_SET_VRSAVE));
19486 /* We need to clobber the registers in the mask so the scheduler
19487 does not move sets to VRSAVE before sets of AltiVec registers.
19489 However, if the function receives nonlocal gotos, reload will set
19490 all call saved registers live. We will end up with:
19492 (set (reg 999) (mem))
19493 (parallel [ (set (reg vrsave) (unspec blah))
19494 (clobber (reg 999))])
19496 The clobber will cause the store into reg 999 to be dead, and
19497 flow will attempt to delete an epilogue insn. In this case, we
19498 need an unspec use/set of the register. */
19500 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19501 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19503 if (!epiloguep || call_used_regs [i])
19504 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19505 gen_rtx_REG (V4SImode, i));
19508 rtx reg = gen_rtx_REG (V4SImode, i);
19511 = gen_rtx_SET (VOIDmode,
19513 gen_rtx_UNSPEC (V4SImode,
19514 gen_rtvec (1, reg), 27));
19518 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19520 for (i = 0; i < nclobs; ++i)
19521 XVECEXP (insn, 0, i) = clobs[i];
19526 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19527 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19530 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19531 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19533 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19534 rtx replacea, replaceb;
19536 int_rtx = GEN_INT (offset);
19538 /* Some cases that need register indexed addressing. */
19539 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19540 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19541 || (TARGET_E500_DOUBLE && mode == DFmode)
19543 && SPE_VECTOR_MODE (mode)
19544 && !SPE_CONST_OFFSET_OK (offset)))
19546 /* Whomever calls us must make sure r11 is available in the
19547 flow path of instructions in the prologue. */
19548 offset_rtx = gen_rtx_REG (Pmode, 11);
19549 emit_move_insn (offset_rtx, int_rtx);
19551 replacea = offset_rtx;
19552 replaceb = int_rtx;
19556 offset_rtx = int_rtx;
19557 replacea = NULL_RTX;
19558 replaceb = NULL_RTX;
19561 reg = gen_rtx_REG (mode, regno);
19562 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19563 mem = gen_frame_mem (mode, addr);
19565 insn = emit_move_insn (mem, reg);
19567 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19570 /* Emit an offset memory reference suitable for a frame store, while
19571 converting to a valid addressing mode. */
19574 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19576 rtx int_rtx, offset_rtx;
19578 int_rtx = GEN_INT (offset);
19580 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19581 || (TARGET_E500_DOUBLE && mode == DFmode))
19583 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19584 emit_move_insn (offset_rtx, int_rtx);
19587 offset_rtx = int_rtx;
19589 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19592 /* Look for user-defined global regs. We should not save and restore these,
19593 and cannot use stmw/lmw if there are any in its range. */
19596 no_global_regs_above (int first, bool gpr)
19599 int last = gpr ? 32 : 64;
19600 for (i = first; i < last; i++)
19601 if (global_regs[i])
19606 #ifndef TARGET_FIX_AND_CONTINUE
19607 #define TARGET_FIX_AND_CONTINUE 0
19610 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19611 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19612 #define LAST_SAVRES_REGISTER 31
19613 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19615 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19617 /* Temporary holding space for an out-of-line register save/restore
19619 static char savres_routine_name[30];
19621 /* Return the name for an out-of-line register save/restore routine.
19622 We are saving/restoring GPRs if GPR is true. */
19625 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19626 bool savep, bool gpr, bool lr)
19628 const char *prefix = "";
19629 const char *suffix = "";
19631 /* Different targets are supposed to define
19632 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19633 routine name could be defined with:
19635 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19637 This is a nice idea in practice, but in reality, things are
19638 complicated in several ways:
19640 - ELF targets have save/restore routines for GPRs.
19642 - SPE targets use different prefixes for 32/64-bit registers, and
19643 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19645 - PPC64 ELF targets have routines for save/restore of GPRs that
19646 differ in what they do with the link register, so having a set
19647 prefix doesn't work. (We only use one of the save routines at
19648 the moment, though.)
19650 - PPC32 elf targets have "exit" versions of the restore routines
19651 that restore the link register and can save some extra space.
19652 These require an extra suffix. (There are also "tail" versions
19653 of the restore routines and "GOT" versions of the save routines,
19654 but we don't generate those at present. Same problems apply,
19657 We deal with all this by synthesizing our own prefix/suffix and
19658 using that for the simple sprintf call shown above. */
19661 /* No floating point saves on the SPE. */
19665 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19667 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19672 else if (DEFAULT_ABI == ABI_V4)
19678 prefix = savep ? "_savegpr_" : "_restgpr_";
19680 prefix = savep ? "_savefpr_" : "_restfpr_";
19685 else if (DEFAULT_ABI == ABI_AIX)
19687 #ifndef POWERPC_LINUX
19688 /* No out-of-line save/restore routines for GPRs on AIX. */
19689 gcc_assert (!TARGET_AIX || !gpr);
19695 ? (lr ? "_savegpr0_" : "_savegpr1_")
19696 : (lr ? "_restgpr0_" : "_restgpr1_"));
19697 #ifdef POWERPC_LINUX
19699 prefix = (savep ? "_savefpr_" : "_restfpr_");
19703 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19704 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19707 else if (DEFAULT_ABI == ABI_DARWIN)
19708 sorry ("Out-of-line save/restore routines not supported on Darwin");
19710 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19712 return savres_routine_name;
19715 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19716 We are saving/restoring GPRs if GPR is true. */
19719 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19722 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19724 int select = ((savep ? 1 : 0) << 2
19726 /* On the SPE, we never have any FPRs, but we do have
19727 32/64-bit versions of the routines. */
19728 ? (info->spe_64bit_regs_used ? 1 : 0)
19729 : (gpr ? 1 : 0)) << 1)
19732 /* Don't generate bogus routine names. */
19733 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19734 && regno <= LAST_SAVRES_REGISTER);
19736 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19742 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19744 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19745 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19746 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19752 /* Emit a sequence of insns, including a stack tie if needed, for
19753 resetting the stack pointer. If SAVRES is true, then don't reset the
19754 stack pointer, but move the base of the frame into r11 for use by
19755 out-of-line register restore routines. */
19758 rs6000_emit_stack_reset (rs6000_stack_t *info,
19759 rtx sp_reg_rtx, rtx frame_reg_rtx,
19760 int sp_offset, bool savres)
19762 /* This blockage is needed so that sched doesn't decide to move
19763 the sp change before the register restores. */
19764 if (frame_reg_rtx != sp_reg_rtx
19766 && info->spe_64bit_regs_used != 0
19767 && info->first_gp_reg_save != 32))
19768 rs6000_emit_stack_tie ();
19770 if (frame_reg_rtx != sp_reg_rtx)
19772 if (sp_offset != 0)
19774 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19775 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19776 GEN_INT (sp_offset)));
19779 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19781 else if (sp_offset != 0)
19783 /* If we are restoring registers out-of-line, we will be using the
19784 "exit" variants of the restore routines, which will reset the
19785 stack for us. But we do need to point r11 into the right place
19786 for those routines. */
19787 rtx dest_reg = (savres
19788 ? gen_rtx_REG (Pmode, 11)
19791 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19792 GEN_INT (sp_offset)));
19799 /* Construct a parallel rtx describing the effect of a call to an
19800 out-of-line register save/restore routine. */
19803 rs6000_make_savres_rtx (rs6000_stack_t *info,
19804 rtx frame_reg_rtx, int save_area_offset,
19805 enum machine_mode reg_mode,
19806 bool savep, bool gpr, bool lr)
19809 int offset, start_reg, end_reg, n_regs;
19810 int reg_size = GET_MODE_SIZE (reg_mode);
19816 ? info->first_gp_reg_save
19817 : info->first_fp_reg_save);
19818 end_reg = gpr ? 32 : 64;
19819 n_regs = end_reg - start_reg;
19820 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19823 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19825 RTVEC_ELT (p, offset++)
19826 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19828 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19829 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19830 RTVEC_ELT (p, offset++)
19831 = gen_rtx_USE (VOIDmode,
19832 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19836 for (i = 0; i < end_reg - start_reg; i++)
19838 rtx addr, reg, mem;
19839 reg = gen_rtx_REG (reg_mode, start_reg + i);
19840 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19841 GEN_INT (save_area_offset + reg_size*i));
19842 mem = gen_frame_mem (reg_mode, addr);
19844 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19846 savep ? reg : mem);
19851 rtx addr, reg, mem;
19852 reg = gen_rtx_REG (Pmode, 0);
19853 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19854 GEN_INT (info->lr_save_offset));
19855 mem = gen_frame_mem (Pmode, addr);
19856 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19859 return gen_rtx_PARALLEL (VOIDmode, p);
19862 /* Determine whether the gp REG is really used. */
19865 rs6000_reg_live_or_pic_offset_p (int reg)
19867 /* If the function calls eh_return, claim used all the registers that would
19868 be checked for liveness otherwise. This is required for the PIC offset
19869 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19870 register allocation purposes in this case. */
19872 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19873 && (!call_used_regs[reg]
19874 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19875 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19876 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19877 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19878 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19881 /* Emit function prologue as insns. */
19884 rs6000_emit_prologue (void)
19886 rs6000_stack_t *info = rs6000_stack_info ();
19887 enum machine_mode reg_mode = Pmode;
19888 int reg_size = TARGET_32BIT ? 4 : 8;
19889 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19890 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19891 rtx frame_reg_rtx = sp_reg_rtx;
19892 rtx cr_save_rtx = NULL_RTX;
19895 int saving_FPRs_inline;
19896 int saving_GPRs_inline;
19897 int using_store_multiple;
19898 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19899 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19900 && call_used_regs[STATIC_CHAIN_REGNUM]);
19901 HOST_WIDE_INT sp_offset = 0;
19903 if (flag_stack_usage)
19904 current_function_static_stack_size = info->total_size;
19906 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19907 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19909 if (TARGET_FIX_AND_CONTINUE)
19911 /* gdb on darwin arranges to forward a function from the old
19912 address by modifying the first 5 instructions of the function
19913 to branch to the overriding function. This is necessary to
19914 permit function pointers that point to the old function to
19915 actually forward to the new function. */
19916 emit_insn (gen_nop ());
19917 emit_insn (gen_nop ());
19918 emit_insn (gen_nop ());
19919 emit_insn (gen_nop ());
19920 emit_insn (gen_nop ());
19923 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19925 reg_mode = V2SImode;
19929 strategy = info->savres_strategy;
19930 using_store_multiple = strategy & SAVRES_MULTIPLE;
19931 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19932 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19934 /* For V.4, update stack before we do any saving and set back pointer. */
19935 if (! WORLD_SAVE_P (info)
19937 && (DEFAULT_ABI == ABI_V4
19938 || crtl->calls_eh_return))
19940 bool need_r11 = (TARGET_SPE
19941 ? (!saving_GPRs_inline
19942 && info->spe_64bit_regs_used == 0)
19943 : (!saving_FPRs_inline || !saving_GPRs_inline));
19944 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19946 if (info->total_size < 32767)
19947 sp_offset = info->total_size;
19949 frame_reg_rtx = copy_reg;
19950 else if (info->cr_save_p
19952 || info->first_fp_reg_save < 64
19953 || info->first_gp_reg_save < 32
19954 || info->altivec_size != 0
19955 || info->vrsave_mask != 0
19956 || crtl->calls_eh_return)
19958 copy_reg = frame_ptr_rtx;
19959 frame_reg_rtx = copy_reg;
19963 /* The prologue won't be saving any regs so there is no need
19964 to set up a frame register to access any frame save area.
19965 We also won't be using sp_offset anywhere below, but set
19966 the correct value anyway to protect against future
19967 changes to this function. */
19968 sp_offset = info->total_size;
19970 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19971 if (frame_reg_rtx != sp_reg_rtx)
19972 rs6000_emit_stack_tie ();
19975 /* Handle world saves specially here. */
19976 if (WORLD_SAVE_P (info))
19983 /* save_world expects lr in r0. */
19984 reg0 = gen_rtx_REG (Pmode, 0);
19985 if (info->lr_save_p)
19987 insn = emit_move_insn (reg0,
19988 gen_rtx_REG (Pmode, LR_REGNO));
19989 RTX_FRAME_RELATED_P (insn) = 1;
19992 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19993 assumptions about the offsets of various bits of the stack
19995 gcc_assert (info->gp_save_offset == -220
19996 && info->fp_save_offset == -144
19997 && info->lr_save_offset == 8
19998 && info->cr_save_offset == 4
20001 && (!crtl->calls_eh_return
20002 || info->ehrd_offset == -432)
20003 && info->vrsave_save_offset == -224
20004 && info->altivec_save_offset == -416);
20006 treg = gen_rtx_REG (SImode, 11);
20007 emit_move_insn (treg, GEN_INT (-info->total_size));
20009 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20010 in R11. It also clobbers R12, so beware! */
20012 /* Preserve CR2 for save_world prologues */
20014 sz += 32 - info->first_gp_reg_save;
20015 sz += 64 - info->first_fp_reg_save;
20016 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20017 p = rtvec_alloc (sz);
20019 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20020 gen_rtx_REG (SImode,
20022 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20023 gen_rtx_SYMBOL_REF (Pmode,
20025 /* We do floats first so that the instruction pattern matches
20027 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20029 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20030 ? DFmode : SFmode),
20031 info->first_fp_reg_save + i);
20032 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20033 GEN_INT (info->fp_save_offset
20034 + sp_offset + 8 * i));
20035 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20036 ? DFmode : SFmode), addr);
20038 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20040 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20042 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20043 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20044 GEN_INT (info->altivec_save_offset
20045 + sp_offset + 16 * i));
20046 rtx mem = gen_frame_mem (V4SImode, addr);
20048 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20050 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20052 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20053 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20054 GEN_INT (info->gp_save_offset
20055 + sp_offset + reg_size * i));
20056 rtx mem = gen_frame_mem (reg_mode, addr);
20058 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20062 /* CR register traditionally saved as CR2. */
20063 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20064 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20065 GEN_INT (info->cr_save_offset
20067 rtx mem = gen_frame_mem (reg_mode, addr);
20069 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20071 /* Explain about use of R0. */
20072 if (info->lr_save_p)
20074 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20075 GEN_INT (info->lr_save_offset
20077 rtx mem = gen_frame_mem (reg_mode, addr);
20079 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20081 /* Explain what happens to the stack pointer. */
20083 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20084 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20087 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20088 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20089 treg, GEN_INT (-info->total_size));
20090 sp_offset = info->total_size;
20093 /* If we use the link register, get it into r0. */
20094 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20096 rtx addr, reg, mem;
20098 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20099 gen_rtx_REG (Pmode, LR_REGNO));
20100 RTX_FRAME_RELATED_P (insn) = 1;
20102 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20103 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20105 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20106 GEN_INT (info->lr_save_offset + sp_offset));
20107 reg = gen_rtx_REG (Pmode, 0);
20108 mem = gen_rtx_MEM (Pmode, addr);
20109 /* This should not be of rs6000_sr_alias_set, because of
20110 __builtin_return_address. */
20112 insn = emit_move_insn (mem, reg);
20113 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20114 NULL_RTX, NULL_RTX);
20118 /* If we need to save CR, put it into r12 or r11. */
20119 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20124 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20126 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20127 RTX_FRAME_RELATED_P (insn) = 1;
20128 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20129 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20130 But that's OK. All we have to do is specify that _one_ condition
20131 code register is saved in this stack slot. The thrower's epilogue
20132 will then restore all the call-saved registers.
20133 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20134 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20135 gen_rtx_REG (SImode, CR2_REGNO));
20136 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20139 /* Do any required saving of fpr's. If only one or two to save, do
20140 it ourselves. Otherwise, call function. */
20141 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20144 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20145 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20146 && ! call_used_regs[info->first_fp_reg_save+i]))
20147 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20148 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20150 info->first_fp_reg_save + i,
20151 info->fp_save_offset + sp_offset + 8 * i,
20154 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20158 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20159 info->fp_save_offset + sp_offset,
20161 /*savep=*/true, /*gpr=*/false,
20163 & SAVE_NOINLINE_FPRS_SAVES_LR)
20165 insn = emit_insn (par);
20166 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20167 NULL_RTX, NULL_RTX);
20170 /* Save GPRs. This is done as a PARALLEL if we are using
20171 the store-multiple instructions. */
20172 if (!WORLD_SAVE_P (info)
20174 && info->spe_64bit_regs_used != 0
20175 && info->first_gp_reg_save != 32)
20178 rtx spe_save_area_ptr;
20180 /* Determine whether we can address all of the registers that need
20181 to be saved with an offset from the stack pointer that fits in
20182 the small const field for SPE memory instructions. */
20183 int spe_regs_addressable_via_sp
20184 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20185 + (32 - info->first_gp_reg_save - 1) * reg_size)
20186 && saving_GPRs_inline);
20189 if (spe_regs_addressable_via_sp)
20191 spe_save_area_ptr = frame_reg_rtx;
20192 spe_offset = info->spe_gp_save_offset + sp_offset;
20196 /* Make r11 point to the start of the SPE save area. We need
20197 to be careful here if r11 is holding the static chain. If
20198 it is, then temporarily save it in r0. We would use r0 as
20199 our base register here, but using r0 as a base register in
20200 loads and stores means something different from what we
20202 int ool_adjust = (saving_GPRs_inline
20204 : (info->first_gp_reg_save
20205 - (FIRST_SAVRES_REGISTER+1))*8);
20206 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20207 + sp_offset - ool_adjust);
20209 if (using_static_chain_p)
20211 rtx r0 = gen_rtx_REG (Pmode, 0);
20212 gcc_assert (info->first_gp_reg_save > 11);
20214 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20217 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20218 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20220 GEN_INT (offset)));
20221 /* We need to make sure the move to r11 gets noted for
20222 properly outputting unwind information. */
20223 if (!saving_GPRs_inline)
20224 rs6000_frame_related (insn, frame_reg_rtx, offset,
20225 NULL_RTX, NULL_RTX);
20229 if (saving_GPRs_inline)
20231 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20232 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20234 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20235 rtx offset, addr, mem;
20237 /* We're doing all this to ensure that the offset fits into
20238 the immediate offset of 'evstdd'. */
20239 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20241 offset = GEN_INT (reg_size * i + spe_offset);
20242 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20243 mem = gen_rtx_MEM (V2SImode, addr);
20245 insn = emit_move_insn (mem, reg);
20247 rs6000_frame_related (insn, spe_save_area_ptr,
20248 info->spe_gp_save_offset
20249 + sp_offset + reg_size * i,
20250 offset, const0_rtx);
20257 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20259 /*savep=*/true, /*gpr=*/true,
20261 insn = emit_insn (par);
20262 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20263 NULL_RTX, NULL_RTX);
20267 /* Move the static chain pointer back. */
20268 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20269 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20271 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20275 /* Need to adjust r11 (r12) if we saved any FPRs. */
20276 if (info->first_fp_reg_save != 64)
20278 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20280 rtx offset = GEN_INT (sp_offset
20281 + (-8 * (64-info->first_fp_reg_save)));
20282 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20285 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20286 info->gp_save_offset + sp_offset,
20288 /*savep=*/true, /*gpr=*/true,
20290 & SAVE_NOINLINE_GPRS_SAVES_LR)
20292 insn = emit_insn (par);
20293 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20294 NULL_RTX, NULL_RTX);
20296 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20300 p = rtvec_alloc (32 - info->first_gp_reg_save);
20301 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20303 rtx addr, reg, mem;
20304 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20305 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20306 GEN_INT (info->gp_save_offset
20309 mem = gen_frame_mem (reg_mode, addr);
20311 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20313 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20314 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20315 NULL_RTX, NULL_RTX);
20317 else if (!WORLD_SAVE_P (info))
20320 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20321 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20323 rtx addr, reg, mem;
20324 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20326 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20327 GEN_INT (info->gp_save_offset
20330 mem = gen_frame_mem (reg_mode, addr);
20332 insn = emit_move_insn (mem, reg);
20333 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20334 NULL_RTX, NULL_RTX);
20338 /* ??? There's no need to emit actual instructions here, but it's the
20339 easiest way to get the frame unwind information emitted. */
20340 if (crtl->calls_eh_return)
20342 unsigned int i, regno;
20346 regno = EH_RETURN_DATA_REGNO (i);
20347 if (regno == INVALID_REGNUM)
20350 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20351 info->ehrd_offset + sp_offset
20352 + reg_size * (int) i,
20357 /* In AIX ABI we need to make sure r2 is really saved. */
20358 if (TARGET_AIX && crtl->calls_eh_return)
20360 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20361 long toc_restore_insn;
20363 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20364 || frame_reg_rtx == sp_reg_rtx);
20365 tmp_reg = gen_rtx_REG (Pmode, 11);
20366 tmp_reg_si = gen_rtx_REG (SImode, 11);
20367 if (using_static_chain_p)
20368 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20369 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20370 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20371 /* Peek at instruction to which this function returns. If it's
20372 restoring r2, then we know we've already saved r2. We can't
20373 unconditionally save r2 because the value we have will already
20374 be updated if we arrived at this function via a plt call or
20375 toc adjusting stub. */
20376 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20377 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20378 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20379 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20380 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20381 validate_condition_mode (EQ, CCUNSmode);
20382 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20383 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20384 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20385 toc_save_done = gen_label_rtx ();
20386 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20387 gen_rtx_EQ (VOIDmode, compare_result,
20389 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20391 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20392 JUMP_LABEL (jump) = toc_save_done;
20393 LABEL_NUSES (toc_save_done) += 1;
20395 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20396 sp_offset + 5 * reg_size, info->total_size);
20397 emit_label (toc_save_done);
20398 if (using_static_chain_p)
20399 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20402 /* Save CR if we use any that must be preserved. */
20403 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20405 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20406 GEN_INT (info->cr_save_offset + sp_offset));
20407 rtx mem = gen_frame_mem (SImode, addr);
20408 /* See the large comment above about why CR2_REGNO is used. */
20409 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20411 /* If r12 was used to hold the original sp, copy cr into r0 now
20413 if (REGNO (frame_reg_rtx) == 12)
20417 cr_save_rtx = gen_rtx_REG (SImode, 0);
20418 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20419 RTX_FRAME_RELATED_P (insn) = 1;
20420 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20421 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20423 insn = emit_move_insn (mem, cr_save_rtx);
20425 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20426 NULL_RTX, NULL_RTX);
20429 /* Update stack and set back pointer unless this is V.4,
20430 for which it was done previously. */
20431 if (!WORLD_SAVE_P (info) && info->push_p
20432 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20434 rtx copy_reg = NULL;
20436 if (info->total_size < 32767)
20437 sp_offset = info->total_size;
20438 else if (info->altivec_size != 0
20439 || info->vrsave_mask != 0)
20441 copy_reg = frame_ptr_rtx;
20442 frame_reg_rtx = copy_reg;
20445 sp_offset = info->total_size;
20446 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20447 if (frame_reg_rtx != sp_reg_rtx)
20448 rs6000_emit_stack_tie ();
20451 /* Set frame pointer, if needed. */
20452 if (frame_pointer_needed)
20454 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20456 RTX_FRAME_RELATED_P (insn) = 1;
20459 /* Save AltiVec registers if needed. Save here because the red zone does
20460 not include AltiVec registers. */
20461 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20465 /* There should be a non inline version of this, for when we
20466 are saving lots of vector registers. */
20467 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20468 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20470 rtx areg, savereg, mem;
20473 offset = info->altivec_save_offset + sp_offset
20474 + 16 * (i - info->first_altivec_reg_save);
20476 savereg = gen_rtx_REG (V4SImode, i);
20478 areg = gen_rtx_REG (Pmode, 0);
20479 emit_move_insn (areg, GEN_INT (offset));
20481 /* AltiVec addressing mode is [reg+reg]. */
20482 mem = gen_frame_mem (V4SImode,
20483 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20485 insn = emit_move_insn (mem, savereg);
20487 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20488 areg, GEN_INT (offset));
20492 /* VRSAVE is a bit vector representing which AltiVec registers
20493 are used. The OS uses this to determine which vector
20494 registers to save on a context switch. We need to save
20495 VRSAVE on the stack frame, add whatever AltiVec registers we
20496 used in this function, and do the corresponding magic in the
20499 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20500 && info->vrsave_mask != 0)
20502 rtx reg, mem, vrsave;
20505 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20506 as frame_reg_rtx and r11 as the static chain pointer for
20507 nested functions. */
20508 reg = gen_rtx_REG (SImode, 0);
20509 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20511 emit_insn (gen_get_vrsave_internal (reg));
20513 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20515 if (!WORLD_SAVE_P (info))
20518 offset = info->vrsave_save_offset + sp_offset;
20519 mem = gen_frame_mem (SImode,
20520 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20521 GEN_INT (offset)));
20522 insn = emit_move_insn (mem, reg);
20525 /* Include the registers in the mask. */
20526 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20528 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20531 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20532 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20533 || (DEFAULT_ABI == ABI_V4
20534 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20535 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20537 /* If emit_load_toc_table will use the link register, we need to save
20538 it. We use R12 for this purpose because emit_load_toc_table
20539 can use register 0. This allows us to use a plain 'blr' to return
20540 from the procedure more often. */
20541 int save_LR_around_toc_setup = (TARGET_ELF
20542 && DEFAULT_ABI != ABI_AIX
20544 && ! info->lr_save_p
20545 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20546 if (save_LR_around_toc_setup)
20548 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20550 insn = emit_move_insn (frame_ptr_rtx, lr);
20551 RTX_FRAME_RELATED_P (insn) = 1;
20553 rs6000_emit_load_toc_table (TRUE);
20555 insn = emit_move_insn (lr, frame_ptr_rtx);
20556 RTX_FRAME_RELATED_P (insn) = 1;
20559 rs6000_emit_load_toc_table (TRUE);
20563 if (DEFAULT_ABI == ABI_DARWIN
20564 && flag_pic && crtl->uses_pic_offset_table)
20566 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20567 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20569 /* Save and restore LR locally around this call (in R0). */
20570 if (!info->lr_save_p)
20571 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20573 emit_insn (gen_load_macho_picbase (src));
20575 emit_move_insn (gen_rtx_REG (Pmode,
20576 RS6000_PIC_OFFSET_TABLE_REGNUM),
20579 if (!info->lr_save_p)
20580 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20585 /* Write function prologue. */
20588 rs6000_output_function_prologue (FILE *file,
20589 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20591 rs6000_stack_t *info = rs6000_stack_info ();
20593 if (TARGET_DEBUG_STACK)
20594 debug_stack_info (info);
20596 /* Write .extern for any function we will call to save and restore
20598 if (info->first_fp_reg_save < 64)
20601 int regno = info->first_fp_reg_save - 32;
20603 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20605 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20606 /*gpr=*/false, /*lr=*/false);
20607 fprintf (file, "\t.extern %s\n", name);
20609 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20611 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20612 /*gpr=*/false, /*lr=*/true);
20613 fprintf (file, "\t.extern %s\n", name);
20617 /* Write .extern for AIX common mode routines, if needed. */
20618 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20620 fputs ("\t.extern __mulh\n", file);
20621 fputs ("\t.extern __mull\n", file);
20622 fputs ("\t.extern __divss\n", file);
20623 fputs ("\t.extern __divus\n", file);
20624 fputs ("\t.extern __quoss\n", file);
20625 fputs ("\t.extern __quous\n", file);
20626 common_mode_defined = 1;
20629 if (! HAVE_prologue)
20635 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20636 the "toplevel" insn chain. */
20637 emit_note (NOTE_INSN_DELETED);
20638 rs6000_emit_prologue ();
20639 emit_note (NOTE_INSN_DELETED);
20641 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20645 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20647 INSN_ADDRESSES_NEW (insn, addr);
20652 prologue = get_insns ();
20655 if (TARGET_DEBUG_STACK)
20656 debug_rtx_list (prologue, 100);
20658 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20662 rs6000_pic_labelno++;
20665 /* Non-zero if vmx regs are restored before the frame pop, zero if
20666 we restore after the pop when possible. */
20667 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20669 /* Reload CR from REG. */
20672 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20677 if (using_mfcr_multiple)
20679 for (i = 0; i < 8; i++)
20680 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20682 gcc_assert (count);
20685 if (using_mfcr_multiple && count > 1)
20690 p = rtvec_alloc (count);
20693 for (i = 0; i < 8; i++)
20694 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20696 rtvec r = rtvec_alloc (2);
20697 RTVEC_ELT (r, 0) = reg;
20698 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20699 RTVEC_ELT (p, ndx) =
20700 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20701 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20704 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20705 gcc_assert (ndx == count);
20708 for (i = 0; i < 8; i++)
20709 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20711 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20717 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20718 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20719 below stack pointer not cloberred by signals. */
20722 offset_below_red_zone_p (HOST_WIDE_INT offset)
20724 return offset < (DEFAULT_ABI == ABI_V4
20726 : TARGET_32BIT ? -220 : -288);
20729 /* Emit function epilogue as insns. */
20732 rs6000_emit_epilogue (int sibcall)
20734 rs6000_stack_t *info;
20735 int restoring_GPRs_inline;
20736 int restoring_FPRs_inline;
20737 int using_load_multiple;
20738 int using_mtcr_multiple;
20739 int use_backchain_to_restore_sp;
20743 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20744 rtx frame_reg_rtx = sp_reg_rtx;
20745 rtx cfa_restores = NULL_RTX;
20747 rtx cr_save_reg = NULL_RTX;
20748 enum machine_mode reg_mode = Pmode;
20749 int reg_size = TARGET_32BIT ? 4 : 8;
20752 info = rs6000_stack_info ();
20754 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20756 reg_mode = V2SImode;
20760 strategy = info->savres_strategy;
20761 using_load_multiple = strategy & SAVRES_MULTIPLE;
20762 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20763 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20764 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20765 || rs6000_cpu == PROCESSOR_PPC603
20766 || rs6000_cpu == PROCESSOR_PPC750
20768 /* Restore via the backchain when we have a large frame, since this
20769 is more efficient than an addis, addi pair. The second condition
20770 here will not trigger at the moment; We don't actually need a
20771 frame pointer for alloca, but the generic parts of the compiler
20772 give us one anyway. */
20773 use_backchain_to_restore_sp = (info->total_size > 32767
20774 || info->total_size
20775 + (info->lr_save_p ? info->lr_save_offset : 0)
20777 || (cfun->calls_alloca
20778 && !frame_pointer_needed));
20779 restore_lr = (info->lr_save_p
20780 && (restoring_FPRs_inline
20781 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20782 && (restoring_GPRs_inline
20783 || info->first_fp_reg_save < 64));
20785 if (WORLD_SAVE_P (info))
20789 const char *alloc_rname;
20792 /* eh_rest_world_r10 will return to the location saved in the LR
20793 stack slot (which is not likely to be our caller.)
20794 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20795 rest_world is similar, except any R10 parameter is ignored.
20796 The exception-handling stuff that was here in 2.95 is no
20797 longer necessary. */
20801 + 32 - info->first_gp_reg_save
20802 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20803 + 63 + 1 - info->first_fp_reg_save);
20805 strcpy (rname, ((crtl->calls_eh_return) ?
20806 "*eh_rest_world_r10" : "*rest_world"));
20807 alloc_rname = ggc_strdup (rname);
20810 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20811 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20812 gen_rtx_REG (Pmode,
20815 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20816 /* The instruction pattern requires a clobber here;
20817 it is shared with the restVEC helper. */
20819 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20822 /* CR register traditionally saved as CR2. */
20823 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20824 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20825 GEN_INT (info->cr_save_offset));
20826 rtx mem = gen_frame_mem (reg_mode, addr);
20828 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20831 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20833 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20834 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20835 GEN_INT (info->gp_save_offset
20837 rtx mem = gen_frame_mem (reg_mode, addr);
20839 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20841 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20843 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20844 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20845 GEN_INT (info->altivec_save_offset
20847 rtx mem = gen_frame_mem (V4SImode, addr);
20849 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20851 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20853 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20854 ? DFmode : SFmode),
20855 info->first_fp_reg_save + i);
20856 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20857 GEN_INT (info->fp_save_offset
20859 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20860 ? DFmode : SFmode), addr);
20862 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20865 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20867 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20869 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20871 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20873 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20874 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20879 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20881 sp_offset = info->total_size;
20883 /* Restore AltiVec registers if we must do so before adjusting the
20885 if (TARGET_ALTIVEC_ABI
20886 && info->altivec_size != 0
20887 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20888 || (DEFAULT_ABI != ABI_V4
20889 && offset_below_red_zone_p (info->altivec_save_offset))))
20893 if (use_backchain_to_restore_sp)
20895 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20896 emit_move_insn (frame_reg_rtx,
20897 gen_rtx_MEM (Pmode, sp_reg_rtx));
20900 else if (frame_pointer_needed)
20901 frame_reg_rtx = hard_frame_pointer_rtx;
20903 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20904 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20906 rtx addr, areg, mem, reg;
20908 areg = gen_rtx_REG (Pmode, 0);
20910 (areg, GEN_INT (info->altivec_save_offset
20912 + 16 * (i - info->first_altivec_reg_save)));
20914 /* AltiVec addressing mode is [reg+reg]. */
20915 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20916 mem = gen_frame_mem (V4SImode, addr);
20918 reg = gen_rtx_REG (V4SImode, i);
20919 emit_move_insn (reg, mem);
20920 if (offset_below_red_zone_p (info->altivec_save_offset
20921 + (i - info->first_altivec_reg_save)
20923 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20928 /* Restore VRSAVE if we must do so before adjusting the stack. */
20930 && TARGET_ALTIVEC_VRSAVE
20931 && info->vrsave_mask != 0
20932 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20933 || (DEFAULT_ABI != ABI_V4
20934 && offset_below_red_zone_p (info->vrsave_save_offset))))
20936 rtx addr, mem, reg;
20938 if (frame_reg_rtx == sp_reg_rtx)
20940 if (use_backchain_to_restore_sp)
20942 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20943 emit_move_insn (frame_reg_rtx,
20944 gen_rtx_MEM (Pmode, sp_reg_rtx));
20947 else if (frame_pointer_needed)
20948 frame_reg_rtx = hard_frame_pointer_rtx;
20951 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20952 GEN_INT (info->vrsave_save_offset + sp_offset));
20953 mem = gen_frame_mem (SImode, addr);
20954 reg = gen_rtx_REG (SImode, 12);
20955 emit_move_insn (reg, mem);
20957 emit_insn (generate_set_vrsave (reg, info, 1));
20961 /* If we have a large stack frame, restore the old stack pointer
20962 using the backchain. */
20963 if (use_backchain_to_restore_sp)
20965 if (frame_reg_rtx == sp_reg_rtx)
20967 /* Under V.4, don't reset the stack pointer until after we're done
20968 loading the saved registers. */
20969 if (DEFAULT_ABI == ABI_V4)
20970 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20972 insn = emit_move_insn (frame_reg_rtx,
20973 gen_rtx_MEM (Pmode, sp_reg_rtx));
20976 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20977 && DEFAULT_ABI == ABI_V4)
20978 /* frame_reg_rtx has been set up by the altivec restore. */
20982 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20983 frame_reg_rtx = sp_reg_rtx;
20986 /* If we have a frame pointer, we can restore the old stack pointer
20988 else if (frame_pointer_needed)
20990 frame_reg_rtx = sp_reg_rtx;
20991 if (DEFAULT_ABI == ABI_V4)
20992 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20993 /* Prevent reordering memory accesses against stack pointer restore. */
20994 else if (cfun->calls_alloca
20995 || offset_below_red_zone_p (-info->total_size))
20997 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
20998 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
20999 MEM_NOTRAP_P (mem1) = 1;
21000 MEM_NOTRAP_P (mem2) = 1;
21001 emit_insn (gen_frame_tie (mem1, mem2));
21004 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21005 GEN_INT (info->total_size)));
21008 else if (info->push_p
21009 && DEFAULT_ABI != ABI_V4
21010 && !crtl->calls_eh_return)
21012 /* Prevent reordering memory accesses against stack pointer restore. */
21013 if (cfun->calls_alloca
21014 || offset_below_red_zone_p (-info->total_size))
21016 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21017 MEM_NOTRAP_P (mem) = 1;
21018 emit_insn (gen_stack_tie (mem));
21020 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21021 GEN_INT (info->total_size)));
21024 if (insn && frame_reg_rtx == sp_reg_rtx)
21028 REG_NOTES (insn) = cfa_restores;
21029 cfa_restores = NULL_RTX;
21031 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21032 RTX_FRAME_RELATED_P (insn) = 1;
21035 /* Restore AltiVec registers if we have not done so already. */
21036 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21037 && TARGET_ALTIVEC_ABI
21038 && info->altivec_size != 0
21039 && (DEFAULT_ABI == ABI_V4
21040 || !offset_below_red_zone_p (info->altivec_save_offset)))
21044 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21045 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21047 rtx addr, areg, mem, reg;
21049 areg = gen_rtx_REG (Pmode, 0);
21051 (areg, GEN_INT (info->altivec_save_offset
21053 + 16 * (i - info->first_altivec_reg_save)));
21055 /* AltiVec addressing mode is [reg+reg]. */
21056 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21057 mem = gen_frame_mem (V4SImode, addr);
21059 reg = gen_rtx_REG (V4SImode, i);
21060 emit_move_insn (reg, mem);
21061 if (DEFAULT_ABI == ABI_V4)
21062 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21067 /* Restore VRSAVE if we have not done so already. */
21068 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21070 && TARGET_ALTIVEC_VRSAVE
21071 && info->vrsave_mask != 0
21072 && (DEFAULT_ABI == ABI_V4
21073 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21075 rtx addr, mem, reg;
21077 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21078 GEN_INT (info->vrsave_save_offset + sp_offset));
21079 mem = gen_frame_mem (SImode, addr);
21080 reg = gen_rtx_REG (SImode, 12);
21081 emit_move_insn (reg, mem);
21083 emit_insn (generate_set_vrsave (reg, info, 1));
21086 /* Get the old lr if we saved it. If we are restoring registers
21087 out-of-line, then the out-of-line routines can do this for us. */
21088 if (restore_lr && restoring_GPRs_inline)
21090 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21091 info->lr_save_offset + sp_offset);
21093 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21096 /* Get the old cr if we saved it. */
21097 if (info->cr_save_p)
21099 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21100 GEN_INT (info->cr_save_offset + sp_offset));
21101 rtx mem = gen_frame_mem (SImode, addr);
21103 cr_save_reg = gen_rtx_REG (SImode,
21104 DEFAULT_ABI == ABI_AIX
21105 && !restoring_GPRs_inline
21106 && info->first_fp_reg_save < 64
21108 emit_move_insn (cr_save_reg, mem);
21111 /* Set LR here to try to overlap restores below. LR is always saved
21112 above incoming stack, so it never needs REG_CFA_RESTORE. */
21113 if (restore_lr && restoring_GPRs_inline)
21114 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21115 gen_rtx_REG (Pmode, 0));
21117 /* Load exception handler data registers, if needed. */
21118 if (crtl->calls_eh_return)
21120 unsigned int i, regno;
21124 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21125 GEN_INT (sp_offset + 5 * reg_size));
21126 rtx mem = gen_frame_mem (reg_mode, addr);
21128 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21135 regno = EH_RETURN_DATA_REGNO (i);
21136 if (regno == INVALID_REGNUM)
21139 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21140 info->ehrd_offset + sp_offset
21141 + reg_size * (int) i);
21143 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21147 /* Restore GPRs. This is done as a PARALLEL if we are using
21148 the load-multiple instructions. */
21150 && info->spe_64bit_regs_used != 0
21151 && info->first_gp_reg_save != 32)
21153 /* Determine whether we can address all of the registers that need
21154 to be saved with an offset from the stack pointer that fits in
21155 the small const field for SPE memory instructions. */
21156 int spe_regs_addressable_via_sp
21157 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21158 + (32 - info->first_gp_reg_save - 1) * reg_size)
21159 && restoring_GPRs_inline);
21162 if (spe_regs_addressable_via_sp)
21163 spe_offset = info->spe_gp_save_offset + sp_offset;
21166 rtx old_frame_reg_rtx = frame_reg_rtx;
21167 /* Make r11 point to the start of the SPE save area. We worried about
21168 not clobbering it when we were saving registers in the prologue.
21169 There's no need to worry here because the static chain is passed
21170 anew to every function. */
21171 int ool_adjust = (restoring_GPRs_inline
21173 : (info->first_gp_reg_save
21174 - (FIRST_SAVRES_REGISTER+1))*8);
21176 if (frame_reg_rtx == sp_reg_rtx)
21177 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21178 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21179 GEN_INT (info->spe_gp_save_offset
21182 /* Keep the invariant that frame_reg_rtx + sp_offset points
21183 at the top of the stack frame. */
21184 sp_offset = -info->spe_gp_save_offset;
21189 if (restoring_GPRs_inline)
21191 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21192 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21194 rtx offset, addr, mem, reg;
21196 /* We're doing all this to ensure that the immediate offset
21197 fits into the immediate field of 'evldd'. */
21198 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21200 offset = GEN_INT (spe_offset + reg_size * i);
21201 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21202 mem = gen_rtx_MEM (V2SImode, addr);
21203 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21205 insn = emit_move_insn (reg, mem);
21206 if (DEFAULT_ABI == ABI_V4)
21208 if (frame_pointer_needed
21209 && info->first_gp_reg_save + i
21210 == HARD_FRAME_POINTER_REGNUM)
21212 add_reg_note (insn, REG_CFA_DEF_CFA,
21213 plus_constant (frame_reg_rtx,
21215 RTX_FRAME_RELATED_P (insn) = 1;
21218 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21227 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21229 /*savep=*/false, /*gpr=*/true,
21231 emit_jump_insn (par);
21232 /* We don't want anybody else emitting things after we jumped
21237 else if (!restoring_GPRs_inline)
21239 /* We are jumping to an out-of-line function. */
21240 bool can_use_exit = info->first_fp_reg_save == 64;
21243 /* Emit stack reset code if we need it. */
21245 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21246 sp_offset, can_use_exit);
21249 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21252 GEN_INT (sp_offset - info->fp_size)));
21253 if (REGNO (frame_reg_rtx) == 11)
21254 sp_offset += info->fp_size;
21257 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21258 info->gp_save_offset, reg_mode,
21259 /*savep=*/false, /*gpr=*/true,
21260 /*lr=*/can_use_exit);
21264 if (info->cr_save_p)
21266 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21267 if (DEFAULT_ABI == ABI_V4)
21269 = alloc_reg_note (REG_CFA_RESTORE,
21270 gen_rtx_REG (SImode, CR2_REGNO),
21274 emit_jump_insn (par);
21276 /* We don't want anybody else emitting things after we jumped
21281 insn = emit_insn (par);
21282 if (DEFAULT_ABI == ABI_V4)
21284 if (frame_pointer_needed)
21286 add_reg_note (insn, REG_CFA_DEF_CFA,
21287 plus_constant (frame_reg_rtx, sp_offset));
21288 RTX_FRAME_RELATED_P (insn) = 1;
21291 for (i = info->first_gp_reg_save; i < 32; i++)
21293 = alloc_reg_note (REG_CFA_RESTORE,
21294 gen_rtx_REG (reg_mode, i), cfa_restores);
21297 else if (using_load_multiple)
21300 p = rtvec_alloc (32 - info->first_gp_reg_save);
21301 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21303 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21304 GEN_INT (info->gp_save_offset
21307 rtx mem = gen_frame_mem (reg_mode, addr);
21308 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21310 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21311 if (DEFAULT_ABI == ABI_V4)
21312 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21315 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21316 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21318 add_reg_note (insn, REG_CFA_DEF_CFA,
21319 plus_constant (frame_reg_rtx, sp_offset));
21320 RTX_FRAME_RELATED_P (insn) = 1;
21325 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21326 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21328 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21329 GEN_INT (info->gp_save_offset
21332 rtx mem = gen_frame_mem (reg_mode, addr);
21333 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21335 insn = emit_move_insn (reg, mem);
21336 if (DEFAULT_ABI == ABI_V4)
21338 if (frame_pointer_needed
21339 && info->first_gp_reg_save + i
21340 == HARD_FRAME_POINTER_REGNUM)
21342 add_reg_note (insn, REG_CFA_DEF_CFA,
21343 plus_constant (frame_reg_rtx, sp_offset));
21344 RTX_FRAME_RELATED_P (insn) = 1;
21347 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21353 if (restore_lr && !restoring_GPRs_inline)
21355 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21356 info->lr_save_offset + sp_offset);
21358 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21359 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21360 gen_rtx_REG (Pmode, 0));
21363 /* Restore fpr's if we need to do it without calling a function. */
21364 if (restoring_FPRs_inline)
21365 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21366 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21367 && ! call_used_regs[info->first_fp_reg_save+i]))
21369 rtx addr, mem, reg;
21370 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21371 GEN_INT (info->fp_save_offset
21374 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21375 ? DFmode : SFmode), addr);
21376 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21377 ? DFmode : SFmode),
21378 info->first_fp_reg_save + i);
21380 emit_move_insn (reg, mem);
21381 if (DEFAULT_ABI == ABI_V4)
21382 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21386 /* If we saved cr, restore it here. Just those that were used. */
21387 if (info->cr_save_p)
21389 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21390 if (DEFAULT_ABI == ABI_V4)
21392 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21396 /* If this is V.4, unwind the stack pointer after all of the loads
21398 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21399 sp_offset, !restoring_FPRs_inline);
21404 REG_NOTES (insn) = cfa_restores;
21405 cfa_restores = NULL_RTX;
21407 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21408 RTX_FRAME_RELATED_P (insn) = 1;
21411 if (crtl->calls_eh_return)
21413 rtx sa = EH_RETURN_STACKADJ_RTX;
21414 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21420 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21421 if (! restoring_FPRs_inline)
21422 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21424 p = rtvec_alloc (2);
21426 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21427 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21428 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21429 : gen_rtx_CLOBBER (VOIDmode,
21430 gen_rtx_REG (Pmode, 65)));
21432 /* If we have to restore more than two FP registers, branch to the
21433 restore function. It will return to our caller. */
21434 if (! restoring_FPRs_inline)
21439 sym = rs6000_savres_routine_sym (info,
21443 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21444 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21445 gen_rtx_REG (Pmode,
21446 DEFAULT_ABI == ABI_AIX
21448 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21451 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21452 GEN_INT (info->fp_save_offset + 8*i));
21453 mem = gen_frame_mem (DFmode, addr);
21455 RTVEC_ELT (p, i+4) =
21456 gen_rtx_SET (VOIDmode,
21457 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21462 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21466 /* Write function epilogue. */
21469 rs6000_output_function_epilogue (FILE *file,
21470 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21472 if (! HAVE_epilogue)
21474 rtx insn = get_last_insn ();
21475 /* If the last insn was a BARRIER, we don't have to write anything except
21476 the trace table. */
21477 if (GET_CODE (insn) == NOTE)
21478 insn = prev_nonnote_insn (insn);
21479 if (insn == 0 || GET_CODE (insn) != BARRIER)
21481 /* This is slightly ugly, but at least we don't have two
21482 copies of the epilogue-emitting code. */
21485 /* A NOTE_INSN_DELETED is supposed to be at the start
21486 and end of the "toplevel" insn chain. */
21487 emit_note (NOTE_INSN_DELETED);
21488 rs6000_emit_epilogue (FALSE);
21489 emit_note (NOTE_INSN_DELETED);
21491 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21495 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21497 INSN_ADDRESSES_NEW (insn, addr);
21502 if (TARGET_DEBUG_STACK)
21503 debug_rtx_list (get_insns (), 100);
21504 final (get_insns (), file, FALSE);
21510 macho_branch_islands ();
21511 /* Mach-O doesn't support labels at the end of objects, so if
21512 it looks like we might want one, insert a NOP. */
21514 rtx insn = get_last_insn ();
21517 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21518 insn = PREV_INSN (insn);
21522 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21523 fputs ("\tnop\n", file);
21527 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21530 We don't output a traceback table if -finhibit-size-directive was
21531 used. The documentation for -finhibit-size-directive reads
21532 ``don't output a @code{.size} assembler directive, or anything
21533 else that would cause trouble if the function is split in the
21534 middle, and the two halves are placed at locations far apart in
21535 memory.'' The traceback table has this property, since it
21536 includes the offset from the start of the function to the
21537 traceback table itself.
21539 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21540 different traceback table. */
21541 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21542 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21544 const char *fname = NULL;
21545 const char *language_string = lang_hooks.name;
21546 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21548 int optional_tbtab;
21549 rs6000_stack_t *info = rs6000_stack_info ();
21551 if (rs6000_traceback == traceback_full)
21552 optional_tbtab = 1;
21553 else if (rs6000_traceback == traceback_part)
21554 optional_tbtab = 0;
21556 optional_tbtab = !optimize_size && !TARGET_ELF;
21558 if (optional_tbtab)
21560 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21561 while (*fname == '.') /* V.4 encodes . in the name */
21564 /* Need label immediately before tbtab, so we can compute
21565 its offset from the function start. */
21566 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21567 ASM_OUTPUT_LABEL (file, fname);
21570 /* The .tbtab pseudo-op can only be used for the first eight
21571 expressions, since it can't handle the possibly variable
21572 length fields that follow. However, if you omit the optional
21573 fields, the assembler outputs zeros for all optional fields
21574 anyways, giving each variable length field is minimum length
21575 (as defined in sys/debug.h). Thus we can not use the .tbtab
21576 pseudo-op at all. */
21578 /* An all-zero word flags the start of the tbtab, for debuggers
21579 that have to find it by searching forward from the entry
21580 point or from the current pc. */
21581 fputs ("\t.long 0\n", file);
21583 /* Tbtab format type. Use format type 0. */
21584 fputs ("\t.byte 0,", file);
21586 /* Language type. Unfortunately, there does not seem to be any
21587 official way to discover the language being compiled, so we
21588 use language_string.
21589 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21590 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21591 a number, so for now use 9. LTO isn't assigned a number either,
21592 so for now use 0. */
21593 if (! strcmp (language_string, "GNU C")
21594 || ! strcmp (language_string, "GNU GIMPLE"))
21596 else if (! strcmp (language_string, "GNU F77")
21597 || ! strcmp (language_string, "GNU Fortran"))
21599 else if (! strcmp (language_string, "GNU Pascal"))
21601 else if (! strcmp (language_string, "GNU Ada"))
21603 else if (! strcmp (language_string, "GNU C++")
21604 || ! strcmp (language_string, "GNU Objective-C++"))
21606 else if (! strcmp (language_string, "GNU Java"))
21608 else if (! strcmp (language_string, "GNU Objective-C"))
21611 gcc_unreachable ();
21612 fprintf (file, "%d,", i);
21614 /* 8 single bit fields: global linkage (not set for C extern linkage,
21615 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21616 from start of procedure stored in tbtab, internal function, function
21617 has controlled storage, function has no toc, function uses fp,
21618 function logs/aborts fp operations. */
21619 /* Assume that fp operations are used if any fp reg must be saved. */
21620 fprintf (file, "%d,",
21621 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21623 /* 6 bitfields: function is interrupt handler, name present in
21624 proc table, function calls alloca, on condition directives
21625 (controls stack walks, 3 bits), saves condition reg, saves
21627 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21628 set up as a frame pointer, even when there is no alloca call. */
21629 fprintf (file, "%d,",
21630 ((optional_tbtab << 6)
21631 | ((optional_tbtab & frame_pointer_needed) << 5)
21632 | (info->cr_save_p << 1)
21633 | (info->lr_save_p)));
21635 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21637 fprintf (file, "%d,",
21638 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21640 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21641 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21643 if (optional_tbtab)
21645 /* Compute the parameter info from the function decl argument
21648 int next_parm_info_bit = 31;
21650 for (decl = DECL_ARGUMENTS (current_function_decl);
21651 decl; decl = DECL_CHAIN (decl))
21653 rtx parameter = DECL_INCOMING_RTL (decl);
21654 enum machine_mode mode = GET_MODE (parameter);
21656 if (GET_CODE (parameter) == REG)
21658 if (SCALAR_FLOAT_MODE_P (mode))
21679 gcc_unreachable ();
21682 /* If only one bit will fit, don't or in this entry. */
21683 if (next_parm_info_bit > 0)
21684 parm_info |= (bits << (next_parm_info_bit - 1));
21685 next_parm_info_bit -= 2;
21689 fixed_parms += ((GET_MODE_SIZE (mode)
21690 + (UNITS_PER_WORD - 1))
21692 next_parm_info_bit -= 1;
21698 /* Number of fixed point parameters. */
21699 /* This is actually the number of words of fixed point parameters; thus
21700 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21701 fprintf (file, "%d,", fixed_parms);
21703 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21705 /* This is actually the number of fp registers that hold parameters;
21706 and thus the maximum value is 13. */
21707 /* Set parameters on stack bit if parameters are not in their original
21708 registers, regardless of whether they are on the stack? Xlc
21709 seems to set the bit when not optimizing. */
21710 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21712 if (! optional_tbtab)
21715 /* Optional fields follow. Some are variable length. */
21717 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21718 11 double float. */
21719 /* There is an entry for each parameter in a register, in the order that
21720 they occur in the parameter list. Any intervening arguments on the
21721 stack are ignored. If the list overflows a long (max possible length
21722 34 bits) then completely leave off all elements that don't fit. */
21723 /* Only emit this long if there was at least one parameter. */
21724 if (fixed_parms || float_parms)
21725 fprintf (file, "\t.long %d\n", parm_info);
21727 /* Offset from start of code to tb table. */
21728 fputs ("\t.long ", file);
21729 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21730 RS6000_OUTPUT_BASENAME (file, fname);
21732 rs6000_output_function_entry (file, fname);
21735 /* Interrupt handler mask. */
21736 /* Omit this long, since we never set the interrupt handler bit
21739 /* Number of CTL (controlled storage) anchors. */
21740 /* Omit this long, since the has_ctl bit is never set above. */
21742 /* Displacement into stack of each CTL anchor. */
21743 /* Omit this list of longs, because there are no CTL anchors. */
21745 /* Length of function name. */
21748 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21750 /* Function name. */
21751 assemble_string (fname, strlen (fname));
21753 /* Register for alloca automatic storage; this is always reg 31.
21754 Only emit this if the alloca bit was set above. */
21755 if (frame_pointer_needed)
21756 fputs ("\t.byte 31\n", file);
21758 fputs ("\t.align 2\n", file);
21762 /* A C compound statement that outputs the assembler code for a thunk
21763 function, used to implement C++ virtual function calls with
21764 multiple inheritance. The thunk acts as a wrapper around a virtual
21765 function, adjusting the implicit object parameter before handing
21766 control off to the real function.
21768 First, emit code to add the integer DELTA to the location that
21769 contains the incoming first argument. Assume that this argument
21770 contains a pointer, and is the one used to pass the `this' pointer
21771 in C++. This is the incoming argument *before* the function
21772 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21773 values of all other incoming arguments.
21775 After the addition, emit code to jump to FUNCTION, which is a
21776 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21777 not touch the return address. Hence returning from FUNCTION will
21778 return to whoever called the current `thunk'.
21780 The effect must be as if FUNCTION had been called directly with the
21781 adjusted first argument. This macro is responsible for emitting
21782 all of the code for a thunk function; output_function_prologue()
21783 and output_function_epilogue() are not invoked.
21785 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21786 been extracted from it.) It might possibly be useful on some
21787 targets, but probably not.
21789 If you do not define this macro, the target-independent code in the
21790 C++ frontend will generate a less efficient heavyweight thunk that
21791 calls FUNCTION instead of jumping to it. The generic approach does
21792 not support varargs. */
21795 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21796 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21799 rtx this_rtx, insn, funexp;
21801 reload_completed = 1;
21802 epilogue_completed = 1;
21804 /* Mark the end of the (empty) prologue. */
21805 emit_note (NOTE_INSN_PROLOGUE_END);
21807 /* Find the "this" pointer. If the function returns a structure,
21808 the structure return pointer is in r3. */
21809 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21810 this_rtx = gen_rtx_REG (Pmode, 4);
21812 this_rtx = gen_rtx_REG (Pmode, 3);
21814 /* Apply the constant offset, if required. */
21816 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21818 /* Apply the offset from the vtable, if required. */
21821 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21822 rtx tmp = gen_rtx_REG (Pmode, 12);
21824 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21825 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21827 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21828 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21832 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21834 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21836 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21839 /* Generate a tail call to the target function. */
21840 if (!TREE_USED (function))
21842 assemble_external (function);
21843 TREE_USED (function) = 1;
21845 funexp = XEXP (DECL_RTL (function), 0);
21846 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21849 if (MACHOPIC_INDIRECT)
21850 funexp = machopic_indirect_call_target (funexp);
21853 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21854 generate sibcall RTL explicitly. */
21855 insn = emit_call_insn (
21856 gen_rtx_PARALLEL (VOIDmode,
21858 gen_rtx_CALL (VOIDmode,
21859 funexp, const0_rtx),
21860 gen_rtx_USE (VOIDmode, const0_rtx),
21861 gen_rtx_USE (VOIDmode,
21862 gen_rtx_REG (SImode,
21864 gen_rtx_RETURN (VOIDmode))));
21865 SIBLING_CALL_P (insn) = 1;
21868 /* Run just enough of rest_of_compilation to get the insns emitted.
21869 There's not really enough bulk here to make other passes such as
21870 instruction scheduling worth while. Note that use_thunk calls
21871 assemble_start_function and assemble_end_function. */
21872 insn = get_insns ();
21873 insn_locators_alloc ();
21874 shorten_branches (insn);
21875 final_start_function (insn, file, 1);
21876 final (insn, file, 1);
21877 final_end_function ();
21879 reload_completed = 0;
21880 epilogue_completed = 0;
21883 /* A quick summary of the various types of 'constant-pool tables'
21886 Target Flags Name One table per
21887 AIX (none) AIX TOC object file
21888 AIX -mfull-toc AIX TOC object file
21889 AIX -mminimal-toc AIX minimal TOC translation unit
21890 SVR4/EABI (none) SVR4 SDATA object file
21891 SVR4/EABI -fpic SVR4 pic object file
21892 SVR4/EABI -fPIC SVR4 PIC translation unit
21893 SVR4/EABI -mrelocatable EABI TOC function
21894 SVR4/EABI -maix AIX TOC object file
21895 SVR4/EABI -maix -mminimal-toc
21896 AIX minimal TOC translation unit
21898 Name Reg. Set by entries contains:
21899 made by addrs? fp? sum?
21901 AIX TOC 2 crt0 as Y option option
21902 AIX minimal TOC 30 prolog gcc Y Y option
21903 SVR4 SDATA 13 crt0 gcc N Y N
21904 SVR4 pic 30 prolog ld Y not yet N
21905 SVR4 PIC 30 prolog gcc Y option option
21906 EABI TOC 30 prolog gcc Y option option
21910 /* Hash functions for the hash table. */
21913 rs6000_hash_constant (rtx k)
21915 enum rtx_code code = GET_CODE (k);
21916 enum machine_mode mode = GET_MODE (k);
21917 unsigned result = (code << 3) ^ mode;
21918 const char *format;
21921 format = GET_RTX_FORMAT (code);
21922 flen = strlen (format);
21928 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21931 if (mode != VOIDmode)
21932 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21944 for (; fidx < flen; fidx++)
21945 switch (format[fidx])
21950 const char *str = XSTR (k, fidx);
21951 len = strlen (str);
21952 result = result * 613 + len;
21953 for (i = 0; i < len; i++)
21954 result = result * 613 + (unsigned) str[i];
21959 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21963 result = result * 613 + (unsigned) XINT (k, fidx);
21966 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21967 result = result * 613 + (unsigned) XWINT (k, fidx);
21971 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21972 result = result * 613 + (unsigned) (XWINT (k, fidx)
21979 gcc_unreachable ();
21986 toc_hash_function (const void *hash_entry)
21988 const struct toc_hash_struct *thc =
21989 (const struct toc_hash_struct *) hash_entry;
21990 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21993 /* Compare H1 and H2 for equivalence. */
21996 toc_hash_eq (const void *h1, const void *h2)
21998 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
21999 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22001 if (((const struct toc_hash_struct *) h1)->key_mode
22002 != ((const struct toc_hash_struct *) h2)->key_mode)
22005 return rtx_equal_p (r1, r2);
22008 /* These are the names given by the C++ front-end to vtables, and
22009 vtable-like objects. Ideally, this logic should not be here;
22010 instead, there should be some programmatic way of inquiring as
22011 to whether or not an object is a vtable. */
22013 #define VTABLE_NAME_P(NAME) \
22014 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22015 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22016 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22017 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22018 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22020 #ifdef NO_DOLLAR_IN_LABEL
22021 /* Return a GGC-allocated character string translating dollar signs in
22022 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22025 rs6000_xcoff_strip_dollar (const char *name)
22030 p = strchr (name, '$');
22032 if (p == 0 || p == name)
22035 len = strlen (name);
22036 strip = (char *) alloca (len + 1);
22037 strcpy (strip, name);
22038 p = strchr (strip, '$');
22042 p = strchr (p + 1, '$');
22045 return ggc_alloc_string (strip, len);
22050 rs6000_output_symbol_ref (FILE *file, rtx x)
22052 /* Currently C++ toc references to vtables can be emitted before it
22053 is decided whether the vtable is public or private. If this is
22054 the case, then the linker will eventually complain that there is
22055 a reference to an unknown section. Thus, for vtables only,
22056 we emit the TOC reference to reference the symbol and not the
22058 const char *name = XSTR (x, 0);
22060 if (VTABLE_NAME_P (name))
22062 RS6000_OUTPUT_BASENAME (file, name);
22065 assemble_name (file, name);
22068 /* Output a TOC entry. We derive the entry name from what is being
22072 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22075 const char *name = buf;
22077 HOST_WIDE_INT offset = 0;
22079 gcc_assert (!TARGET_NO_TOC);
22081 /* When the linker won't eliminate them, don't output duplicate
22082 TOC entries (this happens on AIX if there is any kind of TOC,
22083 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22085 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22087 struct toc_hash_struct *h;
22090 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22091 time because GGC is not initialized at that point. */
22092 if (toc_hash_table == NULL)
22093 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22094 toc_hash_eq, NULL);
22096 h = ggc_alloc_toc_hash_struct ();
22098 h->key_mode = mode;
22099 h->labelno = labelno;
22101 found = htab_find_slot (toc_hash_table, h, INSERT);
22102 if (*found == NULL)
22104 else /* This is indeed a duplicate.
22105 Set this label equal to that label. */
22107 fputs ("\t.set ", file);
22108 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22109 fprintf (file, "%d,", labelno);
22110 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22111 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22117 /* If we're going to put a double constant in the TOC, make sure it's
22118 aligned properly when strict alignment is on. */
22119 if (GET_CODE (x) == CONST_DOUBLE
22120 && STRICT_ALIGNMENT
22121 && GET_MODE_BITSIZE (mode) >= 64
22122 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22123 ASM_OUTPUT_ALIGN (file, 3);
22126 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22128 /* Handle FP constants specially. Note that if we have a minimal
22129 TOC, things we put here aren't actually in the TOC, so we can allow
22131 if (GET_CODE (x) == CONST_DOUBLE &&
22132 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22134 REAL_VALUE_TYPE rv;
22137 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22138 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22139 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22141 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22145 if (TARGET_MINIMAL_TOC)
22146 fputs (DOUBLE_INT_ASM_OP, file);
22148 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22149 k[0] & 0xffffffff, k[1] & 0xffffffff,
22150 k[2] & 0xffffffff, k[3] & 0xffffffff);
22151 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22152 k[0] & 0xffffffff, k[1] & 0xffffffff,
22153 k[2] & 0xffffffff, k[3] & 0xffffffff);
22158 if (TARGET_MINIMAL_TOC)
22159 fputs ("\t.long ", file);
22161 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22162 k[0] & 0xffffffff, k[1] & 0xffffffff,
22163 k[2] & 0xffffffff, k[3] & 0xffffffff);
22164 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22165 k[0] & 0xffffffff, k[1] & 0xffffffff,
22166 k[2] & 0xffffffff, k[3] & 0xffffffff);
22170 else if (GET_CODE (x) == CONST_DOUBLE &&
22171 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22173 REAL_VALUE_TYPE rv;
22176 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22178 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22179 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22181 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22185 if (TARGET_MINIMAL_TOC)
22186 fputs (DOUBLE_INT_ASM_OP, file);
22188 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22189 k[0] & 0xffffffff, k[1] & 0xffffffff);
22190 fprintf (file, "0x%lx%08lx\n",
22191 k[0] & 0xffffffff, k[1] & 0xffffffff);
22196 if (TARGET_MINIMAL_TOC)
22197 fputs ("\t.long ", file);
22199 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22200 k[0] & 0xffffffff, k[1] & 0xffffffff);
22201 fprintf (file, "0x%lx,0x%lx\n",
22202 k[0] & 0xffffffff, k[1] & 0xffffffff);
22206 else if (GET_CODE (x) == CONST_DOUBLE &&
22207 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22209 REAL_VALUE_TYPE rv;
22212 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22213 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22214 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22216 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22220 if (TARGET_MINIMAL_TOC)
22221 fputs (DOUBLE_INT_ASM_OP, file);
22223 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22224 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22229 if (TARGET_MINIMAL_TOC)
22230 fputs ("\t.long ", file);
22232 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22233 fprintf (file, "0x%lx\n", l & 0xffffffff);
22237 else if (GET_MODE (x) == VOIDmode
22238 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22240 unsigned HOST_WIDE_INT low;
22241 HOST_WIDE_INT high;
22243 if (GET_CODE (x) == CONST_DOUBLE)
22245 low = CONST_DOUBLE_LOW (x);
22246 high = CONST_DOUBLE_HIGH (x);
22249 #if HOST_BITS_PER_WIDE_INT == 32
22252 high = (low & 0x80000000) ? ~0 : 0;
22256 low = INTVAL (x) & 0xffffffff;
22257 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22261 /* TOC entries are always Pmode-sized, but since this
22262 is a bigendian machine then if we're putting smaller
22263 integer constants in the TOC we have to pad them.
22264 (This is still a win over putting the constants in
22265 a separate constant pool, because then we'd have
22266 to have both a TOC entry _and_ the actual constant.)
22268 For a 32-bit target, CONST_INT values are loaded and shifted
22269 entirely within `low' and can be stored in one TOC entry. */
22271 /* It would be easy to make this work, but it doesn't now. */
22272 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22274 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22276 #if HOST_BITS_PER_WIDE_INT == 32
22277 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22278 POINTER_SIZE, &low, &high, 0);
22281 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22282 high = (HOST_WIDE_INT) low >> 32;
22289 if (TARGET_MINIMAL_TOC)
22290 fputs (DOUBLE_INT_ASM_OP, file);
22292 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22293 (long) high & 0xffffffff, (long) low & 0xffffffff);
22294 fprintf (file, "0x%lx%08lx\n",
22295 (long) high & 0xffffffff, (long) low & 0xffffffff);
22300 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22302 if (TARGET_MINIMAL_TOC)
22303 fputs ("\t.long ", file);
22305 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22306 (long) high & 0xffffffff, (long) low & 0xffffffff);
22307 fprintf (file, "0x%lx,0x%lx\n",
22308 (long) high & 0xffffffff, (long) low & 0xffffffff);
22312 if (TARGET_MINIMAL_TOC)
22313 fputs ("\t.long ", file);
22315 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22316 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22322 if (GET_CODE (x) == CONST)
22324 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22325 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22327 base = XEXP (XEXP (x, 0), 0);
22328 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22331 switch (GET_CODE (base))
22334 name = XSTR (base, 0);
22338 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22339 CODE_LABEL_NUMBER (XEXP (base, 0)));
22343 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22347 gcc_unreachable ();
22350 if (TARGET_MINIMAL_TOC)
22351 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22354 fputs ("\t.tc ", file);
22355 RS6000_OUTPUT_BASENAME (file, name);
22358 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22360 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22362 fputs ("[TC],", file);
22365 /* Currently C++ toc references to vtables can be emitted before it
22366 is decided whether the vtable is public or private. If this is
22367 the case, then the linker will eventually complain that there is
22368 a TOC reference to an unknown section. Thus, for vtables only,
22369 we emit the TOC reference to reference the symbol and not the
22371 if (VTABLE_NAME_P (name))
22373 RS6000_OUTPUT_BASENAME (file, name);
22375 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22376 else if (offset > 0)
22377 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22380 output_addr_const (file, x);
22384 /* Output an assembler pseudo-op to write an ASCII string of N characters
22385 starting at P to FILE.
22387 On the RS/6000, we have to do this using the .byte operation and
22388 write out special characters outside the quoted string.
22389 Also, the assembler is broken; very long strings are truncated,
22390 so we must artificially break them up early. */
22393 output_ascii (FILE *file, const char *p, int n)
22396 int i, count_string;
22397 const char *for_string = "\t.byte \"";
22398 const char *for_decimal = "\t.byte ";
22399 const char *to_close = NULL;
22402 for (i = 0; i < n; i++)
22405 if (c >= ' ' && c < 0177)
22408 fputs (for_string, file);
22411 /* Write two quotes to get one. */
22419 for_decimal = "\"\n\t.byte ";
22423 if (count_string >= 512)
22425 fputs (to_close, file);
22427 for_string = "\t.byte \"";
22428 for_decimal = "\t.byte ";
22436 fputs (for_decimal, file);
22437 fprintf (file, "%d", c);
22439 for_string = "\n\t.byte \"";
22440 for_decimal = ", ";
22446 /* Now close the string if we have written one. Then end the line. */
22448 fputs (to_close, file);
22451 /* Generate a unique section name for FILENAME for a section type
22452 represented by SECTION_DESC. Output goes into BUF.
22454 SECTION_DESC can be any string, as long as it is different for each
22455 possible section type.
22457 We name the section in the same manner as xlc. The name begins with an
22458 underscore followed by the filename (after stripping any leading directory
22459 names) with the last period replaced by the string SECTION_DESC. If
22460 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22464 rs6000_gen_section_name (char **buf, const char *filename,
22465 const char *section_desc)
22467 const char *q, *after_last_slash, *last_period = 0;
22471 after_last_slash = filename;
22472 for (q = filename; *q; q++)
22475 after_last_slash = q + 1;
22476 else if (*q == '.')
22480 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22481 *buf = (char *) xmalloc (len);
22486 for (q = after_last_slash; *q; q++)
22488 if (q == last_period)
22490 strcpy (p, section_desc);
22491 p += strlen (section_desc);
22495 else if (ISALNUM (*q))
22499 if (last_period == 0)
22500 strcpy (p, section_desc);
22505 /* Emit profile function. */
22508 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22510 /* Non-standard profiling for kernels, which just saves LR then calls
22511 _mcount without worrying about arg saves. The idea is to change
22512 the function prologue as little as possible as it isn't easy to
22513 account for arg save/restore code added just for _mcount. */
22514 if (TARGET_PROFILE_KERNEL)
22517 if (DEFAULT_ABI == ABI_AIX)
22519 #ifndef NO_PROFILE_COUNTERS
22520 # define NO_PROFILE_COUNTERS 0
22522 if (NO_PROFILE_COUNTERS)
22523 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22524 LCT_NORMAL, VOIDmode, 0);
22528 const char *label_name;
22531 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22532 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22533 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22535 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22536 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22539 else if (DEFAULT_ABI == ABI_DARWIN)
22541 const char *mcount_name = RS6000_MCOUNT;
22542 int caller_addr_regno = LR_REGNO;
22544 /* Be conservative and always set this, at least for now. */
22545 crtl->uses_pic_offset_table = 1;
22548 /* For PIC code, set up a stub and collect the caller's address
22549 from r0, which is where the prologue puts it. */
22550 if (MACHOPIC_INDIRECT
22551 && crtl->uses_pic_offset_table)
22552 caller_addr_regno = 0;
22554 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22555 LCT_NORMAL, VOIDmode, 1,
22556 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22560 /* Write function profiler code. */
22563 output_function_profiler (FILE *file, int labelno)
22567 switch (DEFAULT_ABI)
22570 gcc_unreachable ();
22575 warning (0, "no profiling of 64-bit code for this ABI");
22578 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22579 fprintf (file, "\tmflr %s\n", reg_names[0]);
22580 if (NO_PROFILE_COUNTERS)
22582 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22583 reg_names[0], reg_names[1]);
22585 else if (TARGET_SECURE_PLT && flag_pic)
22587 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22588 reg_names[0], reg_names[1]);
22589 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22590 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22591 reg_names[12], reg_names[12]);
22592 assemble_name (file, buf);
22593 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22594 assemble_name (file, buf);
22595 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22597 else if (flag_pic == 1)
22599 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22600 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22601 reg_names[0], reg_names[1]);
22602 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22603 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22604 assemble_name (file, buf);
22605 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22607 else if (flag_pic > 1)
22609 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22610 reg_names[0], reg_names[1]);
22611 /* Now, we need to get the address of the label. */
22612 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22613 assemble_name (file, buf);
22614 fputs ("-.\n1:", file);
22615 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22616 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22617 reg_names[0], reg_names[11]);
22618 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22619 reg_names[0], reg_names[0], reg_names[11]);
22623 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22624 assemble_name (file, buf);
22625 fputs ("@ha\n", file);
22626 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22627 reg_names[0], reg_names[1]);
22628 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22629 assemble_name (file, buf);
22630 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22633 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22634 fprintf (file, "\tbl %s%s\n",
22635 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22640 if (!TARGET_PROFILE_KERNEL)
22642 /* Don't do anything, done in output_profile_hook (). */
22646 gcc_assert (!TARGET_32BIT);
22648 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22649 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22651 if (cfun->static_chain_decl != NULL)
22653 asm_fprintf (file, "\tstd %s,24(%s)\n",
22654 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22655 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22656 asm_fprintf (file, "\tld %s,24(%s)\n",
22657 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22660 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22668 /* The following variable value is the last issued insn. */
22670 static rtx last_scheduled_insn;
22672 /* The following variable helps to balance issuing of load and
22673 store instructions */
22675 static int load_store_pendulum;
22677 /* Power4 load update and store update instructions are cracked into a
22678 load or store and an integer insn which are executed in the same cycle.
22679 Branches have their own dispatch slot which does not count against the
22680 GCC issue rate, but it changes the program flow so there are no other
22681 instructions to issue in this cycle. */
22684 rs6000_variable_issue_1 (rtx insn, int more)
22686 last_scheduled_insn = insn;
22687 if (GET_CODE (PATTERN (insn)) == USE
22688 || GET_CODE (PATTERN (insn)) == CLOBBER)
22690 cached_can_issue_more = more;
22691 return cached_can_issue_more;
22694 if (insn_terminates_group_p (insn, current_group))
22696 cached_can_issue_more = 0;
22697 return cached_can_issue_more;
22700 /* If no reservation, but reach here */
22701 if (recog_memoized (insn) < 0)
22704 if (rs6000_sched_groups)
22706 if (is_microcoded_insn (insn))
22707 cached_can_issue_more = 0;
22708 else if (is_cracked_insn (insn))
22709 cached_can_issue_more = more > 2 ? more - 2 : 0;
22711 cached_can_issue_more = more - 1;
22713 return cached_can_issue_more;
22716 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22719 cached_can_issue_more = more - 1;
22720 return cached_can_issue_more;
22724 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22726 int r = rs6000_variable_issue_1 (insn, more);
22728 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22732 /* Adjust the cost of a scheduling dependency. Return the new cost of
22733 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22736 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22738 enum attr_type attr_type;
22740 if (! recog_memoized (insn))
22743 switch (REG_NOTE_KIND (link))
22747 /* Data dependency; DEP_INSN writes a register that INSN reads
22748 some cycles later. */
22750 /* Separate a load from a narrower, dependent store. */
22751 if (rs6000_sched_groups
22752 && GET_CODE (PATTERN (insn)) == SET
22753 && GET_CODE (PATTERN (dep_insn)) == SET
22754 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22755 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22756 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22757 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22760 attr_type = get_attr_type (insn);
22765 /* Tell the first scheduling pass about the latency between
22766 a mtctr and bctr (and mtlr and br/blr). The first
22767 scheduling pass will not know about this latency since
22768 the mtctr instruction, which has the latency associated
22769 to it, will be generated by reload. */
22770 return TARGET_POWER ? 5 : 4;
22772 /* Leave some extra cycles between a compare and its
22773 dependent branch, to inhibit expensive mispredicts. */
22774 if ((rs6000_cpu_attr == CPU_PPC603
22775 || rs6000_cpu_attr == CPU_PPC604
22776 || rs6000_cpu_attr == CPU_PPC604E
22777 || rs6000_cpu_attr == CPU_PPC620
22778 || rs6000_cpu_attr == CPU_PPC630
22779 || rs6000_cpu_attr == CPU_PPC750
22780 || rs6000_cpu_attr == CPU_PPC7400
22781 || rs6000_cpu_attr == CPU_PPC7450
22782 || rs6000_cpu_attr == CPU_POWER4
22783 || rs6000_cpu_attr == CPU_POWER5
22784 || rs6000_cpu_attr == CPU_POWER7
22785 || rs6000_cpu_attr == CPU_CELL)
22786 && recog_memoized (dep_insn)
22787 && (INSN_CODE (dep_insn) >= 0))
22789 switch (get_attr_type (dep_insn))
22793 case TYPE_DELAYED_COMPARE:
22794 case TYPE_IMUL_COMPARE:
22795 case TYPE_LMUL_COMPARE:
22796 case TYPE_FPCOMPARE:
22797 case TYPE_CR_LOGICAL:
22798 case TYPE_DELAYED_CR:
22807 case TYPE_STORE_UX:
22809 case TYPE_FPSTORE_U:
22810 case TYPE_FPSTORE_UX:
22811 if ((rs6000_cpu == PROCESSOR_POWER6)
22812 && recog_memoized (dep_insn)
22813 && (INSN_CODE (dep_insn) >= 0))
22816 if (GET_CODE (PATTERN (insn)) != SET)
22817 /* If this happens, we have to extend this to schedule
22818 optimally. Return default for now. */
22821 /* Adjust the cost for the case where the value written
22822 by a fixed point operation is used as the address
22823 gen value on a store. */
22824 switch (get_attr_type (dep_insn))
22831 if (! store_data_bypass_p (dep_insn, insn))
22835 case TYPE_LOAD_EXT:
22836 case TYPE_LOAD_EXT_U:
22837 case TYPE_LOAD_EXT_UX:
22838 case TYPE_VAR_SHIFT_ROTATE:
22839 case TYPE_VAR_DELAYED_COMPARE:
22841 if (! store_data_bypass_p (dep_insn, insn))
22847 case TYPE_FAST_COMPARE:
22850 case TYPE_INSERT_WORD:
22851 case TYPE_INSERT_DWORD:
22852 case TYPE_FPLOAD_U:
22853 case TYPE_FPLOAD_UX:
22855 case TYPE_STORE_UX:
22856 case TYPE_FPSTORE_U:
22857 case TYPE_FPSTORE_UX:
22859 if (! store_data_bypass_p (dep_insn, insn))
22867 case TYPE_IMUL_COMPARE:
22868 case TYPE_LMUL_COMPARE:
22870 if (! store_data_bypass_p (dep_insn, insn))
22876 if (! store_data_bypass_p (dep_insn, insn))
22882 if (! store_data_bypass_p (dep_insn, insn))
22895 case TYPE_LOAD_EXT:
22896 case TYPE_LOAD_EXT_U:
22897 case TYPE_LOAD_EXT_UX:
22898 if ((rs6000_cpu == PROCESSOR_POWER6)
22899 && recog_memoized (dep_insn)
22900 && (INSN_CODE (dep_insn) >= 0))
22903 /* Adjust the cost for the case where the value written
22904 by a fixed point instruction is used within the address
22905 gen portion of a subsequent load(u)(x) */
22906 switch (get_attr_type (dep_insn))
22913 if (set_to_load_agen (dep_insn, insn))
22917 case TYPE_LOAD_EXT:
22918 case TYPE_LOAD_EXT_U:
22919 case TYPE_LOAD_EXT_UX:
22920 case TYPE_VAR_SHIFT_ROTATE:
22921 case TYPE_VAR_DELAYED_COMPARE:
22923 if (set_to_load_agen (dep_insn, insn))
22929 case TYPE_FAST_COMPARE:
22932 case TYPE_INSERT_WORD:
22933 case TYPE_INSERT_DWORD:
22934 case TYPE_FPLOAD_U:
22935 case TYPE_FPLOAD_UX:
22937 case TYPE_STORE_UX:
22938 case TYPE_FPSTORE_U:
22939 case TYPE_FPSTORE_UX:
22941 if (set_to_load_agen (dep_insn, insn))
22949 case TYPE_IMUL_COMPARE:
22950 case TYPE_LMUL_COMPARE:
22952 if (set_to_load_agen (dep_insn, insn))
22958 if (set_to_load_agen (dep_insn, insn))
22964 if (set_to_load_agen (dep_insn, insn))
22975 if ((rs6000_cpu == PROCESSOR_POWER6)
22976 && recog_memoized (dep_insn)
22977 && (INSN_CODE (dep_insn) >= 0)
22978 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22985 /* Fall out to return default cost. */
22989 case REG_DEP_OUTPUT:
22990 /* Output dependency; DEP_INSN writes a register that INSN writes some
22992 if ((rs6000_cpu == PROCESSOR_POWER6)
22993 && recog_memoized (dep_insn)
22994 && (INSN_CODE (dep_insn) >= 0))
22996 attr_type = get_attr_type (insn);
23001 if (get_attr_type (dep_insn) == TYPE_FP)
23005 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23013 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23018 gcc_unreachable ();
23024 /* Debug version of rs6000_adjust_cost. */
23027 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23029 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23035 switch (REG_NOTE_KIND (link))
23037 default: dep = "unknown depencency"; break;
23038 case REG_DEP_TRUE: dep = "data dependency"; break;
23039 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23040 case REG_DEP_ANTI: dep = "anti depencency"; break;
23044 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23045 "%s, insn:\n", ret, cost, dep);
23053 /* The function returns a true if INSN is microcoded.
23054 Return false otherwise. */
23057 is_microcoded_insn (rtx insn)
23059 if (!insn || !NONDEBUG_INSN_P (insn)
23060 || GET_CODE (PATTERN (insn)) == USE
23061 || GET_CODE (PATTERN (insn)) == CLOBBER)
23064 if (rs6000_cpu_attr == CPU_CELL)
23065 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23067 if (rs6000_sched_groups)
23069 enum attr_type type = get_attr_type (insn);
23070 if (type == TYPE_LOAD_EXT_U
23071 || type == TYPE_LOAD_EXT_UX
23072 || type == TYPE_LOAD_UX
23073 || type == TYPE_STORE_UX
23074 || type == TYPE_MFCR)
23081 /* The function returns true if INSN is cracked into 2 instructions
23082 by the processor (and therefore occupies 2 issue slots). */
23085 is_cracked_insn (rtx insn)
23087 if (!insn || !NONDEBUG_INSN_P (insn)
23088 || GET_CODE (PATTERN (insn)) == USE
23089 || GET_CODE (PATTERN (insn)) == CLOBBER)
23092 if (rs6000_sched_groups)
23094 enum attr_type type = get_attr_type (insn);
23095 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23096 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23097 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23098 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23099 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23100 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23101 || type == TYPE_IDIV || type == TYPE_LDIV
23102 || type == TYPE_INSERT_WORD)
23109 /* The function returns true if INSN can be issued only from
23110 the branch slot. */
23113 is_branch_slot_insn (rtx insn)
23115 if (!insn || !NONDEBUG_INSN_P (insn)
23116 || GET_CODE (PATTERN (insn)) == USE
23117 || GET_CODE (PATTERN (insn)) == CLOBBER)
23120 if (rs6000_sched_groups)
23122 enum attr_type type = get_attr_type (insn);
23123 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23131 /* The function returns true if out_inst sets a value that is
23132 used in the address generation computation of in_insn */
23134 set_to_load_agen (rtx out_insn, rtx in_insn)
23136 rtx out_set, in_set;
23138 /* For performance reasons, only handle the simple case where
23139 both loads are a single_set. */
23140 out_set = single_set (out_insn);
23143 in_set = single_set (in_insn);
23145 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23151 /* The function returns true if the target storage location of
23152 out_insn is adjacent to the target storage location of in_insn */
23153 /* Return 1 if memory locations are adjacent. */
23156 adjacent_mem_locations (rtx insn1, rtx insn2)
23159 rtx a = get_store_dest (PATTERN (insn1));
23160 rtx b = get_store_dest (PATTERN (insn2));
23162 if ((GET_CODE (XEXP (a, 0)) == REG
23163 || (GET_CODE (XEXP (a, 0)) == PLUS
23164 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23165 && (GET_CODE (XEXP (b, 0)) == REG
23166 || (GET_CODE (XEXP (b, 0)) == PLUS
23167 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23169 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23172 if (GET_CODE (XEXP (a, 0)) == PLUS)
23174 reg0 = XEXP (XEXP (a, 0), 0);
23175 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23178 reg0 = XEXP (a, 0);
23180 if (GET_CODE (XEXP (b, 0)) == PLUS)
23182 reg1 = XEXP (XEXP (b, 0), 0);
23183 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23186 reg1 = XEXP (b, 0);
23188 val_diff = val1 - val0;
23190 return ((REGNO (reg0) == REGNO (reg1))
23191 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23192 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23198 /* A C statement (sans semicolon) to update the integer scheduling
23199 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23200 INSN earlier, reduce the priority to execute INSN later. Do not
23201 define this macro if you do not need to adjust the scheduling
23202 priorities of insns. */
23205 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23207 /* On machines (like the 750) which have asymmetric integer units,
23208 where one integer unit can do multiply and divides and the other
23209 can't, reduce the priority of multiply/divide so it is scheduled
23210 before other integer operations. */
23213 if (! INSN_P (insn))
23216 if (GET_CODE (PATTERN (insn)) == USE)
23219 switch (rs6000_cpu_attr) {
23221 switch (get_attr_type (insn))
23228 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23229 priority, priority);
23230 if (priority >= 0 && priority < 0x01000000)
23237 if (insn_must_be_first_in_group (insn)
23238 && reload_completed
23239 && current_sched_info->sched_max_insns_priority
23240 && rs6000_sched_restricted_insns_priority)
23243 /* Prioritize insns that can be dispatched only in the first
23245 if (rs6000_sched_restricted_insns_priority == 1)
23246 /* Attach highest priority to insn. This means that in
23247 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23248 precede 'priority' (critical path) considerations. */
23249 return current_sched_info->sched_max_insns_priority;
23250 else if (rs6000_sched_restricted_insns_priority == 2)
23251 /* Increase priority of insn by a minimal amount. This means that in
23252 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23253 considerations precede dispatch-slot restriction considerations. */
23254 return (priority + 1);
23257 if (rs6000_cpu == PROCESSOR_POWER6
23258 && ((load_store_pendulum == -2 && is_load_insn (insn))
23259 || (load_store_pendulum == 2 && is_store_insn (insn))))
23260 /* Attach highest priority to insn if the scheduler has just issued two
23261 stores and this instruction is a load, or two loads and this instruction
23262 is a store. Power6 wants loads and stores scheduled alternately
23264 return current_sched_info->sched_max_insns_priority;
23269 /* Return true if the instruction is nonpipelined on the Cell. */
23271 is_nonpipeline_insn (rtx insn)
23273 enum attr_type type;
23274 if (!insn || !NONDEBUG_INSN_P (insn)
23275 || GET_CODE (PATTERN (insn)) == USE
23276 || GET_CODE (PATTERN (insn)) == CLOBBER)
23279 type = get_attr_type (insn);
23280 if (type == TYPE_IMUL
23281 || type == TYPE_IMUL2
23282 || type == TYPE_IMUL3
23283 || type == TYPE_LMUL
23284 || type == TYPE_IDIV
23285 || type == TYPE_LDIV
23286 || type == TYPE_SDIV
23287 || type == TYPE_DDIV
23288 || type == TYPE_SSQRT
23289 || type == TYPE_DSQRT
23290 || type == TYPE_MFCR
23291 || type == TYPE_MFCRF
23292 || type == TYPE_MFJMPR)
23300 /* Return how many instructions the machine can issue per cycle. */
23303 rs6000_issue_rate (void)
23305 /* Unless scheduling for register pressure, use issue rate of 1 for
23306 first scheduling pass to decrease degradation. */
23307 if (!reload_completed && !flag_sched_pressure)
23310 switch (rs6000_cpu_attr) {
23311 case CPU_RIOS1: /* ? */
23313 case CPU_PPC601: /* ? */
23322 case CPU_PPCE300C2:
23323 case CPU_PPCE300C3:
23324 case CPU_PPCE500MC:
23325 case CPU_PPCE500MC64:
23345 /* Return how many instructions to look ahead for better insn
23349 rs6000_use_sched_lookahead (void)
23351 if (rs6000_cpu_attr == CPU_PPC8540)
23353 if (rs6000_cpu_attr == CPU_CELL)
23354 return (reload_completed ? 8 : 0);
23358 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23360 rs6000_use_sched_lookahead_guard (rtx insn)
23362 if (rs6000_cpu_attr != CPU_CELL)
23365 if (insn == NULL_RTX || !INSN_P (insn))
23368 if (!reload_completed
23369 || is_nonpipeline_insn (insn)
23370 || is_microcoded_insn (insn))
23376 /* Determine is PAT refers to memory. */
23379 is_mem_ref (rtx pat)
23385 /* stack_tie does not produce any real memory traffic. */
23386 if (GET_CODE (pat) == UNSPEC
23387 && XINT (pat, 1) == UNSPEC_TIE)
23390 if (GET_CODE (pat) == MEM)
23393 /* Recursively process the pattern. */
23394 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23396 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23399 ret |= is_mem_ref (XEXP (pat, i));
23400 else if (fmt[i] == 'E')
23401 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23402 ret |= is_mem_ref (XVECEXP (pat, i, j));
23408 /* Determine if PAT is a PATTERN of a load insn. */
23411 is_load_insn1 (rtx pat)
23413 if (!pat || pat == NULL_RTX)
23416 if (GET_CODE (pat) == SET)
23417 return is_mem_ref (SET_SRC (pat));
23419 if (GET_CODE (pat) == PARALLEL)
23423 for (i = 0; i < XVECLEN (pat, 0); i++)
23424 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23431 /* Determine if INSN loads from memory. */
23434 is_load_insn (rtx insn)
23436 if (!insn || !INSN_P (insn))
23439 if (GET_CODE (insn) == CALL_INSN)
23442 return is_load_insn1 (PATTERN (insn));
23445 /* Determine if PAT is a PATTERN of a store insn. */
23448 is_store_insn1 (rtx pat)
23450 if (!pat || pat == NULL_RTX)
23453 if (GET_CODE (pat) == SET)
23454 return is_mem_ref (SET_DEST (pat));
23456 if (GET_CODE (pat) == PARALLEL)
23460 for (i = 0; i < XVECLEN (pat, 0); i++)
23461 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23468 /* Determine if INSN stores to memory. */
23471 is_store_insn (rtx insn)
23473 if (!insn || !INSN_P (insn))
23476 return is_store_insn1 (PATTERN (insn));
23479 /* Return the dest of a store insn. */
23482 get_store_dest (rtx pat)
23484 gcc_assert (is_store_insn1 (pat));
23486 if (GET_CODE (pat) == SET)
23487 return SET_DEST (pat);
23488 else if (GET_CODE (pat) == PARALLEL)
23492 for (i = 0; i < XVECLEN (pat, 0); i++)
23494 rtx inner_pat = XVECEXP (pat, 0, i);
23495 if (GET_CODE (inner_pat) == SET
23496 && is_mem_ref (SET_DEST (inner_pat)))
23500 /* We shouldn't get here, because we should have either a simple
23501 store insn or a store with update which are covered above. */
23505 /* Returns whether the dependence between INSN and NEXT is considered
23506 costly by the given target. */
23509 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23514 /* If the flag is not enabled - no dependence is considered costly;
23515 allow all dependent insns in the same group.
23516 This is the most aggressive option. */
23517 if (rs6000_sched_costly_dep == no_dep_costly)
23520 /* If the flag is set to 1 - a dependence is always considered costly;
23521 do not allow dependent instructions in the same group.
23522 This is the most conservative option. */
23523 if (rs6000_sched_costly_dep == all_deps_costly)
23526 insn = DEP_PRO (dep);
23527 next = DEP_CON (dep);
23529 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23530 && is_load_insn (next)
23531 && is_store_insn (insn))
23532 /* Prevent load after store in the same group. */
23535 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23536 && is_load_insn (next)
23537 && is_store_insn (insn)
23538 && DEP_TYPE (dep) == REG_DEP_TRUE)
23539 /* Prevent load after store in the same group if it is a true
23543 /* The flag is set to X; dependences with latency >= X are considered costly,
23544 and will not be scheduled in the same group. */
23545 if (rs6000_sched_costly_dep <= max_dep_latency
23546 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23552 /* Return the next insn after INSN that is found before TAIL is reached,
23553 skipping any "non-active" insns - insns that will not actually occupy
23554 an issue slot. Return NULL_RTX if such an insn is not found. */
23557 get_next_active_insn (rtx insn, rtx tail)
23559 if (insn == NULL_RTX || insn == tail)
23564 insn = NEXT_INSN (insn);
23565 if (insn == NULL_RTX || insn == tail)
23570 || (NONJUMP_INSN_P (insn)
23571 && GET_CODE (PATTERN (insn)) != USE
23572 && GET_CODE (PATTERN (insn)) != CLOBBER
23573 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23579 /* We are about to begin issuing insns for this clock cycle. */
23582 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23583 rtx *ready ATTRIBUTE_UNUSED,
23584 int *pn_ready ATTRIBUTE_UNUSED,
23585 int clock_var ATTRIBUTE_UNUSED)
23587 int n_ready = *pn_ready;
23590 fprintf (dump, "// rs6000_sched_reorder :\n");
23592 /* Reorder the ready list, if the second to last ready insn
23593 is a nonepipeline insn. */
23594 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23596 if (is_nonpipeline_insn (ready[n_ready - 1])
23597 && (recog_memoized (ready[n_ready - 2]) > 0))
23598 /* Simply swap first two insns. */
23600 rtx tmp = ready[n_ready - 1];
23601 ready[n_ready - 1] = ready[n_ready - 2];
23602 ready[n_ready - 2] = tmp;
23606 if (rs6000_cpu == PROCESSOR_POWER6)
23607 load_store_pendulum = 0;
23609 return rs6000_issue_rate ();
23612 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23615 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23616 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23619 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23621 /* For Power6, we need to handle some special cases to try and keep the
23622 store queue from overflowing and triggering expensive flushes.
23624 This code monitors how load and store instructions are being issued
23625 and skews the ready list one way or the other to increase the likelihood
23626 that a desired instruction is issued at the proper time.
23628 A couple of things are done. First, we maintain a "load_store_pendulum"
23629 to track the current state of load/store issue.
23631 - If the pendulum is at zero, then no loads or stores have been
23632 issued in the current cycle so we do nothing.
23634 - If the pendulum is 1, then a single load has been issued in this
23635 cycle and we attempt to locate another load in the ready list to
23638 - If the pendulum is -2, then two stores have already been
23639 issued in this cycle, so we increase the priority of the first load
23640 in the ready list to increase it's likelihood of being chosen first
23643 - If the pendulum is -1, then a single store has been issued in this
23644 cycle and we attempt to locate another store in the ready list to
23645 issue with it, preferring a store to an adjacent memory location to
23646 facilitate store pairing in the store queue.
23648 - If the pendulum is 2, then two loads have already been
23649 issued in this cycle, so we increase the priority of the first store
23650 in the ready list to increase it's likelihood of being chosen first
23653 - If the pendulum < -2 or > 2, then do nothing.
23655 Note: This code covers the most common scenarios. There exist non
23656 load/store instructions which make use of the LSU and which
23657 would need to be accounted for to strictly model the behavior
23658 of the machine. Those instructions are currently unaccounted
23659 for to help minimize compile time overhead of this code.
23661 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23667 if (is_store_insn (last_scheduled_insn))
23668 /* Issuing a store, swing the load_store_pendulum to the left */
23669 load_store_pendulum--;
23670 else if (is_load_insn (last_scheduled_insn))
23671 /* Issuing a load, swing the load_store_pendulum to the right */
23672 load_store_pendulum++;
23674 return cached_can_issue_more;
23676 /* If the pendulum is balanced, or there is only one instruction on
23677 the ready list, then all is well, so return. */
23678 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23679 return cached_can_issue_more;
23681 if (load_store_pendulum == 1)
23683 /* A load has been issued in this cycle. Scan the ready list
23684 for another load to issue with it */
23689 if (is_load_insn (ready[pos]))
23691 /* Found a load. Move it to the head of the ready list,
23692 and adjust it's priority so that it is more likely to
23695 for (i=pos; i<*pn_ready-1; i++)
23696 ready[i] = ready[i + 1];
23697 ready[*pn_ready-1] = tmp;
23699 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23700 INSN_PRIORITY (tmp)++;
23706 else if (load_store_pendulum == -2)
23708 /* Two stores have been issued in this cycle. Increase the
23709 priority of the first load in the ready list to favor it for
23710 issuing in the next cycle. */
23715 if (is_load_insn (ready[pos])
23717 && INSN_PRIORITY_KNOWN (ready[pos]))
23719 INSN_PRIORITY (ready[pos])++;
23721 /* Adjust the pendulum to account for the fact that a load
23722 was found and increased in priority. This is to prevent
23723 increasing the priority of multiple loads */
23724 load_store_pendulum--;
23731 else if (load_store_pendulum == -1)
23733 /* A store has been issued in this cycle. Scan the ready list for
23734 another store to issue with it, preferring a store to an adjacent
23736 int first_store_pos = -1;
23742 if (is_store_insn (ready[pos]))
23744 /* Maintain the index of the first store found on the
23746 if (first_store_pos == -1)
23747 first_store_pos = pos;
23749 if (is_store_insn (last_scheduled_insn)
23750 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23752 /* Found an adjacent store. Move it to the head of the
23753 ready list, and adjust it's priority so that it is
23754 more likely to stay there */
23756 for (i=pos; i<*pn_ready-1; i++)
23757 ready[i] = ready[i + 1];
23758 ready[*pn_ready-1] = tmp;
23760 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23761 INSN_PRIORITY (tmp)++;
23763 first_store_pos = -1;
23771 if (first_store_pos >= 0)
23773 /* An adjacent store wasn't found, but a non-adjacent store was,
23774 so move the non-adjacent store to the front of the ready
23775 list, and adjust its priority so that it is more likely to
23777 tmp = ready[first_store_pos];
23778 for (i=first_store_pos; i<*pn_ready-1; i++)
23779 ready[i] = ready[i + 1];
23780 ready[*pn_ready-1] = tmp;
23781 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23782 INSN_PRIORITY (tmp)++;
23785 else if (load_store_pendulum == 2)
23787 /* Two loads have been issued in this cycle. Increase the priority
23788 of the first store in the ready list to favor it for issuing in
23794 if (is_store_insn (ready[pos])
23796 && INSN_PRIORITY_KNOWN (ready[pos]))
23798 INSN_PRIORITY (ready[pos])++;
23800 /* Adjust the pendulum to account for the fact that a store
23801 was found and increased in priority. This is to prevent
23802 increasing the priority of multiple stores */
23803 load_store_pendulum++;
23812 return cached_can_issue_more;
23815 /* Return whether the presence of INSN causes a dispatch group termination
23816 of group WHICH_GROUP.
23818 If WHICH_GROUP == current_group, this function will return true if INSN
23819 causes the termination of the current group (i.e, the dispatch group to
23820 which INSN belongs). This means that INSN will be the last insn in the
23821 group it belongs to.
23823 If WHICH_GROUP == previous_group, this function will return true if INSN
23824 causes the termination of the previous group (i.e, the dispatch group that
23825 precedes the group to which INSN belongs). This means that INSN will be
23826 the first insn in the group it belongs to). */
23829 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23836 first = insn_must_be_first_in_group (insn);
23837 last = insn_must_be_last_in_group (insn);
23842 if (which_group == current_group)
23844 else if (which_group == previous_group)
23852 insn_must_be_first_in_group (rtx insn)
23854 enum attr_type type;
23857 || GET_CODE (insn) == NOTE
23858 || DEBUG_INSN_P (insn)
23859 || GET_CODE (PATTERN (insn)) == USE
23860 || GET_CODE (PATTERN (insn)) == CLOBBER)
23863 switch (rs6000_cpu)
23865 case PROCESSOR_POWER5:
23866 if (is_cracked_insn (insn))
23868 case PROCESSOR_POWER4:
23869 if (is_microcoded_insn (insn))
23872 if (!rs6000_sched_groups)
23875 type = get_attr_type (insn);
23882 case TYPE_DELAYED_CR:
23883 case TYPE_CR_LOGICAL:
23897 case PROCESSOR_POWER6:
23898 type = get_attr_type (insn);
23902 case TYPE_INSERT_DWORD:
23906 case TYPE_VAR_SHIFT_ROTATE:
23913 case TYPE_INSERT_WORD:
23914 case TYPE_DELAYED_COMPARE:
23915 case TYPE_IMUL_COMPARE:
23916 case TYPE_LMUL_COMPARE:
23917 case TYPE_FPCOMPARE:
23928 case TYPE_LOAD_EXT_UX:
23930 case TYPE_STORE_UX:
23931 case TYPE_FPLOAD_U:
23932 case TYPE_FPLOAD_UX:
23933 case TYPE_FPSTORE_U:
23934 case TYPE_FPSTORE_UX:
23940 case PROCESSOR_POWER7:
23941 type = get_attr_type (insn);
23945 case TYPE_CR_LOGICAL:
23952 case TYPE_DELAYED_COMPARE:
23953 case TYPE_VAR_DELAYED_COMPARE:
23959 case TYPE_LOAD_EXT:
23960 case TYPE_LOAD_EXT_U:
23961 case TYPE_LOAD_EXT_UX:
23963 case TYPE_STORE_UX:
23964 case TYPE_FPLOAD_U:
23965 case TYPE_FPLOAD_UX:
23966 case TYPE_FPSTORE_U:
23967 case TYPE_FPSTORE_UX:
23983 insn_must_be_last_in_group (rtx insn)
23985 enum attr_type type;
23988 || GET_CODE (insn) == NOTE
23989 || DEBUG_INSN_P (insn)
23990 || GET_CODE (PATTERN (insn)) == USE
23991 || GET_CODE (PATTERN (insn)) == CLOBBER)
23994 switch (rs6000_cpu) {
23995 case PROCESSOR_POWER4:
23996 case PROCESSOR_POWER5:
23997 if (is_microcoded_insn (insn))
24000 if (is_branch_slot_insn (insn))
24004 case PROCESSOR_POWER6:
24005 type = get_attr_type (insn);
24012 case TYPE_VAR_SHIFT_ROTATE:
24019 case TYPE_DELAYED_COMPARE:
24020 case TYPE_IMUL_COMPARE:
24021 case TYPE_LMUL_COMPARE:
24022 case TYPE_FPCOMPARE:
24036 case PROCESSOR_POWER7:
24037 type = get_attr_type (insn);
24045 case TYPE_LOAD_EXT_U:
24046 case TYPE_LOAD_EXT_UX:
24047 case TYPE_STORE_UX:
24060 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24061 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24064 is_costly_group (rtx *group_insns, rtx next_insn)
24067 int issue_rate = rs6000_issue_rate ();
24069 for (i = 0; i < issue_rate; i++)
24071 sd_iterator_def sd_it;
24073 rtx insn = group_insns[i];
24078 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24080 rtx next = DEP_CON (dep);
24082 if (next == next_insn
24083 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24091 /* Utility of the function redefine_groups.
24092 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24093 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24094 to keep it "far" (in a separate group) from GROUP_INSNS, following
24095 one of the following schemes, depending on the value of the flag
24096 -minsert_sched_nops = X:
24097 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24098 in order to force NEXT_INSN into a separate group.
24099 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24100 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24101 insertion (has a group just ended, how many vacant issue slots remain in the
24102 last group, and how many dispatch groups were encountered so far). */
24105 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24106 rtx next_insn, bool *group_end, int can_issue_more,
24111 int issue_rate = rs6000_issue_rate ();
24112 bool end = *group_end;
24115 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24116 return can_issue_more;
24118 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24119 return can_issue_more;
24121 force = is_costly_group (group_insns, next_insn);
24123 return can_issue_more;
24125 if (sched_verbose > 6)
24126 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24127 *group_count ,can_issue_more);
24129 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24132 can_issue_more = 0;
24134 /* Since only a branch can be issued in the last issue_slot, it is
24135 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24136 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24137 in this case the last nop will start a new group and the branch
24138 will be forced to the new group. */
24139 if (can_issue_more && !is_branch_slot_insn (next_insn))
24142 while (can_issue_more > 0)
24145 emit_insn_before (nop, next_insn);
24153 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24155 int n_nops = rs6000_sched_insert_nops;
24157 /* Nops can't be issued from the branch slot, so the effective
24158 issue_rate for nops is 'issue_rate - 1'. */
24159 if (can_issue_more == 0)
24160 can_issue_more = issue_rate;
24162 if (can_issue_more == 0)
24164 can_issue_more = issue_rate - 1;
24167 for (i = 0; i < issue_rate; i++)
24169 group_insns[i] = 0;
24176 emit_insn_before (nop, next_insn);
24177 if (can_issue_more == issue_rate - 1) /* new group begins */
24180 if (can_issue_more == 0)
24182 can_issue_more = issue_rate - 1;
24185 for (i = 0; i < issue_rate; i++)
24187 group_insns[i] = 0;
24193 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24196 /* Is next_insn going to start a new group? */
24199 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24200 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24201 || (can_issue_more < issue_rate &&
24202 insn_terminates_group_p (next_insn, previous_group)));
24203 if (*group_end && end)
24206 if (sched_verbose > 6)
24207 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24208 *group_count, can_issue_more);
24209 return can_issue_more;
24212 return can_issue_more;
24215 /* This function tries to synch the dispatch groups that the compiler "sees"
24216 with the dispatch groups that the processor dispatcher is expected to
24217 form in practice. It tries to achieve this synchronization by forcing the
24218 estimated processor grouping on the compiler (as opposed to the function
24219 'pad_goups' which tries to force the scheduler's grouping on the processor).
24221 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24222 examines the (estimated) dispatch groups that will be formed by the processor
24223 dispatcher. It marks these group boundaries to reflect the estimated
24224 processor grouping, overriding the grouping that the scheduler had marked.
24225 Depending on the value of the flag '-minsert-sched-nops' this function can
24226 force certain insns into separate groups or force a certain distance between
24227 them by inserting nops, for example, if there exists a "costly dependence"
24230 The function estimates the group boundaries that the processor will form as
24231 follows: It keeps track of how many vacant issue slots are available after
24232 each insn. A subsequent insn will start a new group if one of the following
24234 - no more vacant issue slots remain in the current dispatch group.
24235 - only the last issue slot, which is the branch slot, is vacant, but the next
24236 insn is not a branch.
24237 - only the last 2 or less issue slots, including the branch slot, are vacant,
24238 which means that a cracked insn (which occupies two issue slots) can't be
24239 issued in this group.
24240 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24241 start a new group. */
24244 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24246 rtx insn, next_insn;
24248 int can_issue_more;
24251 int group_count = 0;
24255 issue_rate = rs6000_issue_rate ();
24256 group_insns = XALLOCAVEC (rtx, issue_rate);
24257 for (i = 0; i < issue_rate; i++)
24259 group_insns[i] = 0;
24261 can_issue_more = issue_rate;
24263 insn = get_next_active_insn (prev_head_insn, tail);
24266 while (insn != NULL_RTX)
24268 slot = (issue_rate - can_issue_more);
24269 group_insns[slot] = insn;
24271 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24272 if (insn_terminates_group_p (insn, current_group))
24273 can_issue_more = 0;
24275 next_insn = get_next_active_insn (insn, tail);
24276 if (next_insn == NULL_RTX)
24277 return group_count + 1;
24279 /* Is next_insn going to start a new group? */
24281 = (can_issue_more == 0
24282 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24283 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24284 || (can_issue_more < issue_rate &&
24285 insn_terminates_group_p (next_insn, previous_group)));
24287 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24288 next_insn, &group_end, can_issue_more,
24294 can_issue_more = 0;
24295 for (i = 0; i < issue_rate; i++)
24297 group_insns[i] = 0;
24301 if (GET_MODE (next_insn) == TImode && can_issue_more)
24302 PUT_MODE (next_insn, VOIDmode);
24303 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24304 PUT_MODE (next_insn, TImode);
24307 if (can_issue_more == 0)
24308 can_issue_more = issue_rate;
24311 return group_count;
24314 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24315 dispatch group boundaries that the scheduler had marked. Pad with nops
24316 any dispatch groups which have vacant issue slots, in order to force the
24317 scheduler's grouping on the processor dispatcher. The function
24318 returns the number of dispatch groups found. */
24321 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24323 rtx insn, next_insn;
24326 int can_issue_more;
24328 int group_count = 0;
24330 /* Initialize issue_rate. */
24331 issue_rate = rs6000_issue_rate ();
24332 can_issue_more = issue_rate;
24334 insn = get_next_active_insn (prev_head_insn, tail);
24335 next_insn = get_next_active_insn (insn, tail);
24337 while (insn != NULL_RTX)
24340 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24342 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24344 if (next_insn == NULL_RTX)
24349 /* If the scheduler had marked group termination at this location
24350 (between insn and next_insn), and neither insn nor next_insn will
24351 force group termination, pad the group with nops to force group
24354 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24355 && !insn_terminates_group_p (insn, current_group)
24356 && !insn_terminates_group_p (next_insn, previous_group))
24358 if (!is_branch_slot_insn (next_insn))
24361 while (can_issue_more)
24364 emit_insn_before (nop, next_insn);
24369 can_issue_more = issue_rate;
24374 next_insn = get_next_active_insn (insn, tail);
24377 return group_count;
24380 /* We're beginning a new block. Initialize data structures as necessary. */
24383 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24384 int sched_verbose ATTRIBUTE_UNUSED,
24385 int max_ready ATTRIBUTE_UNUSED)
24387 last_scheduled_insn = NULL_RTX;
24388 load_store_pendulum = 0;
24391 /* The following function is called at the end of scheduling BB.
24392 After reload, it inserts nops at insn group bundling. */
24395 rs6000_sched_finish (FILE *dump, int sched_verbose)
24400 fprintf (dump, "=== Finishing schedule.\n");
24402 if (reload_completed && rs6000_sched_groups)
24404 /* Do not run sched_finish hook when selective scheduling enabled. */
24405 if (sel_sched_p ())
24408 if (rs6000_sched_insert_nops == sched_finish_none)
24411 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24412 n_groups = pad_groups (dump, sched_verbose,
24413 current_sched_info->prev_head,
24414 current_sched_info->next_tail);
24416 n_groups = redefine_groups (dump, sched_verbose,
24417 current_sched_info->prev_head,
24418 current_sched_info->next_tail);
24420 if (sched_verbose >= 6)
24422 fprintf (dump, "ngroups = %d\n", n_groups);
24423 print_rtl (dump, current_sched_info->prev_head);
24424 fprintf (dump, "Done finish_sched\n");
24429 struct _rs6000_sched_context
24431 short cached_can_issue_more;
24432 rtx last_scheduled_insn;
24433 int load_store_pendulum;
24436 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24437 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24439 /* Allocate store for new scheduling context. */
24441 rs6000_alloc_sched_context (void)
24443 return xmalloc (sizeof (rs6000_sched_context_def));
24446 /* If CLEAN_P is true then initializes _SC with clean data,
24447 and from the global context otherwise. */
24449 rs6000_init_sched_context (void *_sc, bool clean_p)
24451 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24455 sc->cached_can_issue_more = 0;
24456 sc->last_scheduled_insn = NULL_RTX;
24457 sc->load_store_pendulum = 0;
24461 sc->cached_can_issue_more = cached_can_issue_more;
24462 sc->last_scheduled_insn = last_scheduled_insn;
24463 sc->load_store_pendulum = load_store_pendulum;
24467 /* Sets the global scheduling context to the one pointed to by _SC. */
24469 rs6000_set_sched_context (void *_sc)
24471 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24473 gcc_assert (sc != NULL);
24475 cached_can_issue_more = sc->cached_can_issue_more;
24476 last_scheduled_insn = sc->last_scheduled_insn;
24477 load_store_pendulum = sc->load_store_pendulum;
24482 rs6000_free_sched_context (void *_sc)
24484 gcc_assert (_sc != NULL);
24490 /* Length in units of the trampoline for entering a nested function. */
24493 rs6000_trampoline_size (void)
24497 switch (DEFAULT_ABI)
24500 gcc_unreachable ();
24503 ret = (TARGET_32BIT) ? 12 : 24;
24508 ret = (TARGET_32BIT) ? 40 : 48;
24515 /* Emit RTL insns to initialize the variable parts of a trampoline.
24516 FNADDR is an RTX for the address of the function's pure code.
24517 CXT is an RTX for the static chain value for the function. */
24520 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24522 int regsize = (TARGET_32BIT) ? 4 : 8;
24523 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24524 rtx ctx_reg = force_reg (Pmode, cxt);
24525 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24527 switch (DEFAULT_ABI)
24530 gcc_unreachable ();
24532 /* Under AIX, just build the 3 word function descriptor */
24535 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24536 rtx fn_reg = gen_reg_rtx (Pmode);
24537 rtx toc_reg = gen_reg_rtx (Pmode);
24539 /* Macro to shorten the code expansions below. */
24540 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24542 m_tramp = replace_equiv_address (m_tramp, addr);
24544 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24545 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24546 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24547 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24548 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24554 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24557 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24558 LCT_NORMAL, VOIDmode, 4,
24560 GEN_INT (rs6000_trampoline_size ()), SImode,
24568 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24569 identifier as an argument, so the front end shouldn't look it up. */
24572 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24574 return is_attribute_p ("altivec", attr_id);
24577 /* Handle the "altivec" attribute. The attribute may have
24578 arguments as follows:
24580 __attribute__((altivec(vector__)))
24581 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24582 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24584 and may appear more than once (e.g., 'vector bool char') in a
24585 given declaration. */
24588 rs6000_handle_altivec_attribute (tree *node,
24589 tree name ATTRIBUTE_UNUSED,
24591 int flags ATTRIBUTE_UNUSED,
24592 bool *no_add_attrs)
24594 tree type = *node, result = NULL_TREE;
24595 enum machine_mode mode;
24598 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24599 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24600 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24603 while (POINTER_TYPE_P (type)
24604 || TREE_CODE (type) == FUNCTION_TYPE
24605 || TREE_CODE (type) == METHOD_TYPE
24606 || TREE_CODE (type) == ARRAY_TYPE)
24607 type = TREE_TYPE (type);
24609 mode = TYPE_MODE (type);
24611 /* Check for invalid AltiVec type qualifiers. */
24612 if (type == long_double_type_node)
24613 error ("use of %<long double%> in AltiVec types is invalid");
24614 else if (type == boolean_type_node)
24615 error ("use of boolean types in AltiVec types is invalid");
24616 else if (TREE_CODE (type) == COMPLEX_TYPE)
24617 error ("use of %<complex%> in AltiVec types is invalid");
24618 else if (DECIMAL_FLOAT_MODE_P (mode))
24619 error ("use of decimal floating point types in AltiVec types is invalid");
24620 else if (!TARGET_VSX)
24622 if (type == long_unsigned_type_node || type == long_integer_type_node)
24625 error ("use of %<long%> in AltiVec types is invalid for "
24626 "64-bit code without -mvsx");
24627 else if (rs6000_warn_altivec_long)
24628 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24631 else if (type == long_long_unsigned_type_node
24632 || type == long_long_integer_type_node)
24633 error ("use of %<long long%> in AltiVec types is invalid without "
24635 else if (type == double_type_node)
24636 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24639 switch (altivec_type)
24642 unsigned_p = TYPE_UNSIGNED (type);
24646 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24649 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24652 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24655 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24657 case SFmode: result = V4SF_type_node; break;
24658 case DFmode: result = V2DF_type_node; break;
24659 /* If the user says 'vector int bool', we may be handed the 'bool'
24660 attribute _before_ the 'vector' attribute, and so select the
24661 proper type in the 'b' case below. */
24662 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24663 case V2DImode: case V2DFmode:
24671 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24672 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24673 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24674 case QImode: case V16QImode: result = bool_V16QI_type_node;
24681 case V8HImode: result = pixel_V8HI_type_node;
24687 /* Propagate qualifiers attached to the element type
24688 onto the vector type. */
24689 if (result && result != type && TYPE_QUALS (type))
24690 result = build_qualified_type (result, TYPE_QUALS (type));
24692 *no_add_attrs = true; /* No need to hang on to the attribute. */
24695 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24700 /* AltiVec defines four built-in scalar types that serve as vector
24701 elements; we must teach the compiler how to mangle them. */
24703 static const char *
24704 rs6000_mangle_type (const_tree type)
24706 type = TYPE_MAIN_VARIANT (type);
24708 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24709 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24712 if (type == bool_char_type_node) return "U6__boolc";
24713 if (type == bool_short_type_node) return "U6__bools";
24714 if (type == pixel_type_node) return "u7__pixel";
24715 if (type == bool_int_type_node) return "U6__booli";
24716 if (type == bool_long_type_node) return "U6__booll";
24718 /* Mangle IBM extended float long double as `g' (__float128) on
24719 powerpc*-linux where long-double-64 previously was the default. */
24720 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24722 && TARGET_LONG_DOUBLE_128
24723 && !TARGET_IEEEQUAD)
24726 /* For all other types, use normal C++ mangling. */
24730 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24731 struct attribute_spec.handler. */
24734 rs6000_handle_longcall_attribute (tree *node, tree name,
24735 tree args ATTRIBUTE_UNUSED,
24736 int flags ATTRIBUTE_UNUSED,
24737 bool *no_add_attrs)
24739 if (TREE_CODE (*node) != FUNCTION_TYPE
24740 && TREE_CODE (*node) != FIELD_DECL
24741 && TREE_CODE (*node) != TYPE_DECL)
24743 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24745 *no_add_attrs = true;
24751 /* Set longcall attributes on all functions declared when
24752 rs6000_default_long_calls is true. */
24754 rs6000_set_default_type_attributes (tree type)
24756 if (rs6000_default_long_calls
24757 && (TREE_CODE (type) == FUNCTION_TYPE
24758 || TREE_CODE (type) == METHOD_TYPE))
24759 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24761 TYPE_ATTRIBUTES (type));
24764 darwin_set_default_type_attributes (type);
24768 /* Return a reference suitable for calling a function with the
24769 longcall attribute. */
24772 rs6000_longcall_ref (rtx call_ref)
24774 const char *call_name;
24777 if (GET_CODE (call_ref) != SYMBOL_REF)
24780 /* System V adds '.' to the internal name, so skip them. */
24781 call_name = XSTR (call_ref, 0);
24782 if (*call_name == '.')
24784 while (*call_name == '.')
24787 node = get_identifier (call_name);
24788 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24791 return force_reg (Pmode, call_ref);
24794 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24795 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24798 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24799 struct attribute_spec.handler. */
24801 rs6000_handle_struct_attribute (tree *node, tree name,
24802 tree args ATTRIBUTE_UNUSED,
24803 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24806 if (DECL_P (*node))
24808 if (TREE_CODE (*node) == TYPE_DECL)
24809 type = &TREE_TYPE (*node);
24814 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24815 || TREE_CODE (*type) == UNION_TYPE)))
24817 warning (OPT_Wattributes, "%qE attribute ignored", name);
24818 *no_add_attrs = true;
24821 else if ((is_attribute_p ("ms_struct", name)
24822 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24823 || ((is_attribute_p ("gcc_struct", name)
24824 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24826 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24828 *no_add_attrs = true;
24835 rs6000_ms_bitfield_layout_p (const_tree record_type)
24837 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24838 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24839 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24842 #ifdef USING_ELFOS_H
24844 /* A get_unnamed_section callback, used for switching to toc_section. */
24847 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24849 if (DEFAULT_ABI == ABI_AIX
24850 && TARGET_MINIMAL_TOC
24851 && !TARGET_RELOCATABLE)
24853 if (!toc_initialized)
24855 toc_initialized = 1;
24856 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24857 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24858 fprintf (asm_out_file, "\t.tc ");
24859 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24860 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24861 fprintf (asm_out_file, "\n");
24863 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24864 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24865 fprintf (asm_out_file, " = .+32768\n");
24868 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24870 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24871 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24874 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24875 if (!toc_initialized)
24877 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24878 fprintf (asm_out_file, " = .+32768\n");
24879 toc_initialized = 1;
24884 /* Implement TARGET_ASM_INIT_SECTIONS. */
24887 rs6000_elf_asm_init_sections (void)
24890 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24893 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24894 SDATA2_SECTION_ASM_OP);
24897 /* Implement TARGET_SELECT_RTX_SECTION. */
24900 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24901 unsigned HOST_WIDE_INT align)
24903 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24904 return toc_section;
24906 return default_elf_select_rtx_section (mode, x, align);
24909 /* For a SYMBOL_REF, set generic flags and then perform some
24910 target-specific processing.
24912 When the AIX ABI is requested on a non-AIX system, replace the
24913 function name with the real name (with a leading .) rather than the
24914 function descriptor name. This saves a lot of overriding code to
24915 read the prefixes. */
24918 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24920 default_encode_section_info (decl, rtl, first);
24923 && TREE_CODE (decl) == FUNCTION_DECL
24925 && DEFAULT_ABI == ABI_AIX)
24927 rtx sym_ref = XEXP (rtl, 0);
24928 size_t len = strlen (XSTR (sym_ref, 0));
24929 char *str = XALLOCAVEC (char, len + 2);
24931 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24932 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24937 compare_section_name (const char *section, const char *templ)
24941 len = strlen (templ);
24942 return (strncmp (section, templ, len) == 0
24943 && (section[len] == 0 || section[len] == '.'));
24947 rs6000_elf_in_small_data_p (const_tree decl)
24949 if (rs6000_sdata == SDATA_NONE)
24952 /* We want to merge strings, so we never consider them small data. */
24953 if (TREE_CODE (decl) == STRING_CST)
24956 /* Functions are never in the small data area. */
24957 if (TREE_CODE (decl) == FUNCTION_DECL)
24960 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24962 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24963 if (compare_section_name (section, ".sdata")
24964 || compare_section_name (section, ".sdata2")
24965 || compare_section_name (section, ".gnu.linkonce.s")
24966 || compare_section_name (section, ".sbss")
24967 || compare_section_name (section, ".sbss2")
24968 || compare_section_name (section, ".gnu.linkonce.sb")
24969 || strcmp (section, ".PPC.EMB.sdata0") == 0
24970 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24975 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24978 && size <= g_switch_value
24979 /* If it's not public, and we're not going to reference it there,
24980 there's no need to put it in the small data section. */
24981 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24988 #endif /* USING_ELFOS_H */
24990 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24993 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24995 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
24998 /* Return a REG that occurs in ADDR with coefficient 1.
24999 ADDR can be effectively incremented by incrementing REG.
25001 r0 is special and we must not select it as an address
25002 register by this routine since our caller will try to
25003 increment the returned register via an "la" instruction. */
25006 find_addr_reg (rtx addr)
25008 while (GET_CODE (addr) == PLUS)
25010 if (GET_CODE (XEXP (addr, 0)) == REG
25011 && REGNO (XEXP (addr, 0)) != 0)
25012 addr = XEXP (addr, 0);
25013 else if (GET_CODE (XEXP (addr, 1)) == REG
25014 && REGNO (XEXP (addr, 1)) != 0)
25015 addr = XEXP (addr, 1);
25016 else if (CONSTANT_P (XEXP (addr, 0)))
25017 addr = XEXP (addr, 1);
25018 else if (CONSTANT_P (XEXP (addr, 1)))
25019 addr = XEXP (addr, 0);
25021 gcc_unreachable ();
25023 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25028 rs6000_fatal_bad_address (rtx op)
25030 fatal_insn ("bad address", op);
25035 typedef struct branch_island_d {
25036 tree function_name;
25041 DEF_VEC_O(branch_island);
25042 DEF_VEC_ALLOC_O(branch_island,gc);
25044 static VEC(branch_island,gc) *branch_islands;
25046 /* Remember to generate a branch island for far calls to the given
25050 add_compiler_branch_island (tree label_name, tree function_name,
25053 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25055 bi->function_name = function_name;
25056 bi->label_name = label_name;
25057 bi->line_number = line_number;
25060 /* Generate far-jump branch islands for everything recorded in
25061 branch_islands. Invoked immediately after the last instruction of
25062 the epilogue has been emitted; the branch islands must be appended
25063 to, and contiguous with, the function body. Mach-O stubs are
25064 generated in machopic_output_stub(). */
25067 macho_branch_islands (void)
25071 while (!VEC_empty (branch_island, branch_islands))
25073 branch_island *bi = VEC_last (branch_island, branch_islands);
25074 const char *label = IDENTIFIER_POINTER (bi->label_name);
25075 const char *name = IDENTIFIER_POINTER (bi->function_name);
25076 char name_buf[512];
25077 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25078 if (name[0] == '*' || name[0] == '&')
25079 strcpy (name_buf, name+1);
25083 strcpy (name_buf+1, name);
25085 strcpy (tmp_buf, "\n");
25086 strcat (tmp_buf, label);
25087 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25088 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25089 dbxout_stabd (N_SLINE, bi->line_number);
25090 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25093 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25094 strcat (tmp_buf, label);
25095 strcat (tmp_buf, "_pic\n");
25096 strcat (tmp_buf, label);
25097 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25099 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25100 strcat (tmp_buf, name_buf);
25101 strcat (tmp_buf, " - ");
25102 strcat (tmp_buf, label);
25103 strcat (tmp_buf, "_pic)\n");
25105 strcat (tmp_buf, "\tmtlr r0\n");
25107 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25108 strcat (tmp_buf, name_buf);
25109 strcat (tmp_buf, " - ");
25110 strcat (tmp_buf, label);
25111 strcat (tmp_buf, "_pic)\n");
25113 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25117 strcat (tmp_buf, ":\nlis r12,hi16(");
25118 strcat (tmp_buf, name_buf);
25119 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25120 strcat (tmp_buf, name_buf);
25121 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25123 output_asm_insn (tmp_buf, 0);
25124 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25125 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25126 dbxout_stabd (N_SLINE, bi->line_number);
25127 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25128 VEC_pop (branch_island, branch_islands);
25132 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25133 already there or not. */
25136 no_previous_def (tree function_name)
25141 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25142 if (function_name == bi->function_name)
25147 /* GET_PREV_LABEL gets the label name from the previous definition of
25151 get_prev_label (tree function_name)
25156 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25157 if (function_name == bi->function_name)
25158 return bi->label_name;
25162 /* INSN is either a function call or a millicode call. It may have an
25163 unconditional jump in its delay slot.
25165 CALL_DEST is the routine we are calling. */
25168 output_call (rtx insn, rtx *operands, int dest_operand_number,
25169 int cookie_operand_number)
25171 static char buf[256];
25172 if (darwin_emit_branch_islands
25173 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25174 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25177 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25179 if (no_previous_def (funname))
25181 rtx label_rtx = gen_label_rtx ();
25182 char *label_buf, temp_buf[256];
25183 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25184 CODE_LABEL_NUMBER (label_rtx));
25185 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25186 labelname = get_identifier (label_buf);
25187 add_compiler_branch_island (labelname, funname, insn_line (insn));
25190 labelname = get_prev_label (funname);
25192 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25193 instruction will reach 'foo', otherwise link as 'bl L42'".
25194 "L42" should be a 'branch island', that will do a far jump to
25195 'foo'. Branch islands are generated in
25196 macho_branch_islands(). */
25197 sprintf (buf, "jbsr %%z%d,%.246s",
25198 dest_operand_number, IDENTIFIER_POINTER (labelname));
25201 sprintf (buf, "bl %%z%d", dest_operand_number);
25205 /* Generate PIC and indirect symbol stubs. */
25208 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25210 unsigned int length;
25211 char *symbol_name, *lazy_ptr_name;
25212 char *local_label_0;
25213 static int label = 0;
25215 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25216 symb = (*targetm.strip_name_encoding) (symb);
25219 length = strlen (symb);
25220 symbol_name = XALLOCAVEC (char, length + 32);
25221 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25223 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25224 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25227 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25229 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25233 fprintf (file, "\t.align 5\n");
25235 fprintf (file, "%s:\n", stub);
25236 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25239 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25240 sprintf (local_label_0, "\"L%011d$spb\"", label);
25242 fprintf (file, "\tmflr r0\n");
25243 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25244 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25245 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25246 lazy_ptr_name, local_label_0);
25247 fprintf (file, "\tmtlr r0\n");
25248 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25249 (TARGET_64BIT ? "ldu" : "lwzu"),
25250 lazy_ptr_name, local_label_0);
25251 fprintf (file, "\tmtctr r12\n");
25252 fprintf (file, "\tbctr\n");
25256 fprintf (file, "\t.align 4\n");
25258 fprintf (file, "%s:\n", stub);
25259 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25261 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25262 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25263 (TARGET_64BIT ? "ldu" : "lwzu"),
25265 fprintf (file, "\tmtctr r12\n");
25266 fprintf (file, "\tbctr\n");
25269 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25270 fprintf (file, "%s:\n", lazy_ptr_name);
25271 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25272 fprintf (file, "%sdyld_stub_binding_helper\n",
25273 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25276 /* Legitimize PIC addresses. If the address is already
25277 position-independent, we return ORIG. Newly generated
25278 position-independent addresses go into a reg. This is REG if non
25279 zero, otherwise we allocate register(s) as necessary. */
25281 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25284 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25289 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25290 reg = gen_reg_rtx (Pmode);
25292 if (GET_CODE (orig) == CONST)
25296 if (GET_CODE (XEXP (orig, 0)) == PLUS
25297 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25300 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25302 /* Use a different reg for the intermediate value, as
25303 it will be marked UNCHANGING. */
25304 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25305 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25308 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25311 if (GET_CODE (offset) == CONST_INT)
25313 if (SMALL_INT (offset))
25314 return plus_constant (base, INTVAL (offset));
25315 else if (! reload_in_progress && ! reload_completed)
25316 offset = force_reg (Pmode, offset);
25319 rtx mem = force_const_mem (Pmode, orig);
25320 return machopic_legitimize_pic_address (mem, Pmode, reg);
25323 return gen_rtx_PLUS (Pmode, base, offset);
25326 /* Fall back on generic machopic code. */
25327 return machopic_legitimize_pic_address (orig, mode, reg);
25330 /* Output a .machine directive for the Darwin assembler, and call
25331 the generic start_file routine. */
25334 rs6000_darwin_file_start (void)
25336 static const struct
25342 { "ppc64", "ppc64", MASK_64BIT },
25343 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25344 { "power4", "ppc970", 0 },
25345 { "G5", "ppc970", 0 },
25346 { "7450", "ppc7450", 0 },
25347 { "7400", "ppc7400", MASK_ALTIVEC },
25348 { "G4", "ppc7400", 0 },
25349 { "750", "ppc750", 0 },
25350 { "740", "ppc750", 0 },
25351 { "G3", "ppc750", 0 },
25352 { "604e", "ppc604e", 0 },
25353 { "604", "ppc604", 0 },
25354 { "603e", "ppc603", 0 },
25355 { "603", "ppc603", 0 },
25356 { "601", "ppc601", 0 },
25357 { NULL, "ppc", 0 } };
25358 const char *cpu_id = "";
25361 rs6000_file_start ();
25362 darwin_file_start ();
25364 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25365 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25366 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25367 && rs6000_select[i].string[0] != '\0')
25368 cpu_id = rs6000_select[i].string;
25370 /* Look through the mapping array. Pick the first name that either
25371 matches the argument, has a bit set in IF_SET that is also set
25372 in the target flags, or has a NULL name. */
25375 while (mapping[i].arg != NULL
25376 && strcmp (mapping[i].arg, cpu_id) != 0
25377 && (mapping[i].if_set & target_flags) == 0)
25380 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25383 #endif /* TARGET_MACHO */
25387 rs6000_elf_reloc_rw_mask (void)
25391 else if (DEFAULT_ABI == ABI_AIX)
25397 /* Record an element in the table of global constructors. SYMBOL is
25398 a SYMBOL_REF of the function to be called; PRIORITY is a number
25399 between 0 and MAX_INIT_PRIORITY.
25401 This differs from default_named_section_asm_out_constructor in
25402 that we have special handling for -mrelocatable. */
25405 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25407 const char *section = ".ctors";
25410 if (priority != DEFAULT_INIT_PRIORITY)
25412 sprintf (buf, ".ctors.%.5u",
25413 /* Invert the numbering so the linker puts us in the proper
25414 order; constructors are run from right to left, and the
25415 linker sorts in increasing order. */
25416 MAX_INIT_PRIORITY - priority);
25420 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25421 assemble_align (POINTER_SIZE);
25423 if (TARGET_RELOCATABLE)
25425 fputs ("\t.long (", asm_out_file);
25426 output_addr_const (asm_out_file, symbol);
25427 fputs (")@fixup\n", asm_out_file);
25430 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25434 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25436 const char *section = ".dtors";
25439 if (priority != DEFAULT_INIT_PRIORITY)
25441 sprintf (buf, ".dtors.%.5u",
25442 /* Invert the numbering so the linker puts us in the proper
25443 order; constructors are run from right to left, and the
25444 linker sorts in increasing order. */
25445 MAX_INIT_PRIORITY - priority);
25449 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25450 assemble_align (POINTER_SIZE);
25452 if (TARGET_RELOCATABLE)
25454 fputs ("\t.long (", asm_out_file);
25455 output_addr_const (asm_out_file, symbol);
25456 fputs (")@fixup\n", asm_out_file);
25459 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25463 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25467 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25468 ASM_OUTPUT_LABEL (file, name);
25469 fputs (DOUBLE_INT_ASM_OP, file);
25470 rs6000_output_function_entry (file, name);
25471 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25474 fputs ("\t.size\t", file);
25475 assemble_name (file, name);
25476 fputs (",24\n\t.type\t.", file);
25477 assemble_name (file, name);
25478 fputs (",@function\n", file);
25479 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25481 fputs ("\t.globl\t.", file);
25482 assemble_name (file, name);
25487 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25488 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25489 rs6000_output_function_entry (file, name);
25490 fputs (":\n", file);
25494 if (TARGET_RELOCATABLE
25495 && !TARGET_SECURE_PLT
25496 && (get_pool_size () != 0 || crtl->profile)
25501 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25503 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25504 fprintf (file, "\t.long ");
25505 assemble_name (file, buf);
25507 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25508 assemble_name (file, buf);
25512 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25513 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25515 if (DEFAULT_ABI == ABI_AIX)
25517 const char *desc_name, *orig_name;
25519 orig_name = (*targetm.strip_name_encoding) (name);
25520 desc_name = orig_name;
25521 while (*desc_name == '.')
25524 if (TREE_PUBLIC (decl))
25525 fprintf (file, "\t.globl %s\n", desc_name);
25527 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25528 fprintf (file, "%s:\n", desc_name);
25529 fprintf (file, "\t.long %s\n", orig_name);
25530 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25531 if (DEFAULT_ABI == ABI_AIX)
25532 fputs ("\t.long 0\n", file);
25533 fprintf (file, "\t.previous\n");
25535 ASM_OUTPUT_LABEL (file, name);
25539 rs6000_elf_end_indicate_exec_stack (void)
25542 file_end_indicate_exec_stack ();
25548 rs6000_xcoff_asm_output_anchor (rtx symbol)
25552 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25553 SYMBOL_REF_BLOCK_OFFSET (symbol));
25554 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25558 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25560 fputs (GLOBAL_ASM_OP, stream);
25561 RS6000_OUTPUT_BASENAME (stream, name);
25562 putc ('\n', stream);
25565 /* A get_unnamed_decl callback, used for read-only sections. PTR
25566 points to the section string variable. */
25569 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25571 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25572 *(const char *const *) directive,
25573 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25576 /* Likewise for read-write sections. */
25579 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25581 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25582 *(const char *const *) directive,
25583 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25586 /* A get_unnamed_section callback, used for switching to toc_section. */
25589 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25591 if (TARGET_MINIMAL_TOC)
25593 /* toc_section is always selected at least once from
25594 rs6000_xcoff_file_start, so this is guaranteed to
25595 always be defined once and only once in each file. */
25596 if (!toc_initialized)
25598 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25599 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25600 toc_initialized = 1;
25602 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25603 (TARGET_32BIT ? "" : ",3"));
25606 fputs ("\t.toc\n", asm_out_file);
25609 /* Implement TARGET_ASM_INIT_SECTIONS. */
25612 rs6000_xcoff_asm_init_sections (void)
25614 read_only_data_section
25615 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25616 &xcoff_read_only_section_name);
25618 private_data_section
25619 = get_unnamed_section (SECTION_WRITE,
25620 rs6000_xcoff_output_readwrite_section_asm_op,
25621 &xcoff_private_data_section_name);
25623 read_only_private_data_section
25624 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25625 &xcoff_private_data_section_name);
25628 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25630 readonly_data_section = read_only_data_section;
25631 exception_section = data_section;
25635 rs6000_xcoff_reloc_rw_mask (void)
25641 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25642 tree decl ATTRIBUTE_UNUSED)
25645 static const char * const suffix[3] = { "PR", "RO", "RW" };
25647 if (flags & SECTION_CODE)
25649 else if (flags & SECTION_WRITE)
25654 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25655 (flags & SECTION_CODE) ? "." : "",
25656 name, suffix[smclass], flags & SECTION_ENTSIZE);
25660 rs6000_xcoff_select_section (tree decl, int reloc,
25661 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25663 if (decl_readonly_section (decl, reloc))
25665 if (TREE_PUBLIC (decl))
25666 return read_only_data_section;
25668 return read_only_private_data_section;
25672 if (TREE_PUBLIC (decl))
25673 return data_section;
25675 return private_data_section;
25680 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25684 /* Use select_section for private and uninitialized data. */
25685 if (!TREE_PUBLIC (decl)
25686 || DECL_COMMON (decl)
25687 || DECL_INITIAL (decl) == NULL_TREE
25688 || DECL_INITIAL (decl) == error_mark_node
25689 || (flag_zero_initialized_in_bss
25690 && initializer_zerop (DECL_INITIAL (decl))))
25693 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25694 name = (*targetm.strip_name_encoding) (name);
25695 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25698 /* Select section for constant in constant pool.
25700 On RS/6000, all constants are in the private read-only data area.
25701 However, if this is being placed in the TOC it must be output as a
25705 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25706 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25708 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25709 return toc_section;
25711 return read_only_private_data_section;
25714 /* Remove any trailing [DS] or the like from the symbol name. */
25716 static const char *
25717 rs6000_xcoff_strip_name_encoding (const char *name)
25722 len = strlen (name);
25723 if (name[len - 1] == ']')
25724 return ggc_alloc_string (name, len - 4);
25729 /* Section attributes. AIX is always PIC. */
25731 static unsigned int
25732 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25734 unsigned int align;
25735 unsigned int flags = default_section_type_flags (decl, name, reloc);
25737 /* Align to at least UNIT size. */
25738 if (flags & SECTION_CODE)
25739 align = MIN_UNITS_PER_WORD;
25741 /* Increase alignment of large objects if not already stricter. */
25742 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25743 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25744 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25746 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25749 /* Output at beginning of assembler file.
25751 Initialize the section names for the RS/6000 at this point.
25753 Specify filename, including full path, to assembler.
25755 We want to go into the TOC section so at least one .toc will be emitted.
25756 Also, in order to output proper .bs/.es pairs, we need at least one static
25757 [RW] section emitted.
25759 Finally, declare mcount when profiling to make the assembler happy. */
25762 rs6000_xcoff_file_start (void)
25764 rs6000_gen_section_name (&xcoff_bss_section_name,
25765 main_input_filename, ".bss_");
25766 rs6000_gen_section_name (&xcoff_private_data_section_name,
25767 main_input_filename, ".rw_");
25768 rs6000_gen_section_name (&xcoff_read_only_section_name,
25769 main_input_filename, ".ro_");
25771 fputs ("\t.file\t", asm_out_file);
25772 output_quoted_string (asm_out_file, main_input_filename);
25773 fputc ('\n', asm_out_file);
25774 if (write_symbols != NO_DEBUG)
25775 switch_to_section (private_data_section);
25776 switch_to_section (text_section);
25778 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25779 rs6000_file_start ();
25782 /* Output at end of assembler file.
25783 On the RS/6000, referencing data should automatically pull in text. */
25786 rs6000_xcoff_file_end (void)
25788 switch_to_section (text_section);
25789 fputs ("_section_.text:\n", asm_out_file);
25790 switch_to_section (data_section);
25791 fputs (TARGET_32BIT
25792 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25795 #endif /* TARGET_XCOFF */
25797 /* Compute a (partial) cost for rtx X. Return true if the complete
25798 cost has been computed, and false if subexpressions should be
25799 scanned. In either case, *TOTAL contains the cost result. */
25802 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25805 enum machine_mode mode = GET_MODE (x);
25809 /* On the RS/6000, if it is valid in the insn, it is free. */
25811 if (((outer_code == SET
25812 || outer_code == PLUS
25813 || outer_code == MINUS)
25814 && (satisfies_constraint_I (x)
25815 || satisfies_constraint_L (x)))
25816 || (outer_code == AND
25817 && (satisfies_constraint_K (x)
25819 ? satisfies_constraint_L (x)
25820 : satisfies_constraint_J (x))
25821 || mask_operand (x, mode)
25823 && mask64_operand (x, DImode))))
25824 || ((outer_code == IOR || outer_code == XOR)
25825 && (satisfies_constraint_K (x)
25827 ? satisfies_constraint_L (x)
25828 : satisfies_constraint_J (x))))
25829 || outer_code == ASHIFT
25830 || outer_code == ASHIFTRT
25831 || outer_code == LSHIFTRT
25832 || outer_code == ROTATE
25833 || outer_code == ROTATERT
25834 || outer_code == ZERO_EXTRACT
25835 || (outer_code == MULT
25836 && satisfies_constraint_I (x))
25837 || ((outer_code == DIV || outer_code == UDIV
25838 || outer_code == MOD || outer_code == UMOD)
25839 && exact_log2 (INTVAL (x)) >= 0)
25840 || (outer_code == COMPARE
25841 && (satisfies_constraint_I (x)
25842 || satisfies_constraint_K (x)))
25843 || ((outer_code == EQ || outer_code == NE)
25844 && (satisfies_constraint_I (x)
25845 || satisfies_constraint_K (x)
25847 ? satisfies_constraint_L (x)
25848 : satisfies_constraint_J (x))))
25849 || (outer_code == GTU
25850 && satisfies_constraint_I (x))
25851 || (outer_code == LTU
25852 && satisfies_constraint_P (x)))
25857 else if ((outer_code == PLUS
25858 && reg_or_add_cint_operand (x, VOIDmode))
25859 || (outer_code == MINUS
25860 && reg_or_sub_cint_operand (x, VOIDmode))
25861 || ((outer_code == SET
25862 || outer_code == IOR
25863 || outer_code == XOR)
25865 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25867 *total = COSTS_N_INSNS (1);
25873 if (mode == DImode && code == CONST_DOUBLE)
25875 if ((outer_code == IOR || outer_code == XOR)
25876 && CONST_DOUBLE_HIGH (x) == 0
25877 && (CONST_DOUBLE_LOW (x)
25878 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25883 else if ((outer_code == AND && and64_2_operand (x, DImode))
25884 || ((outer_code == SET
25885 || outer_code == IOR
25886 || outer_code == XOR)
25887 && CONST_DOUBLE_HIGH (x) == 0))
25889 *total = COSTS_N_INSNS (1);
25899 /* When optimizing for size, MEM should be slightly more expensive
25900 than generating address, e.g., (plus (reg) (const)).
25901 L1 cache latency is about two instructions. */
25902 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25910 if (mode == DFmode)
25912 if (GET_CODE (XEXP (x, 0)) == MULT)
25914 /* FNMA accounted in outer NEG. */
25915 if (outer_code == NEG)
25916 *total = rs6000_cost->dmul - rs6000_cost->fp;
25918 *total = rs6000_cost->dmul;
25921 *total = rs6000_cost->fp;
25923 else if (mode == SFmode)
25925 /* FNMA accounted in outer NEG. */
25926 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25929 *total = rs6000_cost->fp;
25932 *total = COSTS_N_INSNS (1);
25936 if (mode == DFmode)
25938 if (GET_CODE (XEXP (x, 0)) == MULT
25939 || GET_CODE (XEXP (x, 1)) == MULT)
25941 /* FNMA accounted in outer NEG. */
25942 if (outer_code == NEG)
25943 *total = rs6000_cost->dmul - rs6000_cost->fp;
25945 *total = rs6000_cost->dmul;
25948 *total = rs6000_cost->fp;
25950 else if (mode == SFmode)
25952 /* FNMA accounted in outer NEG. */
25953 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25956 *total = rs6000_cost->fp;
25959 *total = COSTS_N_INSNS (1);
25963 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25964 && satisfies_constraint_I (XEXP (x, 1)))
25966 if (INTVAL (XEXP (x, 1)) >= -256
25967 && INTVAL (XEXP (x, 1)) <= 255)
25968 *total = rs6000_cost->mulsi_const9;
25970 *total = rs6000_cost->mulsi_const;
25972 /* FMA accounted in outer PLUS/MINUS. */
25973 else if ((mode == DFmode || mode == SFmode)
25974 && (outer_code == PLUS || outer_code == MINUS))
25976 else if (mode == DFmode)
25977 *total = rs6000_cost->dmul;
25978 else if (mode == SFmode)
25979 *total = rs6000_cost->fp;
25980 else if (mode == DImode)
25981 *total = rs6000_cost->muldi;
25983 *total = rs6000_cost->mulsi;
25988 if (FLOAT_MODE_P (mode))
25990 *total = mode == DFmode ? rs6000_cost->ddiv
25991 : rs6000_cost->sdiv;
25998 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25999 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26001 if (code == DIV || code == MOD)
26003 *total = COSTS_N_INSNS (2);
26006 *total = COSTS_N_INSNS (1);
26010 if (GET_MODE (XEXP (x, 1)) == DImode)
26011 *total = rs6000_cost->divdi;
26013 *total = rs6000_cost->divsi;
26015 /* Add in shift and subtract for MOD. */
26016 if (code == MOD || code == UMOD)
26017 *total += COSTS_N_INSNS (2);
26022 *total = COSTS_N_INSNS (4);
26026 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26030 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26034 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26046 *total = COSTS_N_INSNS (1);
26054 /* Handle mul_highpart. */
26055 if (outer_code == TRUNCATE
26056 && GET_CODE (XEXP (x, 0)) == MULT)
26058 if (mode == DImode)
26059 *total = rs6000_cost->muldi;
26061 *total = rs6000_cost->mulsi;
26064 else if (outer_code == AND)
26067 *total = COSTS_N_INSNS (1);
26072 if (GET_CODE (XEXP (x, 0)) == MEM)
26075 *total = COSTS_N_INSNS (1);
26081 if (!FLOAT_MODE_P (mode))
26083 *total = COSTS_N_INSNS (1);
26089 case UNSIGNED_FLOAT:
26092 case FLOAT_TRUNCATE:
26093 *total = rs6000_cost->fp;
26097 if (mode == DFmode)
26100 *total = rs6000_cost->fp;
26104 switch (XINT (x, 1))
26107 *total = rs6000_cost->fp;
26119 *total = COSTS_N_INSNS (1);
26122 else if (FLOAT_MODE_P (mode)
26123 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26125 *total = rs6000_cost->fp;
26133 /* Carry bit requires mode == Pmode.
26134 NEG or PLUS already counted so only add one. */
26136 && (outer_code == NEG || outer_code == PLUS))
26138 *total = COSTS_N_INSNS (1);
26141 if (outer_code == SET)
26143 if (XEXP (x, 1) == const0_rtx)
26145 if (TARGET_ISEL && !TARGET_MFCRF)
26146 *total = COSTS_N_INSNS (8);
26148 *total = COSTS_N_INSNS (2);
26151 else if (mode == Pmode)
26153 *total = COSTS_N_INSNS (3);
26162 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26164 if (TARGET_ISEL && !TARGET_MFCRF)
26165 *total = COSTS_N_INSNS (8);
26167 *total = COSTS_N_INSNS (2);
26171 if (outer_code == COMPARE)
26185 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26188 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26191 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26194 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26195 "total = %d, speed = %s, x:\n",
26196 ret ? "complete" : "scan inner",
26197 GET_RTX_NAME (code),
26198 GET_RTX_NAME (outer_code),
26200 speed ? "true" : "false");
26207 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26210 rs6000_debug_address_cost (rtx x, bool speed)
26212 int ret = TARGET_ADDRESS_COST (x, speed);
26214 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26215 ret, speed ? "true" : "false");
26222 /* A C expression returning the cost of moving data from a register of class
26223 CLASS1 to one of CLASS2. */
26226 rs6000_register_move_cost (enum machine_mode mode,
26227 reg_class_t from, reg_class_t to)
26231 /* Moves from/to GENERAL_REGS. */
26232 if (reg_classes_intersect_p (to, GENERAL_REGS)
26233 || reg_classes_intersect_p (from, GENERAL_REGS))
26235 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26238 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26239 ret = (rs6000_memory_move_cost (mode, from, false)
26240 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26242 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26244 else if (from == CR_REGS)
26247 /* Power6 has slower LR/CTR moves so make them more expensive than
26248 memory in order to bias spills to memory .*/
26249 else if (rs6000_cpu == PROCESSOR_POWER6
26250 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26251 ret = 6 * hard_regno_nregs[0][mode];
26254 /* A move will cost one instruction per GPR moved. */
26255 ret = 2 * hard_regno_nregs[0][mode];
26258 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26259 else if (VECTOR_UNIT_VSX_P (mode)
26260 && reg_classes_intersect_p (to, VSX_REGS)
26261 && reg_classes_intersect_p (from, VSX_REGS))
26262 ret = 2 * hard_regno_nregs[32][mode];
26264 /* Moving between two similar registers is just one instruction. */
26265 else if (reg_classes_intersect_p (to, from))
26266 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26268 /* Everything else has to go through GENERAL_REGS. */
26270 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26271 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26273 if (TARGET_DEBUG_COST)
26275 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26276 ret, GET_MODE_NAME (mode), reg_class_names[from],
26277 reg_class_names[to]);
26282 /* A C expressions returning the cost of moving data of MODE from a register to
26286 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26287 bool in ATTRIBUTE_UNUSED)
26291 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26292 ret = 4 * hard_regno_nregs[0][mode];
26293 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26294 ret = 4 * hard_regno_nregs[32][mode];
26295 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26296 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26298 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26300 if (TARGET_DEBUG_COST)
26302 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26303 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26308 /* Returns a code for a target-specific builtin that implements
26309 reciprocal of the function, or NULL_TREE if not available. */
26312 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26313 bool sqrt ATTRIBUTE_UNUSED)
26315 if (optimize_insn_for_size_p ())
26321 case VSX_BUILTIN_XVSQRTDP:
26322 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26325 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26327 case VSX_BUILTIN_XVSQRTSP:
26328 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26331 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26340 case BUILT_IN_SQRT:
26341 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26344 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26346 case BUILT_IN_SQRTF:
26347 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26350 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26357 /* Load up a constant. If the mode is a vector mode, splat the value across
26358 all of the vector elements. */
26361 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26365 if (mode == SFmode || mode == DFmode)
26367 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26368 reg = force_reg (mode, d);
26370 else if (mode == V4SFmode)
26372 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26373 rtvec v = gen_rtvec (4, d, d, d, d);
26374 reg = gen_reg_rtx (mode);
26375 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26377 else if (mode == V2DFmode)
26379 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26380 rtvec v = gen_rtvec (2, d, d);
26381 reg = gen_reg_rtx (mode);
26382 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26385 gcc_unreachable ();
26390 /* Generate a FMADD instruction:
26391 dst = (m1 * m2) + a
26393 generating different RTL based on the fused multiply/add switch. */
26396 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26398 enum machine_mode mode = GET_MODE (dst);
26400 if (!TARGET_FUSED_MADD)
26402 /* For the simple ops, use the generator function, rather than assuming
26403 that the RTL is standard. */
26404 enum insn_code mcode = optab_handler (smul_optab, mode);
26405 enum insn_code acode = optab_handler (add_optab, mode);
26406 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26407 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26408 rtx mreg = gen_reg_rtx (mode);
26410 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26411 emit_insn (gen_mul (mreg, m1, m2));
26412 emit_insn (gen_add (dst, mreg, a));
26416 emit_insn (gen_rtx_SET (VOIDmode, dst,
26417 gen_rtx_PLUS (mode,
26418 gen_rtx_MULT (mode, m1, m2),
26422 /* Generate a FMSUB instruction:
26423 dst = (m1 * m2) - a
26425 generating different RTL based on the fused multiply/add switch. */
26428 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26430 enum machine_mode mode = GET_MODE (dst);
26432 if (!TARGET_FUSED_MADD
26433 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26435 /* For the simple ops, use the generator function, rather than assuming
26436 that the RTL is standard. */
26437 enum insn_code mcode = optab_handler (smul_optab, mode);
26438 enum insn_code scode = optab_handler (add_optab, mode);
26439 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26440 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26441 rtx mreg = gen_reg_rtx (mode);
26443 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26444 emit_insn (gen_mul (mreg, m1, m2));
26445 emit_insn (gen_sub (dst, mreg, a));
26449 emit_insn (gen_rtx_SET (VOIDmode, dst,
26450 gen_rtx_MINUS (mode,
26451 gen_rtx_MULT (mode, m1, m2),
26455 /* Generate a FNMSUB instruction:
26456 dst = - ((m1 * m2) - a)
26458 Which is equivalent to (except in the prescence of -0.0):
26459 dst = a - (m1 * m2)
26461 generating different RTL based on the fast-math and fused multiply/add
26465 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26467 enum machine_mode mode = GET_MODE (dst);
26469 if (!TARGET_FUSED_MADD)
26471 /* For the simple ops, use the generator function, rather than assuming
26472 that the RTL is standard. */
26473 enum insn_code mcode = optab_handler (smul_optab, mode);
26474 enum insn_code scode = optab_handler (sub_optab, mode);
26475 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26476 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26477 rtx mreg = gen_reg_rtx (mode);
26479 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26480 emit_insn (gen_mul (mreg, m1, m2));
26481 emit_insn (gen_sub (dst, a, mreg));
26486 rtx m = gen_rtx_MULT (mode, m1, m2);
26488 if (!HONOR_SIGNED_ZEROS (mode))
26489 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26492 emit_insn (gen_rtx_SET (VOIDmode, dst,
26494 gen_rtx_MINUS (mode, m, a))));
26498 /* Newton-Raphson approximation of floating point divide with just 2 passes
26499 (either single precision floating point, or newer machines with higher
26500 accuracy estimates). Support both scalar and vector divide. Assumes no
26501 trapping math and finite arguments. */
26504 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26506 enum machine_mode mode = GET_MODE (dst);
26507 rtx x0, e0, e1, y1, u0, v0;
26508 enum insn_code code = optab_handler (smul_optab, mode);
26509 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26510 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26512 gcc_assert (code != CODE_FOR_nothing);
26514 /* x0 = 1./d estimate */
26515 x0 = gen_reg_rtx (mode);
26516 emit_insn (gen_rtx_SET (VOIDmode, x0,
26517 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26520 e0 = gen_reg_rtx (mode);
26521 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26523 e1 = gen_reg_rtx (mode);
26524 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26526 y1 = gen_reg_rtx (mode);
26527 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26529 u0 = gen_reg_rtx (mode);
26530 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26532 v0 = gen_reg_rtx (mode);
26533 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26535 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26538 /* Newton-Raphson approximation of floating point divide that has a low
26539 precision estimate. Assumes no trapping math and finite arguments. */
26542 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26544 enum machine_mode mode = GET_MODE (dst);
26545 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26546 enum insn_code code = optab_handler (smul_optab, mode);
26547 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26549 gcc_assert (code != CODE_FOR_nothing);
26551 one = rs6000_load_constant_and_splat (mode, dconst1);
26553 /* x0 = 1./d estimate */
26554 x0 = gen_reg_rtx (mode);
26555 emit_insn (gen_rtx_SET (VOIDmode, x0,
26556 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26559 e0 = gen_reg_rtx (mode);
26560 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26562 y1 = gen_reg_rtx (mode);
26563 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26565 e1 = gen_reg_rtx (mode);
26566 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26568 y2 = gen_reg_rtx (mode);
26569 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26571 e2 = gen_reg_rtx (mode);
26572 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26574 y3 = gen_reg_rtx (mode);
26575 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26577 u0 = gen_reg_rtx (mode);
26578 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26580 v0 = gen_reg_rtx (mode);
26581 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26583 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26586 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26587 add a reg_note saying that this was a division. Support both scalar and
26588 vector divide. Assumes no trapping math and finite arguments. */
26591 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26593 enum machine_mode mode = GET_MODE (dst);
26595 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26596 rs6000_emit_swdiv_high_precision (dst, n, d);
26598 rs6000_emit_swdiv_low_precision (dst, n, d);
26601 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26604 /* Newton-Raphson approximation of single/double-precision floating point
26605 rsqrt. Assumes no trapping math and finite arguments. */
26608 rs6000_emit_swrsqrt (rtx dst, rtx src)
26610 enum machine_mode mode = GET_MODE (src);
26611 rtx x0 = gen_reg_rtx (mode);
26612 rtx y = gen_reg_rtx (mode);
26613 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26614 REAL_VALUE_TYPE dconst3_2;
26617 enum insn_code code = optab_handler (smul_optab, mode);
26618 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26620 gcc_assert (code != CODE_FOR_nothing);
26622 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26623 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26624 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26626 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26628 /* x0 = rsqrt estimate */
26629 emit_insn (gen_rtx_SET (VOIDmode, x0,
26630 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26633 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26634 rs6000_emit_msub (y, src, halfthree, src);
26636 for (i = 0; i < passes; i++)
26638 rtx x1 = gen_reg_rtx (mode);
26639 rtx u = gen_reg_rtx (mode);
26640 rtx v = gen_reg_rtx (mode);
26642 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26643 emit_insn (gen_mul (u, x0, x0));
26644 rs6000_emit_nmsub (v, y, u, halfthree);
26645 emit_insn (gen_mul (x1, x0, v));
26649 emit_move_insn (dst, x0);
26653 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26654 (Power7) targets. DST is the target, and SRC is the argument operand. */
26657 rs6000_emit_popcount (rtx dst, rtx src)
26659 enum machine_mode mode = GET_MODE (dst);
26662 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26663 if (TARGET_POPCNTD)
26665 if (mode == SImode)
26666 emit_insn (gen_popcntdsi2 (dst, src));
26668 emit_insn (gen_popcntddi2 (dst, src));
26672 tmp1 = gen_reg_rtx (mode);
26674 if (mode == SImode)
26676 emit_insn (gen_popcntbsi2 (tmp1, src));
26677 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26679 tmp2 = force_reg (SImode, tmp2);
26680 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26684 emit_insn (gen_popcntbdi2 (tmp1, src));
26685 tmp2 = expand_mult (DImode, tmp1,
26686 GEN_INT ((HOST_WIDE_INT)
26687 0x01010101 << 32 | 0x01010101),
26689 tmp2 = force_reg (DImode, tmp2);
26690 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26695 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26696 target, and SRC is the argument operand. */
26699 rs6000_emit_parity (rtx dst, rtx src)
26701 enum machine_mode mode = GET_MODE (dst);
26704 tmp = gen_reg_rtx (mode);
26706 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26709 if (mode == SImode)
26711 emit_insn (gen_popcntbsi2 (tmp, src));
26712 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26716 emit_insn (gen_popcntbdi2 (tmp, src));
26717 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26722 if (mode == SImode)
26724 /* Is mult+shift >= shift+xor+shift+xor? */
26725 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26727 rtx tmp1, tmp2, tmp3, tmp4;
26729 tmp1 = gen_reg_rtx (SImode);
26730 emit_insn (gen_popcntbsi2 (tmp1, src));
26732 tmp2 = gen_reg_rtx (SImode);
26733 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26734 tmp3 = gen_reg_rtx (SImode);
26735 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26737 tmp4 = gen_reg_rtx (SImode);
26738 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26739 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26742 rs6000_emit_popcount (tmp, src);
26743 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26747 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26748 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26750 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26752 tmp1 = gen_reg_rtx (DImode);
26753 emit_insn (gen_popcntbdi2 (tmp1, src));
26755 tmp2 = gen_reg_rtx (DImode);
26756 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26757 tmp3 = gen_reg_rtx (DImode);
26758 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26760 tmp4 = gen_reg_rtx (DImode);
26761 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26762 tmp5 = gen_reg_rtx (DImode);
26763 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26765 tmp6 = gen_reg_rtx (DImode);
26766 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26767 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26770 rs6000_emit_popcount (tmp, src);
26771 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26775 /* Return an RTX representing where to find the function value of a
26776 function returning MODE. */
26778 rs6000_complex_function_value (enum machine_mode mode)
26780 unsigned int regno;
26782 enum machine_mode inner = GET_MODE_INNER (mode);
26783 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26785 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26786 regno = FP_ARG_RETURN;
26789 regno = GP_ARG_RETURN;
26791 /* 32-bit is OK since it'll go in r3/r4. */
26792 if (TARGET_32BIT && inner_bytes >= 4)
26793 return gen_rtx_REG (mode, regno);
26796 if (inner_bytes >= 8)
26797 return gen_rtx_REG (mode, regno);
26799 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26801 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26802 GEN_INT (inner_bytes));
26803 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26806 /* Target hook for TARGET_FUNCTION_VALUE.
26808 On the SPE, both FPs and vectors are returned in r3.
26810 On RS/6000 an integer value is in r3 and a floating-point value is in
26811 fp1, unless -msoft-float. */
26814 rs6000_function_value (const_tree valtype,
26815 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26816 bool outgoing ATTRIBUTE_UNUSED)
26818 enum machine_mode mode;
26819 unsigned int regno;
26821 /* Special handling for structs in darwin64. */
26823 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26825 CUMULATIVE_ARGS valcum;
26829 valcum.fregno = FP_ARG_MIN_REG;
26830 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26831 /* Do a trial code generation as if this were going to be passed as
26832 an argument; if any part goes in memory, we return NULL. */
26833 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26836 /* Otherwise fall through to standard ABI rules. */
26839 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26841 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26842 return gen_rtx_PARALLEL (DImode,
26844 gen_rtx_EXPR_LIST (VOIDmode,
26845 gen_rtx_REG (SImode, GP_ARG_RETURN),
26847 gen_rtx_EXPR_LIST (VOIDmode,
26848 gen_rtx_REG (SImode,
26849 GP_ARG_RETURN + 1),
26852 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26854 return gen_rtx_PARALLEL (DCmode,
26856 gen_rtx_EXPR_LIST (VOIDmode,
26857 gen_rtx_REG (SImode, GP_ARG_RETURN),
26859 gen_rtx_EXPR_LIST (VOIDmode,
26860 gen_rtx_REG (SImode,
26861 GP_ARG_RETURN + 1),
26863 gen_rtx_EXPR_LIST (VOIDmode,
26864 gen_rtx_REG (SImode,
26865 GP_ARG_RETURN + 2),
26867 gen_rtx_EXPR_LIST (VOIDmode,
26868 gen_rtx_REG (SImode,
26869 GP_ARG_RETURN + 3),
26873 mode = TYPE_MODE (valtype);
26874 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26875 || POINTER_TYPE_P (valtype))
26876 mode = TARGET_32BIT ? SImode : DImode;
26878 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26879 /* _Decimal128 must use an even/odd register pair. */
26880 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26881 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26882 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26883 regno = FP_ARG_RETURN;
26884 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26885 && targetm.calls.split_complex_arg)
26886 return rs6000_complex_function_value (mode);
26887 else if (TREE_CODE (valtype) == VECTOR_TYPE
26888 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26889 && ALTIVEC_VECTOR_MODE (mode))
26890 regno = ALTIVEC_ARG_RETURN;
26891 else if (TREE_CODE (valtype) == VECTOR_TYPE
26892 && TARGET_VSX && TARGET_ALTIVEC_ABI
26893 && VSX_VECTOR_MODE (mode))
26894 regno = ALTIVEC_ARG_RETURN;
26895 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26896 && (mode == DFmode || mode == DCmode
26897 || mode == TFmode || mode == TCmode))
26898 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26900 regno = GP_ARG_RETURN;
26902 return gen_rtx_REG (mode, regno);
26905 /* Define how to find the value returned by a library function
26906 assuming the value has mode MODE. */
26908 rs6000_libcall_value (enum machine_mode mode)
26910 unsigned int regno;
26912 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26914 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26915 return gen_rtx_PARALLEL (DImode,
26917 gen_rtx_EXPR_LIST (VOIDmode,
26918 gen_rtx_REG (SImode, GP_ARG_RETURN),
26920 gen_rtx_EXPR_LIST (VOIDmode,
26921 gen_rtx_REG (SImode,
26922 GP_ARG_RETURN + 1),
26926 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26927 /* _Decimal128 must use an even/odd register pair. */
26928 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26929 else if (SCALAR_FLOAT_MODE_P (mode)
26930 && TARGET_HARD_FLOAT && TARGET_FPRS
26931 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26932 regno = FP_ARG_RETURN;
26933 else if (ALTIVEC_VECTOR_MODE (mode)
26934 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26935 regno = ALTIVEC_ARG_RETURN;
26936 else if (VSX_VECTOR_MODE (mode)
26937 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26938 regno = ALTIVEC_ARG_RETURN;
26939 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26940 return rs6000_complex_function_value (mode);
26941 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26942 && (mode == DFmode || mode == DCmode
26943 || mode == TFmode || mode == TCmode))
26944 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26946 regno = GP_ARG_RETURN;
26948 return gen_rtx_REG (mode, regno);
26952 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26953 Frame pointer elimination is automatically handled.
26955 For the RS/6000, if frame pointer elimination is being done, we would like
26956 to convert ap into fp, not sp.
26958 We need r30 if -mminimal-toc was specified, and there are constant pool
26962 rs6000_can_eliminate (const int from, const int to)
26964 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26965 ? ! frame_pointer_needed
26966 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26967 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26971 /* Define the offset between two registers, FROM to be eliminated and its
26972 replacement TO, at the start of a routine. */
26974 rs6000_initial_elimination_offset (int from, int to)
26976 rs6000_stack_t *info = rs6000_stack_info ();
26977 HOST_WIDE_INT offset;
26979 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26980 offset = info->push_p ? 0 : -info->total_size;
26981 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26983 offset = info->push_p ? 0 : -info->total_size;
26984 if (FRAME_GROWS_DOWNWARD)
26985 offset += info->fixed_size + info->vars_size + info->parm_size;
26987 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26988 offset = FRAME_GROWS_DOWNWARD
26989 ? info->fixed_size + info->vars_size + info->parm_size
26991 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26992 offset = info->total_size;
26993 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26994 offset = info->push_p ? info->total_size : 0;
26995 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
26998 gcc_unreachable ();
27004 rs6000_dwarf_register_span (rtx reg)
27008 unsigned regno = REGNO (reg);
27009 enum machine_mode mode = GET_MODE (reg);
27013 && (SPE_VECTOR_MODE (GET_MODE (reg))
27014 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27015 && mode != SFmode && mode != SDmode && mode != SCmode)))
27020 regno = REGNO (reg);
27022 /* The duality of the SPE register size wreaks all kinds of havoc.
27023 This is a way of distinguishing r0 in 32-bits from r0 in
27025 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27026 gcc_assert (words <= 4);
27027 for (i = 0; i < words; i++, regno++)
27029 if (BYTES_BIG_ENDIAN)
27031 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27032 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27036 parts[2 * i] = gen_rtx_REG (SImode, regno);
27037 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27041 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27044 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27047 rs6000_init_dwarf_reg_sizes_extra (tree address)
27052 enum machine_mode mode = TYPE_MODE (char_type_node);
27053 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27054 rtx mem = gen_rtx_MEM (BLKmode, addr);
27055 rtx value = gen_int_mode (4, mode);
27057 for (i = 1201; i < 1232; i++)
27059 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27060 HOST_WIDE_INT offset
27061 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27063 emit_move_insn (adjust_address (mem, mode, offset), value);
27068 /* Map internal gcc register numbers to DWARF2 register numbers. */
27071 rs6000_dbx_register_number (unsigned int regno)
27073 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27075 if (regno == MQ_REGNO)
27077 if (regno == LR_REGNO)
27079 if (regno == CTR_REGNO)
27081 if (CR_REGNO_P (regno))
27082 return regno - CR0_REGNO + 86;
27083 if (regno == CA_REGNO)
27084 return 101; /* XER */
27085 if (ALTIVEC_REGNO_P (regno))
27086 return regno - FIRST_ALTIVEC_REGNO + 1124;
27087 if (regno == VRSAVE_REGNO)
27089 if (regno == VSCR_REGNO)
27091 if (regno == SPE_ACC_REGNO)
27093 if (regno == SPEFSCR_REGNO)
27095 /* SPE high reg number. We get these values of regno from
27096 rs6000_dwarf_register_span. */
27097 gcc_assert (regno >= 1200 && regno < 1232);
27101 /* target hook eh_return_filter_mode */
27102 static enum machine_mode
27103 rs6000_eh_return_filter_mode (void)
27105 return TARGET_32BIT ? SImode : word_mode;
27108 /* Target hook for scalar_mode_supported_p. */
27110 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27112 if (DECIMAL_FLOAT_MODE_P (mode))
27113 return default_decimal_float_supported_p ();
27115 return default_scalar_mode_supported_p (mode);
27118 /* Target hook for vector_mode_supported_p. */
27120 rs6000_vector_mode_supported_p (enum machine_mode mode)
27123 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27126 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27129 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27136 /* Target hook for invalid_arg_for_unprototyped_fn. */
27137 static const char *
27138 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27140 return (!rs6000_darwin64_abi
27142 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27143 && (funcdecl == NULL_TREE
27144 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27145 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27146 ? N_("AltiVec argument passed to unprototyped function")
27150 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27151 setup by using __stack_chk_fail_local hidden function instead of
27152 calling __stack_chk_fail directly. Otherwise it is better to call
27153 __stack_chk_fail directly. */
27156 rs6000_stack_protect_fail (void)
27158 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27159 ? default_hidden_stack_protect_fail ()
27160 : default_external_stack_protect_fail ();
27164 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27165 int num_operands ATTRIBUTE_UNUSED)
27167 if (rs6000_warn_cell_microcode)
27170 int insn_code_number = recog_memoized (insn);
27171 location_t location = locator_location (INSN_LOCATOR (insn));
27173 /* Punt on insns we cannot recognize. */
27174 if (insn_code_number < 0)
27177 temp = get_insn_template (insn_code_number, insn);
27179 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27180 warning_at (location, OPT_mwarn_cell_microcode,
27181 "emitting microcode insn %s\t[%s] #%d",
27182 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27183 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27184 warning_at (location, OPT_mwarn_cell_microcode,
27185 "emitting conditional microcode insn %s\t[%s] #%d",
27186 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27191 /* Allocate a stack temp and fixup the address so it meets the particular
27192 memory requirements (either offetable or REG+REG addressing). */
27195 rs6000_allocate_stack_temp (enum machine_mode mode,
27196 bool offsettable_p,
27199 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27200 rtx addr = XEXP (stack, 0);
27201 int strict_p = (reload_in_progress || reload_completed);
27203 if (!legitimate_indirect_address_p (addr, strict_p))
27206 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27207 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27209 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27210 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27216 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27217 to such a form to deal with memory reference instructions like STFIWX that
27218 only take reg+reg addressing. */
27221 rs6000_address_for_fpconvert (rtx x)
27223 int strict_p = (reload_in_progress || reload_completed);
27226 gcc_assert (MEM_P (x));
27227 addr = XEXP (x, 0);
27228 if (! legitimate_indirect_address_p (addr, strict_p)
27229 && ! legitimate_indexed_address_p (addr, strict_p))
27230 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27235 /* Expand 32-bit int -> floating point conversions. Return true if
27239 rs6000_expand_convert_si_to_sfdf (rtx dest, rtx src, bool unsigned_p)
27241 enum machine_mode dmode = GET_MODE (dest);
27242 rtx (*func_si) (rtx, rtx, rtx, rtx);
27243 rtx (*func_si_mem) (rtx, rtx);
27244 rtx (*func_di) (rtx, rtx);
27247 gcc_assert (GET_MODE (src) == SImode);
27249 if (dmode == SFmode)
27253 gcc_assert (TARGET_FCFIDUS && TARGET_LFIWZX);
27254 func_si = gen_floatunssisf2_lfiwzx;
27255 func_si_mem = gen_floatunssisf2_lfiwzx_mem;
27256 func_di = gen_floatunsdisf2;
27260 gcc_assert (TARGET_FCFIDS && TARGET_LFIWAX);
27261 func_si = gen_floatsisf2_lfiwax;
27262 func_si_mem = gen_floatsisf2_lfiwax_mem;
27263 func_di = gen_floatdisf2;
27267 else if (dmode == DFmode)
27271 gcc_assert (TARGET_FCFIDU && TARGET_LFIWZX);
27272 func_si = gen_floatunssidf2_lfiwzx;
27273 func_si_mem = gen_floatunssidf2_lfiwzx_mem;
27274 func_di = gen_floatunsdidf2;
27278 gcc_assert (TARGET_FCFID && TARGET_LFIWAX);
27279 func_si = gen_floatsidf2_lfiwax;
27280 func_si_mem = gen_floatsidf2_lfiwax_mem;
27281 func_di = gen_floatdidf2;
27286 gcc_unreachable ();
27290 src = rs6000_address_for_fpconvert (src);
27291 emit_insn (func_si_mem (dest, src));
27293 else if (!TARGET_MFPGPR)
27295 reg = gen_reg_rtx (DImode);
27296 stack = rs6000_allocate_stack_temp (SImode, false, true);
27297 emit_insn (func_si (dest, src, stack, reg));
27302 src = force_reg (SImode, src);
27303 reg = convert_to_mode (DImode, src, unsigned_p);
27304 emit_insn (func_di (dest, reg));
27308 #include "gt-rs6000.h"