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),
2581 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
2583 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't
2584 add ALTIVEC, since in general it isn't a win on power6. In ISA 2.04,
2585 fsel, fre, fsqrt, etc. were no longer documented as optional. Group
2586 masks by server and embedded. */
2587 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
2588 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
2589 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
2591 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
2592 altivec is a win so enable it. */
2593 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
2594 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
2598 /* Numerous experiment shows that IRA based loop pressure
2599 calculation works better for RTL loop invariant motion on targets
2600 with enough (>= 32) registers. It is an expensive optimization.
2601 So it is on only for peak performance. */
2603 flag_ira_loop_pressure = 1;
2605 /* Set the pointer size. */
2608 rs6000_pmode = (int)DImode;
2609 rs6000_pointer_size = 64;
2613 rs6000_pmode = (int)SImode;
2614 rs6000_pointer_size = 32;
2617 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2618 #ifdef OS_MISSING_POWERPC64
2619 if (OS_MISSING_POWERPC64)
2620 set_masks &= ~MASK_POWERPC64;
2622 #ifdef OS_MISSING_ALTIVEC
2623 if (OS_MISSING_ALTIVEC)
2624 set_masks &= ~MASK_ALTIVEC;
2627 /* Don't override by the processor default if given explicitly. */
2628 set_masks &= ~target_flags_explicit;
2630 /* Identify the processor type. */
2631 rs6000_select[0].string = default_cpu;
2632 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
2634 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
2636 ptr = &rs6000_select[i];
2637 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2639 for (j = 0; j < ptt_size; j++)
2640 if (! strcmp (ptr->string, processor_target_table[j].name))
2642 if (ptr->set_tune_p)
2643 rs6000_cpu = processor_target_table[j].processor;
2645 if (ptr->set_arch_p)
2647 target_flags &= ~set_masks;
2648 target_flags |= (processor_target_table[j].target_enable
2655 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
2659 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2660 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2663 error ("AltiVec not supported in this target");
2665 error ("SPE not supported in this target");
2668 /* Disable Cell microcode if we are optimizing for the Cell
2669 and not optimizing for size. */
2670 if (rs6000_gen_cell_microcode == -1)
2671 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2674 /* If we are optimizing big endian systems for space and it's OK to
2675 use instructions that would be microcoded on the Cell, use the
2676 load/store multiple and string instructions. */
2677 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2678 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2680 /* Don't allow -mmultiple or -mstring on little endian systems
2681 unless the cpu is a 750, because the hardware doesn't support the
2682 instructions used in little endian mode, and causes an alignment
2683 trap. The 750 does not cause an alignment trap (except when the
2684 target is unaligned). */
2686 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2688 if (TARGET_MULTIPLE)
2690 target_flags &= ~MASK_MULTIPLE;
2691 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2692 warning (0, "-mmultiple is not supported on little endian systems");
2697 target_flags &= ~MASK_STRING;
2698 if ((target_flags_explicit & MASK_STRING) != 0)
2699 warning (0, "-mstring is not supported on little endian systems");
2703 /* Add some warnings for VSX. */
2706 const char *msg = NULL;
2707 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2708 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2710 if (target_flags_explicit & MASK_VSX)
2711 msg = N_("-mvsx requires hardware floating point");
2713 target_flags &= ~ MASK_VSX;
2715 else if (TARGET_PAIRED_FLOAT)
2716 msg = N_("-mvsx and -mpaired are incompatible");
2717 /* The hardware will allow VSX and little endian, but until we make sure
2718 things like vector select, etc. work don't allow VSX on little endian
2719 systems at this point. */
2720 else if (!BYTES_BIG_ENDIAN)
2721 msg = N_("-mvsx used with little endian code");
2722 else if (TARGET_AVOID_XFORM > 0)
2723 msg = N_("-mvsx needs indexed addressing");
2724 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2726 if (target_flags_explicit & MASK_VSX)
2727 msg = N_("-mvsx and -mno-altivec are incompatible");
2729 msg = N_("-mno-altivec disables vsx");
2735 target_flags &= ~ MASK_VSX;
2736 target_flags_explicit |= MASK_VSX;
2740 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2741 unless the user explicitly used the -mno-<option> to disable the code. */
2743 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2744 else if (TARGET_POPCNTD)
2745 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2746 else if (TARGET_DFP)
2747 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2748 else if (TARGET_CMPB)
2749 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2750 else if (TARGET_FPRND)
2751 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2752 else if (TARGET_POPCNTB)
2753 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2754 else if (TARGET_ALTIVEC)
2755 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2757 /* E500mc does "better" if we inline more aggressively. Respect the
2758 user's opinion, though. */
2759 if (rs6000_block_move_inline_limit == 0
2760 && (rs6000_cpu == PROCESSOR_PPCE500MC
2761 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2762 rs6000_block_move_inline_limit = 128;
2764 /* store_one_arg depends on expand_block_move to handle at least the
2765 size of reg_parm_stack_space. */
2766 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2767 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2769 /* Set debug flags */
2770 if (rs6000_debug_name)
2772 if (! strcmp (rs6000_debug_name, "all"))
2773 rs6000_debug_stack = rs6000_debug_arg = rs6000_debug_reg
2774 = rs6000_debug_addr = rs6000_debug_cost = 1;
2775 else if (! strcmp (rs6000_debug_name, "stack"))
2776 rs6000_debug_stack = 1;
2777 else if (! strcmp (rs6000_debug_name, "arg"))
2778 rs6000_debug_arg = 1;
2779 else if (! strcmp (rs6000_debug_name, "reg"))
2780 rs6000_debug_reg = 1;
2781 else if (! strcmp (rs6000_debug_name, "addr"))
2782 rs6000_debug_addr = 1;
2783 else if (! strcmp (rs6000_debug_name, "cost"))
2784 rs6000_debug_cost = 1;
2786 error ("unknown -mdebug-%s switch", rs6000_debug_name);
2788 /* If the appropriate debug option is enabled, replace the target hooks
2789 with debug versions that call the real version and then prints
2790 debugging information. */
2791 if (TARGET_DEBUG_COST)
2793 targetm.rtx_costs = rs6000_debug_rtx_costs;
2794 targetm.address_cost = rs6000_debug_address_cost;
2795 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2798 if (TARGET_DEBUG_ADDR)
2800 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2801 targetm.legitimize_address = rs6000_debug_legitimize_address;
2802 rs6000_secondary_reload_class_ptr
2803 = rs6000_debug_secondary_reload_class;
2804 rs6000_secondary_memory_needed_ptr
2805 = rs6000_debug_secondary_memory_needed;
2806 rs6000_cannot_change_mode_class_ptr
2807 = rs6000_debug_cannot_change_mode_class;
2808 rs6000_preferred_reload_class_ptr
2809 = rs6000_debug_preferred_reload_class;
2810 rs6000_legitimize_reload_address_ptr
2811 = rs6000_debug_legitimize_reload_address;
2812 rs6000_mode_dependent_address_ptr
2813 = rs6000_debug_mode_dependent_address;
2817 if (rs6000_traceback_name)
2819 if (! strncmp (rs6000_traceback_name, "full", 4))
2820 rs6000_traceback = traceback_full;
2821 else if (! strncmp (rs6000_traceback_name, "part", 4))
2822 rs6000_traceback = traceback_part;
2823 else if (! strncmp (rs6000_traceback_name, "no", 2))
2824 rs6000_traceback = traceback_none;
2826 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
2827 rs6000_traceback_name);
2830 if (rs6000_veclibabi_name)
2832 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2833 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2835 error ("unknown vectorization library ABI type (%s) for "
2836 "-mveclibabi= switch", rs6000_veclibabi_name);
2839 if (!rs6000_explicit_options.long_double)
2840 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2842 #ifndef POWERPC_LINUX
2843 if (!rs6000_explicit_options.ieee)
2844 rs6000_ieeequad = 1;
2847 /* Enable Altivec ABI for AIX -maltivec. */
2848 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2849 rs6000_altivec_abi = 1;
2851 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2852 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2853 be explicitly overridden in either case. */
2856 if (!rs6000_explicit_options.altivec_abi
2857 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2858 rs6000_altivec_abi = 1;
2860 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2861 if (!rs6000_explicit_options.vrsave)
2862 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2865 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2866 So far, the only darwin64 targets are also MACH-O. */
2868 && DEFAULT_ABI == ABI_DARWIN
2871 rs6000_darwin64_abi = 1;
2872 /* Default to natural alignment, for better performance. */
2873 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2876 /* Place FP constants in the constant pool instead of TOC
2877 if section anchors enabled. */
2878 if (flag_section_anchors)
2879 TARGET_NO_FP_IN_TOC = 1;
2881 /* Handle -mtls-size option. */
2882 rs6000_parse_tls_size_option ();
2884 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2885 SUBTARGET_OVERRIDE_OPTIONS;
2887 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2888 SUBSUBTARGET_OVERRIDE_OPTIONS;
2890 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2891 SUB3TARGET_OVERRIDE_OPTIONS;
2894 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2895 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2897 /* The e500 and e500mc do not have string instructions, and we set
2898 MASK_STRING above when optimizing for size. */
2899 if ((target_flags & MASK_STRING) != 0)
2900 target_flags = target_flags & ~MASK_STRING;
2902 else if (rs6000_select[1].string != NULL)
2904 /* For the powerpc-eabispe configuration, we set all these by
2905 default, so let's unset them if we manually set another
2906 CPU that is not the E500. */
2907 if (!rs6000_explicit_options.spe_abi)
2909 if (!rs6000_explicit_options.spe)
2911 if (!rs6000_explicit_options.float_gprs)
2912 rs6000_float_gprs = 0;
2913 if (!(target_flags_explicit & MASK_ISEL))
2914 target_flags &= ~MASK_ISEL;
2917 /* Detect invalid option combinations with E500. */
2920 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
2921 && rs6000_cpu != PROCESSOR_POWER5
2922 && rs6000_cpu != PROCESSOR_POWER6
2923 && rs6000_cpu != PROCESSOR_POWER7
2924 && rs6000_cpu != PROCESSOR_PPCA2
2925 && rs6000_cpu != PROCESSOR_CELL);
2926 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
2927 || rs6000_cpu == PROCESSOR_POWER5
2928 || rs6000_cpu == PROCESSOR_POWER7);
2929 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
2930 || rs6000_cpu == PROCESSOR_POWER5
2931 || rs6000_cpu == PROCESSOR_POWER6
2932 || rs6000_cpu == PROCESSOR_POWER7
2933 || rs6000_cpu == PROCESSOR_PPCE500MC
2934 || rs6000_cpu == PROCESSOR_PPCE500MC64);
2936 /* Allow debug switches to override the above settings. */
2937 if (TARGET_ALWAYS_HINT > 0)
2938 rs6000_always_hint = TARGET_ALWAYS_HINT;
2940 if (TARGET_SCHED_GROUPS > 0)
2941 rs6000_sched_groups = TARGET_SCHED_GROUPS;
2943 if (TARGET_ALIGN_BRANCH_TARGETS > 0)
2944 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
2946 rs6000_sched_restricted_insns_priority
2947 = (rs6000_sched_groups ? 1 : 0);
2949 /* Handle -msched-costly-dep option. */
2950 rs6000_sched_costly_dep
2951 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
2953 if (rs6000_sched_costly_dep_str)
2955 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
2956 rs6000_sched_costly_dep = no_dep_costly;
2957 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
2958 rs6000_sched_costly_dep = all_deps_costly;
2959 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
2960 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
2961 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
2962 rs6000_sched_costly_dep = store_to_load_dep_costly;
2964 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
2965 atoi (rs6000_sched_costly_dep_str));
2968 /* Handle -minsert-sched-nops option. */
2969 rs6000_sched_insert_nops
2970 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
2972 if (rs6000_sched_insert_nops_str)
2974 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
2975 rs6000_sched_insert_nops = sched_finish_none;
2976 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
2977 rs6000_sched_insert_nops = sched_finish_pad_groups;
2978 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
2979 rs6000_sched_insert_nops = sched_finish_regroup_exact;
2981 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
2982 atoi (rs6000_sched_insert_nops_str));
2985 #ifdef TARGET_REGNAMES
2986 /* If the user desires alternate register names, copy in the
2987 alternate names now. */
2988 if (TARGET_REGNAMES)
2989 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
2992 /* Set aix_struct_return last, after the ABI is determined.
2993 If -maix-struct-return or -msvr4-struct-return was explicitly
2994 used, don't override with the ABI default. */
2995 if (!rs6000_explicit_options.aix_struct_ret)
2996 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
2999 /* IBM XL compiler defaults to unsigned bitfields. */
3000 if (TARGET_XL_COMPAT)
3001 flag_signed_bitfields = 0;
3004 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3005 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3008 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3010 /* We can only guarantee the availability of DI pseudo-ops when
3011 assembling for 64-bit targets. */
3014 targetm.asm_out.aligned_op.di = NULL;
3015 targetm.asm_out.unaligned_op.di = NULL;
3018 /* Set branch target alignment, if not optimizing for size. */
3021 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3022 aligned 8byte to avoid misprediction by the branch predictor. */
3023 if (rs6000_cpu == PROCESSOR_TITAN
3024 || rs6000_cpu == PROCESSOR_CELL)
3026 if (align_functions <= 0)
3027 align_functions = 8;
3028 if (align_jumps <= 0)
3030 if (align_loops <= 0)
3033 if (rs6000_align_branch_targets)
3035 if (align_functions <= 0)
3036 align_functions = 16;
3037 if (align_jumps <= 0)
3039 if (align_loops <= 0)
3041 can_override_loop_align = 1;
3045 if (align_jumps_max_skip <= 0)
3046 align_jumps_max_skip = 15;
3047 if (align_loops_max_skip <= 0)
3048 align_loops_max_skip = 15;
3051 /* Arrange to save and restore machine status around nested functions. */
3052 init_machine_status = rs6000_init_machine_status;
3054 /* We should always be splitting complex arguments, but we can't break
3055 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3056 if (DEFAULT_ABI != ABI_AIX)
3057 targetm.calls.split_complex_arg = NULL;
3059 /* Initialize rs6000_cost with the appropriate target costs. */
3061 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3065 case PROCESSOR_RIOS1:
3066 rs6000_cost = &rios1_cost;
3069 case PROCESSOR_RIOS2:
3070 rs6000_cost = &rios2_cost;
3073 case PROCESSOR_RS64A:
3074 rs6000_cost = &rs64a_cost;
3077 case PROCESSOR_MPCCORE:
3078 rs6000_cost = &mpccore_cost;
3081 case PROCESSOR_PPC403:
3082 rs6000_cost = &ppc403_cost;
3085 case PROCESSOR_PPC405:
3086 rs6000_cost = &ppc405_cost;
3089 case PROCESSOR_PPC440:
3090 rs6000_cost = &ppc440_cost;
3093 case PROCESSOR_PPC476:
3094 rs6000_cost = &ppc476_cost;
3097 case PROCESSOR_PPC601:
3098 rs6000_cost = &ppc601_cost;
3101 case PROCESSOR_PPC603:
3102 rs6000_cost = &ppc603_cost;
3105 case PROCESSOR_PPC604:
3106 rs6000_cost = &ppc604_cost;
3109 case PROCESSOR_PPC604e:
3110 rs6000_cost = &ppc604e_cost;
3113 case PROCESSOR_PPC620:
3114 rs6000_cost = &ppc620_cost;
3117 case PROCESSOR_PPC630:
3118 rs6000_cost = &ppc630_cost;
3121 case PROCESSOR_CELL:
3122 rs6000_cost = &ppccell_cost;
3125 case PROCESSOR_PPC750:
3126 case PROCESSOR_PPC7400:
3127 rs6000_cost = &ppc750_cost;
3130 case PROCESSOR_PPC7450:
3131 rs6000_cost = &ppc7450_cost;
3134 case PROCESSOR_PPC8540:
3135 rs6000_cost = &ppc8540_cost;
3138 case PROCESSOR_PPCE300C2:
3139 case PROCESSOR_PPCE300C3:
3140 rs6000_cost = &ppce300c2c3_cost;
3143 case PROCESSOR_PPCE500MC:
3144 rs6000_cost = &ppce500mc_cost;
3147 case PROCESSOR_PPCE500MC64:
3148 rs6000_cost = &ppce500mc64_cost;
3151 case PROCESSOR_TITAN:
3152 rs6000_cost = &titan_cost;
3155 case PROCESSOR_POWER4:
3156 case PROCESSOR_POWER5:
3157 rs6000_cost = &power4_cost;
3160 case PROCESSOR_POWER6:
3161 rs6000_cost = &power6_cost;
3164 case PROCESSOR_POWER7:
3165 rs6000_cost = &power7_cost;
3168 case PROCESSOR_PPCA2:
3169 rs6000_cost = &ppca2_cost;
3176 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3177 rs6000_cost->simultaneous_prefetches,
3178 global_options.x_param_values,
3179 global_options_set.x_param_values);
3180 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3181 global_options.x_param_values,
3182 global_options_set.x_param_values);
3183 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3184 rs6000_cost->cache_line_size,
3185 global_options.x_param_values,
3186 global_options_set.x_param_values);
3187 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3188 global_options.x_param_values,
3189 global_options_set.x_param_values);
3191 /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0)
3192 can be optimized to ap = __builtin_next_arg (0). */
3193 if (DEFAULT_ABI != ABI_V4)
3194 targetm.expand_builtin_va_start = NULL;
3196 /* Set up single/double float flags.
3197 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3198 then set both flags. */
3199 if (TARGET_HARD_FLOAT && TARGET_FPRS
3200 && rs6000_single_float == 0 && rs6000_double_float == 0)
3201 rs6000_single_float = rs6000_double_float = 1;
3203 /* Reset single and double FP flags if target is E500. */
3206 rs6000_single_float = rs6000_double_float = 0;
3207 if (TARGET_E500_SINGLE)
3208 rs6000_single_float = 1;
3209 if (TARGET_E500_DOUBLE)
3210 rs6000_single_float = rs6000_double_float = 1;
3213 /* If not explicitly specified via option, decide whether to generate indexed
3214 load/store instructions. */
3215 if (TARGET_AVOID_XFORM == -1)
3216 /* Avoid indexed addressing when targeting Power6 in order to avoid
3217 the DERAT mispredict penalty. */
3218 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
3220 /* Set the -mrecip options. */
3221 if (rs6000_recip_name)
3223 char *p = ASTRDUP (rs6000_recip_name);
3225 unsigned int mask, i;
3228 while ((q = strtok (p, ",")) != NULL)
3239 if (!strcmp (q, "default"))
3240 mask = ((TARGET_RECIP_PRECISION)
3241 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3244 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3245 if (!strcmp (q, recip_options[i].string))
3247 mask = recip_options[i].mask;
3251 if (i == ARRAY_SIZE (recip_options))
3253 error ("unknown option for -mrecip=%s", q);
3260 rs6000_recip_control &= ~mask;
3262 rs6000_recip_control |= mask;
3266 rs6000_init_hard_regno_mode_ok ();
3269 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3270 define the target cpu type. */
3273 rs6000_option_override (void)
3275 rs6000_option_override_internal (OPTION_TARGET_CPU_DEFAULT);
3278 /* Implement targetm.vectorize.builtin_mask_for_load. */
3280 rs6000_builtin_mask_for_load (void)
3282 if (TARGET_ALTIVEC || TARGET_VSX)
3283 return altivec_builtin_mask_for_load;
3288 /* Implement LOOP_ALIGN. */
3290 rs6000_loop_align (rtx label)
3295 /* Don't override loop alignment if -falign-loops was specified. */
3296 if (!can_override_loop_align)
3297 return align_loops_log;
3299 bb = BLOCK_FOR_INSN (label);
3300 ninsns = num_loop_insns(bb->loop_father);
3302 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3303 if (ninsns > 4 && ninsns <= 8
3304 && (rs6000_cpu == PROCESSOR_POWER4
3305 || rs6000_cpu == PROCESSOR_POWER5
3306 || rs6000_cpu == PROCESSOR_POWER6
3307 || rs6000_cpu == PROCESSOR_POWER7))
3310 return align_loops_log;
3313 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3315 rs6000_loop_align_max_skip (rtx label)
3317 return (1 << rs6000_loop_align (label)) - 1;
3320 /* Implement targetm.vectorize.builtin_conversion.
3321 Returns a decl of a function that implements conversion of an integer vector
3322 into a floating-point vector, or vice-versa. DEST_TYPE is the
3323 destination type and SRC_TYPE the source type of the conversion.
3324 Return NULL_TREE if it is not available. */
3326 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3328 enum tree_code code = (enum tree_code) tcode;
3332 case FIX_TRUNC_EXPR:
3333 switch (TYPE_MODE (dest_type))
3336 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3339 return TYPE_UNSIGNED (dest_type)
3340 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3341 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3344 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3347 return TYPE_UNSIGNED (dest_type)
3348 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3349 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3356 switch (TYPE_MODE (src_type))
3359 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3362 return TYPE_UNSIGNED (src_type)
3363 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3364 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3367 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3370 return TYPE_UNSIGNED (src_type)
3371 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3372 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3383 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3385 rs6000_builtin_mul_widen_even (tree type)
3387 if (!TARGET_ALTIVEC)
3390 switch (TYPE_MODE (type))
3393 return TYPE_UNSIGNED (type)
3394 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3395 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3398 return TYPE_UNSIGNED (type)
3399 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3400 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3406 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3408 rs6000_builtin_mul_widen_odd (tree type)
3410 if (!TARGET_ALTIVEC)
3413 switch (TYPE_MODE (type))
3416 return TYPE_UNSIGNED (type)
3417 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3418 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3421 return TYPE_UNSIGNED (type)
3422 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3423 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3430 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3431 after applying N number of iterations. This routine does not determine
3432 how may iterations are required to reach desired alignment. */
3435 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3442 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3445 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3455 /* Assuming that all other types are naturally aligned. CHECKME! */
3460 /* Return true if the vector misalignment factor is supported by the
3463 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3470 /* Return if movmisalign pattern is not supported for this mode. */
3471 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3474 if (misalignment == -1)
3476 /* Misalignment factor is unknown at compile time but we know
3477 it's word aligned. */
3478 if (rs6000_vector_alignment_reachable (type, is_packed))
3480 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3482 if (element_size == 64 || element_size == 32)
3489 /* VSX supports word-aligned vector. */
3490 if (misalignment % 4 == 0)
3496 /* Implement targetm.vectorize.builtin_vec_perm. */
3498 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3500 tree inner_type = TREE_TYPE (type);
3501 bool uns_p = TYPE_UNSIGNED (inner_type);
3504 *mask_element_type = unsigned_char_type_node;
3506 switch (TYPE_MODE (type))
3510 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3511 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3516 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3517 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3522 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3523 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3527 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3531 if (!TARGET_ALLOW_DF_PERMUTE)
3534 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3538 if (!TARGET_ALLOW_DF_PERMUTE)
3542 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3543 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3555 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3557 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3558 tree vectype, int misalign)
3562 switch (type_of_cost)
3572 case cond_branch_not_taken:
3576 case cond_branch_taken:
3579 case unaligned_load:
3580 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3582 elements = TYPE_VECTOR_SUBPARTS (vectype);
3584 /* Double word aligned. */
3592 /* Double word aligned. */
3596 /* Unknown misalignment. */
3609 /* Misaligned loads are not supported. */
3614 case unaligned_store:
3615 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3617 elements = TYPE_VECTOR_SUBPARTS (vectype);
3619 /* Double word aligned. */
3627 /* Double word aligned. */
3631 /* Unknown misalignment. */
3644 /* Misaligned stores are not supported. */
3654 /* Implement targetm.vectorize.preferred_simd_mode. */
3656 static enum machine_mode
3657 rs6000_preferred_simd_mode (enum machine_mode mode)
3666 if (TARGET_ALTIVEC || TARGET_VSX)
3690 if (TARGET_PAIRED_FLOAT
3696 /* Handle generic options of the form -mfoo=yes/no.
3697 NAME is the option name.
3698 VALUE is the option value.
3699 FLAG is the pointer to the flag where to store a 1 or 0, depending on
3700 whether the option value is 'yes' or 'no' respectively. */
3702 rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
3706 else if (!strcmp (value, "yes"))
3708 else if (!strcmp (value, "no"))
3711 error ("unknown -m%s= option specified: '%s'", name, value);
3714 /* Validate and record the size specified with the -mtls-size option. */
3717 rs6000_parse_tls_size_option (void)
3719 if (rs6000_tls_size_string == 0)
3721 else if (strcmp (rs6000_tls_size_string, "16") == 0)
3722 rs6000_tls_size = 16;
3723 else if (strcmp (rs6000_tls_size_string, "32") == 0)
3724 rs6000_tls_size = 32;
3725 else if (strcmp (rs6000_tls_size_string, "64") == 0)
3726 rs6000_tls_size = 64;
3728 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
3731 /* Implement TARGET_OPTION_INIT_STRUCT. */
3734 rs6000_option_init_struct (struct gcc_options *opts)
3736 if (DEFAULT_ABI == ABI_DARWIN)
3737 /* The Darwin libraries never set errno, so we might as well
3738 avoid calling them when that's the only reason we would. */
3739 opts->x_flag_errno_math = 0;
3741 /* Enable section anchors by default. */
3743 opts->x_flag_section_anchors = 1;
3746 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3749 rs6000_option_default_params (void)
3751 /* Double growth factor to counter reduced min jump length. */
3752 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3755 static enum fpu_type_t
3756 rs6000_parse_fpu_option (const char *option)
3758 if (!strcmp("none", option)) return FPU_NONE;
3759 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3760 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3761 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3762 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3763 error("unknown value %s for -mfpu", option);
3768 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3769 library with vectorized intrinsics. */
3772 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3775 const char *suffix = NULL;
3776 tree fntype, new_fndecl, bdecl = NULL_TREE;
3779 enum machine_mode el_mode, in_mode;
3782 /* Libmass is suitable for unsafe math only as it does not correctly support
3783 parts of IEEE with the required precision such as denormals. Only support
3784 it if we have VSX to use the simd d2 or f4 functions.
3785 XXX: Add variable length support. */
3786 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3789 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3790 n = TYPE_VECTOR_SUBPARTS (type_out);
3791 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3792 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3793 if (el_mode != in_mode
3797 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3799 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3802 case BUILT_IN_ATAN2:
3803 case BUILT_IN_HYPOT:
3809 case BUILT_IN_ACOSH:
3811 case BUILT_IN_ASINH:
3813 case BUILT_IN_ATANH:
3821 case BUILT_IN_EXPM1:
3822 case BUILT_IN_LGAMMA:
3823 case BUILT_IN_LOG10:
3824 case BUILT_IN_LOG1P:
3832 bdecl = implicit_built_in_decls[fn];
3833 suffix = "d2"; /* pow -> powd2 */
3834 if (el_mode != DFmode
3839 case BUILT_IN_ATAN2F:
3840 case BUILT_IN_HYPOTF:
3845 case BUILT_IN_ACOSF:
3846 case BUILT_IN_ACOSHF:
3847 case BUILT_IN_ASINF:
3848 case BUILT_IN_ASINHF:
3849 case BUILT_IN_ATANF:
3850 case BUILT_IN_ATANHF:
3851 case BUILT_IN_CBRTF:
3853 case BUILT_IN_COSHF:
3855 case BUILT_IN_ERFCF:
3856 case BUILT_IN_EXP2F:
3858 case BUILT_IN_EXPM1F:
3859 case BUILT_IN_LGAMMAF:
3860 case BUILT_IN_LOG10F:
3861 case BUILT_IN_LOG1PF:
3862 case BUILT_IN_LOG2F:
3865 case BUILT_IN_SINHF:
3866 case BUILT_IN_SQRTF:
3868 case BUILT_IN_TANHF:
3869 bdecl = implicit_built_in_decls[fn];
3870 suffix = "4"; /* powf -> powf4 */
3871 if (el_mode != SFmode
3883 gcc_assert (suffix != NULL);
3884 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3885 strcpy (name, bname + sizeof ("__builtin_") - 1);
3886 strcat (name, suffix);
3889 fntype = build_function_type_list (type_out, type_in, NULL);
3890 else if (n_args == 2)
3891 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3895 /* Build a function declaration for the vectorized function. */
3896 new_fndecl = build_decl (BUILTINS_LOCATION,
3897 FUNCTION_DECL, get_identifier (name), fntype);
3898 TREE_PUBLIC (new_fndecl) = 1;
3899 DECL_EXTERNAL (new_fndecl) = 1;
3900 DECL_IS_NOVOPS (new_fndecl) = 1;
3901 TREE_READONLY (new_fndecl) = 1;
3906 /* Returns a function decl for a vectorized version of the builtin function
3907 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3908 if it is not available. */
3911 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
3914 enum machine_mode in_mode, out_mode;
3917 if (TREE_CODE (type_out) != VECTOR_TYPE
3918 || TREE_CODE (type_in) != VECTOR_TYPE
3919 || !TARGET_VECTORIZE_BUILTINS)
3922 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3923 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3924 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3925 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3927 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3929 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3932 case BUILT_IN_COPYSIGN:
3933 if (VECTOR_UNIT_VSX_P (V2DFmode)
3934 && out_mode == DFmode && out_n == 2
3935 && in_mode == DFmode && in_n == 2)
3936 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
3938 case BUILT_IN_COPYSIGNF:
3939 if (out_mode != SFmode || out_n != 4
3940 || in_mode != SFmode || in_n != 4)
3942 if (VECTOR_UNIT_VSX_P (V4SFmode))
3943 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
3944 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3945 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
3948 if (VECTOR_UNIT_VSX_P (V2DFmode)
3949 && out_mode == DFmode && out_n == 2
3950 && in_mode == DFmode && in_n == 2)
3951 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
3953 case BUILT_IN_SQRTF:
3954 if (VECTOR_UNIT_VSX_P (V4SFmode)
3955 && out_mode == SFmode && out_n == 4
3956 && in_mode == SFmode && in_n == 4)
3957 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
3960 if (VECTOR_UNIT_VSX_P (V2DFmode)
3961 && out_mode == DFmode && out_n == 2
3962 && in_mode == DFmode && in_n == 2)
3963 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
3965 case BUILT_IN_CEILF:
3966 if (out_mode != SFmode || out_n != 4
3967 || in_mode != SFmode || in_n != 4)
3969 if (VECTOR_UNIT_VSX_P (V4SFmode))
3970 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
3971 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3972 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
3974 case BUILT_IN_FLOOR:
3975 if (VECTOR_UNIT_VSX_P (V2DFmode)
3976 && out_mode == DFmode && out_n == 2
3977 && in_mode == DFmode && in_n == 2)
3978 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
3980 case BUILT_IN_FLOORF:
3981 if (out_mode != SFmode || out_n != 4
3982 || in_mode != SFmode || in_n != 4)
3984 if (VECTOR_UNIT_VSX_P (V4SFmode))
3985 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
3986 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
3987 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
3990 if (VECTOR_UNIT_VSX_P (V2DFmode)
3991 && out_mode == DFmode && out_n == 2
3992 && in_mode == DFmode && in_n == 2)
3993 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
3996 if (VECTOR_UNIT_VSX_P (V4SFmode)
3997 && out_mode == SFmode && out_n == 4
3998 && in_mode == SFmode && in_n == 4)
3999 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4000 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4001 && out_mode == SFmode && out_n == 4
4002 && in_mode == SFmode && in_n == 4)
4003 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4005 case BUILT_IN_TRUNC:
4006 if (VECTOR_UNIT_VSX_P (V2DFmode)
4007 && out_mode == DFmode && out_n == 2
4008 && in_mode == DFmode && in_n == 2)
4009 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4011 case BUILT_IN_TRUNCF:
4012 if (out_mode != SFmode || out_n != 4
4013 || in_mode != SFmode || in_n != 4)
4015 if (VECTOR_UNIT_VSX_P (V4SFmode))
4016 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4017 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4018 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4020 case BUILT_IN_NEARBYINT:
4021 if (VECTOR_UNIT_VSX_P (V2DFmode)
4022 && flag_unsafe_math_optimizations
4023 && out_mode == DFmode && out_n == 2
4024 && in_mode == DFmode && in_n == 2)
4025 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4027 case BUILT_IN_NEARBYINTF:
4028 if (VECTOR_UNIT_VSX_P (V4SFmode)
4029 && flag_unsafe_math_optimizations
4030 && out_mode == SFmode && out_n == 4
4031 && in_mode == SFmode && in_n == 4)
4032 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4035 if (VECTOR_UNIT_VSX_P (V2DFmode)
4036 && !flag_trapping_math
4037 && out_mode == DFmode && out_n == 2
4038 && in_mode == DFmode && in_n == 2)
4039 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4041 case BUILT_IN_RINTF:
4042 if (VECTOR_UNIT_VSX_P (V4SFmode)
4043 && !flag_trapping_math
4044 && out_mode == SFmode && out_n == 4
4045 && in_mode == SFmode && in_n == 4)
4046 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4053 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4055 enum rs6000_builtins fn
4056 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4059 case RS6000_BUILTIN_RSQRTF:
4060 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4061 && out_mode == SFmode && out_n == 4
4062 && in_mode == SFmode && in_n == 4)
4063 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4065 case RS6000_BUILTIN_RSQRT:
4066 if (VECTOR_UNIT_VSX_P (V2DFmode)
4067 && out_mode == DFmode && out_n == 2
4068 && in_mode == DFmode && in_n == 2)
4069 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4071 case RS6000_BUILTIN_RECIPF:
4072 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4073 && out_mode == SFmode && out_n == 4
4074 && in_mode == SFmode && in_n == 4)
4075 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4077 case RS6000_BUILTIN_RECIP:
4078 if (VECTOR_UNIT_VSX_P (V2DFmode)
4079 && out_mode == DFmode && out_n == 2
4080 && in_mode == DFmode && in_n == 2)
4081 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4088 /* Generate calls to libmass if appropriate. */
4089 if (rs6000_veclib_handler)
4090 return rs6000_veclib_handler (fndecl, type_out, type_in);
4096 /* Implement TARGET_HANDLE_OPTION. */
4099 rs6000_handle_option (size_t code, const char *arg, int value)
4101 enum fpu_type_t fpu_type = FPU_NONE;
4107 target_flags &= ~(MASK_POWER | MASK_POWER2
4108 | MASK_MULTIPLE | MASK_STRING);
4109 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4110 | MASK_MULTIPLE | MASK_STRING);
4112 case OPT_mno_powerpc:
4113 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4114 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4115 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4116 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4119 target_flags &= ~MASK_MINIMAL_TOC;
4120 TARGET_NO_FP_IN_TOC = 0;
4121 TARGET_NO_SUM_IN_TOC = 0;
4122 target_flags_explicit |= MASK_MINIMAL_TOC;
4123 #ifdef TARGET_USES_SYSV4_OPT
4124 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4125 just the same as -mminimal-toc. */
4126 target_flags |= MASK_MINIMAL_TOC;
4127 target_flags_explicit |= MASK_MINIMAL_TOC;
4131 #ifdef TARGET_USES_SYSV4_OPT
4133 /* Make -mtoc behave like -mminimal-toc. */
4134 target_flags |= MASK_MINIMAL_TOC;
4135 target_flags_explicit |= MASK_MINIMAL_TOC;
4139 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4141 if (strcmp (arg, "small") == 0)
4142 cmodel = CMODEL_SMALL;
4143 else if (strcmp (arg, "medium") == 0)
4144 cmodel = CMODEL_MEDIUM;
4145 else if (strcmp (arg, "large") == 0)
4146 cmodel = CMODEL_LARGE;
4149 error ("invalid option for -mcmodel: '%s'", arg);
4152 rs6000_explicit_options.cmodel = true;
4155 #ifdef TARGET_USES_AIX64_OPT
4160 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4161 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4162 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4165 #ifdef TARGET_USES_AIX64_OPT
4170 target_flags &= ~MASK_POWERPC64;
4171 target_flags_explicit |= MASK_POWERPC64;
4174 case OPT_minsert_sched_nops_:
4175 rs6000_sched_insert_nops_str = arg;
4178 case OPT_mminimal_toc:
4181 TARGET_NO_FP_IN_TOC = 0;
4182 TARGET_NO_SUM_IN_TOC = 0;
4189 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4190 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4197 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4198 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4202 case OPT_mpowerpc_gpopt:
4203 case OPT_mpowerpc_gfxopt:
4206 target_flags |= MASK_POWERPC;
4207 target_flags_explicit |= MASK_POWERPC;
4211 case OPT_maix_struct_return:
4212 case OPT_msvr4_struct_return:
4213 rs6000_explicit_options.aix_struct_ret = true;
4217 rs6000_explicit_options.vrsave = true;
4218 TARGET_ALTIVEC_VRSAVE = value;
4222 rs6000_explicit_options.vrsave = true;
4223 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
4227 target_flags_explicit |= MASK_ISEL;
4229 rs6000_parse_yes_no_option ("isel", arg, &isel);
4231 target_flags |= MASK_ISEL;
4233 target_flags &= ~MASK_ISEL;
4237 rs6000_explicit_options.spe = true;
4242 rs6000_explicit_options.spe = true;
4243 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
4247 rs6000_debug_name = arg;
4250 #ifdef TARGET_USES_SYSV4_OPT
4252 rs6000_abi_name = arg;
4256 rs6000_sdata_name = arg;
4259 case OPT_mtls_size_:
4260 rs6000_tls_size_string = arg;
4263 case OPT_mrelocatable:
4266 target_flags |= MASK_MINIMAL_TOC;
4267 target_flags_explicit |= MASK_MINIMAL_TOC;
4268 TARGET_NO_FP_IN_TOC = 1;
4272 case OPT_mrelocatable_lib:
4275 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4276 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4277 TARGET_NO_FP_IN_TOC = 1;
4281 target_flags &= ~MASK_RELOCATABLE;
4282 target_flags_explicit |= MASK_RELOCATABLE;
4288 if (!strcmp (arg, "altivec"))
4290 rs6000_explicit_options.altivec_abi = true;
4291 rs6000_altivec_abi = 1;
4293 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4296 else if (! strcmp (arg, "no-altivec"))
4298 rs6000_explicit_options.altivec_abi = true;
4299 rs6000_altivec_abi = 0;
4301 else if (! strcmp (arg, "spe"))
4303 rs6000_explicit_options.spe_abi = true;
4305 rs6000_altivec_abi = 0;
4306 if (!TARGET_SPE_ABI)
4307 error ("not configured for ABI: '%s'", arg);
4309 else if (! strcmp (arg, "no-spe"))
4311 rs6000_explicit_options.spe_abi = true;
4315 /* These are here for testing during development only, do not
4316 document in the manual please. */
4317 else if (! strcmp (arg, "d64"))
4319 rs6000_darwin64_abi = 1;
4320 warning (0, "using darwin64 ABI");
4322 else if (! strcmp (arg, "d32"))
4324 rs6000_darwin64_abi = 0;
4325 warning (0, "using old darwin ABI");
4328 else if (! strcmp (arg, "ibmlongdouble"))
4330 rs6000_explicit_options.ieee = true;
4331 rs6000_ieeequad = 0;
4332 warning (0, "using IBM extended precision long double");
4334 else if (! strcmp (arg, "ieeelongdouble"))
4336 rs6000_explicit_options.ieee = true;
4337 rs6000_ieeequad = 1;
4338 warning (0, "using IEEE extended precision long double");
4343 error ("unknown ABI specified: '%s'", arg);
4349 rs6000_select[1].string = arg;
4353 rs6000_select[2].string = arg;
4356 case OPT_mtraceback_:
4357 rs6000_traceback_name = arg;
4360 case OPT_mfloat_gprs_:
4361 rs6000_explicit_options.float_gprs = true;
4362 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4363 rs6000_float_gprs = 1;
4364 else if (! strcmp (arg, "double"))
4365 rs6000_float_gprs = 2;
4366 else if (! strcmp (arg, "no"))
4367 rs6000_float_gprs = 0;
4370 error ("invalid option for -mfloat-gprs: '%s'", arg);
4375 case OPT_mlong_double_:
4376 rs6000_explicit_options.long_double = true;
4377 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4378 if (value != 64 && value != 128)
4380 error ("unknown switch -mlong-double-%s", arg);
4381 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4385 rs6000_long_double_type_size = value;
4388 case OPT_msched_costly_dep_:
4389 rs6000_sched_costly_dep_str = arg;
4393 rs6000_explicit_options.alignment = true;
4394 if (! strcmp (arg, "power"))
4396 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4397 some C library functions, so warn about it. The flag may be
4398 useful for performance studies from time to time though, so
4399 don't disable it entirely. */
4400 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4401 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4402 " it is incompatible with the installed C and C++ libraries");
4403 rs6000_alignment_flags = MASK_ALIGN_POWER;
4405 else if (! strcmp (arg, "natural"))
4406 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4409 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4414 case OPT_msingle_float:
4415 if (!TARGET_SINGLE_FPU)
4416 warning (0, "-msingle-float option equivalent to -mhard-float");
4417 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4418 rs6000_double_float = 0;
4419 target_flags &= ~MASK_SOFT_FLOAT;
4420 target_flags_explicit |= MASK_SOFT_FLOAT;
4423 case OPT_mdouble_float:
4424 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4425 rs6000_single_float = 1;
4426 target_flags &= ~MASK_SOFT_FLOAT;
4427 target_flags_explicit |= MASK_SOFT_FLOAT;
4430 case OPT_msimple_fpu:
4431 if (!TARGET_SINGLE_FPU)
4432 warning (0, "-msimple-fpu option ignored");
4435 case OPT_mhard_float:
4436 /* -mhard_float implies -msingle-float and -mdouble-float. */
4437 rs6000_single_float = rs6000_double_float = 1;
4440 case OPT_msoft_float:
4441 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4442 rs6000_single_float = rs6000_double_float = 0;
4446 fpu_type = rs6000_parse_fpu_option(arg);
4447 if (fpu_type != FPU_NONE)
4448 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4450 target_flags &= ~MASK_SOFT_FLOAT;
4451 target_flags_explicit |= MASK_SOFT_FLOAT;
4452 rs6000_xilinx_fpu = 1;
4453 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4454 rs6000_single_float = 1;
4455 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4456 rs6000_single_float = rs6000_double_float = 1;
4457 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4458 rs6000_simple_fpu = 1;
4462 /* -mfpu=none is equivalent to -msoft-float */
4463 target_flags |= MASK_SOFT_FLOAT;
4464 target_flags_explicit |= MASK_SOFT_FLOAT;
4465 rs6000_single_float = rs6000_double_float = 0;
4469 rs6000_recip_name = (value) ? "default" : "none";
4473 rs6000_recip_name = arg;
4479 /* Do anything needed at the start of the asm file. */
4482 rs6000_file_start (void)
4486 const char *start = buffer;
4487 struct rs6000_cpu_select *ptr;
4488 const char *default_cpu = TARGET_CPU_DEFAULT;
4489 FILE *file = asm_out_file;
4491 default_file_start ();
4493 #ifdef TARGET_BI_ARCH
4494 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4498 if (flag_verbose_asm)
4500 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4501 rs6000_select[0].string = default_cpu;
4503 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4505 ptr = &rs6000_select[i];
4506 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4508 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4513 if (PPC405_ERRATUM77)
4515 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4519 #ifdef USING_ELFOS_H
4520 switch (rs6000_sdata)
4522 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4523 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4524 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4525 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4528 if (rs6000_sdata && g_switch_value)
4530 fprintf (file, "%s -G %d", start,
4540 #ifdef HAVE_AS_GNU_ATTRIBUTE
4541 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
4543 fprintf (file, "\t.gnu_attribute 4, %d\n",
4544 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
4545 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
4547 fprintf (file, "\t.gnu_attribute 8, %d\n",
4548 (TARGET_ALTIVEC_ABI ? 2
4549 : TARGET_SPE_ABI ? 3
4551 fprintf (file, "\t.gnu_attribute 12, %d\n",
4552 aix_struct_return ? 2 : 1);
4557 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4559 switch_to_section (toc_section);
4560 switch_to_section (text_section);
4565 /* Return nonzero if this function is known to have a null epilogue. */
4568 direct_return (void)
4570 if (reload_completed)
4572 rs6000_stack_t *info = rs6000_stack_info ();
4574 if (info->first_gp_reg_save == 32
4575 && info->first_fp_reg_save == 64
4576 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4577 && ! info->lr_save_p
4578 && ! info->cr_save_p
4579 && info->vrsave_mask == 0
4587 /* Return the number of instructions it takes to form a constant in an
4588 integer register. */
4591 num_insns_constant_wide (HOST_WIDE_INT value)
4593 /* signed constant loadable with {cal|addi} */
4594 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4597 /* constant loadable with {cau|addis} */
4598 else if ((value & 0xffff) == 0
4599 && (value >> 31 == -1 || value >> 31 == 0))
4602 #if HOST_BITS_PER_WIDE_INT == 64
4603 else if (TARGET_POWERPC64)
4605 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4606 HOST_WIDE_INT high = value >> 31;
4608 if (high == 0 || high == -1)
4614 return num_insns_constant_wide (high) + 1;
4616 return num_insns_constant_wide (low) + 1;
4618 return (num_insns_constant_wide (high)
4619 + num_insns_constant_wide (low) + 1);
4628 num_insns_constant (rtx op, enum machine_mode mode)
4630 HOST_WIDE_INT low, high;
4632 switch (GET_CODE (op))
4635 #if HOST_BITS_PER_WIDE_INT == 64
4636 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4637 && mask64_operand (op, mode))
4641 return num_insns_constant_wide (INTVAL (op));
4644 if (mode == SFmode || mode == SDmode)
4649 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4650 if (DECIMAL_FLOAT_MODE_P (mode))
4651 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4653 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4654 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4657 if (mode == VOIDmode || mode == DImode)
4659 high = CONST_DOUBLE_HIGH (op);
4660 low = CONST_DOUBLE_LOW (op);
4667 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4668 if (DECIMAL_FLOAT_MODE_P (mode))
4669 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4671 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4672 high = l[WORDS_BIG_ENDIAN == 0];
4673 low = l[WORDS_BIG_ENDIAN != 0];
4677 return (num_insns_constant_wide (low)
4678 + num_insns_constant_wide (high));
4681 if ((high == 0 && low >= 0)
4682 || (high == -1 && low < 0))
4683 return num_insns_constant_wide (low);
4685 else if (mask64_operand (op, mode))
4689 return num_insns_constant_wide (high) + 1;
4692 return (num_insns_constant_wide (high)
4693 + num_insns_constant_wide (low) + 1);
4701 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4702 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4703 corresponding element of the vector, but for V4SFmode and V2SFmode,
4704 the corresponding "float" is interpreted as an SImode integer. */
4707 const_vector_elt_as_int (rtx op, unsigned int elt)
4709 rtx tmp = CONST_VECTOR_ELT (op, elt);
4710 if (GET_MODE (op) == V4SFmode
4711 || GET_MODE (op) == V2SFmode)
4712 tmp = gen_lowpart (SImode, tmp);
4713 return INTVAL (tmp);
4716 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4717 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4718 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4719 all items are set to the same value and contain COPIES replicas of the
4720 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4721 operand and the others are set to the value of the operand's msb. */
4724 vspltis_constant (rtx op, unsigned step, unsigned copies)
4726 enum machine_mode mode = GET_MODE (op);
4727 enum machine_mode inner = GET_MODE_INNER (mode);
4730 unsigned nunits = GET_MODE_NUNITS (mode);
4731 unsigned bitsize = GET_MODE_BITSIZE (inner);
4732 unsigned mask = GET_MODE_MASK (inner);
4734 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
4735 HOST_WIDE_INT splat_val = val;
4736 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
4738 /* Construct the value to be splatted, if possible. If not, return 0. */
4739 for (i = 2; i <= copies; i *= 2)
4741 HOST_WIDE_INT small_val;
4743 small_val = splat_val >> bitsize;
4745 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4747 splat_val = small_val;
4750 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4751 if (EASY_VECTOR_15 (splat_val))
4754 /* Also check if we can splat, and then add the result to itself. Do so if
4755 the value is positive, of if the splat instruction is using OP's mode;
4756 for splat_val < 0, the splat and the add should use the same mode. */
4757 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4758 && (splat_val >= 0 || (step == 1 && copies == 1)))
4761 /* Also check if are loading up the most significant bit which can be done by
4762 loading up -1 and shifting the value left by -1. */
4763 else if (EASY_VECTOR_MSB (splat_val, inner))
4769 /* Check if VAL is present in every STEP-th element, and the
4770 other elements are filled with its most significant bit. */
4771 for (i = 0; i < nunits - 1; ++i)
4773 HOST_WIDE_INT desired_val;
4774 if (((i + 1) & (step - 1)) == 0)
4777 desired_val = msb_val;
4779 if (desired_val != const_vector_elt_as_int (op, i))
4787 /* Return true if OP is of the given MODE and can be synthesized
4788 with a vspltisb, vspltish or vspltisw. */
4791 easy_altivec_constant (rtx op, enum machine_mode mode)
4793 unsigned step, copies;
4795 if (mode == VOIDmode)
4796 mode = GET_MODE (op);
4797 else if (mode != GET_MODE (op))
4800 /* Start with a vspltisw. */
4801 step = GET_MODE_NUNITS (mode) / 4;
4804 if (vspltis_constant (op, step, copies))
4807 /* Then try with a vspltish. */
4813 if (vspltis_constant (op, step, copies))
4816 /* And finally a vspltisb. */
4822 if (vspltis_constant (op, step, copies))
4828 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4829 result is OP. Abort if it is not possible. */
4832 gen_easy_altivec_constant (rtx op)
4834 enum machine_mode mode = GET_MODE (op);
4835 int nunits = GET_MODE_NUNITS (mode);
4836 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4837 unsigned step = nunits / 4;
4838 unsigned copies = 1;
4840 /* Start with a vspltisw. */
4841 if (vspltis_constant (op, step, copies))
4842 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
4844 /* Then try with a vspltish. */
4850 if (vspltis_constant (op, step, copies))
4851 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
4853 /* And finally a vspltisb. */
4859 if (vspltis_constant (op, step, copies))
4860 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
4866 output_vec_const_move (rtx *operands)
4869 enum machine_mode mode;
4874 mode = GET_MODE (dest);
4876 if (TARGET_VSX && zero_constant (vec, mode))
4877 return "xxlxor %x0,%x0,%x0";
4882 if (zero_constant (vec, mode))
4883 return "vxor %0,%0,%0";
4885 splat_vec = gen_easy_altivec_constant (vec);
4886 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
4887 operands[1] = XEXP (splat_vec, 0);
4888 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
4891 switch (GET_MODE (splat_vec))
4894 return "vspltisw %0,%1";
4897 return "vspltish %0,%1";
4900 return "vspltisb %0,%1";
4907 gcc_assert (TARGET_SPE);
4909 /* Vector constant 0 is handled as a splitter of V2SI, and in the
4910 pattern of V1DI, V4HI, and V2SF.
4912 FIXME: We should probably return # and add post reload
4913 splitters for these, but this way is so easy ;-). */
4914 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
4915 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
4916 operands[1] = CONST_VECTOR_ELT (vec, 0);
4917 operands[2] = CONST_VECTOR_ELT (vec, 1);
4919 return "li %0,%1\n\tevmergelo %0,%0,%0";
4921 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
4924 /* Initialize TARGET of vector PAIRED to VALS. */
4927 paired_expand_vector_init (rtx target, rtx vals)
4929 enum machine_mode mode = GET_MODE (target);
4930 int n_elts = GET_MODE_NUNITS (mode);
4932 rtx x, new_rtx, tmp, constant_op, op1, op2;
4935 for (i = 0; i < n_elts; ++i)
4937 x = XVECEXP (vals, 0, i);
4938 if (!CONSTANT_P (x))
4943 /* Load from constant pool. */
4944 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
4950 /* The vector is initialized only with non-constants. */
4951 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
4952 XVECEXP (vals, 0, 1));
4954 emit_move_insn (target, new_rtx);
4958 /* One field is non-constant and the other one is a constant. Load the
4959 constant from the constant pool and use ps_merge instruction to
4960 construct the whole vector. */
4961 op1 = XVECEXP (vals, 0, 0);
4962 op2 = XVECEXP (vals, 0, 1);
4964 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
4966 tmp = gen_reg_rtx (GET_MODE (constant_op));
4967 emit_move_insn (tmp, constant_op);
4969 if (CONSTANT_P (op1))
4970 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
4972 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
4974 emit_move_insn (target, new_rtx);
4978 paired_expand_vector_move (rtx operands[])
4980 rtx op0 = operands[0], op1 = operands[1];
4982 emit_move_insn (op0, op1);
4985 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
4986 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
4987 operands for the relation operation COND. This is a recursive
4991 paired_emit_vector_compare (enum rtx_code rcode,
4992 rtx dest, rtx op0, rtx op1,
4993 rtx cc_op0, rtx cc_op1)
4995 rtx tmp = gen_reg_rtx (V2SFmode);
4998 gcc_assert (TARGET_PAIRED_FLOAT);
4999 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5005 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5009 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5010 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5014 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5017 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5020 tmp1 = gen_reg_rtx (V2SFmode);
5021 max = gen_reg_rtx (V2SFmode);
5022 min = gen_reg_rtx (V2SFmode);
5023 gen_reg_rtx (V2SFmode);
5025 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5026 emit_insn (gen_selv2sf4
5027 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5028 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5029 emit_insn (gen_selv2sf4
5030 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5031 emit_insn (gen_subv2sf3 (tmp1, min, max));
5032 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5035 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5038 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5041 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5044 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5047 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5056 /* Emit vector conditional expression.
5057 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5058 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5061 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5062 rtx cond, rtx cc_op0, rtx cc_op1)
5064 enum rtx_code rcode = GET_CODE (cond);
5066 if (!TARGET_PAIRED_FLOAT)
5069 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5074 /* Initialize vector TARGET to VALS. */
5077 rs6000_expand_vector_init (rtx target, rtx vals)
5079 enum machine_mode mode = GET_MODE (target);
5080 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5081 int n_elts = GET_MODE_NUNITS (mode);
5082 int n_var = 0, one_var = -1;
5083 bool all_same = true, all_const_zero = true;
5087 for (i = 0; i < n_elts; ++i)
5089 x = XVECEXP (vals, 0, i);
5090 if (!CONSTANT_P (x))
5091 ++n_var, one_var = i;
5092 else if (x != CONST0_RTX (inner_mode))
5093 all_const_zero = false;
5095 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5101 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5102 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5103 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5105 /* Zero register. */
5106 emit_insn (gen_rtx_SET (VOIDmode, target,
5107 gen_rtx_XOR (mode, target, target)));
5110 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5112 /* Splat immediate. */
5113 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5118 /* Load from constant pool. */
5119 emit_move_insn (target, const_vec);
5124 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5125 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5129 rtx element = XVECEXP (vals, 0, 0);
5130 if (mode == V2DFmode)
5131 emit_insn (gen_vsx_splat_v2df (target, element));
5133 emit_insn (gen_vsx_splat_v2di (target, element));
5137 rtx op0 = copy_to_reg (XVECEXP (vals, 0, 0));
5138 rtx op1 = copy_to_reg (XVECEXP (vals, 0, 1));
5139 if (mode == V2DFmode)
5140 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5142 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5147 /* With single precision floating point on VSX, know that internally single
5148 precision is actually represented as a double, and either make 2 V2DF
5149 vectors, and convert these vectors to single precision, or do one
5150 conversion, and splat the result to the other elements. */
5151 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5155 rtx freg = gen_reg_rtx (V4SFmode);
5156 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5158 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5159 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5163 rtx dbl_even = gen_reg_rtx (V2DFmode);
5164 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5165 rtx flt_even = gen_reg_rtx (V4SFmode);
5166 rtx flt_odd = gen_reg_rtx (V4SFmode);
5168 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5169 copy_to_reg (XVECEXP (vals, 0, 0)),
5170 copy_to_reg (XVECEXP (vals, 0, 1))));
5171 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5172 copy_to_reg (XVECEXP (vals, 0, 2)),
5173 copy_to_reg (XVECEXP (vals, 0, 3))));
5174 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5175 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5176 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5181 /* Store value to stack temp. Load vector element. Splat. However, splat
5182 of 64-bit items is not supported on Altivec. */
5183 if (all_same && GET_MODE_SIZE (mode) <= 4)
5185 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5186 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5187 XVECEXP (vals, 0, 0));
5188 x = gen_rtx_UNSPEC (VOIDmode,
5189 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5190 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5192 gen_rtx_SET (VOIDmode,
5195 x = gen_rtx_VEC_SELECT (inner_mode, target,
5196 gen_rtx_PARALLEL (VOIDmode,
5197 gen_rtvec (1, const0_rtx)));
5198 emit_insn (gen_rtx_SET (VOIDmode, target,
5199 gen_rtx_VEC_DUPLICATE (mode, x)));
5203 /* One field is non-constant. Load constant then overwrite
5207 rtx copy = copy_rtx (vals);
5209 /* Load constant part of vector, substitute neighboring value for
5211 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5212 rs6000_expand_vector_init (target, copy);
5214 /* Insert variable. */
5215 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5219 /* Construct the vector in memory one field at a time
5220 and load the whole vector. */
5221 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5222 for (i = 0; i < n_elts; i++)
5223 emit_move_insn (adjust_address_nv (mem, inner_mode,
5224 i * GET_MODE_SIZE (inner_mode)),
5225 XVECEXP (vals, 0, i));
5226 emit_move_insn (target, mem);
5229 /* Set field ELT of TARGET to VAL. */
5232 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5234 enum machine_mode mode = GET_MODE (target);
5235 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5236 rtx reg = gen_reg_rtx (mode);
5238 int width = GET_MODE_SIZE (inner_mode);
5241 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5243 rtx (*set_func) (rtx, rtx, rtx, rtx)
5244 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5245 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5249 /* Load single variable value. */
5250 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5251 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5252 x = gen_rtx_UNSPEC (VOIDmode,
5253 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5254 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5256 gen_rtx_SET (VOIDmode,
5260 /* Linear sequence. */
5261 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5262 for (i = 0; i < 16; ++i)
5263 XVECEXP (mask, 0, i) = GEN_INT (i);
5265 /* Set permute mask to insert element into target. */
5266 for (i = 0; i < width; ++i)
5267 XVECEXP (mask, 0, elt*width + i)
5268 = GEN_INT (i + 0x10);
5269 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5270 x = gen_rtx_UNSPEC (mode,
5271 gen_rtvec (3, target, reg,
5272 force_reg (V16QImode, x)),
5274 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5277 /* Extract field ELT from VEC into TARGET. */
5280 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5282 enum machine_mode mode = GET_MODE (vec);
5283 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5286 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5288 rtx (*extract_func) (rtx, rtx, rtx)
5289 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5290 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5294 /* Allocate mode-sized buffer. */
5295 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5297 /* Add offset to field within buffer matching vector element. */
5298 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
5300 /* Store single field into mode-sized buffer. */
5301 x = gen_rtx_UNSPEC (VOIDmode,
5302 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
5303 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5305 gen_rtx_SET (VOIDmode,
5308 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5311 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5312 implement ANDing by the mask IN. */
5314 build_mask64_2_operands (rtx in, rtx *out)
5316 #if HOST_BITS_PER_WIDE_INT >= 64
5317 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5320 gcc_assert (GET_CODE (in) == CONST_INT);
5325 /* Assume c initially something like 0x00fff000000fffff. The idea
5326 is to rotate the word so that the middle ^^^^^^ group of zeros
5327 is at the MS end and can be cleared with an rldicl mask. We then
5328 rotate back and clear off the MS ^^ group of zeros with a
5330 c = ~c; /* c == 0xff000ffffff00000 */
5331 lsb = c & -c; /* lsb == 0x0000000000100000 */
5332 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5333 c = ~c; /* c == 0x00fff000000fffff */
5334 c &= -lsb; /* c == 0x00fff00000000000 */
5335 lsb = c & -c; /* lsb == 0x0000100000000000 */
5336 c = ~c; /* c == 0xff000fffffffffff */
5337 c &= -lsb; /* c == 0xff00000000000000 */
5339 while ((lsb >>= 1) != 0)
5340 shift++; /* shift == 44 on exit from loop */
5341 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5342 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5343 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5347 /* Assume c initially something like 0xff000f0000000000. The idea
5348 is to rotate the word so that the ^^^ middle group of zeros
5349 is at the LS end and can be cleared with an rldicr mask. We then
5350 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5352 lsb = c & -c; /* lsb == 0x0000010000000000 */
5353 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5354 c = ~c; /* c == 0x00fff0ffffffffff */
5355 c &= -lsb; /* c == 0x00fff00000000000 */
5356 lsb = c & -c; /* lsb == 0x0000100000000000 */
5357 c = ~c; /* c == 0xff000fffffffffff */
5358 c &= -lsb; /* c == 0xff00000000000000 */
5360 while ((lsb >>= 1) != 0)
5361 shift++; /* shift == 44 on exit from loop */
5362 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5363 m1 >>= shift; /* m1 == 0x0000000000000fff */
5364 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5367 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5368 masks will be all 1's. We are guaranteed more than one transition. */
5369 out[0] = GEN_INT (64 - shift);
5370 out[1] = GEN_INT (m1);
5371 out[2] = GEN_INT (shift);
5372 out[3] = GEN_INT (m2);
5380 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5383 invalid_e500_subreg (rtx op, enum machine_mode mode)
5385 if (TARGET_E500_DOUBLE)
5387 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5388 subreg:TI and reg:TF. Decimal float modes are like integer
5389 modes (only low part of each register used) for this
5391 if (GET_CODE (op) == SUBREG
5392 && (mode == SImode || mode == DImode || mode == TImode
5393 || mode == DDmode || mode == TDmode)
5394 && REG_P (SUBREG_REG (op))
5395 && (GET_MODE (SUBREG_REG (op)) == DFmode
5396 || GET_MODE (SUBREG_REG (op)) == TFmode))
5399 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5401 if (GET_CODE (op) == SUBREG
5402 && (mode == DFmode || mode == TFmode)
5403 && REG_P (SUBREG_REG (op))
5404 && (GET_MODE (SUBREG_REG (op)) == DImode
5405 || GET_MODE (SUBREG_REG (op)) == TImode
5406 || GET_MODE (SUBREG_REG (op)) == DDmode
5407 || GET_MODE (SUBREG_REG (op)) == TDmode))
5412 && GET_CODE (op) == SUBREG
5414 && REG_P (SUBREG_REG (op))
5415 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5421 /* AIX increases natural record alignment to doubleword if the first
5422 field is an FP double while the FP fields remain word aligned. */
5425 rs6000_special_round_type_align (tree type, unsigned int computed,
5426 unsigned int specified)
5428 unsigned int align = MAX (computed, specified);
5429 tree field = TYPE_FIELDS (type);
5431 /* Skip all non field decls */
5432 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5433 field = DECL_CHAIN (field);
5435 if (field != NULL && field != type)
5437 type = TREE_TYPE (field);
5438 while (TREE_CODE (type) == ARRAY_TYPE)
5439 type = TREE_TYPE (type);
5441 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5442 align = MAX (align, 64);
5448 /* Darwin increases record alignment to the natural alignment of
5452 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5453 unsigned int specified)
5455 unsigned int align = MAX (computed, specified);
5457 if (TYPE_PACKED (type))
5460 /* Find the first field, looking down into aggregates. */
5462 tree field = TYPE_FIELDS (type);
5463 /* Skip all non field decls */
5464 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5465 field = DECL_CHAIN (field);
5468 /* A packed field does not contribute any extra alignment. */
5469 if (DECL_PACKED (field))
5471 type = TREE_TYPE (field);
5472 while (TREE_CODE (type) == ARRAY_TYPE)
5473 type = TREE_TYPE (type);
5474 } while (AGGREGATE_TYPE_P (type));
5476 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5477 align = MAX (align, TYPE_ALIGN (type));
5482 /* Return 1 for an operand in small memory on V.4/eabi. */
5485 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5486 enum machine_mode mode ATTRIBUTE_UNUSED)
5491 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5494 if (DEFAULT_ABI != ABI_V4)
5497 /* Vector and float memory instructions have a limited offset on the
5498 SPE, so using a vector or float variable directly as an operand is
5501 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5504 if (GET_CODE (op) == SYMBOL_REF)
5507 else if (GET_CODE (op) != CONST
5508 || GET_CODE (XEXP (op, 0)) != PLUS
5509 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5510 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5515 rtx sum = XEXP (op, 0);
5516 HOST_WIDE_INT summand;
5518 /* We have to be careful here, because it is the referenced address
5519 that must be 32k from _SDA_BASE_, not just the symbol. */
5520 summand = INTVAL (XEXP (sum, 1));
5521 if (summand < 0 || summand > g_switch_value)
5524 sym_ref = XEXP (sum, 0);
5527 return SYMBOL_REF_SMALL_P (sym_ref);
5533 /* Return true if either operand is a general purpose register. */
5536 gpr_or_gpr_p (rtx op0, rtx op1)
5538 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5539 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5543 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5546 reg_offset_addressing_ok_p (enum machine_mode mode)
5556 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5557 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5565 /* Paired vector modes. Only reg+reg addressing is valid. */
5566 if (TARGET_PAIRED_FLOAT)
5578 virtual_stack_registers_memory_p (rtx op)
5582 if (GET_CODE (op) == REG)
5583 regnum = REGNO (op);
5585 else if (GET_CODE (op) == PLUS
5586 && GET_CODE (XEXP (op, 0)) == REG
5587 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5588 regnum = REGNO (XEXP (op, 0));
5593 return (regnum >= FIRST_VIRTUAL_REGISTER
5594 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5598 constant_pool_expr_p (rtx op)
5602 split_const (op, &base, &offset);
5603 return (GET_CODE (base) == SYMBOL_REF
5604 && CONSTANT_POOL_ADDRESS_P (base)
5605 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5608 static rtx tocrel_base, tocrel_offset;
5611 toc_relative_expr_p (rtx op)
5613 if (GET_CODE (op) != CONST)
5616 split_const (op, &tocrel_base, &tocrel_offset);
5617 return (GET_CODE (tocrel_base) == UNSPEC
5618 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5622 legitimate_constant_pool_address_p (const_rtx x, bool strict)
5625 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5626 && GET_CODE (XEXP (x, 0)) == REG
5627 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5628 || ((TARGET_MINIMAL_TOC
5629 || TARGET_CMODEL != CMODEL_SMALL)
5630 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5631 && toc_relative_expr_p (XEXP (x, 1)));
5635 legitimate_small_data_p (enum machine_mode mode, rtx x)
5637 return (DEFAULT_ABI == ABI_V4
5638 && !flag_pic && !TARGET_TOC
5639 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5640 && small_data_operand (x, mode));
5643 /* SPE offset addressing is limited to 5-bits worth of double words. */
5644 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5647 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5649 unsigned HOST_WIDE_INT offset, extra;
5651 if (GET_CODE (x) != PLUS)
5653 if (GET_CODE (XEXP (x, 0)) != REG)
5655 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5657 if (!reg_offset_addressing_ok_p (mode))
5658 return virtual_stack_registers_memory_p (x);
5659 if (legitimate_constant_pool_address_p (x, strict))
5661 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5664 offset = INTVAL (XEXP (x, 1));
5672 /* SPE vector modes. */
5673 return SPE_CONST_OFFSET_OK (offset);
5676 if (TARGET_E500_DOUBLE)
5677 return SPE_CONST_OFFSET_OK (offset);
5679 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5681 if (VECTOR_MEM_VSX_P (DFmode))
5686 /* On e500v2, we may have:
5688 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5690 Which gets addressed with evldd instructions. */
5691 if (TARGET_E500_DOUBLE)
5692 return SPE_CONST_OFFSET_OK (offset);
5694 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5696 else if (offset & 3)
5701 if (TARGET_E500_DOUBLE)
5702 return (SPE_CONST_OFFSET_OK (offset)
5703 && SPE_CONST_OFFSET_OK (offset + 8));
5707 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5709 else if (offset & 3)
5720 return (offset < 0x10000) && (offset + extra < 0x10000);
5724 legitimate_indexed_address_p (rtx x, int strict)
5728 if (GET_CODE (x) != PLUS)
5734 /* Recognize the rtl generated by reload which we know will later be
5735 replaced with proper base and index regs. */
5737 && reload_in_progress
5738 && (REG_P (op0) || GET_CODE (op0) == PLUS)
5742 return (REG_P (op0) && REG_P (op1)
5743 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
5744 && INT_REG_OK_FOR_INDEX_P (op1, strict))
5745 || (INT_REG_OK_FOR_BASE_P (op1, strict)
5746 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
5750 avoiding_indexed_address_p (enum machine_mode mode)
5752 /* Avoid indexed addressing for modes that have non-indexed
5753 load/store instruction forms. */
5754 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
5758 legitimate_indirect_address_p (rtx x, int strict)
5760 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
5764 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
5766 if (!TARGET_MACHO || !flag_pic
5767 || mode != SImode || GET_CODE (x) != MEM)
5771 if (GET_CODE (x) != LO_SUM)
5773 if (GET_CODE (XEXP (x, 0)) != REG)
5775 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
5779 return CONSTANT_P (x);
5783 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
5785 if (GET_CODE (x) != LO_SUM)
5787 if (GET_CODE (XEXP (x, 0)) != REG)
5789 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5791 /* Restrict addressing for DI because of our SUBREG hackery. */
5792 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5793 || mode == DDmode || mode == TDmode
5798 if (TARGET_ELF || TARGET_MACHO)
5800 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
5804 if (GET_MODE_NUNITS (mode) != 1)
5806 if (GET_MODE_BITSIZE (mode) > 64
5807 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
5808 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5809 && (mode == DFmode || mode == DDmode))))
5812 return CONSTANT_P (x);
5819 /* Try machine-dependent ways of modifying an illegitimate address
5820 to be legitimate. If we find one, return the new, valid address.
5821 This is used from only one place: `memory_address' in explow.c.
5823 OLDX is the address as it was before break_out_memory_refs was
5824 called. In some cases it is useful to look at this to decide what
5827 It is always safe for this function to do nothing. It exists to
5828 recognize opportunities to optimize the output.
5830 On RS/6000, first check for the sum of a register with a constant
5831 integer that is out of range. If so, generate code to add the
5832 constant with the low-order 16 bits masked to the register and force
5833 this result into another register (this can be done with `cau').
5834 Then generate an address of REG+(CONST&0xffff), allowing for the
5835 possibility of bit 16 being a one.
5837 Then check for the sum of a register and something not constant, try to
5838 load the other things into a register and return the sum. */
5841 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
5842 enum machine_mode mode)
5844 unsigned int extra = 0;
5846 if (!reg_offset_addressing_ok_p (mode))
5848 if (virtual_stack_registers_memory_p (x))
5851 /* In theory we should not be seeing addresses of the form reg+0,
5852 but just in case it is generated, optimize it away. */
5853 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
5854 return force_reg (Pmode, XEXP (x, 0));
5856 /* Make sure both operands are registers. */
5857 else if (GET_CODE (x) == PLUS)
5858 return gen_rtx_PLUS (Pmode,
5859 force_reg (Pmode, XEXP (x, 0)),
5860 force_reg (Pmode, XEXP (x, 1)));
5862 return force_reg (Pmode, x);
5864 if (GET_CODE (x) == SYMBOL_REF)
5866 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
5868 return rs6000_legitimize_tls_address (x, model);
5878 if (!TARGET_POWERPC64)
5886 extra = TARGET_POWERPC64 ? 8 : 12;
5892 if (GET_CODE (x) == PLUS
5893 && GET_CODE (XEXP (x, 0)) == REG
5894 && GET_CODE (XEXP (x, 1)) == CONST_INT
5895 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
5897 && !((TARGET_POWERPC64
5898 && (mode == DImode || mode == TImode)
5899 && (INTVAL (XEXP (x, 1)) & 3) != 0)
5900 || SPE_VECTOR_MODE (mode)
5901 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5902 || mode == DImode || mode == DDmode
5903 || mode == TDmode))))
5905 HOST_WIDE_INT high_int, low_int;
5907 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
5908 if (low_int >= 0x8000 - extra)
5910 high_int = INTVAL (XEXP (x, 1)) - low_int;
5911 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
5912 GEN_INT (high_int)), 0);
5913 return plus_constant (sum, low_int);
5915 else if (GET_CODE (x) == PLUS
5916 && GET_CODE (XEXP (x, 0)) == REG
5917 && GET_CODE (XEXP (x, 1)) != CONST_INT
5918 && GET_MODE_NUNITS (mode) == 1
5919 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5921 || ((mode != DImode && mode != DFmode && mode != DDmode)
5922 || (TARGET_E500_DOUBLE && mode != DDmode)))
5923 && (TARGET_POWERPC64 || mode != DImode)
5924 && !avoiding_indexed_address_p (mode)
5929 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
5930 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
5932 else if (SPE_VECTOR_MODE (mode)
5933 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
5934 || mode == DDmode || mode == TDmode
5935 || mode == DImode)))
5939 /* We accept [reg + reg] and [reg + OFFSET]. */
5941 if (GET_CODE (x) == PLUS)
5943 rtx op1 = XEXP (x, 0);
5944 rtx op2 = XEXP (x, 1);
5947 op1 = force_reg (Pmode, op1);
5949 if (GET_CODE (op2) != REG
5950 && (GET_CODE (op2) != CONST_INT
5951 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
5952 || (GET_MODE_SIZE (mode) > 8
5953 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
5954 op2 = force_reg (Pmode, op2);
5956 /* We can't always do [reg + reg] for these, because [reg +
5957 reg + offset] is not a legitimate addressing mode. */
5958 y = gen_rtx_PLUS (Pmode, op1, op2);
5960 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
5961 return force_reg (Pmode, y);
5966 return force_reg (Pmode, x);
5972 && GET_CODE (x) != CONST_INT
5973 && GET_CODE (x) != CONST_DOUBLE
5975 && GET_MODE_NUNITS (mode) == 1
5976 && (GET_MODE_BITSIZE (mode) <= 32
5977 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5978 && (mode == DFmode || mode == DDmode))))
5980 rtx reg = gen_reg_rtx (Pmode);
5981 emit_insn (gen_elf_high (reg, x));
5982 return gen_rtx_LO_SUM (Pmode, reg, x);
5984 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
5987 && ! MACHO_DYNAMIC_NO_PIC_P
5989 && GET_CODE (x) != CONST_INT
5990 && GET_CODE (x) != CONST_DOUBLE
5992 && GET_MODE_NUNITS (mode) == 1
5993 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
5994 || (mode != DFmode && mode != DDmode))
5998 rtx reg = gen_reg_rtx (Pmode);
5999 emit_insn (gen_macho_high (reg, x));
6000 return gen_rtx_LO_SUM (Pmode, reg, x);
6003 && GET_CODE (x) == SYMBOL_REF
6004 && constant_pool_expr_p (x)
6005 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6007 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6008 return create_TOC_reference (x, reg);
6014 /* Debug version of rs6000_legitimize_address. */
6016 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6022 ret = rs6000_legitimize_address (x, oldx, mode);
6023 insns = get_insns ();
6029 "\nrs6000_legitimize_address: mode %s, old code %s, "
6030 "new code %s, modified\n",
6031 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6032 GET_RTX_NAME (GET_CODE (ret)));
6034 fprintf (stderr, "Original address:\n");
6037 fprintf (stderr, "oldx:\n");
6040 fprintf (stderr, "New address:\n");
6045 fprintf (stderr, "Insns added:\n");
6046 debug_rtx_list (insns, 20);
6052 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6053 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6064 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6065 We need to emit DTP-relative relocations. */
6068 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6073 fputs ("\t.long\t", file);
6076 fputs (DOUBLE_INT_ASM_OP, file);
6081 output_addr_const (file, x);
6082 fputs ("@dtprel+0x8000", file);
6085 /* In the name of slightly smaller debug output, and to cater to
6086 general assembler lossage, recognize various UNSPEC sequences
6087 and turn them back into a direct symbol reference. */
6090 rs6000_delegitimize_address (rtx orig_x)
6094 orig_x = delegitimize_mem_from_attrs (orig_x);
6099 if ((GET_CODE (x) == PLUS
6100 || GET_CODE (x) == LO_SUM)
6101 && GET_CODE (XEXP (x, 0)) == REG
6102 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6103 || TARGET_MINIMAL_TOC
6104 || TARGET_CMODEL != CMODEL_SMALL)
6105 && GET_CODE (XEXP (x, 1)) == CONST)
6107 y = XEXP (XEXP (x, 1), 0);
6108 if (GET_CODE (y) == UNSPEC
6109 && XINT (y, 1) == UNSPEC_TOCREL)
6111 y = XVECEXP (y, 0, 0);
6112 if (!MEM_P (orig_x))
6115 return replace_equiv_address_nv (orig_x, y);
6120 && GET_CODE (orig_x) == LO_SUM
6121 && GET_CODE (XEXP (x, 1)) == CONST)
6123 y = XEXP (XEXP (x, 1), 0);
6124 if (GET_CODE (y) == UNSPEC
6125 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6126 return XVECEXP (y, 0, 0);
6132 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6134 static GTY(()) rtx rs6000_tls_symbol;
6136 rs6000_tls_get_addr (void)
6138 if (!rs6000_tls_symbol)
6139 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6141 return rs6000_tls_symbol;
6144 /* Construct the SYMBOL_REF for TLS GOT references. */
6146 static GTY(()) rtx rs6000_got_symbol;
6148 rs6000_got_sym (void)
6150 if (!rs6000_got_symbol)
6152 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6153 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6154 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6157 return rs6000_got_symbol;
6160 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6161 this (thread-local) address. */
6164 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6168 dest = gen_reg_rtx (Pmode);
6169 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6175 tlsreg = gen_rtx_REG (Pmode, 13);
6176 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6180 tlsreg = gen_rtx_REG (Pmode, 2);
6181 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6185 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6189 tmp = gen_reg_rtx (Pmode);
6192 tlsreg = gen_rtx_REG (Pmode, 13);
6193 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6197 tlsreg = gen_rtx_REG (Pmode, 2);
6198 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6202 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6204 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6209 rtx r3, got, tga, tmp1, tmp2, call_insn;
6211 /* We currently use relocations like @got@tlsgd for tls, which
6212 means the linker will handle allocation of tls entries, placing
6213 them in the .got section. So use a pointer to the .got section,
6214 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6215 or to secondary GOT sections used by 32-bit -fPIC. */
6217 got = gen_rtx_REG (Pmode, 2);
6221 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6224 rtx gsym = rs6000_got_sym ();
6225 got = gen_reg_rtx (Pmode);
6227 rs6000_emit_move (got, gsym, Pmode);
6232 tmp1 = gen_reg_rtx (Pmode);
6233 tmp2 = gen_reg_rtx (Pmode);
6234 mem = gen_const_mem (Pmode, tmp1);
6235 lab = gen_label_rtx ();
6236 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6237 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6238 emit_move_insn (tmp2, mem);
6239 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6240 set_unique_reg_note (last, REG_EQUAL, gsym);
6245 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6247 r3 = gen_rtx_REG (Pmode, 3);
6248 tga = rs6000_tls_get_addr ();
6249 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6251 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6252 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6253 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6254 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6255 else if (DEFAULT_ABI == ABI_V4)
6256 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6259 call_insn = last_call_insn ();
6260 PATTERN (call_insn) = insn;
6261 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6262 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6263 pic_offset_table_rtx);
6265 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6267 r3 = gen_rtx_REG (Pmode, 3);
6268 tga = rs6000_tls_get_addr ();
6269 tmp1 = gen_reg_rtx (Pmode);
6270 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6272 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6273 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6274 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6275 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6276 else if (DEFAULT_ABI == ABI_V4)
6277 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6280 call_insn = last_call_insn ();
6281 PATTERN (call_insn) = insn;
6282 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6283 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6284 pic_offset_table_rtx);
6286 if (rs6000_tls_size == 16)
6289 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6291 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6293 else if (rs6000_tls_size == 32)
6295 tmp2 = gen_reg_rtx (Pmode);
6297 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6299 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6302 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6304 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6308 tmp2 = gen_reg_rtx (Pmode);
6310 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6312 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6314 insn = gen_rtx_SET (Pmode, dest,
6315 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6321 /* IE, or 64-bit offset LE. */
6322 tmp2 = gen_reg_rtx (Pmode);
6324 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6326 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6329 insn = gen_tls_tls_64 (dest, tmp2, addr);
6331 insn = gen_tls_tls_32 (dest, tmp2, addr);
6339 /* Return 1 if X contains a thread-local symbol. */
6342 rs6000_tls_referenced_p (rtx x)
6344 if (! TARGET_HAVE_TLS)
6347 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6350 /* Return 1 if *X is a thread-local symbol. This is the same as
6351 rs6000_tls_symbol_ref except for the type of the unused argument. */
6354 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6356 return RS6000_SYMBOL_REF_TLS_P (*x);
6359 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6360 replace the input X, or the original X if no replacement is called for.
6361 The output parameter *WIN is 1 if the calling macro should goto WIN,
6364 For RS/6000, we wish to handle large displacements off a base
6365 register by splitting the addend across an addiu/addis and the mem insn.
6366 This cuts number of extra insns needed from 3 to 1.
6368 On Darwin, we use this to generate code for floating point constants.
6369 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6370 The Darwin code is inside #if TARGET_MACHO because only then are the
6371 machopic_* functions defined. */
6373 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6374 int opnum, int type,
6375 int ind_levels ATTRIBUTE_UNUSED, int *win)
6377 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6379 /* We must recognize output that we have already generated ourselves. */
6380 if (GET_CODE (x) == PLUS
6381 && GET_CODE (XEXP (x, 0)) == PLUS
6382 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6383 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6384 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6386 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6387 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6388 opnum, (enum reload_type)type);
6393 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6394 if (GET_CODE (x) == LO_SUM
6395 && GET_CODE (XEXP (x, 0)) == HIGH)
6397 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6398 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6399 opnum, (enum reload_type)type);
6405 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6406 && GET_CODE (x) == LO_SUM
6407 && GET_CODE (XEXP (x, 0)) == PLUS
6408 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6409 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6410 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6411 && machopic_operand_p (XEXP (x, 1)))
6413 /* Result of previous invocation of this function on Darwin
6414 floating point constant. */
6415 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6416 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6417 opnum, (enum reload_type)type);
6423 if (TARGET_CMODEL != CMODEL_SMALL
6424 && GET_CODE (x) == LO_SUM
6425 && GET_CODE (XEXP (x, 0)) == PLUS
6426 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6427 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6428 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6429 && GET_CODE (XEXP (x, 1)) == CONST
6430 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6431 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6432 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6434 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6435 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6436 opnum, (enum reload_type) type);
6441 /* Force ld/std non-word aligned offset into base register by wrapping
6443 if (GET_CODE (x) == PLUS
6444 && GET_CODE (XEXP (x, 0)) == REG
6445 && REGNO (XEXP (x, 0)) < 32
6446 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6447 && GET_CODE (XEXP (x, 1)) == CONST_INT
6449 && (INTVAL (XEXP (x, 1)) & 3) != 0
6450 && VECTOR_MEM_NONE_P (mode)
6451 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6452 && TARGET_POWERPC64)
6454 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6455 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6456 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6457 opnum, (enum reload_type) type);
6462 if (GET_CODE (x) == PLUS
6463 && GET_CODE (XEXP (x, 0)) == REG
6464 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6465 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6466 && GET_CODE (XEXP (x, 1)) == CONST_INT
6468 && !SPE_VECTOR_MODE (mode)
6469 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6470 || mode == DDmode || mode == TDmode
6472 && VECTOR_MEM_NONE_P (mode))
6474 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6475 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6477 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6479 /* Check for 32-bit overflow. */
6480 if (high + low != val)
6486 /* Reload the high part into a base reg; leave the low part
6487 in the mem directly. */
6489 x = gen_rtx_PLUS (GET_MODE (x),
6490 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6494 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6495 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6496 opnum, (enum reload_type)type);
6501 if (GET_CODE (x) == SYMBOL_REF
6503 && VECTOR_MEM_NONE_P (mode)
6504 && !SPE_VECTOR_MODE (mode)
6506 && DEFAULT_ABI == ABI_DARWIN
6507 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6509 && DEFAULT_ABI == ABI_V4
6512 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6513 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6517 && (mode != DImode || TARGET_POWERPC64)
6518 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6519 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6524 rtx offset = machopic_gen_offset (x);
6525 x = gen_rtx_LO_SUM (GET_MODE (x),
6526 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6527 gen_rtx_HIGH (Pmode, offset)), offset);
6531 x = gen_rtx_LO_SUM (GET_MODE (x),
6532 gen_rtx_HIGH (Pmode, x), x);
6534 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6535 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6536 opnum, (enum reload_type)type);
6541 /* Reload an offset address wrapped by an AND that represents the
6542 masking of the lower bits. Strip the outer AND and let reload
6543 convert the offset address into an indirect address. For VSX,
6544 force reload to create the address with an AND in a separate
6545 register, because we can't guarantee an altivec register will
6547 if (VECTOR_MEM_ALTIVEC_P (mode)
6548 && GET_CODE (x) == AND
6549 && GET_CODE (XEXP (x, 0)) == PLUS
6550 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6551 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6552 && GET_CODE (XEXP (x, 1)) == CONST_INT
6553 && INTVAL (XEXP (x, 1)) == -16)
6562 && GET_CODE (x) == SYMBOL_REF
6563 && constant_pool_expr_p (x)
6564 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6566 x = create_TOC_reference (x, NULL_RTX);
6567 if (TARGET_CMODEL != CMODEL_SMALL)
6568 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6569 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6570 opnum, (enum reload_type) type);
6578 /* Debug version of rs6000_legitimize_reload_address. */
6580 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6581 int opnum, int type,
6582 int ind_levels, int *win)
6584 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6587 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6588 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6589 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6593 fprintf (stderr, "Same address returned\n");
6595 fprintf (stderr, "NULL returned\n");
6598 fprintf (stderr, "New address:\n");
6605 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6606 that is a valid memory address for an instruction.
6607 The MODE argument is the machine mode for the MEM expression
6608 that wants to use this address.
6610 On the RS/6000, there are four valid address: a SYMBOL_REF that
6611 refers to a constant pool entry of an address (or the sum of it
6612 plus a constant), a short (16-bit signed) constant plus a register,
6613 the sum of two registers, or a register indirect, possibly with an
6614 auto-increment. For DFmode, DDmode and DImode with a constant plus
6615 register, we must ensure that both words are addressable or PowerPC64
6616 with offset word aligned.
6618 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6619 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6620 because adjacent memory cells are accessed by adding word-sized offsets
6621 during assembly output. */
6623 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6625 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6627 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6628 if (VECTOR_MEM_ALTIVEC_P (mode)
6629 && GET_CODE (x) == AND
6630 && GET_CODE (XEXP (x, 1)) == CONST_INT
6631 && INTVAL (XEXP (x, 1)) == -16)
6634 if (RS6000_SYMBOL_REF_TLS_P (x))
6636 if (legitimate_indirect_address_p (x, reg_ok_strict))
6638 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6639 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6640 && !SPE_VECTOR_MODE (mode)
6643 /* Restrict addressing for DI because of our SUBREG hackery. */
6644 && !(TARGET_E500_DOUBLE
6645 && (mode == DFmode || mode == DDmode || mode == DImode))
6647 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6649 if (virtual_stack_registers_memory_p (x))
6651 if (reg_offset_p && legitimate_small_data_p (mode, x))
6653 if (reg_offset_p && legitimate_constant_pool_address_p (x, reg_ok_strict))
6655 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6658 && GET_CODE (x) == PLUS
6659 && GET_CODE (XEXP (x, 0)) == REG
6660 && (XEXP (x, 0) == virtual_stack_vars_rtx
6661 || XEXP (x, 0) == arg_pointer_rtx)
6662 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6664 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6669 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6671 || (mode != DFmode && mode != DDmode)
6672 || (TARGET_E500_DOUBLE && mode != DDmode))
6673 && (TARGET_POWERPC64 || mode != DImode)
6674 && !avoiding_indexed_address_p (mode)
6675 && legitimate_indexed_address_p (x, reg_ok_strict))
6677 if (GET_CODE (x) == PRE_MODIFY
6681 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6683 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6684 && (TARGET_POWERPC64 || mode != DImode)
6685 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6686 && !SPE_VECTOR_MODE (mode)
6687 /* Restrict addressing for DI because of our SUBREG hackery. */
6688 && !(TARGET_E500_DOUBLE
6689 && (mode == DFmode || mode == DDmode || mode == DImode))
6691 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6692 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6693 || (!avoiding_indexed_address_p (mode)
6694 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6695 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6697 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6702 /* Debug version of rs6000_legitimate_address_p. */
6704 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6707 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6709 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6710 "strict = %d, code = %s\n",
6711 ret ? "true" : "false",
6712 GET_MODE_NAME (mode),
6714 GET_RTX_NAME (GET_CODE (x)));
6720 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
6723 rs6000_mode_dependent_address_p (const_rtx addr)
6725 return rs6000_mode_dependent_address_ptr (addr);
6728 /* Go to LABEL if ADDR (a legitimate address expression)
6729 has an effect that depends on the machine mode it is used for.
6731 On the RS/6000 this is true of all integral offsets (since AltiVec
6732 and VSX modes don't allow them) or is a pre-increment or decrement.
6734 ??? Except that due to conceptual problems in offsettable_address_p
6735 we can't really report the problems of integral offsets. So leave
6736 this assuming that the adjustable offset must be valid for the
6737 sub-words of a TFmode operand, which is what we had before. */
6740 rs6000_mode_dependent_address (const_rtx addr)
6742 switch (GET_CODE (addr))
6745 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
6746 is considered a legitimate address before reload, so there
6747 are no offset restrictions in that case. Note that this
6748 condition is safe in strict mode because any address involving
6749 virtual_stack_vars_rtx or arg_pointer_rtx would already have
6750 been rejected as illegitimate. */
6751 if (XEXP (addr, 0) != virtual_stack_vars_rtx
6752 && XEXP (addr, 0) != arg_pointer_rtx
6753 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
6755 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
6756 return val + 12 + 0x8000 >= 0x10000;
6761 /* Anything in the constant pool is sufficiently aligned that
6762 all bytes have the same high part address. */
6763 return !legitimate_constant_pool_address_p (addr, false);
6765 /* Auto-increment cases are now treated generically in recog.c. */
6767 return TARGET_UPDATE;
6769 /* AND is only allowed in Altivec loads. */
6780 /* Debug version of rs6000_mode_dependent_address. */
6782 rs6000_debug_mode_dependent_address (const_rtx addr)
6784 bool ret = rs6000_mode_dependent_address (addr);
6786 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
6787 ret ? "true" : "false");
6793 /* Implement FIND_BASE_TERM. */
6796 rs6000_find_base_term (rtx op)
6800 split_const (op, &base, &offset);
6801 if (GET_CODE (base) == UNSPEC)
6802 switch (XINT (base, 1))
6805 case UNSPEC_MACHOPIC_OFFSET:
6806 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
6807 for aliasing purposes. */
6808 return XVECEXP (base, 0, 0);
6814 /* More elaborate version of recog's offsettable_memref_p predicate
6815 that works around the ??? note of rs6000_mode_dependent_address.
6816 In particular it accepts
6818 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
6820 in 32-bit mode, that the recog predicate rejects. */
6823 rs6000_offsettable_memref_p (rtx op)
6828 /* First mimic offsettable_memref_p. */
6829 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
6832 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
6833 the latter predicate knows nothing about the mode of the memory
6834 reference and, therefore, assumes that it is the largest supported
6835 mode (TFmode). As a consequence, legitimate offsettable memory
6836 references are rejected. rs6000_legitimate_offset_address_p contains
6837 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
6838 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
6841 /* Change register usage conditional on target flags. */
6843 rs6000_conditional_register_usage (void)
6847 /* Set MQ register fixed (already call_used) if not POWER
6848 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
6853 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
6855 fixed_regs[13] = call_used_regs[13]
6856 = call_really_used_regs[13] = 1;
6858 /* Conditionally disable FPRs. */
6859 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
6860 for (i = 32; i < 64; i++)
6861 fixed_regs[i] = call_used_regs[i]
6862 = call_really_used_regs[i] = 1;
6864 /* The TOC register is not killed across calls in a way that is
6865 visible to the compiler. */
6866 if (DEFAULT_ABI == ABI_AIX)
6867 call_really_used_regs[2] = 0;
6869 if (DEFAULT_ABI == ABI_V4
6870 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6872 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6874 if (DEFAULT_ABI == ABI_V4
6875 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
6877 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6878 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6879 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6881 if (DEFAULT_ABI == ABI_DARWIN
6882 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6883 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6884 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6885 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6887 if (TARGET_TOC && TARGET_MINIMAL_TOC)
6888 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
6889 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
6893 global_regs[SPEFSCR_REGNO] = 1;
6894 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
6895 registers in prologues and epilogues. We no longer use r14
6896 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
6897 pool for link-compatibility with older versions of GCC. Once
6898 "old" code has died out, we can return r14 to the allocation
6901 = call_used_regs[14]
6902 = call_really_used_regs[14] = 1;
6905 if (!TARGET_ALTIVEC && !TARGET_VSX)
6907 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6908 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6909 call_really_used_regs[VRSAVE_REGNO] = 1;
6912 if (TARGET_ALTIVEC || TARGET_VSX)
6913 global_regs[VSCR_REGNO] = 1;
6915 if (TARGET_ALTIVEC_ABI)
6917 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
6918 call_used_regs[i] = call_really_used_regs[i] = 1;
6920 /* AIX reserves VR20:31 in non-extended ABI mode. */
6922 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
6923 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
6927 /* Try to output insns to set TARGET equal to the constant C if it can
6928 be done in less than N insns. Do all computations in MODE.
6929 Returns the place where the output has been placed if it can be
6930 done and the insns have been emitted. If it would take more than N
6931 insns, zero is returned and no insns and emitted. */
6934 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
6935 rtx source, int n ATTRIBUTE_UNUSED)
6937 rtx result, insn, set;
6938 HOST_WIDE_INT c0, c1;
6945 dest = gen_reg_rtx (mode);
6946 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
6950 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
6952 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
6953 GEN_INT (INTVAL (source)
6954 & (~ (HOST_WIDE_INT) 0xffff))));
6955 emit_insn (gen_rtx_SET (VOIDmode, dest,
6956 gen_rtx_IOR (SImode, copy_rtx (result),
6957 GEN_INT (INTVAL (source) & 0xffff))));
6962 switch (GET_CODE (source))
6965 c0 = INTVAL (source);
6970 #if HOST_BITS_PER_WIDE_INT >= 64
6971 c0 = CONST_DOUBLE_LOW (source);
6974 c0 = CONST_DOUBLE_LOW (source);
6975 c1 = CONST_DOUBLE_HIGH (source);
6983 result = rs6000_emit_set_long_const (dest, c0, c1);
6990 insn = get_last_insn ();
6991 set = single_set (insn);
6992 if (! CONSTANT_P (SET_SRC (set)))
6993 set_unique_reg_note (insn, REG_EQUAL, source);
6998 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
6999 fall back to a straight forward decomposition. We do this to avoid
7000 exponential run times encountered when looking for longer sequences
7001 with rs6000_emit_set_const. */
7003 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7005 if (!TARGET_POWERPC64)
7007 rtx operand1, operand2;
7009 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7011 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7013 emit_move_insn (operand1, GEN_INT (c1));
7014 emit_move_insn (operand2, GEN_INT (c2));
7018 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7021 ud2 = (c1 & 0xffff0000) >> 16;
7022 #if HOST_BITS_PER_WIDE_INT >= 64
7026 ud4 = (c2 & 0xffff0000) >> 16;
7028 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7029 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7032 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7034 emit_move_insn (dest, GEN_INT (ud1));
7037 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7038 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7041 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7044 emit_move_insn (dest, GEN_INT (ud2 << 16));
7046 emit_move_insn (copy_rtx (dest),
7047 gen_rtx_IOR (DImode, copy_rtx (dest),
7050 else if (ud3 == 0 && ud4 == 0)
7052 gcc_assert (ud2 & 0x8000);
7053 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7056 emit_move_insn (copy_rtx (dest),
7057 gen_rtx_IOR (DImode, copy_rtx (dest),
7059 emit_move_insn (copy_rtx (dest),
7060 gen_rtx_ZERO_EXTEND (DImode,
7061 gen_lowpart (SImode,
7064 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7065 || (ud4 == 0 && ! (ud3 & 0x8000)))
7068 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7071 emit_move_insn (dest, GEN_INT (ud3 << 16));
7074 emit_move_insn (copy_rtx (dest),
7075 gen_rtx_IOR (DImode, copy_rtx (dest),
7077 emit_move_insn (copy_rtx (dest),
7078 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7081 emit_move_insn (copy_rtx (dest),
7082 gen_rtx_IOR (DImode, copy_rtx (dest),
7088 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7091 emit_move_insn (dest, GEN_INT (ud4 << 16));
7094 emit_move_insn (copy_rtx (dest),
7095 gen_rtx_IOR (DImode, copy_rtx (dest),
7098 emit_move_insn (copy_rtx (dest),
7099 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7102 emit_move_insn (copy_rtx (dest),
7103 gen_rtx_IOR (DImode, copy_rtx (dest),
7104 GEN_INT (ud2 << 16)));
7106 emit_move_insn (copy_rtx (dest),
7107 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7113 /* Helper for the following. Get rid of [r+r] memory refs
7114 in cases where it won't work (TImode, TFmode, TDmode). */
7117 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7119 if (reload_in_progress)
7122 if (GET_CODE (operands[0]) == MEM
7123 && GET_CODE (XEXP (operands[0], 0)) != REG
7124 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0), false))
7126 = replace_equiv_address (operands[0],
7127 copy_addr_to_reg (XEXP (operands[0], 0)));
7129 if (GET_CODE (operands[1]) == MEM
7130 && GET_CODE (XEXP (operands[1], 0)) != REG
7131 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0), false))
7133 = replace_equiv_address (operands[1],
7134 copy_addr_to_reg (XEXP (operands[1], 0)));
7137 /* Return true if memory accesses to DECL are known to never straddle
7141 offsettable_ok_by_alignment (tree decl)
7143 unsigned HOST_WIDE_INT dsize, dalign;
7145 /* Presume any compiler generated symbol_ref is suitably aligned. */
7149 if (TREE_CODE (decl) != VAR_DECL
7150 && TREE_CODE (decl) != PARM_DECL
7151 && TREE_CODE (decl) != RESULT_DECL
7152 && TREE_CODE (decl) != FIELD_DECL)
7155 if (!DECL_SIZE_UNIT (decl))
7158 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
7161 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
7167 dalign = DECL_ALIGN_UNIT (decl);
7168 return dalign >= dsize;
7171 /* Emit a move from SOURCE to DEST in mode MODE. */
7173 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7177 operands[1] = source;
7179 if (TARGET_DEBUG_ADDR)
7182 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7183 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7184 GET_MODE_NAME (mode),
7187 can_create_pseudo_p ());
7189 fprintf (stderr, "source:\n");
7193 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7194 if (GET_CODE (operands[1]) == CONST_DOUBLE
7195 && ! FLOAT_MODE_P (mode)
7196 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7198 /* FIXME. This should never happen. */
7199 /* Since it seems that it does, do the safe thing and convert
7201 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7203 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7204 || FLOAT_MODE_P (mode)
7205 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7206 || CONST_DOUBLE_LOW (operands[1]) < 0)
7207 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7208 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7210 /* Check if GCC is setting up a block move that will end up using FP
7211 registers as temporaries. We must make sure this is acceptable. */
7212 if (GET_CODE (operands[0]) == MEM
7213 && GET_CODE (operands[1]) == MEM
7215 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7216 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7217 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7218 ? 32 : MEM_ALIGN (operands[0])))
7219 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7221 : MEM_ALIGN (operands[1]))))
7222 && ! MEM_VOLATILE_P (operands [0])
7223 && ! MEM_VOLATILE_P (operands [1]))
7225 emit_move_insn (adjust_address (operands[0], SImode, 0),
7226 adjust_address (operands[1], SImode, 0));
7227 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7228 adjust_address (copy_rtx (operands[1]), SImode, 4));
7232 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7233 && !gpc_reg_operand (operands[1], mode))
7234 operands[1] = force_reg (mode, operands[1]);
7236 if (mode == SFmode && ! TARGET_POWERPC
7237 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7238 && GET_CODE (operands[0]) == MEM)
7242 if (reload_in_progress || reload_completed)
7243 regnum = true_regnum (operands[1]);
7244 else if (GET_CODE (operands[1]) == REG)
7245 regnum = REGNO (operands[1]);
7249 /* If operands[1] is a register, on POWER it may have
7250 double-precision data in it, so truncate it to single
7252 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7255 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7256 : gen_reg_rtx (mode));
7257 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7258 operands[1] = newreg;
7262 /* Recognize the case where operand[1] is a reference to thread-local
7263 data and load its address to a register. */
7264 if (rs6000_tls_referenced_p (operands[1]))
7266 enum tls_model model;
7267 rtx tmp = operands[1];
7270 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7272 addend = XEXP (XEXP (tmp, 0), 1);
7273 tmp = XEXP (XEXP (tmp, 0), 0);
7276 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7277 model = SYMBOL_REF_TLS_MODEL (tmp);
7278 gcc_assert (model != 0);
7280 tmp = rs6000_legitimize_tls_address (tmp, model);
7283 tmp = gen_rtx_PLUS (mode, tmp, addend);
7284 tmp = force_operand (tmp, operands[0]);
7289 /* Handle the case where reload calls us with an invalid address. */
7290 if (reload_in_progress && mode == Pmode
7291 && (! general_operand (operands[1], mode)
7292 || ! nonimmediate_operand (operands[0], mode)))
7295 /* 128-bit constant floating-point values on Darwin should really be
7296 loaded as two parts. */
7297 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7298 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7300 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7301 know how to get a DFmode SUBREG of a TFmode. */
7302 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7303 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7304 simplify_gen_subreg (imode, operands[1], mode, 0),
7306 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7307 GET_MODE_SIZE (imode)),
7308 simplify_gen_subreg (imode, operands[1], mode,
7309 GET_MODE_SIZE (imode)),
7314 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7315 cfun->machine->sdmode_stack_slot =
7316 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7318 if (reload_in_progress
7320 && MEM_P (operands[0])
7321 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7322 && REG_P (operands[1]))
7324 if (FP_REGNO_P (REGNO (operands[1])))
7326 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7327 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7328 emit_insn (gen_movsd_store (mem, operands[1]));
7330 else if (INT_REGNO_P (REGNO (operands[1])))
7332 rtx mem = adjust_address_nv (operands[0], mode, 4);
7333 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7334 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7340 if (reload_in_progress
7342 && REG_P (operands[0])
7343 && MEM_P (operands[1])
7344 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7346 if (FP_REGNO_P (REGNO (operands[0])))
7348 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7349 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7350 emit_insn (gen_movsd_load (operands[0], mem));
7352 else if (INT_REGNO_P (REGNO (operands[0])))
7354 rtx mem = adjust_address_nv (operands[1], mode, 4);
7355 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7356 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7363 /* FIXME: In the long term, this switch statement should go away
7364 and be replaced by a sequence of tests based on things like
7370 if (CONSTANT_P (operands[1])
7371 && GET_CODE (operands[1]) != CONST_INT)
7372 operands[1] = force_const_mem (mode, operands[1]);
7377 rs6000_eliminate_indexed_memrefs (operands);
7384 if (CONSTANT_P (operands[1])
7385 && ! easy_fp_constant (operands[1], mode))
7386 operands[1] = force_const_mem (mode, operands[1]);
7399 if (CONSTANT_P (operands[1])
7400 && !easy_vector_constant (operands[1], mode))
7401 operands[1] = force_const_mem (mode, operands[1]);
7406 /* Use default pattern for address of ELF small data */
7409 && DEFAULT_ABI == ABI_V4
7410 && (GET_CODE (operands[1]) == SYMBOL_REF
7411 || GET_CODE (operands[1]) == CONST)
7412 && small_data_operand (operands[1], mode))
7414 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7418 if (DEFAULT_ABI == ABI_V4
7419 && mode == Pmode && mode == SImode
7420 && flag_pic == 1 && got_operand (operands[1], mode))
7422 emit_insn (gen_movsi_got (operands[0], operands[1]));
7426 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7430 && CONSTANT_P (operands[1])
7431 && GET_CODE (operands[1]) != HIGH
7432 && GET_CODE (operands[1]) != CONST_INT)
7434 rtx target = (!can_create_pseudo_p ()
7436 : gen_reg_rtx (mode));
7438 /* If this is a function address on -mcall-aixdesc,
7439 convert it to the address of the descriptor. */
7440 if (DEFAULT_ABI == ABI_AIX
7441 && GET_CODE (operands[1]) == SYMBOL_REF
7442 && XSTR (operands[1], 0)[0] == '.')
7444 const char *name = XSTR (operands[1], 0);
7446 while (*name == '.')
7448 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7449 CONSTANT_POOL_ADDRESS_P (new_ref)
7450 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7451 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7452 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7453 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7454 operands[1] = new_ref;
7457 if (DEFAULT_ABI == ABI_DARWIN)
7460 if (MACHO_DYNAMIC_NO_PIC_P)
7462 /* Take care of any required data indirection. */
7463 operands[1] = rs6000_machopic_legitimize_pic_address (
7464 operands[1], mode, operands[0]);
7465 if (operands[0] != operands[1])
7466 emit_insn (gen_rtx_SET (VOIDmode,
7467 operands[0], operands[1]));
7471 emit_insn (gen_macho_high (target, operands[1]));
7472 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7476 emit_insn (gen_elf_high (target, operands[1]));
7477 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7481 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7482 and we have put it in the TOC, we just need to make a TOC-relative
7485 && GET_CODE (operands[1]) == SYMBOL_REF
7486 && constant_pool_expr_p (operands[1])
7487 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7488 get_pool_mode (operands[1])))
7489 || (TARGET_CMODEL == CMODEL_MEDIUM
7490 && GET_CODE (operands[1]) == SYMBOL_REF
7491 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7492 && SYMBOL_REF_LOCAL_P (operands[1])
7493 && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
7496 if (TARGET_CMODEL != CMODEL_SMALL)
7498 if (can_create_pseudo_p ())
7499 reg = gen_reg_rtx (Pmode);
7503 operands[1] = create_TOC_reference (operands[1], reg);
7505 else if (mode == Pmode
7506 && CONSTANT_P (operands[1])
7507 && ((GET_CODE (operands[1]) != CONST_INT
7508 && ! easy_fp_constant (operands[1], mode))
7509 || (GET_CODE (operands[1]) == CONST_INT
7510 && (num_insns_constant (operands[1], mode)
7511 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7512 || (GET_CODE (operands[0]) == REG
7513 && FP_REGNO_P (REGNO (operands[0]))))
7514 && GET_CODE (operands[1]) != HIGH
7515 && ! legitimate_constant_pool_address_p (operands[1], false)
7516 && ! toc_relative_expr_p (operands[1])
7517 && (TARGET_CMODEL == CMODEL_SMALL
7518 || can_create_pseudo_p ()
7519 || (REG_P (operands[0])
7520 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7524 /* Darwin uses a special PIC legitimizer. */
7525 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7528 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7530 if (operands[0] != operands[1])
7531 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7536 /* If we are to limit the number of things we put in the TOC and
7537 this is a symbol plus a constant we can add in one insn,
7538 just put the symbol in the TOC and add the constant. Don't do
7539 this if reload is in progress. */
7540 if (GET_CODE (operands[1]) == CONST
7541 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7542 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7543 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7544 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7545 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7546 && ! side_effects_p (operands[0]))
7549 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7550 rtx other = XEXP (XEXP (operands[1], 0), 1);
7552 sym = force_reg (mode, sym);
7553 emit_insn (gen_add3_insn (operands[0], sym, other));
7557 operands[1] = force_const_mem (mode, operands[1]);
7560 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7561 && constant_pool_expr_p (XEXP (operands[1], 0))
7562 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7563 get_pool_constant (XEXP (operands[1], 0)),
7564 get_pool_mode (XEXP (operands[1], 0))))
7568 if (TARGET_CMODEL != CMODEL_SMALL)
7570 if (can_create_pseudo_p ())
7571 reg = gen_reg_rtx (Pmode);
7575 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7576 operands[1] = gen_const_mem (mode, tocref);
7577 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7583 rs6000_eliminate_indexed_memrefs (operands);
7587 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7589 gen_rtx_SET (VOIDmode,
7590 operands[0], operands[1]),
7591 gen_rtx_CLOBBER (VOIDmode,
7592 gen_rtx_SCRATCH (SImode)))));
7598 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7601 /* Above, we may have called force_const_mem which may have returned
7602 an invalid address. If we can, fix this up; otherwise, reload will
7603 have to deal with it. */
7604 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7605 operands[1] = validize_mem (operands[1]);
7608 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7611 /* Nonzero if we can use a floating-point register to pass this arg. */
7612 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7613 (SCALAR_FLOAT_MODE_P (MODE) \
7614 && (CUM)->fregno <= FP_ARG_MAX_REG \
7615 && TARGET_HARD_FLOAT && TARGET_FPRS)
7617 /* Nonzero if we can use an AltiVec register to pass this arg. */
7618 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7619 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7620 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7621 && TARGET_ALTIVEC_ABI \
7624 /* Return a nonzero value to say to return the function value in
7625 memory, just as large structures are always returned. TYPE will be
7626 the data type of the value, and FNTYPE will be the type of the
7627 function doing the returning, or @code{NULL} for libcalls.
7629 The AIX ABI for the RS/6000 specifies that all structures are
7630 returned in memory. The Darwin ABI does the same.
7632 For the Darwin 64 Bit ABI, a function result can be returned in
7633 registers or in memory, depending on the size of the return data
7634 type. If it is returned in registers, the value occupies the same
7635 registers as it would if it were the first and only function
7636 argument. Otherwise, the function places its result in memory at
7637 the location pointed to by GPR3.
7639 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7640 but a draft put them in memory, and GCC used to implement the draft
7641 instead of the final standard. Therefore, aix_struct_return
7642 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7643 compatibility can change DRAFT_V4_STRUCT_RET to override the
7644 default, and -m switches get the final word. See
7645 rs6000_option_override_internal for more details.
7647 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7648 long double support is enabled. These values are returned in memory.
7650 int_size_in_bytes returns -1 for variable size objects, which go in
7651 memory always. The cast to unsigned makes -1 > 8. */
7654 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7656 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7658 && rs6000_darwin64_abi
7659 && TREE_CODE (type) == RECORD_TYPE
7660 && int_size_in_bytes (type) > 0)
7662 CUMULATIVE_ARGS valcum;
7666 valcum.fregno = FP_ARG_MIN_REG;
7667 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7668 /* Do a trial code generation as if this were going to be passed
7669 as an argument; if any part goes in memory, we return NULL. */
7670 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7673 /* Otherwise fall through to more conventional ABI rules. */
7676 if (AGGREGATE_TYPE_P (type)
7677 && (aix_struct_return
7678 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7681 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7682 modes only exist for GCC vector types if -maltivec. */
7683 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7684 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7687 /* Return synthetic vectors in memory. */
7688 if (TREE_CODE (type) == VECTOR_TYPE
7689 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7691 static bool warned_for_return_big_vectors = false;
7692 if (!warned_for_return_big_vectors)
7694 warning (0, "GCC vector returned by reference: "
7695 "non-standard ABI extension with no compatibility guarantee");
7696 warned_for_return_big_vectors = true;
7701 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7707 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7708 for a call to a function whose data type is FNTYPE.
7709 For a library call, FNTYPE is 0.
7711 For incoming args we set the number of arguments in the prototype large
7712 so we never return a PARALLEL. */
7715 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7716 rtx libname ATTRIBUTE_UNUSED, int incoming,
7717 int libcall, int n_named_args)
7719 static CUMULATIVE_ARGS zero_cumulative;
7721 *cum = zero_cumulative;
7723 cum->fregno = FP_ARG_MIN_REG;
7724 cum->vregno = ALTIVEC_ARG_MIN_REG;
7725 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7726 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
7727 ? CALL_LIBCALL : CALL_NORMAL);
7728 cum->sysv_gregno = GP_ARG_MIN_REG;
7729 cum->stdarg = stdarg_p (fntype);
7731 cum->nargs_prototype = 0;
7732 if (incoming || cum->prototype)
7733 cum->nargs_prototype = n_named_args;
7735 /* Check for a longcall attribute. */
7736 if ((!fntype && rs6000_default_long_calls)
7738 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
7739 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
7740 cum->call_cookie |= CALL_LONG;
7742 if (TARGET_DEBUG_ARG)
7744 fprintf (stderr, "\ninit_cumulative_args:");
7747 tree ret_type = TREE_TYPE (fntype);
7748 fprintf (stderr, " ret code = %s,",
7749 tree_code_name[ (int)TREE_CODE (ret_type) ]);
7752 if (cum->call_cookie & CALL_LONG)
7753 fprintf (stderr, " longcall,");
7755 fprintf (stderr, " proto = %d, nargs = %d\n",
7756 cum->prototype, cum->nargs_prototype);
7761 && TARGET_ALTIVEC_ABI
7762 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
7764 error ("cannot return value in vector register because"
7765 " altivec instructions are disabled, use -maltivec"
7770 /* Return true if TYPE must be passed on the stack and not in registers. */
7773 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
7775 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
7776 return must_pass_in_stack_var_size (mode, type);
7778 return must_pass_in_stack_var_size_or_pad (mode, type);
7781 /* If defined, a C expression which determines whether, and in which
7782 direction, to pad out an argument with extra space. The value
7783 should be of type `enum direction': either `upward' to pad above
7784 the argument, `downward' to pad below, or `none' to inhibit
7787 For the AIX ABI structs are always stored left shifted in their
7791 function_arg_padding (enum machine_mode mode, const_tree type)
7793 #ifndef AGGREGATE_PADDING_FIXED
7794 #define AGGREGATE_PADDING_FIXED 0
7796 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
7797 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
7800 if (!AGGREGATE_PADDING_FIXED)
7802 /* GCC used to pass structures of the same size as integer types as
7803 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
7804 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
7805 passed padded downward, except that -mstrict-align further
7806 muddied the water in that multi-component structures of 2 and 4
7807 bytes in size were passed padded upward.
7809 The following arranges for best compatibility with previous
7810 versions of gcc, but removes the -mstrict-align dependency. */
7811 if (BYTES_BIG_ENDIAN)
7813 HOST_WIDE_INT size = 0;
7815 if (mode == BLKmode)
7817 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
7818 size = int_size_in_bytes (type);
7821 size = GET_MODE_SIZE (mode);
7823 if (size == 1 || size == 2 || size == 4)
7829 if (AGGREGATES_PAD_UPWARD_ALWAYS)
7831 if (type != 0 && AGGREGATE_TYPE_P (type))
7835 /* Fall back to the default. */
7836 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
7839 /* If defined, a C expression that gives the alignment boundary, in bits,
7840 of an argument with the specified mode and type. If it is not defined,
7841 PARM_BOUNDARY is used for all arguments.
7843 V.4 wants long longs and doubles to be double word aligned. Just
7844 testing the mode size is a boneheaded way to do this as it means
7845 that other types such as complex int are also double word aligned.
7846 However, we're stuck with this because changing the ABI might break
7847 existing library interfaces.
7849 Doubleword align SPE vectors.
7850 Quadword align Altivec vectors.
7851 Quadword align large synthetic vector types. */
7854 function_arg_boundary (enum machine_mode mode, const_tree type)
7856 if (DEFAULT_ABI == ABI_V4
7857 && (GET_MODE_SIZE (mode) == 8
7858 || (TARGET_HARD_FLOAT
7860 && (mode == TFmode || mode == TDmode))))
7862 else if (SPE_VECTOR_MODE (mode)
7863 || (type && TREE_CODE (type) == VECTOR_TYPE
7864 && int_size_in_bytes (type) >= 8
7865 && int_size_in_bytes (type) < 16))
7867 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
7868 || (type && TREE_CODE (type) == VECTOR_TYPE
7869 && int_size_in_bytes (type) >= 16))
7871 else if (TARGET_MACHO
7872 && rs6000_darwin64_abi
7874 && type && TYPE_ALIGN (type) > 64)
7877 return PARM_BOUNDARY;
7880 /* For a function parm of MODE and TYPE, return the starting word in
7881 the parameter area. NWORDS of the parameter area are already used. */
7884 rs6000_parm_start (enum machine_mode mode, const_tree type,
7885 unsigned int nwords)
7888 unsigned int parm_offset;
7890 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
7891 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
7892 return nwords + (-(parm_offset + nwords) & align);
7895 /* Compute the size (in words) of a function argument. */
7897 static unsigned long
7898 rs6000_arg_size (enum machine_mode mode, const_tree type)
7902 if (mode != BLKmode)
7903 size = GET_MODE_SIZE (mode);
7905 size = int_size_in_bytes (type);
7908 return (size + 3) >> 2;
7910 return (size + 7) >> 3;
7913 /* Use this to flush pending int fields. */
7916 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
7917 HOST_WIDE_INT bitpos, int final)
7919 unsigned int startbit, endbit;
7920 int intregs, intoffset;
7921 enum machine_mode mode;
7923 /* Handle the situations where a float is taking up the first half
7924 of the GPR, and the other half is empty (typically due to
7925 alignment restrictions). We can detect this by a 8-byte-aligned
7926 int field, or by seeing that this is the final flush for this
7927 argument. Count the word and continue on. */
7928 if (cum->floats_in_gpr == 1
7929 && (cum->intoffset % 64 == 0
7930 || (cum->intoffset == -1 && final)))
7933 cum->floats_in_gpr = 0;
7936 if (cum->intoffset == -1)
7939 intoffset = cum->intoffset;
7940 cum->intoffset = -1;
7941 cum->floats_in_gpr = 0;
7943 if (intoffset % BITS_PER_WORD != 0)
7945 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
7947 if (mode == BLKmode)
7949 /* We couldn't find an appropriate mode, which happens,
7950 e.g., in packed structs when there are 3 bytes to load.
7951 Back intoffset back to the beginning of the word in this
7953 intoffset = intoffset & -BITS_PER_WORD;
7957 startbit = intoffset & -BITS_PER_WORD;
7958 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
7959 intregs = (endbit - startbit) / BITS_PER_WORD;
7960 cum->words += intregs;
7961 /* words should be unsigned. */
7962 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
7964 int pad = (endbit/BITS_PER_WORD) - cum->words;
7969 /* The darwin64 ABI calls for us to recurse down through structs,
7970 looking for elements passed in registers. Unfortunately, we have
7971 to track int register count here also because of misalignments
7972 in powerpc alignment mode. */
7975 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
7977 HOST_WIDE_INT startbitpos)
7981 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7982 if (TREE_CODE (f) == FIELD_DECL)
7984 HOST_WIDE_INT bitpos = startbitpos;
7985 tree ftype = TREE_TYPE (f);
7986 enum machine_mode mode;
7987 if (ftype == error_mark_node)
7989 mode = TYPE_MODE (ftype);
7991 if (DECL_SIZE (f) != 0
7992 && host_integerp (bit_position (f), 1))
7993 bitpos += int_bit_position (f);
7995 /* ??? FIXME: else assume zero offset. */
7997 if (TREE_CODE (ftype) == RECORD_TYPE)
7998 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
7999 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8001 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8002 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8003 /* Single-precision floats present a special problem for
8004 us, because they are smaller than an 8-byte GPR, and so
8005 the structure-packing rules combined with the standard
8006 varargs behavior mean that we want to pack float/float
8007 and float/int combinations into a single register's
8008 space. This is complicated by the arg advance flushing,
8009 which works on arbitrarily large groups of int-type
8013 if (cum->floats_in_gpr == 1)
8015 /* Two floats in a word; count the word and reset
8018 cum->floats_in_gpr = 0;
8020 else if (bitpos % 64 == 0)
8022 /* A float at the beginning of an 8-byte word;
8023 count it and put off adjusting cum->words until
8024 we see if a arg advance flush is going to do it
8026 cum->floats_in_gpr++;
8030 /* The float is at the end of a word, preceded
8031 by integer fields, so the arg advance flush
8032 just above has already set cum->words and
8033 everything is taken care of. */
8037 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
8039 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8041 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8045 else if (cum->intoffset == -1)
8046 cum->intoffset = bitpos;
8050 /* Check for an item that needs to be considered specially under the darwin 64
8051 bit ABI. These are record types where the mode is BLK or the structure is
8054 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8056 return rs6000_darwin64_abi
8057 && ((mode == BLKmode
8058 && TREE_CODE (type) == RECORD_TYPE
8059 && int_size_in_bytes (type) > 0)
8060 || (type && TREE_CODE (type) == RECORD_TYPE
8061 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8064 /* Update the data in CUM to advance over an argument
8065 of mode MODE and data type TYPE.
8066 (TYPE is null for libcalls where that information may not be available.)
8068 Note that for args passed by reference, function_arg will be called
8069 with MODE and TYPE set to that of the pointer to the arg, not the arg
8073 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8074 const_tree type, bool named, int depth)
8077 /* Only tick off an argument if we're not recursing. */
8079 cum->nargs_prototype--;
8081 if (TARGET_ALTIVEC_ABI
8082 && (ALTIVEC_VECTOR_MODE (mode)
8083 || VSX_VECTOR_MODE (mode)
8084 || (type && TREE_CODE (type) == VECTOR_TYPE
8085 && int_size_in_bytes (type) == 16)))
8089 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8092 if (!TARGET_ALTIVEC)
8093 error ("cannot pass argument in vector register because"
8094 " altivec instructions are disabled, use -maltivec"
8097 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8098 even if it is going to be passed in a vector register.
8099 Darwin does the same for variable-argument functions. */
8100 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8101 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8111 /* Vector parameters must be 16-byte aligned. This places
8112 them at 2 mod 4 in terms of words in 32-bit mode, since
8113 the parameter save area starts at offset 24 from the
8114 stack. In 64-bit mode, they just have to start on an
8115 even word, since the parameter save area is 16-byte
8116 aligned. Space for GPRs is reserved even if the argument
8117 will be passed in memory. */
8119 align = (2 - cum->words) & 3;
8121 align = cum->words & 1;
8122 cum->words += align + rs6000_arg_size (mode, type);
8124 if (TARGET_DEBUG_ARG)
8126 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8128 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8129 cum->nargs_prototype, cum->prototype,
8130 GET_MODE_NAME (mode));
8134 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8136 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8139 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8141 int size = int_size_in_bytes (type);
8142 /* Variable sized types have size == -1 and are
8143 treated as if consisting entirely of ints.
8144 Pad to 16 byte boundary if needed. */
8145 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8146 && (cum->words % 2) != 0)
8148 /* For varargs, we can just go up by the size of the struct. */
8150 cum->words += (size + 7) / 8;
8153 /* It is tempting to say int register count just goes up by
8154 sizeof(type)/8, but this is wrong in a case such as
8155 { int; double; int; } [powerpc alignment]. We have to
8156 grovel through the fields for these too. */
8158 cum->floats_in_gpr = 0;
8159 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8160 rs6000_darwin64_record_arg_advance_flush (cum,
8161 size * BITS_PER_UNIT, 1);
8163 if (TARGET_DEBUG_ARG)
8165 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8166 cum->words, TYPE_ALIGN (type), size);
8168 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8169 cum->nargs_prototype, cum->prototype,
8170 GET_MODE_NAME (mode));
8173 else if (DEFAULT_ABI == ABI_V4)
8175 if (TARGET_HARD_FLOAT && TARGET_FPRS
8176 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8177 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8178 || (mode == TFmode && !TARGET_IEEEQUAD)
8179 || mode == SDmode || mode == DDmode || mode == TDmode))
8181 /* _Decimal128 must use an even/odd register pair. This assumes
8182 that the register number is odd when fregno is odd. */
8183 if (mode == TDmode && (cum->fregno % 2) == 1)
8186 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8187 <= FP_ARG_V4_MAX_REG)
8188 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8191 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8192 if (mode == DFmode || mode == TFmode
8193 || mode == DDmode || mode == TDmode)
8194 cum->words += cum->words & 1;
8195 cum->words += rs6000_arg_size (mode, type);
8200 int n_words = rs6000_arg_size (mode, type);
8201 int gregno = cum->sysv_gregno;
8203 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8204 (r7,r8) or (r9,r10). As does any other 2 word item such
8205 as complex int due to a historical mistake. */
8207 gregno += (1 - gregno) & 1;
8209 /* Multi-reg args are not split between registers and stack. */
8210 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8212 /* Long long and SPE vectors are aligned on the stack.
8213 So are other 2 word items such as complex int due to
8214 a historical mistake. */
8216 cum->words += cum->words & 1;
8217 cum->words += n_words;
8220 /* Note: continuing to accumulate gregno past when we've started
8221 spilling to the stack indicates the fact that we've started
8222 spilling to the stack to expand_builtin_saveregs. */
8223 cum->sysv_gregno = gregno + n_words;
8226 if (TARGET_DEBUG_ARG)
8228 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8229 cum->words, cum->fregno);
8230 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8231 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8232 fprintf (stderr, "mode = %4s, named = %d\n",
8233 GET_MODE_NAME (mode), named);
8238 int n_words = rs6000_arg_size (mode, type);
8239 int start_words = cum->words;
8240 int align_words = rs6000_parm_start (mode, type, start_words);
8242 cum->words = align_words + n_words;
8244 if (SCALAR_FLOAT_MODE_P (mode)
8245 && TARGET_HARD_FLOAT && TARGET_FPRS)
8247 /* _Decimal128 must be passed in an even/odd float register pair.
8248 This assumes that the register number is odd when fregno is
8250 if (mode == TDmode && (cum->fregno % 2) == 1)
8252 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8255 if (TARGET_DEBUG_ARG)
8257 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8258 cum->words, cum->fregno);
8259 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8260 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8261 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8262 named, align_words - start_words, depth);
8268 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8269 const_tree type, bool named)
8271 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8275 spe_build_register_parallel (enum machine_mode mode, int gregno)
8282 r1 = gen_rtx_REG (DImode, gregno);
8283 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8284 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8288 r1 = gen_rtx_REG (DImode, gregno);
8289 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8290 r3 = gen_rtx_REG (DImode, gregno + 2);
8291 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8292 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8295 r1 = gen_rtx_REG (DImode, gregno);
8296 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8297 r3 = gen_rtx_REG (DImode, gregno + 2);
8298 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8299 r5 = gen_rtx_REG (DImode, gregno + 4);
8300 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8301 r7 = gen_rtx_REG (DImode, gregno + 6);
8302 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8303 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8310 /* Determine where to put a SIMD argument on the SPE. */
8312 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8315 int gregno = cum->sysv_gregno;
8317 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8318 are passed and returned in a pair of GPRs for ABI compatibility. */
8319 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8320 || mode == DCmode || mode == TCmode))
8322 int n_words = rs6000_arg_size (mode, type);
8324 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8326 gregno += (1 - gregno) & 1;
8328 /* Multi-reg args are not split between registers and stack. */
8329 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8332 return spe_build_register_parallel (mode, gregno);
8336 int n_words = rs6000_arg_size (mode, type);
8338 /* SPE vectors are put in odd registers. */
8339 if (n_words == 2 && (gregno & 1) == 0)
8342 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8345 enum machine_mode m = SImode;
8347 r1 = gen_rtx_REG (m, gregno);
8348 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8349 r2 = gen_rtx_REG (m, gregno + 1);
8350 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8351 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8358 if (gregno <= GP_ARG_MAX_REG)
8359 return gen_rtx_REG (mode, gregno);
8365 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8366 structure between cum->intoffset and bitpos to integer registers. */
8369 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8370 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8372 enum machine_mode mode;
8374 unsigned int startbit, endbit;
8375 int this_regno, intregs, intoffset;
8378 if (cum->intoffset == -1)
8381 intoffset = cum->intoffset;
8382 cum->intoffset = -1;
8384 /* If this is the trailing part of a word, try to only load that
8385 much into the register. Otherwise load the whole register. Note
8386 that in the latter case we may pick up unwanted bits. It's not a
8387 problem at the moment but may wish to revisit. */
8389 if (intoffset % BITS_PER_WORD != 0)
8391 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8393 if (mode == BLKmode)
8395 /* We couldn't find an appropriate mode, which happens,
8396 e.g., in packed structs when there are 3 bytes to load.
8397 Back intoffset back to the beginning of the word in this
8399 intoffset = intoffset & -BITS_PER_WORD;
8406 startbit = intoffset & -BITS_PER_WORD;
8407 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8408 intregs = (endbit - startbit) / BITS_PER_WORD;
8409 this_regno = cum->words + intoffset / BITS_PER_WORD;
8411 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8414 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8418 intoffset /= BITS_PER_UNIT;
8421 regno = GP_ARG_MIN_REG + this_regno;
8422 reg = gen_rtx_REG (mode, regno);
8424 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8427 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8431 while (intregs > 0);
8434 /* Recursive workhorse for the following. */
8437 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8438 HOST_WIDE_INT startbitpos, rtx rvec[],
8443 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8444 if (TREE_CODE (f) == FIELD_DECL)
8446 HOST_WIDE_INT bitpos = startbitpos;
8447 tree ftype = TREE_TYPE (f);
8448 enum machine_mode mode;
8449 if (ftype == error_mark_node)
8451 mode = TYPE_MODE (ftype);
8453 if (DECL_SIZE (f) != 0
8454 && host_integerp (bit_position (f), 1))
8455 bitpos += int_bit_position (f);
8457 /* ??? FIXME: else assume zero offset. */
8459 if (TREE_CODE (ftype) == RECORD_TYPE)
8460 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8461 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8466 case SCmode: mode = SFmode; break;
8467 case DCmode: mode = DFmode; break;
8468 case TCmode: mode = TFmode; break;
8472 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8474 = gen_rtx_EXPR_LIST (VOIDmode,
8475 gen_rtx_REG (mode, cum->fregno++),
8476 GEN_INT (bitpos / BITS_PER_UNIT));
8477 if (mode == TFmode || mode == TDmode)
8480 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8482 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8484 = gen_rtx_EXPR_LIST (VOIDmode,
8485 gen_rtx_REG (mode, cum->vregno++),
8486 GEN_INT (bitpos / BITS_PER_UNIT));
8488 else if (cum->intoffset == -1)
8489 cum->intoffset = bitpos;
8493 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8494 the register(s) to be used for each field and subfield of a struct
8495 being passed by value, along with the offset of where the
8496 register's value may be found in the block. FP fields go in FP
8497 register, vector fields go in vector registers, and everything
8498 else goes in int registers, packed as in memory.
8500 This code is also used for function return values. RETVAL indicates
8501 whether this is the case.
8503 Much of this is taken from the SPARC V9 port, which has a similar
8504 calling convention. */
8507 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8508 bool named, bool retval)
8510 rtx rvec[FIRST_PSEUDO_REGISTER];
8511 int k = 1, kbase = 1;
8512 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8513 /* This is a copy; modifications are not visible to our caller. */
8514 CUMULATIVE_ARGS copy_cum = *orig_cum;
8515 CUMULATIVE_ARGS *cum = ©_cum;
8517 /* Pad to 16 byte boundary if needed. */
8518 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8519 && (cum->words % 2) != 0)
8526 /* Put entries into rvec[] for individual FP and vector fields, and
8527 for the chunks of memory that go in int regs. Note we start at
8528 element 1; 0 is reserved for an indication of using memory, and
8529 may or may not be filled in below. */
8530 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
8531 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8533 /* If any part of the struct went on the stack put all of it there.
8534 This hack is because the generic code for
8535 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8536 parts of the struct are not at the beginning. */
8540 return NULL_RTX; /* doesn't go in registers at all */
8542 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8544 if (k > 1 || cum->use_stack)
8545 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8550 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8553 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8558 rtx rvec[GP_ARG_NUM_REG + 1];
8560 if (align_words >= GP_ARG_NUM_REG)
8563 n_units = rs6000_arg_size (mode, type);
8565 /* Optimize the simple case where the arg fits in one gpr, except in
8566 the case of BLKmode due to assign_parms assuming that registers are
8567 BITS_PER_WORD wide. */
8569 || (n_units == 1 && mode != BLKmode))
8570 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8573 if (align_words + n_units > GP_ARG_NUM_REG)
8574 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8575 using a magic NULL_RTX component.
8576 This is not strictly correct. Only some of the arg belongs in
8577 memory, not all of it. However, the normal scheme using
8578 function_arg_partial_nregs can result in unusual subregs, eg.
8579 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8580 store the whole arg to memory is often more efficient than code
8581 to store pieces, and we know that space is available in the right
8582 place for the whole arg. */
8583 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8588 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8589 rtx off = GEN_INT (i++ * 4);
8590 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8592 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8594 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8597 /* Determine where to put an argument to a function.
8598 Value is zero to push the argument on the stack,
8599 or a hard register in which to store the argument.
8601 MODE is the argument's machine mode.
8602 TYPE is the data type of the argument (as a tree).
8603 This is null for libcalls where that information may
8605 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8606 the preceding args and about the function being called. It is
8607 not modified in this routine.
8608 NAMED is nonzero if this argument is a named parameter
8609 (otherwise it is an extra parameter matching an ellipsis).
8611 On RS/6000 the first eight words of non-FP are normally in registers
8612 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8613 Under V.4, the first 8 FP args are in registers.
8615 If this is floating-point and no prototype is specified, we use
8616 both an FP and integer register (or possibly FP reg and stack). Library
8617 functions (when CALL_LIBCALL is set) always have the proper types for args,
8618 so we can pass the FP value just in one register. emit_library_function
8619 doesn't support PARALLEL anyway.
8621 Note that for args passed by reference, function_arg will be called
8622 with MODE and TYPE set to that of the pointer to the arg, not the arg
8626 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8627 const_tree type, bool named)
8629 enum rs6000_abi abi = DEFAULT_ABI;
8631 /* Return a marker to indicate whether CR1 needs to set or clear the
8632 bit that V.4 uses to say fp args were passed in registers.
8633 Assume that we don't need the marker for software floating point,
8634 or compiler generated library calls. */
8635 if (mode == VOIDmode)
8638 && (cum->call_cookie & CALL_LIBCALL) == 0
8640 || (cum->nargs_prototype < 0
8641 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8643 /* For the SPE, we need to crxor CR6 always. */
8645 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8646 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8647 return GEN_INT (cum->call_cookie
8648 | ((cum->fregno == FP_ARG_MIN_REG)
8649 ? CALL_V4_SET_FP_ARGS
8650 : CALL_V4_CLEAR_FP_ARGS));
8653 return GEN_INT (cum->call_cookie);
8656 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8658 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8659 if (rslt != NULL_RTX)
8661 /* Else fall through to usual handling. */
8664 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8665 if (TARGET_64BIT && ! cum->prototype)
8667 /* Vector parameters get passed in vector register
8668 and also in GPRs or memory, in absence of prototype. */
8671 align_words = (cum->words + 1) & ~1;
8673 if (align_words >= GP_ARG_NUM_REG)
8679 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8681 return gen_rtx_PARALLEL (mode,
8683 gen_rtx_EXPR_LIST (VOIDmode,
8685 gen_rtx_EXPR_LIST (VOIDmode,
8686 gen_rtx_REG (mode, cum->vregno),
8690 return gen_rtx_REG (mode, cum->vregno);
8691 else if (TARGET_ALTIVEC_ABI
8692 && (ALTIVEC_VECTOR_MODE (mode)
8693 || VSX_VECTOR_MODE (mode)
8694 || (type && TREE_CODE (type) == VECTOR_TYPE
8695 && int_size_in_bytes (type) == 16)))
8697 if (named || abi == ABI_V4)
8701 /* Vector parameters to varargs functions under AIX or Darwin
8702 get passed in memory and possibly also in GPRs. */
8703 int align, align_words, n_words;
8704 enum machine_mode part_mode;
8706 /* Vector parameters must be 16-byte aligned. This places them at
8707 2 mod 4 in terms of words in 32-bit mode, since the parameter
8708 save area starts at offset 24 from the stack. In 64-bit mode,
8709 they just have to start on an even word, since the parameter
8710 save area is 16-byte aligned. */
8712 align = (2 - cum->words) & 3;
8714 align = cum->words & 1;
8715 align_words = cum->words + align;
8717 /* Out of registers? Memory, then. */
8718 if (align_words >= GP_ARG_NUM_REG)
8721 if (TARGET_32BIT && TARGET_POWERPC64)
8722 return rs6000_mixed_function_arg (mode, type, align_words);
8724 /* The vector value goes in GPRs. Only the part of the
8725 value in GPRs is reported here. */
8727 n_words = rs6000_arg_size (mode, type);
8728 if (align_words + n_words > GP_ARG_NUM_REG)
8729 /* Fortunately, there are only two possibilities, the value
8730 is either wholly in GPRs or half in GPRs and half not. */
8733 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
8736 else if (TARGET_SPE_ABI && TARGET_SPE
8737 && (SPE_VECTOR_MODE (mode)
8738 || (TARGET_E500_DOUBLE && (mode == DFmode
8741 || mode == TCmode))))
8742 return rs6000_spe_function_arg (cum, mode, type);
8744 else if (abi == ABI_V4)
8746 if (TARGET_HARD_FLOAT && TARGET_FPRS
8747 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8748 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8749 || (mode == TFmode && !TARGET_IEEEQUAD)
8750 || mode == SDmode || mode == DDmode || mode == TDmode))
8752 /* _Decimal128 must use an even/odd register pair. This assumes
8753 that the register number is odd when fregno is odd. */
8754 if (mode == TDmode && (cum->fregno % 2) == 1)
8757 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8758 <= FP_ARG_V4_MAX_REG)
8759 return gen_rtx_REG (mode, cum->fregno);
8765 int n_words = rs6000_arg_size (mode, type);
8766 int gregno = cum->sysv_gregno;
8768 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8769 (r7,r8) or (r9,r10). As does any other 2 word item such
8770 as complex int due to a historical mistake. */
8772 gregno += (1 - gregno) & 1;
8774 /* Multi-reg args are not split between registers and stack. */
8775 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8778 if (TARGET_32BIT && TARGET_POWERPC64)
8779 return rs6000_mixed_function_arg (mode, type,
8780 gregno - GP_ARG_MIN_REG);
8781 return gen_rtx_REG (mode, gregno);
8786 int align_words = rs6000_parm_start (mode, type, cum->words);
8788 /* _Decimal128 must be passed in an even/odd float register pair.
8789 This assumes that the register number is odd when fregno is odd. */
8790 if (mode == TDmode && (cum->fregno % 2) == 1)
8793 if (USE_FP_FOR_ARG_P (cum, mode, type))
8795 rtx rvec[GP_ARG_NUM_REG + 1];
8799 enum machine_mode fmode = mode;
8800 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8802 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8804 /* Currently, we only ever need one reg here because complex
8805 doubles are split. */
8806 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8807 && (fmode == TFmode || fmode == TDmode));
8809 /* Long double or _Decimal128 split over regs and memory. */
8810 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
8813 /* Do we also need to pass this arg in the parameter save
8816 && (cum->nargs_prototype <= 0
8817 || (DEFAULT_ABI == ABI_AIX
8819 && align_words >= GP_ARG_NUM_REG)));
8821 if (!needs_psave && mode == fmode)
8822 return gen_rtx_REG (fmode, cum->fregno);
8827 /* Describe the part that goes in gprs or the stack.
8828 This piece must come first, before the fprs. */
8829 if (align_words < GP_ARG_NUM_REG)
8831 unsigned long n_words = rs6000_arg_size (mode, type);
8833 if (align_words + n_words > GP_ARG_NUM_REG
8834 || (TARGET_32BIT && TARGET_POWERPC64))
8836 /* If this is partially on the stack, then we only
8837 include the portion actually in registers here. */
8838 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
8841 if (align_words + n_words > GP_ARG_NUM_REG)
8842 /* Not all of the arg fits in gprs. Say that it
8843 goes in memory too, using a magic NULL_RTX
8844 component. Also see comment in
8845 rs6000_mixed_function_arg for why the normal
8846 function_arg_partial_nregs scheme doesn't work
8848 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
8852 r = gen_rtx_REG (rmode,
8853 GP_ARG_MIN_REG + align_words);
8854 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
8855 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8857 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
8861 /* The whole arg fits in gprs. */
8862 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8863 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8867 /* It's entirely in memory. */
8868 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8871 /* Describe where this piece goes in the fprs. */
8872 r = gen_rtx_REG (fmode, cum->fregno);
8873 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
8875 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8877 else if (align_words < GP_ARG_NUM_REG)
8879 if (TARGET_32BIT && TARGET_POWERPC64)
8880 return rs6000_mixed_function_arg (mode, type, align_words);
8882 if (mode == BLKmode)
8885 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8892 /* For an arg passed partly in registers and partly in memory, this is
8893 the number of bytes passed in registers. For args passed entirely in
8894 registers or entirely in memory, zero. When an arg is described by a
8895 PARALLEL, perhaps using more than one register type, this function
8896 returns the number of bytes used by the first element of the PARALLEL. */
8899 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8900 tree type, bool named)
8905 if (DEFAULT_ABI == ABI_V4)
8908 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
8909 && cum->nargs_prototype >= 0)
8912 /* In this complicated case we just disable the partial_nregs code. */
8913 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8916 align_words = rs6000_parm_start (mode, type, cum->words);
8918 if (USE_FP_FOR_ARG_P (cum, mode, type))
8920 /* If we are passing this arg in the fixed parameter save area
8921 (gprs or memory) as well as fprs, then this function should
8922 return the number of partial bytes passed in the parameter
8923 save area rather than partial bytes passed in fprs. */
8925 && (cum->nargs_prototype <= 0
8926 || (DEFAULT_ABI == ABI_AIX
8928 && align_words >= GP_ARG_NUM_REG)))
8930 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
8931 > FP_ARG_MAX_REG + 1)
8932 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
8933 else if (cum->nargs_prototype >= 0)
8937 if (align_words < GP_ARG_NUM_REG
8938 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
8939 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
8941 if (ret != 0 && TARGET_DEBUG_ARG)
8942 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
8947 /* A C expression that indicates when an argument must be passed by
8948 reference. If nonzero for an argument, a copy of that argument is
8949 made in memory and a pointer to the argument is passed instead of
8950 the argument itself. The pointer is passed in whatever way is
8951 appropriate for passing a pointer to that type.
8953 Under V.4, aggregates and long double are passed by reference.
8955 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
8956 reference unless the AltiVec vector extension ABI is in force.
8958 As an extension to all ABIs, variable sized types are passed by
8962 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
8963 enum machine_mode mode, const_tree type,
8964 bool named ATTRIBUTE_UNUSED)
8966 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
8968 if (TARGET_DEBUG_ARG)
8969 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
8976 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
8978 if (TARGET_DEBUG_ARG)
8979 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
8983 if (int_size_in_bytes (type) < 0)
8985 if (TARGET_DEBUG_ARG)
8986 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
8990 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
8991 modes only exist for GCC vector types if -maltivec. */
8992 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
8994 if (TARGET_DEBUG_ARG)
8995 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
8999 /* Pass synthetic vectors in memory. */
9000 if (TREE_CODE (type) == VECTOR_TYPE
9001 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9003 static bool warned_for_pass_big_vectors = false;
9004 if (TARGET_DEBUG_ARG)
9005 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9006 if (!warned_for_pass_big_vectors)
9008 warning (0, "GCC vector passed by reference: "
9009 "non-standard ABI extension with no compatibility guarantee");
9010 warned_for_pass_big_vectors = true;
9019 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9022 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9027 for (i = 0; i < nregs; i++)
9029 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9030 if (reload_completed)
9032 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9035 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9036 i * GET_MODE_SIZE (reg_mode));
9039 tem = replace_equiv_address (tem, XEXP (tem, 0));
9043 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9047 /* Perform any needed actions needed for a function that is receiving a
9048 variable number of arguments.
9052 MODE and TYPE are the mode and type of the current parameter.
9054 PRETEND_SIZE is a variable that should be set to the amount of stack
9055 that must be pushed by the prolog to pretend that our caller pushed
9058 Normally, this macro will push all remaining incoming registers on the
9059 stack and set PRETEND_SIZE to the length of the registers pushed. */
9062 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9063 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9066 CUMULATIVE_ARGS next_cum;
9067 int reg_size = TARGET_32BIT ? 4 : 8;
9068 rtx save_area = NULL_RTX, mem;
9069 int first_reg_offset;
9072 /* Skip the last named argument. */
9074 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9076 if (DEFAULT_ABI == ABI_V4)
9078 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9082 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9083 HOST_WIDE_INT offset = 0;
9085 /* Try to optimize the size of the varargs save area.
9086 The ABI requires that ap.reg_save_area is doubleword
9087 aligned, but we don't need to allocate space for all
9088 the bytes, only those to which we actually will save
9090 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9091 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9092 if (TARGET_HARD_FLOAT && TARGET_FPRS
9093 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9094 && cfun->va_list_fpr_size)
9097 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9098 * UNITS_PER_FP_WORD;
9099 if (cfun->va_list_fpr_size
9100 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9101 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9103 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9104 * UNITS_PER_FP_WORD;
9108 offset = -((first_reg_offset * reg_size) & ~7);
9109 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9111 gpr_reg_num = cfun->va_list_gpr_size;
9112 if (reg_size == 4 && (first_reg_offset & 1))
9115 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9118 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9120 - (int) (GP_ARG_NUM_REG * reg_size);
9122 if (gpr_size + fpr_size)
9125 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9126 gcc_assert (GET_CODE (reg_save_area) == MEM);
9127 reg_save_area = XEXP (reg_save_area, 0);
9128 if (GET_CODE (reg_save_area) == PLUS)
9130 gcc_assert (XEXP (reg_save_area, 0)
9131 == virtual_stack_vars_rtx);
9132 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9133 offset += INTVAL (XEXP (reg_save_area, 1));
9136 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9139 cfun->machine->varargs_save_offset = offset;
9140 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9145 first_reg_offset = next_cum.words;
9146 save_area = virtual_incoming_args_rtx;
9148 if (targetm.calls.must_pass_in_stack (mode, type))
9149 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9152 set = get_varargs_alias_set ();
9153 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9154 && cfun->va_list_gpr_size)
9156 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9158 if (va_list_gpr_counter_field)
9160 /* V4 va_list_gpr_size counts number of registers needed. */
9161 if (nregs > cfun->va_list_gpr_size)
9162 nregs = cfun->va_list_gpr_size;
9166 /* char * va_list instead counts number of bytes needed. */
9167 if (nregs > cfun->va_list_gpr_size / reg_size)
9168 nregs = cfun->va_list_gpr_size / reg_size;
9171 mem = gen_rtx_MEM (BLKmode,
9172 plus_constant (save_area,
9173 first_reg_offset * reg_size));
9174 MEM_NOTRAP_P (mem) = 1;
9175 set_mem_alias_set (mem, set);
9176 set_mem_align (mem, BITS_PER_WORD);
9178 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9182 /* Save FP registers if needed. */
9183 if (DEFAULT_ABI == ABI_V4
9184 && TARGET_HARD_FLOAT && TARGET_FPRS
9186 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9187 && cfun->va_list_fpr_size)
9189 int fregno = next_cum.fregno, nregs;
9190 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9191 rtx lab = gen_label_rtx ();
9192 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9193 * UNITS_PER_FP_WORD);
9196 (gen_rtx_SET (VOIDmode,
9198 gen_rtx_IF_THEN_ELSE (VOIDmode,
9199 gen_rtx_NE (VOIDmode, cr1,
9201 gen_rtx_LABEL_REF (VOIDmode, lab),
9205 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9206 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9208 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9210 plus_constant (save_area, off));
9211 MEM_NOTRAP_P (mem) = 1;
9212 set_mem_alias_set (mem, set);
9213 set_mem_align (mem, GET_MODE_ALIGNMENT (
9214 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9215 ? DFmode : SFmode));
9216 emit_move_insn (mem, gen_rtx_REG (
9217 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9218 ? DFmode : SFmode, fregno));
9225 /* Create the va_list data type. */
9228 rs6000_build_builtin_va_list (void)
9230 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9232 /* For AIX, prefer 'char *' because that's what the system
9233 header files like. */
9234 if (DEFAULT_ABI != ABI_V4)
9235 return build_pointer_type (char_type_node);
9237 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9238 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9239 get_identifier ("__va_list_tag"), record);
9241 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9242 unsigned_char_type_node);
9243 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9244 unsigned_char_type_node);
9245 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9247 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9248 get_identifier ("reserved"), short_unsigned_type_node);
9249 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9250 get_identifier ("overflow_arg_area"),
9252 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9253 get_identifier ("reg_save_area"),
9256 va_list_gpr_counter_field = f_gpr;
9257 va_list_fpr_counter_field = f_fpr;
9259 DECL_FIELD_CONTEXT (f_gpr) = record;
9260 DECL_FIELD_CONTEXT (f_fpr) = record;
9261 DECL_FIELD_CONTEXT (f_res) = record;
9262 DECL_FIELD_CONTEXT (f_ovf) = record;
9263 DECL_FIELD_CONTEXT (f_sav) = record;
9265 TYPE_STUB_DECL (record) = type_decl;
9266 TYPE_NAME (record) = type_decl;
9267 TYPE_FIELDS (record) = f_gpr;
9268 DECL_CHAIN (f_gpr) = f_fpr;
9269 DECL_CHAIN (f_fpr) = f_res;
9270 DECL_CHAIN (f_res) = f_ovf;
9271 DECL_CHAIN (f_ovf) = f_sav;
9273 layout_type (record);
9275 /* The correct type is an array type of one element. */
9276 return build_array_type (record, build_index_type (size_zero_node));
9279 /* Implement va_start. */
9282 rs6000_va_start (tree valist, rtx nextarg)
9284 HOST_WIDE_INT words, n_gpr, n_fpr;
9285 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9286 tree gpr, fpr, ovf, sav, t;
9288 /* Only SVR4 needs something special. */
9289 if (DEFAULT_ABI != ABI_V4)
9291 std_expand_builtin_va_start (valist, nextarg);
9295 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9296 f_fpr = DECL_CHAIN (f_gpr);
9297 f_res = DECL_CHAIN (f_fpr);
9298 f_ovf = DECL_CHAIN (f_res);
9299 f_sav = DECL_CHAIN (f_ovf);
9301 valist = build_simple_mem_ref (valist);
9302 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9303 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9305 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9307 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9310 /* Count number of gp and fp argument registers used. */
9311 words = crtl->args.info.words;
9312 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9314 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9317 if (TARGET_DEBUG_ARG)
9318 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9319 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9320 words, n_gpr, n_fpr);
9322 if (cfun->va_list_gpr_size)
9324 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9325 build_int_cst (NULL_TREE, n_gpr));
9326 TREE_SIDE_EFFECTS (t) = 1;
9327 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9330 if (cfun->va_list_fpr_size)
9332 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9333 build_int_cst (NULL_TREE, n_fpr));
9334 TREE_SIDE_EFFECTS (t) = 1;
9335 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9338 /* Find the overflow area. */
9339 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9341 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9342 size_int (words * UNITS_PER_WORD));
9343 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9344 TREE_SIDE_EFFECTS (t) = 1;
9345 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9347 /* If there were no va_arg invocations, don't set up the register
9349 if (!cfun->va_list_gpr_size
9350 && !cfun->va_list_fpr_size
9351 && n_gpr < GP_ARG_NUM_REG
9352 && n_fpr < FP_ARG_V4_MAX_REG)
9355 /* Find the register save area. */
9356 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9357 if (cfun->machine->varargs_save_offset)
9358 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9359 size_int (cfun->machine->varargs_save_offset));
9360 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9361 TREE_SIDE_EFFECTS (t) = 1;
9362 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9365 /* Implement va_arg. */
9368 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9371 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9372 tree gpr, fpr, ovf, sav, reg, t, u;
9373 int size, rsize, n_reg, sav_ofs, sav_scale;
9374 tree lab_false, lab_over, addr;
9376 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9380 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9382 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9383 return build_va_arg_indirect_ref (t);
9386 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9387 earlier version of gcc, with the property that it always applied alignment
9388 adjustments to the va-args (even for zero-sized types). The cheapest way
9389 to deal with this is to replicate the effect of the part of
9390 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9392 We don't need to check for pass-by-reference because of the test above.
9393 We can return a simplifed answer, since we know there's no offset to add. */
9396 && rs6000_darwin64_abi
9397 && integer_zerop (TYPE_SIZE (type)))
9399 unsigned HOST_WIDE_INT align, boundary;
9400 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9401 align = PARM_BOUNDARY / BITS_PER_UNIT;
9402 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
9403 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9404 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9405 boundary /= BITS_PER_UNIT;
9406 if (boundary > align)
9409 /* This updates arg ptr by the amount that would be necessary
9410 to align the zero-sized (but not zero-alignment) item. */
9411 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9412 fold_build2 (POINTER_PLUS_EXPR,
9414 valist_tmp, size_int (boundary - 1)));
9415 gimplify_and_add (t, pre_p);
9417 t = fold_convert (sizetype, valist_tmp);
9418 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9419 fold_convert (TREE_TYPE (valist),
9420 fold_build2 (BIT_AND_EXPR, sizetype, t,
9421 size_int (-boundary))));
9422 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9423 gimplify_and_add (t, pre_p);
9425 /* Since it is zero-sized there's no increment for the item itself. */
9426 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9427 return build_va_arg_indirect_ref (valist_tmp);
9430 if (DEFAULT_ABI != ABI_V4)
9432 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9434 tree elem_type = TREE_TYPE (type);
9435 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9436 int elem_size = GET_MODE_SIZE (elem_mode);
9438 if (elem_size < UNITS_PER_WORD)
9440 tree real_part, imag_part;
9441 gimple_seq post = NULL;
9443 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9445 /* Copy the value into a temporary, lest the formal temporary
9446 be reused out from under us. */
9447 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9448 gimple_seq_add_seq (pre_p, post);
9450 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9453 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9457 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9460 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9461 f_fpr = DECL_CHAIN (f_gpr);
9462 f_res = DECL_CHAIN (f_fpr);
9463 f_ovf = DECL_CHAIN (f_res);
9464 f_sav = DECL_CHAIN (f_ovf);
9466 valist = build_va_arg_indirect_ref (valist);
9467 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9468 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9470 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9472 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9475 size = int_size_in_bytes (type);
9476 rsize = (size + 3) / 4;
9479 if (TARGET_HARD_FLOAT && TARGET_FPRS
9480 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9481 || (TARGET_DOUBLE_FLOAT
9482 && (TYPE_MODE (type) == DFmode
9483 || TYPE_MODE (type) == TFmode
9484 || TYPE_MODE (type) == SDmode
9485 || TYPE_MODE (type) == DDmode
9486 || TYPE_MODE (type) == TDmode))))
9488 /* FP args go in FP registers, if present. */
9490 n_reg = (size + 7) / 8;
9491 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9492 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9493 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9498 /* Otherwise into GP registers. */
9507 /* Pull the value out of the saved registers.... */
9510 addr = create_tmp_var (ptr_type_node, "addr");
9512 /* AltiVec vectors never go in registers when -mabi=altivec. */
9513 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9517 lab_false = create_artificial_label (input_location);
9518 lab_over = create_artificial_label (input_location);
9520 /* Long long and SPE vectors are aligned in the registers.
9521 As are any other 2 gpr item such as complex int due to a
9522 historical mistake. */
9524 if (n_reg == 2 && reg == gpr)
9527 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9528 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9529 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9530 unshare_expr (reg), u);
9532 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9533 reg number is 0 for f1, so we want to make it odd. */
9534 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9536 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9537 build_int_cst (TREE_TYPE (reg), 1));
9538 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9541 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9542 t = build2 (GE_EXPR, boolean_type_node, u, t);
9543 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9544 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9545 gimplify_and_add (t, pre_p);
9549 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9551 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9552 build_int_cst (TREE_TYPE (reg), n_reg));
9553 u = fold_convert (sizetype, u);
9554 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9555 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9557 /* _Decimal32 varargs are located in the second word of the 64-bit
9558 FP register for 32-bit binaries. */
9559 if (!TARGET_POWERPC64
9560 && TARGET_HARD_FLOAT && TARGET_FPRS
9561 && TYPE_MODE (type) == SDmode)
9562 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9564 gimplify_assign (addr, t, pre_p);
9566 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9568 stmt = gimple_build_label (lab_false);
9569 gimple_seq_add_stmt (pre_p, stmt);
9571 if ((n_reg == 2 && !regalign) || n_reg > 2)
9573 /* Ensure that we don't find any more args in regs.
9574 Alignment has taken care of for special cases. */
9575 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9579 /* ... otherwise out of the overflow area. */
9581 /* Care for on-stack alignment if needed. */
9585 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9586 t = fold_convert (sizetype, t);
9587 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9589 t = fold_convert (TREE_TYPE (ovf), t);
9591 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9593 gimplify_assign (unshare_expr (addr), t, pre_p);
9595 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9596 gimplify_assign (unshare_expr (ovf), t, pre_p);
9600 stmt = gimple_build_label (lab_over);
9601 gimple_seq_add_stmt (pre_p, stmt);
9604 if (STRICT_ALIGNMENT
9605 && (TYPE_ALIGN (type)
9606 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9608 /* The value (of type complex double, for example) may not be
9609 aligned in memory in the saved registers, so copy via a
9610 temporary. (This is the same code as used for SPARC.) */
9611 tree tmp = create_tmp_var (type, "va_arg_tmp");
9612 tree dest_addr = build_fold_addr_expr (tmp);
9614 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9615 3, dest_addr, addr, size_int (rsize * 4));
9617 gimplify_and_add (copy, pre_p);
9621 addr = fold_convert (ptrtype, addr);
9622 return build_va_arg_indirect_ref (addr);
9628 def_builtin (int mask, const char *name, tree type, int code)
9630 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9633 if (rs6000_builtin_decls[code])
9634 fatal_error ("internal error: builtin function to %s already processed",
9637 rs6000_builtin_decls[code] = t =
9638 add_builtin_function (name, type, code, BUILT_IN_MD,
9641 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9642 switch (builtin_classify[code])
9647 /* assume builtin can do anything. */
9648 case RS6000_BTC_MISC:
9651 /* const function, function only depends on the inputs. */
9652 case RS6000_BTC_CONST:
9653 TREE_READONLY (t) = 1;
9654 TREE_NOTHROW (t) = 1;
9657 /* pure function, function can read global memory. */
9658 case RS6000_BTC_PURE:
9659 DECL_PURE_P (t) = 1;
9660 TREE_NOTHROW (t) = 1;
9663 /* Function is a math function. If rounding mode is on, then treat
9664 the function as not reading global memory, but it can have
9665 arbitrary side effects. If it is off, then assume the function is
9666 a const function. This mimics the ATTR_MATHFN_FPROUNDING
9667 attribute in builtin-attribute.def that is used for the math
9669 case RS6000_BTC_FP_PURE:
9670 TREE_NOTHROW (t) = 1;
9671 if (flag_rounding_math)
9673 DECL_PURE_P (t) = 1;
9674 DECL_IS_NOVOPS (t) = 1;
9677 TREE_READONLY (t) = 1;
9683 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
9685 static const struct builtin_description bdesc_3arg[] =
9687 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
9688 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
9689 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
9690 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
9691 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
9692 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
9693 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
9694 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
9695 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
9696 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
9697 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
9698 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
9699 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
9700 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
9701 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
9702 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
9703 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
9704 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
9705 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
9706 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
9707 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
9708 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
9709 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
9710 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
9711 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
9712 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
9713 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
9714 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
9715 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
9716 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
9717 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
9718 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
9719 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
9720 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
9721 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
9723 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
9724 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
9725 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
9726 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
9727 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
9728 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
9729 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
9730 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
9731 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
9732 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
9733 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
9734 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
9735 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
9736 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
9737 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
9739 { MASK_VSX, CODE_FOR_vsx_fmaddv2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
9740 { MASK_VSX, CODE_FOR_vsx_fmsubv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
9741 { MASK_VSX, CODE_FOR_vsx_fnmaddv2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
9742 { MASK_VSX, CODE_FOR_vsx_fnmsubv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
9744 { MASK_VSX, CODE_FOR_vsx_fmaddv4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
9745 { MASK_VSX, CODE_FOR_vsx_fmsubv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
9746 { MASK_VSX, CODE_FOR_vsx_fnmaddv4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
9747 { MASK_VSX, CODE_FOR_vsx_fnmsubv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
9749 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
9750 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
9752 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
9753 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
9754 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
9755 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
9756 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
9757 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
9758 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
9759 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
9760 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
9761 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
9763 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
9764 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
9765 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
9766 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
9767 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
9768 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
9769 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
9770 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
9771 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
9772 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
9774 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
9775 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
9776 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
9777 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
9778 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
9779 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
9780 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
9781 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
9782 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
9784 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
9785 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
9786 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
9787 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
9788 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
9789 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
9790 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
9792 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
9793 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
9794 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
9795 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
9796 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
9797 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
9798 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
9799 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
9800 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
9803 /* DST operations: void foo (void *, const int, const char). */
9805 static const struct builtin_description bdesc_dst[] =
9807 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
9808 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
9809 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
9810 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
9812 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
9813 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
9814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
9815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
9818 /* Simple binary operations: VECc = foo (VECa, VECb). */
9820 static struct builtin_description bdesc_2arg[] =
9822 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
9823 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
9824 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
9825 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
9826 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
9827 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
9828 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
9829 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
9830 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
9831 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
9832 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
9833 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
9834 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
9835 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
9836 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
9837 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
9838 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
9839 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
9840 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
9841 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
9842 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
9843 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
9844 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
9845 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
9846 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
9847 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
9848 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
9849 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
9850 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
9851 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
9852 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
9853 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
9854 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
9855 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
9856 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
9857 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
9858 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
9859 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
9860 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
9861 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
9862 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
9863 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
9864 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
9865 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
9866 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
9867 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
9868 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
9869 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
9870 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
9871 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
9872 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
9873 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
9874 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
9875 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
9876 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
9877 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
9878 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
9879 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
9880 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
9881 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
9882 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
9883 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
9884 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
9885 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
9886 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
9887 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
9888 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
9889 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
9890 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
9891 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
9892 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
9893 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
9894 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
9895 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
9896 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
9897 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
9898 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
9899 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
9900 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
9901 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
9902 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
9903 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
9904 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
9905 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
9906 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
9907 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
9908 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
9909 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
9910 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
9911 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
9912 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
9913 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
9914 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
9915 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
9916 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
9917 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
9918 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
9919 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
9920 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
9921 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
9922 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
9923 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
9924 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
9925 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
9926 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
9927 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
9928 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
9929 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
9930 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
9931 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
9932 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
9933 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
9934 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
9935 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
9936 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
9937 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
9938 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
9940 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
9941 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
9942 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
9943 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
9944 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
9945 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
9946 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
9947 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
9948 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
9949 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
9950 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
9951 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
9953 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
9954 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
9955 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
9956 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
9957 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
9958 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
9959 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
9960 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
9961 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
9962 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
9963 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
9964 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
9966 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
9967 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
9968 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
9969 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
9970 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
9971 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
9973 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
9974 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
9975 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
9976 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
9977 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
9978 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
9979 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
9980 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
9981 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
9982 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
9983 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
9984 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
9986 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
9987 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
9988 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
9989 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
9990 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
9991 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
9992 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
9993 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
9994 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
9995 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
9996 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
9997 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
9998 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
9999 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10000 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10014 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10015 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10016 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10017 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10018 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10019 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10020 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10021 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10022 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10023 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10024 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10026 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10027 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10029 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10030 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10031 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10032 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10033 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10034 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10035 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10036 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10037 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10038 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10039 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10040 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10041 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10042 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10043 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10044 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10045 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10046 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10047 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10048 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10049 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10050 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10051 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10052 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10053 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10054 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10055 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10056 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10057 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10058 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10059 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10060 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10061 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10062 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10063 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10064 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10065 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10066 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10067 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10068 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10069 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10070 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10071 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10075 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10095 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10096 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10100 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10101 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10102 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10103 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10104 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10105 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10106 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10109 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10110 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10113 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10114 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10116 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10117 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10119 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10120 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10121 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10122 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10123 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10124 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10125 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10126 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10127 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10128 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10130 /* Place holder, leave as first spe builtin. */
10131 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10132 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10133 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10134 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10135 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10136 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10137 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10138 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10139 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10140 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10141 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10142 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10143 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10144 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10145 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10146 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10147 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10148 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10149 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10150 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10151 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10152 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10153 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10154 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10155 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10156 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10157 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10158 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10159 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10160 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10161 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10162 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10163 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10164 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10165 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10166 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10167 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10168 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10169 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10170 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10171 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10172 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10173 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10174 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10175 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10176 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10177 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10178 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10179 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10180 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10181 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10182 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10183 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10184 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10185 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10186 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10187 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10188 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10189 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10190 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10191 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10192 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10193 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10194 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10195 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10196 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10197 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10198 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10199 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10200 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10201 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10202 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10203 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10204 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10205 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10206 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10207 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10208 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10209 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10210 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10211 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10212 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10213 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10214 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10215 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10216 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10217 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10218 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10219 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10220 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10221 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10222 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10223 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10224 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10225 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10226 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10227 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10228 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10229 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10230 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10231 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10232 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10233 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10234 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10235 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10236 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10237 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10238 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10239 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10241 /* SPE binary operations expecting a 5-bit unsigned literal. */
10242 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10244 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10245 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10246 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10247 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10248 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10249 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10250 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10251 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10252 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10253 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10254 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10255 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10256 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10257 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10258 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10259 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10260 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10261 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10262 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10263 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10264 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10265 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10266 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10267 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10268 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10269 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10271 /* Place-holder. Leave as last binary SPE builtin. */
10272 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10275 /* AltiVec predicates. */
10277 struct builtin_description_predicates
10279 const unsigned int mask;
10280 const enum insn_code icode;
10281 const char *const name;
10282 const enum rs6000_builtins code;
10285 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10287 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10288 ALTIVEC_BUILTIN_VCMPBFP_P },
10289 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10290 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10291 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10292 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10293 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10294 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10295 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10296 ALTIVEC_BUILTIN_VCMPEQUW_P },
10297 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10298 ALTIVEC_BUILTIN_VCMPGTSW_P },
10299 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10300 ALTIVEC_BUILTIN_VCMPGTUW_P },
10301 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10302 ALTIVEC_BUILTIN_VCMPEQUH_P },
10303 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10304 ALTIVEC_BUILTIN_VCMPGTSH_P },
10305 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10306 ALTIVEC_BUILTIN_VCMPGTUH_P },
10307 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10308 ALTIVEC_BUILTIN_VCMPEQUB_P },
10309 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10310 ALTIVEC_BUILTIN_VCMPGTSB_P },
10311 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10312 ALTIVEC_BUILTIN_VCMPGTUB_P },
10314 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10315 VSX_BUILTIN_XVCMPEQSP_P },
10316 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10317 VSX_BUILTIN_XVCMPGESP_P },
10318 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10319 VSX_BUILTIN_XVCMPGTSP_P },
10320 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10321 VSX_BUILTIN_XVCMPEQDP_P },
10322 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10323 VSX_BUILTIN_XVCMPGEDP_P },
10324 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10325 VSX_BUILTIN_XVCMPGTDP_P },
10327 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10328 ALTIVEC_BUILTIN_VCMPEQ_P },
10329 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10330 ALTIVEC_BUILTIN_VCMPGT_P },
10331 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10332 ALTIVEC_BUILTIN_VCMPGE_P }
10335 /* SPE predicates. */
10336 static struct builtin_description bdesc_spe_predicates[] =
10338 /* Place-holder. Leave as first. */
10339 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10340 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10341 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10342 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10343 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10344 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10345 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10346 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10347 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10348 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10349 /* Place-holder. Leave as last. */
10350 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10353 /* SPE evsel predicates. */
10354 static struct builtin_description bdesc_spe_evsel[] =
10356 /* Place-holder. Leave as first. */
10357 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10358 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10359 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10360 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10361 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10362 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10363 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10364 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10365 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10366 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10367 /* Place-holder. Leave as last. */
10368 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10371 /* PAIRED predicates. */
10372 static const struct builtin_description bdesc_paired_preds[] =
10374 /* Place-holder. Leave as first. */
10375 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10376 /* Place-holder. Leave as last. */
10377 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10380 /* ABS* operations. */
10382 static const struct builtin_description bdesc_abs[] =
10384 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10385 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10386 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10387 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10388 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10389 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10390 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10391 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10392 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10393 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10394 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10397 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10400 static struct builtin_description bdesc_1arg[] =
10402 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10403 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10404 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10405 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10406 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10407 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10408 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10409 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10410 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10411 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10412 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10413 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10414 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10415 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10416 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10417 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10418 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10419 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10421 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10422 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10423 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10424 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10425 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10426 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10427 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10429 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10430 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10431 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10432 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10433 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10434 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10435 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10437 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10438 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10439 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10440 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10441 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10442 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10444 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10445 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10446 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10447 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10448 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10449 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10451 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10452 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10453 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10454 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10456 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10457 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10458 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10459 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10460 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10461 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10462 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10463 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10464 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10466 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10467 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10468 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10469 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10470 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10471 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10472 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10473 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10474 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10476 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10477 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10478 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10479 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10480 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10482 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10483 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10484 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10485 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10486 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10487 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10488 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10489 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10490 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10491 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10492 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10493 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10494 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10495 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10496 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10497 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10498 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10499 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10500 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10501 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10503 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10504 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10505 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10507 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10508 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10509 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10510 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10512 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10513 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10514 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10515 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10516 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10517 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10518 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10519 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10520 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10521 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10522 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10523 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10524 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10525 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10526 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10527 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10528 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10529 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10530 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10531 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10532 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10533 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10534 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10535 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10536 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10537 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10538 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10539 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10540 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10541 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10543 /* Place-holder. Leave as last unary SPE builtin. */
10544 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10546 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10547 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10548 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10549 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10550 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10554 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10557 tree arg0 = CALL_EXPR_ARG (exp, 0);
10558 rtx op0 = expand_normal (arg0);
10559 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10560 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10562 if (icode == CODE_FOR_nothing)
10563 /* Builtin not supported on this processor. */
10566 /* If we got invalid arguments bail out before generating bad rtl. */
10567 if (arg0 == error_mark_node)
10570 if (icode == CODE_FOR_altivec_vspltisb
10571 || icode == CODE_FOR_altivec_vspltish
10572 || icode == CODE_FOR_altivec_vspltisw
10573 || icode == CODE_FOR_spe_evsplatfi
10574 || icode == CODE_FOR_spe_evsplati)
10576 /* Only allow 5-bit *signed* literals. */
10577 if (GET_CODE (op0) != CONST_INT
10578 || INTVAL (op0) > 15
10579 || INTVAL (op0) < -16)
10581 error ("argument 1 must be a 5-bit signed literal");
10587 || GET_MODE (target) != tmode
10588 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10589 target = gen_reg_rtx (tmode);
10591 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10592 op0 = copy_to_mode_reg (mode0, op0);
10594 pat = GEN_FCN (icode) (target, op0);
10603 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10605 rtx pat, scratch1, scratch2;
10606 tree arg0 = CALL_EXPR_ARG (exp, 0);
10607 rtx op0 = expand_normal (arg0);
10608 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10609 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10611 /* If we have invalid arguments, bail out before generating bad rtl. */
10612 if (arg0 == error_mark_node)
10616 || GET_MODE (target) != tmode
10617 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10618 target = gen_reg_rtx (tmode);
10620 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10621 op0 = copy_to_mode_reg (mode0, op0);
10623 scratch1 = gen_reg_rtx (mode0);
10624 scratch2 = gen_reg_rtx (mode0);
10626 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10635 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10638 tree arg0 = CALL_EXPR_ARG (exp, 0);
10639 tree arg1 = CALL_EXPR_ARG (exp, 1);
10640 rtx op0 = expand_normal (arg0);
10641 rtx op1 = expand_normal (arg1);
10642 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10643 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10644 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10646 if (icode == CODE_FOR_nothing)
10647 /* Builtin not supported on this processor. */
10650 /* If we got invalid arguments bail out before generating bad rtl. */
10651 if (arg0 == error_mark_node || arg1 == error_mark_node)
10654 if (icode == CODE_FOR_altivec_vcfux
10655 || icode == CODE_FOR_altivec_vcfsx
10656 || icode == CODE_FOR_altivec_vctsxs
10657 || icode == CODE_FOR_altivec_vctuxs
10658 || icode == CODE_FOR_altivec_vspltb
10659 || icode == CODE_FOR_altivec_vsplth
10660 || icode == CODE_FOR_altivec_vspltw
10661 || icode == CODE_FOR_spe_evaddiw
10662 || icode == CODE_FOR_spe_evldd
10663 || icode == CODE_FOR_spe_evldh
10664 || icode == CODE_FOR_spe_evldw
10665 || icode == CODE_FOR_spe_evlhhesplat
10666 || icode == CODE_FOR_spe_evlhhossplat
10667 || icode == CODE_FOR_spe_evlhhousplat
10668 || icode == CODE_FOR_spe_evlwhe
10669 || icode == CODE_FOR_spe_evlwhos
10670 || icode == CODE_FOR_spe_evlwhou
10671 || icode == CODE_FOR_spe_evlwhsplat
10672 || icode == CODE_FOR_spe_evlwwsplat
10673 || icode == CODE_FOR_spe_evrlwi
10674 || icode == CODE_FOR_spe_evslwi
10675 || icode == CODE_FOR_spe_evsrwis
10676 || icode == CODE_FOR_spe_evsubifw
10677 || icode == CODE_FOR_spe_evsrwiu)
10679 /* Only allow 5-bit unsigned literals. */
10681 if (TREE_CODE (arg1) != INTEGER_CST
10682 || TREE_INT_CST_LOW (arg1) & ~0x1f)
10684 error ("argument 2 must be a 5-bit unsigned literal");
10690 || GET_MODE (target) != tmode
10691 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10692 target = gen_reg_rtx (tmode);
10694 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10695 op0 = copy_to_mode_reg (mode0, op0);
10696 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10697 op1 = copy_to_mode_reg (mode1, op1);
10699 pat = GEN_FCN (icode) (target, op0, op1);
10708 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
10711 tree cr6_form = CALL_EXPR_ARG (exp, 0);
10712 tree arg0 = CALL_EXPR_ARG (exp, 1);
10713 tree arg1 = CALL_EXPR_ARG (exp, 2);
10714 rtx op0 = expand_normal (arg0);
10715 rtx op1 = expand_normal (arg1);
10716 enum machine_mode tmode = SImode;
10717 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10718 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10721 if (TREE_CODE (cr6_form) != INTEGER_CST)
10723 error ("argument 1 of __builtin_altivec_predicate must be a constant");
10727 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
10729 gcc_assert (mode0 == mode1);
10731 /* If we have invalid arguments, bail out before generating bad rtl. */
10732 if (arg0 == error_mark_node || arg1 == error_mark_node)
10736 || GET_MODE (target) != tmode
10737 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10738 target = gen_reg_rtx (tmode);
10740 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10741 op0 = copy_to_mode_reg (mode0, op0);
10742 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
10743 op1 = copy_to_mode_reg (mode1, op1);
10745 scratch = gen_reg_rtx (mode0);
10747 pat = GEN_FCN (icode) (scratch, op0, op1);
10752 /* The vec_any* and vec_all* predicates use the same opcodes for two
10753 different operations, but the bits in CR6 will be different
10754 depending on what information we want. So we have to play tricks
10755 with CR6 to get the right bits out.
10757 If you think this is disgusting, look at the specs for the
10758 AltiVec predicates. */
10760 switch (cr6_form_int)
10763 emit_insn (gen_cr6_test_for_zero (target));
10766 emit_insn (gen_cr6_test_for_zero_reverse (target));
10769 emit_insn (gen_cr6_test_for_lt (target));
10772 emit_insn (gen_cr6_test_for_lt_reverse (target));
10775 error ("argument 1 of __builtin_altivec_predicate is out of range");
10783 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
10786 tree arg0 = CALL_EXPR_ARG (exp, 0);
10787 tree arg1 = CALL_EXPR_ARG (exp, 1);
10788 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10789 enum machine_mode mode0 = Pmode;
10790 enum machine_mode mode1 = Pmode;
10791 rtx op0 = expand_normal (arg0);
10792 rtx op1 = expand_normal (arg1);
10794 if (icode == CODE_FOR_nothing)
10795 /* Builtin not supported on this processor. */
10798 /* If we got invalid arguments bail out before generating bad rtl. */
10799 if (arg0 == error_mark_node || arg1 == error_mark_node)
10803 || GET_MODE (target) != tmode
10804 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10805 target = gen_reg_rtx (tmode);
10807 op1 = copy_to_mode_reg (mode1, op1);
10809 if (op0 == const0_rtx)
10811 addr = gen_rtx_MEM (tmode, op1);
10815 op0 = copy_to_mode_reg (mode0, op0);
10816 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
10819 pat = GEN_FCN (icode) (target, addr);
10829 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
10832 tree arg0 = CALL_EXPR_ARG (exp, 0);
10833 tree arg1 = CALL_EXPR_ARG (exp, 1);
10834 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10835 enum machine_mode mode0 = Pmode;
10836 enum machine_mode mode1 = Pmode;
10837 rtx op0 = expand_normal (arg0);
10838 rtx op1 = expand_normal (arg1);
10840 if (icode == CODE_FOR_nothing)
10841 /* Builtin not supported on this processor. */
10844 /* If we got invalid arguments bail out before generating bad rtl. */
10845 if (arg0 == error_mark_node || arg1 == error_mark_node)
10849 || GET_MODE (target) != tmode
10850 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10851 target = gen_reg_rtx (tmode);
10853 op1 = copy_to_mode_reg (mode1, op1);
10855 if (op0 == const0_rtx)
10857 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
10861 op0 = copy_to_mode_reg (mode0, op0);
10862 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
10865 pat = GEN_FCN (icode) (target, addr);
10875 spe_expand_stv_builtin (enum insn_code icode, tree exp)
10877 tree arg0 = CALL_EXPR_ARG (exp, 0);
10878 tree arg1 = CALL_EXPR_ARG (exp, 1);
10879 tree arg2 = CALL_EXPR_ARG (exp, 2);
10880 rtx op0 = expand_normal (arg0);
10881 rtx op1 = expand_normal (arg1);
10882 rtx op2 = expand_normal (arg2);
10884 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
10885 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
10886 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
10888 /* Invalid arguments. Bail before doing anything stoopid! */
10889 if (arg0 == error_mark_node
10890 || arg1 == error_mark_node
10891 || arg2 == error_mark_node)
10894 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
10895 op0 = copy_to_mode_reg (mode2, op0);
10896 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
10897 op1 = copy_to_mode_reg (mode0, op1);
10898 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
10899 op2 = copy_to_mode_reg (mode1, op2);
10901 pat = GEN_FCN (icode) (op1, op2, op0);
10908 paired_expand_stv_builtin (enum insn_code icode, tree exp)
10910 tree arg0 = CALL_EXPR_ARG (exp, 0);
10911 tree arg1 = CALL_EXPR_ARG (exp, 1);
10912 tree arg2 = CALL_EXPR_ARG (exp, 2);
10913 rtx op0 = expand_normal (arg0);
10914 rtx op1 = expand_normal (arg1);
10915 rtx op2 = expand_normal (arg2);
10917 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10918 enum machine_mode mode1 = Pmode;
10919 enum machine_mode mode2 = Pmode;
10921 /* Invalid arguments. Bail before doing anything stoopid! */
10922 if (arg0 == error_mark_node
10923 || arg1 == error_mark_node
10924 || arg2 == error_mark_node)
10927 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10928 op0 = copy_to_mode_reg (tmode, op0);
10930 op2 = copy_to_mode_reg (mode2, op2);
10932 if (op1 == const0_rtx)
10934 addr = gen_rtx_MEM (tmode, op2);
10938 op1 = copy_to_mode_reg (mode1, op1);
10939 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10942 pat = GEN_FCN (icode) (addr, op0);
10949 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
10951 tree arg0 = CALL_EXPR_ARG (exp, 0);
10952 tree arg1 = CALL_EXPR_ARG (exp, 1);
10953 tree arg2 = CALL_EXPR_ARG (exp, 2);
10954 rtx op0 = expand_normal (arg0);
10955 rtx op1 = expand_normal (arg1);
10956 rtx op2 = expand_normal (arg2);
10958 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10959 enum machine_mode mode1 = Pmode;
10960 enum machine_mode mode2 = Pmode;
10962 /* Invalid arguments. Bail before doing anything stoopid! */
10963 if (arg0 == error_mark_node
10964 || arg1 == error_mark_node
10965 || arg2 == error_mark_node)
10968 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
10969 op0 = copy_to_mode_reg (tmode, op0);
10971 op2 = copy_to_mode_reg (mode2, op2);
10973 if (op1 == const0_rtx)
10975 addr = gen_rtx_MEM (tmode, op2);
10979 op1 = copy_to_mode_reg (mode1, op1);
10980 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
10983 pat = GEN_FCN (icode) (addr, op0);
10990 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
10993 tree arg0 = CALL_EXPR_ARG (exp, 0);
10994 tree arg1 = CALL_EXPR_ARG (exp, 1);
10995 tree arg2 = CALL_EXPR_ARG (exp, 2);
10996 rtx op0 = expand_normal (arg0);
10997 rtx op1 = expand_normal (arg1);
10998 rtx op2 = expand_normal (arg2);
10999 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11000 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11001 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11002 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11004 if (icode == CODE_FOR_nothing)
11005 /* Builtin not supported on this processor. */
11008 /* If we got invalid arguments bail out before generating bad rtl. */
11009 if (arg0 == error_mark_node
11010 || arg1 == error_mark_node
11011 || arg2 == error_mark_node)
11014 /* Check and prepare argument depending on the instruction code.
11016 Note that a switch statement instead of the sequence of tests
11017 would be incorrect as many of the CODE_FOR values could be
11018 CODE_FOR_nothing and that would yield multiple alternatives
11019 with identical values. We'd never reach here at runtime in
11021 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11022 || icode == CODE_FOR_altivec_vsldoi_v4si
11023 || icode == CODE_FOR_altivec_vsldoi_v8hi
11024 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11026 /* Only allow 4-bit unsigned literals. */
11028 if (TREE_CODE (arg2) != INTEGER_CST
11029 || TREE_INT_CST_LOW (arg2) & ~0xf)
11031 error ("argument 3 must be a 4-bit unsigned literal");
11035 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11036 || icode == CODE_FOR_vsx_xxpermdi_v2di
11037 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11038 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11039 || icode == CODE_FOR_vsx_xxsldwi_v4si
11040 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11041 || icode == CODE_FOR_vsx_xxsldwi_v2di
11042 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11044 /* Only allow 2-bit unsigned literals. */
11046 if (TREE_CODE (arg2) != INTEGER_CST
11047 || TREE_INT_CST_LOW (arg2) & ~0x3)
11049 error ("argument 3 must be a 2-bit unsigned literal");
11053 else if (icode == CODE_FOR_vsx_set_v2df
11054 || icode == CODE_FOR_vsx_set_v2di)
11056 /* Only allow 1-bit unsigned literals. */
11058 if (TREE_CODE (arg2) != INTEGER_CST
11059 || TREE_INT_CST_LOW (arg2) & ~0x1)
11061 error ("argument 3 must be a 1-bit unsigned literal");
11067 || GET_MODE (target) != tmode
11068 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11069 target = gen_reg_rtx (tmode);
11071 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11072 op0 = copy_to_mode_reg (mode0, op0);
11073 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11074 op1 = copy_to_mode_reg (mode1, op1);
11075 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11076 op2 = copy_to_mode_reg (mode2, op2);
11078 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11079 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11081 pat = GEN_FCN (icode) (target, op0, op1, op2);
11089 /* Expand the lvx builtins. */
11091 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11093 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11094 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11096 enum machine_mode tmode, mode0;
11098 enum insn_code icode;
11102 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11103 icode = CODE_FOR_vector_load_v16qi;
11105 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11106 icode = CODE_FOR_vector_load_v8hi;
11108 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11109 icode = CODE_FOR_vector_load_v4si;
11111 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11112 icode = CODE_FOR_vector_load_v4sf;
11115 *expandedp = false;
11121 arg0 = CALL_EXPR_ARG (exp, 0);
11122 op0 = expand_normal (arg0);
11123 tmode = insn_data[icode].operand[0].mode;
11124 mode0 = insn_data[icode].operand[1].mode;
11127 || GET_MODE (target) != tmode
11128 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11129 target = gen_reg_rtx (tmode);
11131 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11132 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11134 pat = GEN_FCN (icode) (target, op0);
11141 /* Expand the stvx builtins. */
11143 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11146 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11147 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11149 enum machine_mode mode0, mode1;
11151 enum insn_code icode;
11155 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11156 icode = CODE_FOR_vector_store_v16qi;
11158 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11159 icode = CODE_FOR_vector_store_v8hi;
11161 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11162 icode = CODE_FOR_vector_store_v4si;
11164 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11165 icode = CODE_FOR_vector_store_v4sf;
11168 *expandedp = false;
11172 arg0 = CALL_EXPR_ARG (exp, 0);
11173 arg1 = CALL_EXPR_ARG (exp, 1);
11174 op0 = expand_normal (arg0);
11175 op1 = expand_normal (arg1);
11176 mode0 = insn_data[icode].operand[0].mode;
11177 mode1 = insn_data[icode].operand[1].mode;
11179 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11180 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11181 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11182 op1 = copy_to_mode_reg (mode1, op1);
11184 pat = GEN_FCN (icode) (op0, op1);
11192 /* Expand the dst builtins. */
11194 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11197 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11198 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11199 tree arg0, arg1, arg2;
11200 enum machine_mode mode0, mode1;
11201 rtx pat, op0, op1, op2;
11202 const struct builtin_description *d;
11205 *expandedp = false;
11207 /* Handle DST variants. */
11209 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11210 if (d->code == fcode)
11212 arg0 = CALL_EXPR_ARG (exp, 0);
11213 arg1 = CALL_EXPR_ARG (exp, 1);
11214 arg2 = CALL_EXPR_ARG (exp, 2);
11215 op0 = expand_normal (arg0);
11216 op1 = expand_normal (arg1);
11217 op2 = expand_normal (arg2);
11218 mode0 = insn_data[d->icode].operand[0].mode;
11219 mode1 = insn_data[d->icode].operand[1].mode;
11221 /* Invalid arguments, bail out before generating bad rtl. */
11222 if (arg0 == error_mark_node
11223 || arg1 == error_mark_node
11224 || arg2 == error_mark_node)
11229 if (TREE_CODE (arg2) != INTEGER_CST
11230 || TREE_INT_CST_LOW (arg2) & ~0x3)
11232 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11236 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11237 op0 = copy_to_mode_reg (Pmode, op0);
11238 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11239 op1 = copy_to_mode_reg (mode1, op1);
11241 pat = GEN_FCN (d->icode) (op0, op1, op2);
11251 /* Expand vec_init builtin. */
11253 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11255 enum machine_mode tmode = TYPE_MODE (type);
11256 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11257 int i, n_elt = GET_MODE_NUNITS (tmode);
11258 rtvec v = rtvec_alloc (n_elt);
11260 gcc_assert (VECTOR_MODE_P (tmode));
11261 gcc_assert (n_elt == call_expr_nargs (exp));
11263 for (i = 0; i < n_elt; ++i)
11265 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11266 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11269 if (!target || !register_operand (target, tmode))
11270 target = gen_reg_rtx (tmode);
11272 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11276 /* Return the integer constant in ARG. Constrain it to be in the range
11277 of the subparts of VEC_TYPE; issue an error if not. */
11280 get_element_number (tree vec_type, tree arg)
11282 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11284 if (!host_integerp (arg, 1)
11285 || (elt = tree_low_cst (arg, 1), elt > max))
11287 error ("selector must be an integer constant in the range 0..%wi", max);
11294 /* Expand vec_set builtin. */
11296 altivec_expand_vec_set_builtin (tree exp)
11298 enum machine_mode tmode, mode1;
11299 tree arg0, arg1, arg2;
11303 arg0 = CALL_EXPR_ARG (exp, 0);
11304 arg1 = CALL_EXPR_ARG (exp, 1);
11305 arg2 = CALL_EXPR_ARG (exp, 2);
11307 tmode = TYPE_MODE (TREE_TYPE (arg0));
11308 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11309 gcc_assert (VECTOR_MODE_P (tmode));
11311 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11312 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11313 elt = get_element_number (TREE_TYPE (arg0), arg2);
11315 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11316 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11318 op0 = force_reg (tmode, op0);
11319 op1 = force_reg (mode1, op1);
11321 rs6000_expand_vector_set (op0, op1, elt);
11326 /* Expand vec_ext builtin. */
11328 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11330 enum machine_mode tmode, mode0;
11335 arg0 = CALL_EXPR_ARG (exp, 0);
11336 arg1 = CALL_EXPR_ARG (exp, 1);
11338 op0 = expand_normal (arg0);
11339 elt = get_element_number (TREE_TYPE (arg0), arg1);
11341 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11342 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11343 gcc_assert (VECTOR_MODE_P (mode0));
11345 op0 = force_reg (mode0, op0);
11347 if (optimize || !target || !register_operand (target, tmode))
11348 target = gen_reg_rtx (tmode);
11350 rs6000_expand_vector_extract (target, op0, elt);
11355 /* Expand the builtin in EXP and store the result in TARGET. Store
11356 true in *EXPANDEDP if we found a builtin to expand. */
11358 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11360 const struct builtin_description *d;
11361 const struct builtin_description_predicates *dp;
11363 enum insn_code icode;
11364 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11367 enum machine_mode tmode, mode0;
11368 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11370 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11371 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11372 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11373 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11376 error ("unresolved overload for Altivec builtin %qF", fndecl);
11380 target = altivec_expand_ld_builtin (exp, target, expandedp);
11384 target = altivec_expand_st_builtin (exp, target, expandedp);
11388 target = altivec_expand_dst_builtin (exp, target, expandedp);
11396 case ALTIVEC_BUILTIN_STVX:
11397 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
11398 case ALTIVEC_BUILTIN_STVEBX:
11399 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11400 case ALTIVEC_BUILTIN_STVEHX:
11401 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11402 case ALTIVEC_BUILTIN_STVEWX:
11403 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11404 case ALTIVEC_BUILTIN_STVXL:
11405 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11407 case ALTIVEC_BUILTIN_STVLX:
11408 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11409 case ALTIVEC_BUILTIN_STVLXL:
11410 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11411 case ALTIVEC_BUILTIN_STVRX:
11412 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11413 case ALTIVEC_BUILTIN_STVRXL:
11414 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11416 case ALTIVEC_BUILTIN_MFVSCR:
11417 icode = CODE_FOR_altivec_mfvscr;
11418 tmode = insn_data[icode].operand[0].mode;
11421 || GET_MODE (target) != tmode
11422 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11423 target = gen_reg_rtx (tmode);
11425 pat = GEN_FCN (icode) (target);
11431 case ALTIVEC_BUILTIN_MTVSCR:
11432 icode = CODE_FOR_altivec_mtvscr;
11433 arg0 = CALL_EXPR_ARG (exp, 0);
11434 op0 = expand_normal (arg0);
11435 mode0 = insn_data[icode].operand[0].mode;
11437 /* If we got invalid arguments bail out before generating bad rtl. */
11438 if (arg0 == error_mark_node)
11441 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11442 op0 = copy_to_mode_reg (mode0, op0);
11444 pat = GEN_FCN (icode) (op0);
11449 case ALTIVEC_BUILTIN_DSSALL:
11450 emit_insn (gen_altivec_dssall ());
11453 case ALTIVEC_BUILTIN_DSS:
11454 icode = CODE_FOR_altivec_dss;
11455 arg0 = CALL_EXPR_ARG (exp, 0);
11457 op0 = expand_normal (arg0);
11458 mode0 = insn_data[icode].operand[0].mode;
11460 /* If we got invalid arguments bail out before generating bad rtl. */
11461 if (arg0 == error_mark_node)
11464 if (TREE_CODE (arg0) != INTEGER_CST
11465 || TREE_INT_CST_LOW (arg0) & ~0x3)
11467 error ("argument to dss must be a 2-bit unsigned literal");
11471 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11472 op0 = copy_to_mode_reg (mode0, op0);
11474 emit_insn (gen_altivec_dss (op0));
11477 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11478 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11479 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11480 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11481 case VSX_BUILTIN_VEC_INIT_V2DF:
11482 case VSX_BUILTIN_VEC_INIT_V2DI:
11483 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11485 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11486 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11487 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11488 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11489 case VSX_BUILTIN_VEC_SET_V2DF:
11490 case VSX_BUILTIN_VEC_SET_V2DI:
11491 return altivec_expand_vec_set_builtin (exp);
11493 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11494 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11495 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11496 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11497 case VSX_BUILTIN_VEC_EXT_V2DF:
11498 case VSX_BUILTIN_VEC_EXT_V2DI:
11499 return altivec_expand_vec_ext_builtin (exp, target);
11503 /* Fall through. */
11506 /* Expand abs* operations. */
11508 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11509 if (d->code == fcode)
11510 return altivec_expand_abs_builtin (d->icode, exp, target);
11512 /* Expand the AltiVec predicates. */
11513 dp = bdesc_altivec_preds;
11514 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11515 if (dp->code == fcode)
11516 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11518 /* LV* are funky. We initialized them differently. */
11521 case ALTIVEC_BUILTIN_LVSL:
11522 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11523 exp, target, false);
11524 case ALTIVEC_BUILTIN_LVSR:
11525 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11526 exp, target, false);
11527 case ALTIVEC_BUILTIN_LVEBX:
11528 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11529 exp, target, false);
11530 case ALTIVEC_BUILTIN_LVEHX:
11531 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11532 exp, target, false);
11533 case ALTIVEC_BUILTIN_LVEWX:
11534 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11535 exp, target, false);
11536 case ALTIVEC_BUILTIN_LVXL:
11537 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11538 exp, target, false);
11539 case ALTIVEC_BUILTIN_LVX:
11540 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
11541 exp, target, false);
11542 case ALTIVEC_BUILTIN_LVLX:
11543 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11544 exp, target, true);
11545 case ALTIVEC_BUILTIN_LVLXL:
11546 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11547 exp, target, true);
11548 case ALTIVEC_BUILTIN_LVRX:
11549 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11550 exp, target, true);
11551 case ALTIVEC_BUILTIN_LVRXL:
11552 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11553 exp, target, true);
11556 /* Fall through. */
11559 *expandedp = false;
11563 /* Expand the builtin in EXP and store the result in TARGET. Store
11564 true in *EXPANDEDP if we found a builtin to expand. */
11566 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11568 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11569 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11570 const struct builtin_description *d;
11577 case PAIRED_BUILTIN_STX:
11578 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11579 case PAIRED_BUILTIN_LX:
11580 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11583 /* Fall through. */
11586 /* Expand the paired predicates. */
11587 d = bdesc_paired_preds;
11588 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11589 if (d->code == fcode)
11590 return paired_expand_predicate_builtin (d->icode, exp, target);
11592 *expandedp = false;
11596 /* Binops that need to be initialized manually, but can be expanded
11597 automagically by rs6000_expand_binop_builtin. */
11598 static struct builtin_description bdesc_2arg_spe[] =
11600 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11601 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11602 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11603 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11604 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11605 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
11606 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
11607 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
11608 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
11609 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
11610 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
11611 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
11612 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
11613 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
11614 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
11615 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
11616 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
11617 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
11618 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
11619 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
11620 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
11621 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
11624 /* Expand the builtin in EXP and store the result in TARGET. Store
11625 true in *EXPANDEDP if we found a builtin to expand.
11627 This expands the SPE builtins that are not simple unary and binary
11630 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
11632 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11634 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11635 enum insn_code icode;
11636 enum machine_mode tmode, mode0;
11638 struct builtin_description *d;
11643 /* Syntax check for a 5-bit unsigned immediate. */
11646 case SPE_BUILTIN_EVSTDD:
11647 case SPE_BUILTIN_EVSTDH:
11648 case SPE_BUILTIN_EVSTDW:
11649 case SPE_BUILTIN_EVSTWHE:
11650 case SPE_BUILTIN_EVSTWHO:
11651 case SPE_BUILTIN_EVSTWWE:
11652 case SPE_BUILTIN_EVSTWWO:
11653 arg1 = CALL_EXPR_ARG (exp, 2);
11654 if (TREE_CODE (arg1) != INTEGER_CST
11655 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11657 error ("argument 2 must be a 5-bit unsigned literal");
11665 /* The evsplat*i instructions are not quite generic. */
11668 case SPE_BUILTIN_EVSPLATFI:
11669 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
11671 case SPE_BUILTIN_EVSPLATI:
11672 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
11678 d = (struct builtin_description *) bdesc_2arg_spe;
11679 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
11680 if (d->code == fcode)
11681 return rs6000_expand_binop_builtin (d->icode, exp, target);
11683 d = (struct builtin_description *) bdesc_spe_predicates;
11684 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
11685 if (d->code == fcode)
11686 return spe_expand_predicate_builtin (d->icode, exp, target);
11688 d = (struct builtin_description *) bdesc_spe_evsel;
11689 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
11690 if (d->code == fcode)
11691 return spe_expand_evsel_builtin (d->icode, exp, target);
11695 case SPE_BUILTIN_EVSTDDX:
11696 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
11697 case SPE_BUILTIN_EVSTDHX:
11698 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
11699 case SPE_BUILTIN_EVSTDWX:
11700 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
11701 case SPE_BUILTIN_EVSTWHEX:
11702 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
11703 case SPE_BUILTIN_EVSTWHOX:
11704 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
11705 case SPE_BUILTIN_EVSTWWEX:
11706 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
11707 case SPE_BUILTIN_EVSTWWOX:
11708 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
11709 case SPE_BUILTIN_EVSTDD:
11710 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
11711 case SPE_BUILTIN_EVSTDH:
11712 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
11713 case SPE_BUILTIN_EVSTDW:
11714 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
11715 case SPE_BUILTIN_EVSTWHE:
11716 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
11717 case SPE_BUILTIN_EVSTWHO:
11718 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
11719 case SPE_BUILTIN_EVSTWWE:
11720 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
11721 case SPE_BUILTIN_EVSTWWO:
11722 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
11723 case SPE_BUILTIN_MFSPEFSCR:
11724 icode = CODE_FOR_spe_mfspefscr;
11725 tmode = insn_data[icode].operand[0].mode;
11728 || GET_MODE (target) != tmode
11729 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11730 target = gen_reg_rtx (tmode);
11732 pat = GEN_FCN (icode) (target);
11737 case SPE_BUILTIN_MTSPEFSCR:
11738 icode = CODE_FOR_spe_mtspefscr;
11739 arg0 = CALL_EXPR_ARG (exp, 0);
11740 op0 = expand_normal (arg0);
11741 mode0 = insn_data[icode].operand[0].mode;
11743 if (arg0 == error_mark_node)
11746 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11747 op0 = copy_to_mode_reg (mode0, op0);
11749 pat = GEN_FCN (icode) (op0);
11757 *expandedp = false;
11762 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11764 rtx pat, scratch, tmp;
11765 tree form = CALL_EXPR_ARG (exp, 0);
11766 tree arg0 = CALL_EXPR_ARG (exp, 1);
11767 tree arg1 = CALL_EXPR_ARG (exp, 2);
11768 rtx op0 = expand_normal (arg0);
11769 rtx op1 = expand_normal (arg1);
11770 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11771 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11773 enum rtx_code code;
11775 if (TREE_CODE (form) != INTEGER_CST)
11777 error ("argument 1 of __builtin_paired_predicate must be a constant");
11781 form_int = TREE_INT_CST_LOW (form);
11783 gcc_assert (mode0 == mode1);
11785 if (arg0 == error_mark_node || arg1 == error_mark_node)
11789 || GET_MODE (target) != SImode
11790 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
11791 target = gen_reg_rtx (SImode);
11792 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
11793 op0 = copy_to_mode_reg (mode0, op0);
11794 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
11795 op1 = copy_to_mode_reg (mode1, op1);
11797 scratch = gen_reg_rtx (CCFPmode);
11799 pat = GEN_FCN (icode) (scratch, op0, op1);
11821 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11824 error ("argument 1 of __builtin_paired_predicate is out of range");
11828 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11829 emit_move_insn (target, tmp);
11834 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11836 rtx pat, scratch, tmp;
11837 tree form = CALL_EXPR_ARG (exp, 0);
11838 tree arg0 = CALL_EXPR_ARG (exp, 1);
11839 tree arg1 = CALL_EXPR_ARG (exp, 2);
11840 rtx op0 = expand_normal (arg0);
11841 rtx op1 = expand_normal (arg1);
11842 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11843 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11845 enum rtx_code code;
11847 if (TREE_CODE (form) != INTEGER_CST)
11849 error ("argument 1 of __builtin_spe_predicate must be a constant");
11853 form_int = TREE_INT_CST_LOW (form);
11855 gcc_assert (mode0 == mode1);
11857 if (arg0 == error_mark_node || arg1 == error_mark_node)
11861 || GET_MODE (target) != SImode
11862 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
11863 target = gen_reg_rtx (SImode);
11865 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11866 op0 = copy_to_mode_reg (mode0, op0);
11867 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11868 op1 = copy_to_mode_reg (mode1, op1);
11870 scratch = gen_reg_rtx (CCmode);
11872 pat = GEN_FCN (icode) (scratch, op0, op1);
11877 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
11878 _lower_. We use one compare, but look in different bits of the
11879 CR for each variant.
11881 There are 2 elements in each SPE simd type (upper/lower). The CR
11882 bits are set as follows:
11884 BIT0 | BIT 1 | BIT 2 | BIT 3
11885 U | L | (U | L) | (U & L)
11887 So, for an "all" relationship, BIT 3 would be set.
11888 For an "any" relationship, BIT 2 would be set. Etc.
11890 Following traditional nomenclature, these bits map to:
11892 BIT0 | BIT 1 | BIT 2 | BIT 3
11895 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
11900 /* All variant. OV bit. */
11902 /* We need to get to the OV bit, which is the ORDERED bit. We
11903 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
11904 that's ugly and will make validate_condition_mode die.
11905 So let's just use another pattern. */
11906 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
11908 /* Any variant. EQ bit. */
11912 /* Upper variant. LT bit. */
11916 /* Lower variant. GT bit. */
11921 error ("argument 1 of __builtin_spe_predicate is out of range");
11925 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
11926 emit_move_insn (target, tmp);
11931 /* The evsel builtins look like this:
11933 e = __builtin_spe_evsel_OP (a, b, c, d);
11935 and work like this:
11937 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
11938 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
11942 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
11945 tree arg0 = CALL_EXPR_ARG (exp, 0);
11946 tree arg1 = CALL_EXPR_ARG (exp, 1);
11947 tree arg2 = CALL_EXPR_ARG (exp, 2);
11948 tree arg3 = CALL_EXPR_ARG (exp, 3);
11949 rtx op0 = expand_normal (arg0);
11950 rtx op1 = expand_normal (arg1);
11951 rtx op2 = expand_normal (arg2);
11952 rtx op3 = expand_normal (arg3);
11953 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11954 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11956 gcc_assert (mode0 == mode1);
11958 if (arg0 == error_mark_node || arg1 == error_mark_node
11959 || arg2 == error_mark_node || arg3 == error_mark_node)
11963 || GET_MODE (target) != mode0
11964 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
11965 target = gen_reg_rtx (mode0);
11967 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11968 op0 = copy_to_mode_reg (mode0, op0);
11969 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11970 op1 = copy_to_mode_reg (mode0, op1);
11971 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11972 op2 = copy_to_mode_reg (mode0, op2);
11973 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
11974 op3 = copy_to_mode_reg (mode0, op3);
11976 /* Generate the compare. */
11977 scratch = gen_reg_rtx (CCmode);
11978 pat = GEN_FCN (icode) (scratch, op0, op1);
11983 if (mode0 == V2SImode)
11984 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
11986 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
11991 /* Expand an expression EXP that calls a built-in function,
11992 with result going to TARGET if that's convenient
11993 (and in mode MODE if that's convenient).
11994 SUBTARGET may be used as the target for computing one of EXP's operands.
11995 IGNORE is nonzero if the value is to be ignored. */
11998 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
11999 enum machine_mode mode ATTRIBUTE_UNUSED,
12000 int ignore ATTRIBUTE_UNUSED)
12002 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12003 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12004 const struct builtin_description *d;
12011 case RS6000_BUILTIN_RECIP:
12012 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12014 case RS6000_BUILTIN_RECIPF:
12015 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12017 case RS6000_BUILTIN_RSQRTF:
12018 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12020 case RS6000_BUILTIN_RSQRT:
12021 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12023 case RS6000_BUILTIN_BSWAP_HI:
12024 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12026 case POWER7_BUILTIN_BPERMD:
12027 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12028 ? CODE_FOR_bpermd_di
12029 : CODE_FOR_bpermd_si), exp, target);
12031 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12032 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12034 int icode = (int) CODE_FOR_altivec_lvsr;
12035 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12036 enum machine_mode mode = insn_data[icode].operand[1].mode;
12040 gcc_assert (TARGET_ALTIVEC);
12042 arg = CALL_EXPR_ARG (exp, 0);
12043 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12044 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12045 addr = memory_address (mode, op);
12046 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12050 /* For the load case need to negate the address. */
12051 op = gen_reg_rtx (GET_MODE (addr));
12052 emit_insn (gen_rtx_SET (VOIDmode, op,
12053 gen_rtx_NEG (GET_MODE (addr), addr)));
12055 op = gen_rtx_MEM (mode, op);
12058 || GET_MODE (target) != tmode
12059 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12060 target = gen_reg_rtx (tmode);
12062 /*pat = gen_altivec_lvsr (target, op);*/
12063 pat = GEN_FCN (icode) (target, op);
12071 case ALTIVEC_BUILTIN_VCFUX:
12072 case ALTIVEC_BUILTIN_VCFSX:
12073 case ALTIVEC_BUILTIN_VCTUXS:
12074 case ALTIVEC_BUILTIN_VCTSXS:
12075 /* FIXME: There's got to be a nicer way to handle this case than
12076 constructing a new CALL_EXPR. */
12077 if (call_expr_nargs (exp) == 1)
12079 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12080 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12088 if (TARGET_ALTIVEC)
12090 ret = altivec_expand_builtin (exp, target, &success);
12097 ret = spe_expand_builtin (exp, target, &success);
12102 if (TARGET_PAIRED_FLOAT)
12104 ret = paired_expand_builtin (exp, target, &success);
12110 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12112 /* Handle simple unary operations. */
12113 d = (struct builtin_description *) bdesc_1arg;
12114 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12115 if (d->code == fcode)
12116 return rs6000_expand_unop_builtin (d->icode, exp, target);
12118 /* Handle simple binary operations. */
12119 d = (struct builtin_description *) bdesc_2arg;
12120 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12121 if (d->code == fcode)
12122 return rs6000_expand_binop_builtin (d->icode, exp, target);
12124 /* Handle simple ternary operations. */
12126 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12127 if (d->code == fcode)
12128 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12130 gcc_unreachable ();
12134 rs6000_init_builtins (void)
12139 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12140 V2SF_type_node = build_vector_type (float_type_node, 2);
12141 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12142 V2DF_type_node = build_vector_type (double_type_node, 2);
12143 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12144 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12145 V4SF_type_node = build_vector_type (float_type_node, 4);
12146 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12147 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12149 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12150 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12151 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12152 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12154 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12155 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12156 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12157 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12159 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12160 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12161 'vector unsigned short'. */
12163 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12164 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12165 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12166 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12167 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12169 long_integer_type_internal_node = long_integer_type_node;
12170 long_unsigned_type_internal_node = long_unsigned_type_node;
12171 intQI_type_internal_node = intQI_type_node;
12172 uintQI_type_internal_node = unsigned_intQI_type_node;
12173 intHI_type_internal_node = intHI_type_node;
12174 uintHI_type_internal_node = unsigned_intHI_type_node;
12175 intSI_type_internal_node = intSI_type_node;
12176 uintSI_type_internal_node = unsigned_intSI_type_node;
12177 intDI_type_internal_node = intDI_type_node;
12178 uintDI_type_internal_node = unsigned_intDI_type_node;
12179 float_type_internal_node = float_type_node;
12180 double_type_internal_node = float_type_node;
12181 void_type_internal_node = void_type_node;
12183 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12185 builtin_mode_to_type[QImode][0] = integer_type_node;
12186 builtin_mode_to_type[HImode][0] = integer_type_node;
12187 builtin_mode_to_type[SImode][0] = intSI_type_node;
12188 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12189 builtin_mode_to_type[DImode][0] = intDI_type_node;
12190 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12191 builtin_mode_to_type[SFmode][0] = float_type_node;
12192 builtin_mode_to_type[DFmode][0] = double_type_node;
12193 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12194 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12195 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12196 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12197 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12198 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12199 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12200 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12201 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12202 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12203 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12204 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12205 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12207 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12208 get_identifier ("__bool char"),
12209 bool_char_type_node);
12210 TYPE_NAME (bool_char_type_node) = tdecl;
12211 (*lang_hooks.decls.pushdecl) (tdecl);
12212 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12213 get_identifier ("__bool short"),
12214 bool_short_type_node);
12215 TYPE_NAME (bool_short_type_node) = tdecl;
12216 (*lang_hooks.decls.pushdecl) (tdecl);
12217 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12218 get_identifier ("__bool int"),
12219 bool_int_type_node);
12220 TYPE_NAME (bool_int_type_node) = tdecl;
12221 (*lang_hooks.decls.pushdecl) (tdecl);
12222 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12224 TYPE_NAME (pixel_type_node) = tdecl;
12225 (*lang_hooks.decls.pushdecl) (tdecl);
12227 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12228 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12229 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12230 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12231 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12233 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12234 get_identifier ("__vector unsigned char"),
12235 unsigned_V16QI_type_node);
12236 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12237 (*lang_hooks.decls.pushdecl) (tdecl);
12238 tdecl = build_decl (BUILTINS_LOCATION,
12239 TYPE_DECL, get_identifier ("__vector signed char"),
12241 TYPE_NAME (V16QI_type_node) = tdecl;
12242 (*lang_hooks.decls.pushdecl) (tdecl);
12243 tdecl = build_decl (BUILTINS_LOCATION,
12244 TYPE_DECL, get_identifier ("__vector __bool char"),
12245 bool_V16QI_type_node);
12246 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12247 (*lang_hooks.decls.pushdecl) (tdecl);
12249 tdecl = build_decl (BUILTINS_LOCATION,
12250 TYPE_DECL, get_identifier ("__vector unsigned short"),
12251 unsigned_V8HI_type_node);
12252 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12253 (*lang_hooks.decls.pushdecl) (tdecl);
12254 tdecl = build_decl (BUILTINS_LOCATION,
12255 TYPE_DECL, get_identifier ("__vector signed short"),
12257 TYPE_NAME (V8HI_type_node) = tdecl;
12258 (*lang_hooks.decls.pushdecl) (tdecl);
12259 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12260 get_identifier ("__vector __bool short"),
12261 bool_V8HI_type_node);
12262 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12263 (*lang_hooks.decls.pushdecl) (tdecl);
12265 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12266 get_identifier ("__vector unsigned int"),
12267 unsigned_V4SI_type_node);
12268 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12269 (*lang_hooks.decls.pushdecl) (tdecl);
12270 tdecl = build_decl (BUILTINS_LOCATION,
12271 TYPE_DECL, get_identifier ("__vector signed int"),
12273 TYPE_NAME (V4SI_type_node) = tdecl;
12274 (*lang_hooks.decls.pushdecl) (tdecl);
12275 tdecl = build_decl (BUILTINS_LOCATION,
12276 TYPE_DECL, get_identifier ("__vector __bool int"),
12277 bool_V4SI_type_node);
12278 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12279 (*lang_hooks.decls.pushdecl) (tdecl);
12281 tdecl = build_decl (BUILTINS_LOCATION,
12282 TYPE_DECL, get_identifier ("__vector float"),
12284 TYPE_NAME (V4SF_type_node) = tdecl;
12285 (*lang_hooks.decls.pushdecl) (tdecl);
12286 tdecl = build_decl (BUILTINS_LOCATION,
12287 TYPE_DECL, get_identifier ("__vector __pixel"),
12288 pixel_V8HI_type_node);
12289 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12290 (*lang_hooks.decls.pushdecl) (tdecl);
12294 tdecl = build_decl (BUILTINS_LOCATION,
12295 TYPE_DECL, get_identifier ("__vector double"),
12297 TYPE_NAME (V2DF_type_node) = tdecl;
12298 (*lang_hooks.decls.pushdecl) (tdecl);
12300 tdecl = build_decl (BUILTINS_LOCATION,
12301 TYPE_DECL, get_identifier ("__vector long"),
12303 TYPE_NAME (V2DI_type_node) = tdecl;
12304 (*lang_hooks.decls.pushdecl) (tdecl);
12306 tdecl = build_decl (BUILTINS_LOCATION,
12307 TYPE_DECL, get_identifier ("__vector unsigned long"),
12308 unsigned_V2DI_type_node);
12309 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12310 (*lang_hooks.decls.pushdecl) (tdecl);
12312 tdecl = build_decl (BUILTINS_LOCATION,
12313 TYPE_DECL, get_identifier ("__vector __bool long"),
12314 bool_V2DI_type_node);
12315 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12316 (*lang_hooks.decls.pushdecl) (tdecl);
12319 if (TARGET_PAIRED_FLOAT)
12320 paired_init_builtins ();
12322 spe_init_builtins ();
12323 if (TARGET_ALTIVEC)
12324 altivec_init_builtins ();
12325 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12326 rs6000_common_init_builtins ();
12329 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12330 RS6000_BUILTIN_RECIP,
12331 "__builtin_recipdiv");
12332 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12333 RS6000_BUILTIN_RECIP);
12337 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12338 RS6000_BUILTIN_RECIPF,
12339 "__builtin_recipdivf");
12340 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12341 RS6000_BUILTIN_RECIPF);
12343 if (TARGET_FRSQRTE)
12345 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12346 RS6000_BUILTIN_RSQRT,
12347 "__builtin_rsqrt");
12348 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12349 RS6000_BUILTIN_RSQRT);
12351 if (TARGET_FRSQRTES)
12353 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12354 RS6000_BUILTIN_RSQRTF,
12355 "__builtin_rsqrtf");
12356 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12357 RS6000_BUILTIN_RSQRTF);
12359 if (TARGET_POPCNTD)
12361 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12362 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12363 POWER7_BUILTIN_BPERMD,
12364 "__builtin_bpermd");
12365 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12366 POWER7_BUILTIN_BPERMD);
12368 if (TARGET_POWERPC)
12370 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12371 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12372 unsigned_intHI_type_node,
12374 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12375 RS6000_BUILTIN_BSWAP_HI);
12379 /* AIX libm provides clog as __clog. */
12380 if (built_in_decls [BUILT_IN_CLOG])
12381 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12384 #ifdef SUBTARGET_INIT_BUILTINS
12385 SUBTARGET_INIT_BUILTINS;
12389 /* Returns the rs6000 builtin decl for CODE. */
12392 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12394 if (code >= RS6000_BUILTIN_COUNT)
12395 return error_mark_node;
12397 return rs6000_builtin_decls[code];
12400 /* Search through a set of builtins and enable the mask bits.
12401 DESC is an array of builtins.
12402 SIZE is the total number of builtins.
12403 START is the builtin enum at which to start.
12404 END is the builtin enum at which to end. */
12406 enable_mask_for_builtins (struct builtin_description *desc, int size,
12407 enum rs6000_builtins start,
12408 enum rs6000_builtins end)
12412 for (i = 0; i < size; ++i)
12413 if (desc[i].code == start)
12419 for (; i < size; ++i)
12421 /* Flip all the bits on. */
12422 desc[i].mask = target_flags;
12423 if (desc[i].code == end)
12429 spe_init_builtins (void)
12431 tree endlink = void_list_node;
12432 tree puint_type_node = build_pointer_type (unsigned_type_node);
12433 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12434 struct builtin_description *d;
12437 tree v2si_ftype_4_v2si
12438 = build_function_type
12439 (opaque_V2SI_type_node,
12440 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12441 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12442 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12443 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12446 tree v2sf_ftype_4_v2sf
12447 = build_function_type
12448 (opaque_V2SF_type_node,
12449 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12450 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12451 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12452 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12455 tree int_ftype_int_v2si_v2si
12456 = build_function_type
12457 (integer_type_node,
12458 tree_cons (NULL_TREE, integer_type_node,
12459 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12460 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12463 tree int_ftype_int_v2sf_v2sf
12464 = build_function_type
12465 (integer_type_node,
12466 tree_cons (NULL_TREE, integer_type_node,
12467 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12468 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12471 tree void_ftype_v2si_puint_int
12472 = build_function_type (void_type_node,
12473 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12474 tree_cons (NULL_TREE, puint_type_node,
12475 tree_cons (NULL_TREE,
12479 tree void_ftype_v2si_puint_char
12480 = build_function_type (void_type_node,
12481 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12482 tree_cons (NULL_TREE, puint_type_node,
12483 tree_cons (NULL_TREE,
12487 tree void_ftype_v2si_pv2si_int
12488 = build_function_type (void_type_node,
12489 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12490 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12491 tree_cons (NULL_TREE,
12495 tree void_ftype_v2si_pv2si_char
12496 = build_function_type (void_type_node,
12497 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12498 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12499 tree_cons (NULL_TREE,
12503 tree void_ftype_int
12504 = build_function_type (void_type_node,
12505 tree_cons (NULL_TREE, integer_type_node, endlink));
12507 tree int_ftype_void
12508 = build_function_type (integer_type_node, endlink);
12510 tree v2si_ftype_pv2si_int
12511 = build_function_type (opaque_V2SI_type_node,
12512 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12513 tree_cons (NULL_TREE, integer_type_node,
12516 tree v2si_ftype_puint_int
12517 = build_function_type (opaque_V2SI_type_node,
12518 tree_cons (NULL_TREE, puint_type_node,
12519 tree_cons (NULL_TREE, integer_type_node,
12522 tree v2si_ftype_pushort_int
12523 = build_function_type (opaque_V2SI_type_node,
12524 tree_cons (NULL_TREE, pushort_type_node,
12525 tree_cons (NULL_TREE, integer_type_node,
12528 tree v2si_ftype_signed_char
12529 = build_function_type (opaque_V2SI_type_node,
12530 tree_cons (NULL_TREE, signed_char_type_node,
12533 /* The initialization of the simple binary and unary builtins is
12534 done in rs6000_common_init_builtins, but we have to enable the
12535 mask bits here manually because we have run out of `target_flags'
12536 bits. We really need to redesign this mask business. */
12538 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12539 ARRAY_SIZE (bdesc_2arg),
12540 SPE_BUILTIN_EVADDW,
12541 SPE_BUILTIN_EVXOR);
12542 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12543 ARRAY_SIZE (bdesc_1arg),
12545 SPE_BUILTIN_EVSUBFUSIAAW);
12546 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12547 ARRAY_SIZE (bdesc_spe_predicates),
12548 SPE_BUILTIN_EVCMPEQ,
12549 SPE_BUILTIN_EVFSTSTLT);
12550 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12551 ARRAY_SIZE (bdesc_spe_evsel),
12552 SPE_BUILTIN_EVSEL_CMPGTS,
12553 SPE_BUILTIN_EVSEL_FSTSTEQ);
12555 (*lang_hooks.decls.pushdecl)
12556 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12557 get_identifier ("__ev64_opaque__"),
12558 opaque_V2SI_type_node));
12560 /* Initialize irregular SPE builtins. */
12562 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12563 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12564 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12565 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12566 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12567 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12568 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12569 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12570 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12571 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12572 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12573 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12574 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12575 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12576 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12577 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12578 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12579 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12582 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12583 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12584 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12585 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12586 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12587 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12588 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12589 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12590 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12591 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12592 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12593 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12594 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12595 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12596 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12597 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12598 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12599 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12600 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12601 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12602 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12603 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
12606 d = (struct builtin_description *) bdesc_spe_predicates;
12607 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
12611 switch (insn_data[d->icode].operand[1].mode)
12614 type = int_ftype_int_v2si_v2si;
12617 type = int_ftype_int_v2sf_v2sf;
12620 gcc_unreachable ();
12623 def_builtin (d->mask, d->name, type, d->code);
12626 /* Evsel predicates. */
12627 d = (struct builtin_description *) bdesc_spe_evsel;
12628 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
12632 switch (insn_data[d->icode].operand[1].mode)
12635 type = v2si_ftype_4_v2si;
12638 type = v2sf_ftype_4_v2sf;
12641 gcc_unreachable ();
12644 def_builtin (d->mask, d->name, type, d->code);
12649 paired_init_builtins (void)
12651 const struct builtin_description *d;
12653 tree endlink = void_list_node;
12655 tree int_ftype_int_v2sf_v2sf
12656 = build_function_type
12657 (integer_type_node,
12658 tree_cons (NULL_TREE, integer_type_node,
12659 tree_cons (NULL_TREE, V2SF_type_node,
12660 tree_cons (NULL_TREE, V2SF_type_node,
12662 tree pcfloat_type_node =
12663 build_pointer_type (build_qualified_type
12664 (float_type_node, TYPE_QUAL_CONST));
12666 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
12667 long_integer_type_node,
12670 tree void_ftype_v2sf_long_pcfloat =
12671 build_function_type_list (void_type_node,
12673 long_integer_type_node,
12678 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
12679 PAIRED_BUILTIN_LX);
12682 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
12683 PAIRED_BUILTIN_STX);
12686 d = bdesc_paired_preds;
12687 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
12691 switch (insn_data[d->icode].operand[1].mode)
12694 type = int_ftype_int_v2sf_v2sf;
12697 gcc_unreachable ();
12700 def_builtin (d->mask, d->name, type, d->code);
12705 altivec_init_builtins (void)
12707 const struct builtin_description *d;
12708 const struct builtin_description_predicates *dp;
12712 tree pfloat_type_node = build_pointer_type (float_type_node);
12713 tree pint_type_node = build_pointer_type (integer_type_node);
12714 tree pshort_type_node = build_pointer_type (short_integer_type_node);
12715 tree pchar_type_node = build_pointer_type (char_type_node);
12717 tree pvoid_type_node = build_pointer_type (void_type_node);
12719 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
12720 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
12721 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
12722 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
12724 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
12726 tree int_ftype_opaque
12727 = build_function_type_list (integer_type_node,
12728 opaque_V4SI_type_node, NULL_TREE);
12729 tree opaque_ftype_opaque
12730 = build_function_type (integer_type_node,
12732 tree opaque_ftype_opaque_int
12733 = build_function_type_list (opaque_V4SI_type_node,
12734 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
12735 tree opaque_ftype_opaque_opaque_int
12736 = build_function_type_list (opaque_V4SI_type_node,
12737 opaque_V4SI_type_node, opaque_V4SI_type_node,
12738 integer_type_node, NULL_TREE);
12739 tree int_ftype_int_opaque_opaque
12740 = build_function_type_list (integer_type_node,
12741 integer_type_node, opaque_V4SI_type_node,
12742 opaque_V4SI_type_node, NULL_TREE);
12743 tree int_ftype_int_v4si_v4si
12744 = build_function_type_list (integer_type_node,
12745 integer_type_node, V4SI_type_node,
12746 V4SI_type_node, NULL_TREE);
12747 tree v4sf_ftype_pcfloat
12748 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
12749 tree void_ftype_pfloat_v4sf
12750 = build_function_type_list (void_type_node,
12751 pfloat_type_node, V4SF_type_node, NULL_TREE);
12752 tree v4si_ftype_pcint
12753 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
12754 tree void_ftype_pint_v4si
12755 = build_function_type_list (void_type_node,
12756 pint_type_node, V4SI_type_node, NULL_TREE);
12757 tree v8hi_ftype_pcshort
12758 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
12759 tree void_ftype_pshort_v8hi
12760 = build_function_type_list (void_type_node,
12761 pshort_type_node, V8HI_type_node, NULL_TREE);
12762 tree v16qi_ftype_pcchar
12763 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
12764 tree void_ftype_pchar_v16qi
12765 = build_function_type_list (void_type_node,
12766 pchar_type_node, V16QI_type_node, NULL_TREE);
12767 tree void_ftype_v4si
12768 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
12769 tree v8hi_ftype_void
12770 = build_function_type (V8HI_type_node, void_list_node);
12771 tree void_ftype_void
12772 = build_function_type (void_type_node, void_list_node);
12773 tree void_ftype_int
12774 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
12776 tree opaque_ftype_long_pcvoid
12777 = build_function_type_list (opaque_V4SI_type_node,
12778 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12779 tree v16qi_ftype_long_pcvoid
12780 = build_function_type_list (V16QI_type_node,
12781 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12782 tree v8hi_ftype_long_pcvoid
12783 = build_function_type_list (V8HI_type_node,
12784 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12785 tree v4si_ftype_long_pcvoid
12786 = build_function_type_list (V4SI_type_node,
12787 long_integer_type_node, pcvoid_type_node, NULL_TREE);
12789 tree void_ftype_opaque_long_pvoid
12790 = build_function_type_list (void_type_node,
12791 opaque_V4SI_type_node, long_integer_type_node,
12792 pvoid_type_node, NULL_TREE);
12793 tree void_ftype_v4si_long_pvoid
12794 = build_function_type_list (void_type_node,
12795 V4SI_type_node, long_integer_type_node,
12796 pvoid_type_node, NULL_TREE);
12797 tree void_ftype_v16qi_long_pvoid
12798 = build_function_type_list (void_type_node,
12799 V16QI_type_node, long_integer_type_node,
12800 pvoid_type_node, NULL_TREE);
12801 tree void_ftype_v8hi_long_pvoid
12802 = build_function_type_list (void_type_node,
12803 V8HI_type_node, long_integer_type_node,
12804 pvoid_type_node, NULL_TREE);
12805 tree int_ftype_int_v8hi_v8hi
12806 = build_function_type_list (integer_type_node,
12807 integer_type_node, V8HI_type_node,
12808 V8HI_type_node, NULL_TREE);
12809 tree int_ftype_int_v16qi_v16qi
12810 = build_function_type_list (integer_type_node,
12811 integer_type_node, V16QI_type_node,
12812 V16QI_type_node, NULL_TREE);
12813 tree int_ftype_int_v4sf_v4sf
12814 = build_function_type_list (integer_type_node,
12815 integer_type_node, V4SF_type_node,
12816 V4SF_type_node, NULL_TREE);
12817 tree int_ftype_int_v2df_v2df
12818 = build_function_type_list (integer_type_node,
12819 integer_type_node, V2DF_type_node,
12820 V2DF_type_node, NULL_TREE);
12821 tree v4si_ftype_v4si
12822 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
12823 tree v8hi_ftype_v8hi
12824 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
12825 tree v16qi_ftype_v16qi
12826 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
12827 tree v4sf_ftype_v4sf
12828 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
12829 tree v2df_ftype_v2df
12830 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
12831 tree void_ftype_pcvoid_int_int
12832 = build_function_type_list (void_type_node,
12833 pcvoid_type_node, integer_type_node,
12834 integer_type_node, NULL_TREE);
12836 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
12837 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
12838 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
12839 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
12840 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
12841 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
12842 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
12843 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
12844 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
12845 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
12846 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
12847 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
12848 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
12849 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
12850 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
12851 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
12852 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
12853 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
12854 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
12855 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
12856 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
12857 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
12858 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
12859 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
12860 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
12861 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
12862 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
12863 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
12864 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
12865 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
12866 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
12867 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
12868 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
12869 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
12870 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
12871 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
12872 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
12873 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
12874 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
12875 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
12876 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
12877 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
12878 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
12879 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
12880 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
12881 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
12883 if (rs6000_cpu == PROCESSOR_CELL)
12885 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
12886 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
12887 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
12888 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
12890 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
12891 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
12892 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
12893 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
12895 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
12896 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
12897 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
12898 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
12900 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
12901 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
12902 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
12903 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
12905 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
12906 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
12907 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
12909 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
12910 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
12911 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
12912 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
12913 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
12914 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
12915 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
12916 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
12917 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
12918 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
12919 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
12920 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
12922 /* Add the DST variants. */
12924 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
12925 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
12927 /* Initialize the predicates. */
12928 dp = bdesc_altivec_preds;
12929 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
12931 enum machine_mode mode1;
12933 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
12934 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
12935 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
12936 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
12941 mode1 = insn_data[dp->icode].operand[1].mode;
12946 type = int_ftype_int_opaque_opaque;
12949 type = int_ftype_int_v4si_v4si;
12952 type = int_ftype_int_v8hi_v8hi;
12955 type = int_ftype_int_v16qi_v16qi;
12958 type = int_ftype_int_v4sf_v4sf;
12961 type = int_ftype_int_v2df_v2df;
12964 gcc_unreachable ();
12967 def_builtin (dp->mask, dp->name, type, dp->code);
12970 /* Initialize the abs* operators. */
12972 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
12974 enum machine_mode mode0;
12977 mode0 = insn_data[d->icode].operand[0].mode;
12982 type = v4si_ftype_v4si;
12985 type = v8hi_ftype_v8hi;
12988 type = v16qi_ftype_v16qi;
12991 type = v4sf_ftype_v4sf;
12994 type = v2df_ftype_v2df;
12997 gcc_unreachable ();
13000 def_builtin (d->mask, d->name, type, d->code);
13003 if (TARGET_ALTIVEC)
13007 /* Initialize target builtin that implements
13008 targetm.vectorize.builtin_mask_for_load. */
13010 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13011 v16qi_ftype_long_pcvoid,
13012 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13013 BUILT_IN_MD, NULL, NULL_TREE);
13014 TREE_READONLY (decl) = 1;
13015 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13016 altivec_builtin_mask_for_load = decl;
13019 /* Access to the vec_init patterns. */
13020 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13021 integer_type_node, integer_type_node,
13022 integer_type_node, NULL_TREE);
13023 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13024 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13026 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13027 short_integer_type_node,
13028 short_integer_type_node,
13029 short_integer_type_node,
13030 short_integer_type_node,
13031 short_integer_type_node,
13032 short_integer_type_node,
13033 short_integer_type_node, NULL_TREE);
13034 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13035 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13037 ftype = build_function_type_list (V16QI_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, char_type_node,
13043 char_type_node, char_type_node,
13044 char_type_node, char_type_node,
13045 char_type_node, NULL_TREE);
13046 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13047 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13049 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13050 float_type_node, float_type_node,
13051 float_type_node, NULL_TREE);
13052 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13053 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13057 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13058 double_type_node, NULL_TREE);
13059 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13060 VSX_BUILTIN_VEC_INIT_V2DF);
13062 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13063 intDI_type_node, NULL_TREE);
13064 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13065 VSX_BUILTIN_VEC_INIT_V2DI);
13068 /* Access to the vec_set patterns. */
13069 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13071 integer_type_node, NULL_TREE);
13072 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13073 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13075 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13077 integer_type_node, NULL_TREE);
13078 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13079 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13081 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13083 integer_type_node, NULL_TREE);
13084 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13085 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13087 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13089 integer_type_node, NULL_TREE);
13090 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13091 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13095 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13097 integer_type_node, NULL_TREE);
13098 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13099 VSX_BUILTIN_VEC_SET_V2DF);
13101 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13103 integer_type_node, NULL_TREE);
13104 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13105 VSX_BUILTIN_VEC_SET_V2DI);
13108 /* Access to the vec_extract patterns. */
13109 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13110 integer_type_node, NULL_TREE);
13111 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13112 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13114 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13115 integer_type_node, NULL_TREE);
13116 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13117 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13119 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13120 integer_type_node, NULL_TREE);
13121 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13122 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13124 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13125 integer_type_node, NULL_TREE);
13126 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13127 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13131 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13132 integer_type_node, NULL_TREE);
13133 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13134 VSX_BUILTIN_VEC_EXT_V2DF);
13136 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13137 integer_type_node, NULL_TREE);
13138 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13139 VSX_BUILTIN_VEC_EXT_V2DI);
13143 /* Hash function for builtin functions with up to 3 arguments and a return
13146 builtin_hash_function (const void *hash_entry)
13150 const struct builtin_hash_struct *bh =
13151 (const struct builtin_hash_struct *) hash_entry;
13153 for (i = 0; i < 4; i++)
13155 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13156 ret = (ret * 2) + bh->uns_p[i];
13162 /* Compare builtin hash entries H1 and H2 for equivalence. */
13164 builtin_hash_eq (const void *h1, const void *h2)
13166 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13167 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13169 return ((p1->mode[0] == p2->mode[0])
13170 && (p1->mode[1] == p2->mode[1])
13171 && (p1->mode[2] == p2->mode[2])
13172 && (p1->mode[3] == p2->mode[3])
13173 && (p1->uns_p[0] == p2->uns_p[0])
13174 && (p1->uns_p[1] == p2->uns_p[1])
13175 && (p1->uns_p[2] == p2->uns_p[2])
13176 && (p1->uns_p[3] == p2->uns_p[3]));
13179 /* Map types for builtin functions with an explicit return type and up to 3
13180 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13181 of the argument. */
13183 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13184 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13185 enum rs6000_builtins builtin, const char *name)
13187 struct builtin_hash_struct h;
13188 struct builtin_hash_struct *h2;
13192 tree ret_type = NULL_TREE;
13193 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13196 /* Create builtin_hash_table. */
13197 if (builtin_hash_table == NULL)
13198 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13199 builtin_hash_eq, NULL);
13201 h.type = NULL_TREE;
13202 h.mode[0] = mode_ret;
13203 h.mode[1] = mode_arg0;
13204 h.mode[2] = mode_arg1;
13205 h.mode[3] = mode_arg2;
13211 /* If the builtin is a type that produces unsigned results or takes unsigned
13212 arguments, and it is returned as a decl for the vectorizer (such as
13213 widening multiplies, permute), make sure the arguments and return value
13214 are type correct. */
13217 /* unsigned 2 argument functions. */
13218 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13219 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13220 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13221 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13227 /* unsigned 3 argument functions. */
13228 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13229 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13230 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13231 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13232 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13233 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13234 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13235 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13236 case VSX_BUILTIN_VPERM_16QI_UNS:
13237 case VSX_BUILTIN_VPERM_8HI_UNS:
13238 case VSX_BUILTIN_VPERM_4SI_UNS:
13239 case VSX_BUILTIN_VPERM_2DI_UNS:
13240 case VSX_BUILTIN_XXSEL_16QI_UNS:
13241 case VSX_BUILTIN_XXSEL_8HI_UNS:
13242 case VSX_BUILTIN_XXSEL_4SI_UNS:
13243 case VSX_BUILTIN_XXSEL_2DI_UNS:
13250 /* signed permute functions with unsigned char mask. */
13251 case ALTIVEC_BUILTIN_VPERM_16QI:
13252 case ALTIVEC_BUILTIN_VPERM_8HI:
13253 case ALTIVEC_BUILTIN_VPERM_4SI:
13254 case ALTIVEC_BUILTIN_VPERM_4SF:
13255 case ALTIVEC_BUILTIN_VPERM_2DI:
13256 case ALTIVEC_BUILTIN_VPERM_2DF:
13257 case VSX_BUILTIN_VPERM_16QI:
13258 case VSX_BUILTIN_VPERM_8HI:
13259 case VSX_BUILTIN_VPERM_4SI:
13260 case VSX_BUILTIN_VPERM_4SF:
13261 case VSX_BUILTIN_VPERM_2DI:
13262 case VSX_BUILTIN_VPERM_2DF:
13266 /* unsigned args, signed return. */
13267 case VSX_BUILTIN_XVCVUXDDP_UNS:
13268 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13272 /* signed args, unsigned return. */
13273 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13274 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13282 /* Figure out how many args are present. */
13283 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13287 fatal_error ("internal error: builtin function %s had no type", name);
13289 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13290 if (!ret_type && h.uns_p[0])
13291 ret_type = builtin_mode_to_type[h.mode[0]][0];
13294 fatal_error ("internal error: builtin function %s had an unexpected "
13295 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13297 for (i = 0; i < num_args; i++)
13299 int m = (int) h.mode[i+1];
13300 int uns_p = h.uns_p[i+1];
13302 arg_type[i] = builtin_mode_to_type[m][uns_p];
13303 if (!arg_type[i] && uns_p)
13304 arg_type[i] = builtin_mode_to_type[m][0];
13307 fatal_error ("internal error: builtin function %s, argument %d "
13308 "had unexpected argument type %s", name, i,
13309 GET_MODE_NAME (m));
13312 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13313 if (*found == NULL)
13315 h2 = ggc_alloc_builtin_hash_struct ();
13317 *found = (void *)h2;
13318 args = void_list_node;
13320 for (i = num_args - 1; i >= 0; i--)
13321 args = tree_cons (NULL_TREE, arg_type[i], args);
13323 h2->type = build_function_type (ret_type, args);
13326 return ((struct builtin_hash_struct *)(*found))->type;
13330 rs6000_common_init_builtins (void)
13332 const struct builtin_description *d;
13335 tree opaque_ftype_opaque = NULL_TREE;
13336 tree opaque_ftype_opaque_opaque = NULL_TREE;
13337 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13338 tree v2si_ftype_qi = NULL_TREE;
13339 tree v2si_ftype_v2si_qi = NULL_TREE;
13340 tree v2si_ftype_int_qi = NULL_TREE;
13342 if (!TARGET_PAIRED_FLOAT)
13344 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13345 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13348 /* Add the ternary operators. */
13350 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13353 int mask = d->mask;
13355 if ((mask != 0 && (mask & target_flags) == 0)
13356 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13359 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13360 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13361 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13362 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13364 if (! (type = opaque_ftype_opaque_opaque_opaque))
13365 type = opaque_ftype_opaque_opaque_opaque
13366 = build_function_type_list (opaque_V4SI_type_node,
13367 opaque_V4SI_type_node,
13368 opaque_V4SI_type_node,
13369 opaque_V4SI_type_node,
13374 enum insn_code icode = d->icode;
13375 if (d->name == 0 || icode == CODE_FOR_nothing)
13378 type = builtin_function_type (insn_data[icode].operand[0].mode,
13379 insn_data[icode].operand[1].mode,
13380 insn_data[icode].operand[2].mode,
13381 insn_data[icode].operand[3].mode,
13385 def_builtin (d->mask, d->name, type, d->code);
13388 /* Add the binary operators. */
13390 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13392 enum machine_mode mode0, mode1, mode2;
13394 int mask = d->mask;
13396 if ((mask != 0 && (mask & target_flags) == 0)
13397 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13400 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13401 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13402 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13403 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13405 if (! (type = opaque_ftype_opaque_opaque))
13406 type = opaque_ftype_opaque_opaque
13407 = build_function_type_list (opaque_V4SI_type_node,
13408 opaque_V4SI_type_node,
13409 opaque_V4SI_type_node,
13414 enum insn_code icode = d->icode;
13415 if (d->name == 0 || icode == CODE_FOR_nothing)
13418 mode0 = insn_data[icode].operand[0].mode;
13419 mode1 = insn_data[icode].operand[1].mode;
13420 mode2 = insn_data[icode].operand[2].mode;
13422 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13424 if (! (type = v2si_ftype_v2si_qi))
13425 type = v2si_ftype_v2si_qi
13426 = build_function_type_list (opaque_V2SI_type_node,
13427 opaque_V2SI_type_node,
13432 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13433 && mode2 == QImode)
13435 if (! (type = v2si_ftype_int_qi))
13436 type = v2si_ftype_int_qi
13437 = build_function_type_list (opaque_V2SI_type_node,
13444 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13448 def_builtin (d->mask, d->name, type, d->code);
13451 /* Add the simple unary operators. */
13452 d = (struct builtin_description *) bdesc_1arg;
13453 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13455 enum machine_mode mode0, mode1;
13457 int mask = d->mask;
13459 if ((mask != 0 && (mask & target_flags) == 0)
13460 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13463 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13464 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13465 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13466 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13468 if (! (type = opaque_ftype_opaque))
13469 type = opaque_ftype_opaque
13470 = build_function_type_list (opaque_V4SI_type_node,
13471 opaque_V4SI_type_node,
13476 enum insn_code icode = d->icode;
13477 if (d->name == 0 || icode == CODE_FOR_nothing)
13480 mode0 = insn_data[icode].operand[0].mode;
13481 mode1 = insn_data[icode].operand[1].mode;
13483 if (mode0 == V2SImode && mode1 == QImode)
13485 if (! (type = v2si_ftype_qi))
13486 type = v2si_ftype_qi
13487 = build_function_type_list (opaque_V2SI_type_node,
13493 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13497 def_builtin (d->mask, d->name, type, d->code);
13502 rs6000_init_libfuncs (void)
13504 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13505 && !TARGET_POWER2 && !TARGET_POWERPC)
13507 /* AIX library routines for float->int conversion. */
13508 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13509 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13510 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13511 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13514 if (!TARGET_IEEEQUAD)
13515 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13516 if (!TARGET_XL_COMPAT)
13518 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13519 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13520 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13521 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13523 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13525 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13526 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13527 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13528 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13529 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13530 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13531 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13533 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13534 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13535 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13536 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13537 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13538 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13539 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13540 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13543 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13544 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13548 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13549 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13550 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13551 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13555 /* 32-bit SVR4 quad floating point routines. */
13557 set_optab_libfunc (add_optab, TFmode, "_q_add");
13558 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13559 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13560 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13561 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13562 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13563 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13565 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13566 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13567 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13568 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13569 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13570 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13572 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13573 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13574 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13575 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13576 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13577 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13578 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13579 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13584 /* Expand a block clear operation, and return 1 if successful. Return 0
13585 if we should let the compiler generate normal code.
13587 operands[0] is the destination
13588 operands[1] is the length
13589 operands[3] is the alignment */
13592 expand_block_clear (rtx operands[])
13594 rtx orig_dest = operands[0];
13595 rtx bytes_rtx = operands[1];
13596 rtx align_rtx = operands[3];
13597 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
13598 HOST_WIDE_INT align;
13599 HOST_WIDE_INT bytes;
13604 /* If this is not a fixed size move, just call memcpy */
13608 /* This must be a fixed size alignment */
13609 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13610 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13612 /* Anything to clear? */
13613 bytes = INTVAL (bytes_rtx);
13617 /* Use the builtin memset after a point, to avoid huge code bloat.
13618 When optimize_size, avoid any significant code bloat; calling
13619 memset is about 4 instructions, so allow for one instruction to
13620 load zero and three to do clearing. */
13621 if (TARGET_ALTIVEC && align >= 128)
13623 else if (TARGET_POWERPC64 && align >= 32)
13625 else if (TARGET_SPE && align >= 64)
13630 if (optimize_size && bytes > 3 * clear_step)
13632 if (! optimize_size && bytes > 8 * clear_step)
13635 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
13637 enum machine_mode mode = BLKmode;
13640 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
13645 else if (bytes >= 8 && TARGET_SPE && align >= 64)
13650 else if (bytes >= 8 && TARGET_POWERPC64
13651 /* 64-bit loads and stores require word-aligned
13653 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13658 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13659 { /* move 4 bytes */
13663 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13664 { /* move 2 bytes */
13668 else /* move 1 byte at a time */
13674 dest = adjust_address (orig_dest, mode, offset);
13676 emit_move_insn (dest, CONST0_RTX (mode));
13683 /* Expand a block move operation, and return 1 if successful. Return 0
13684 if we should let the compiler generate normal code.
13686 operands[0] is the destination
13687 operands[1] is the source
13688 operands[2] is the length
13689 operands[3] is the alignment */
13691 #define MAX_MOVE_REG 4
13694 expand_block_move (rtx operands[])
13696 rtx orig_dest = operands[0];
13697 rtx orig_src = operands[1];
13698 rtx bytes_rtx = operands[2];
13699 rtx align_rtx = operands[3];
13700 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
13705 rtx stores[MAX_MOVE_REG];
13708 /* If this is not a fixed size move, just call memcpy */
13712 /* This must be a fixed size alignment */
13713 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
13714 align = INTVAL (align_rtx) * BITS_PER_UNIT;
13716 /* Anything to move? */
13717 bytes = INTVAL (bytes_rtx);
13721 if (bytes > rs6000_block_move_inline_limit)
13724 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
13727 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
13728 rtx (*mov) (rtx, rtx);
13730 enum machine_mode mode = BLKmode;
13733 /* Altivec first, since it will be faster than a string move
13734 when it applies, and usually not significantly larger. */
13735 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
13739 gen_func.mov = gen_movv4si;
13741 else if (TARGET_SPE && bytes >= 8 && align >= 64)
13745 gen_func.mov = gen_movv2si;
13747 else if (TARGET_STRING
13748 && bytes > 24 /* move up to 32 bytes at a time */
13754 && ! fixed_regs[10]
13755 && ! fixed_regs[11]
13756 && ! fixed_regs[12])
13758 move_bytes = (bytes > 32) ? 32 : bytes;
13759 gen_func.movmemsi = gen_movmemsi_8reg;
13761 else if (TARGET_STRING
13762 && bytes > 16 /* move up to 24 bytes at a time */
13768 && ! fixed_regs[10])
13770 move_bytes = (bytes > 24) ? 24 : bytes;
13771 gen_func.movmemsi = gen_movmemsi_6reg;
13773 else if (TARGET_STRING
13774 && bytes > 8 /* move up to 16 bytes at a time */
13778 && ! fixed_regs[8])
13780 move_bytes = (bytes > 16) ? 16 : bytes;
13781 gen_func.movmemsi = gen_movmemsi_4reg;
13783 else if (bytes >= 8 && TARGET_POWERPC64
13784 /* 64-bit loads and stores require word-aligned
13786 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
13790 gen_func.mov = gen_movdi;
13792 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
13793 { /* move up to 8 bytes at a time */
13794 move_bytes = (bytes > 8) ? 8 : bytes;
13795 gen_func.movmemsi = gen_movmemsi_2reg;
13797 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
13798 { /* move 4 bytes */
13801 gen_func.mov = gen_movsi;
13803 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
13804 { /* move 2 bytes */
13807 gen_func.mov = gen_movhi;
13809 else if (TARGET_STRING && bytes > 1)
13810 { /* move up to 4 bytes at a time */
13811 move_bytes = (bytes > 4) ? 4 : bytes;
13812 gen_func.movmemsi = gen_movmemsi_1reg;
13814 else /* move 1 byte at a time */
13818 gen_func.mov = gen_movqi;
13821 src = adjust_address (orig_src, mode, offset);
13822 dest = adjust_address (orig_dest, mode, offset);
13824 if (mode != BLKmode)
13826 rtx tmp_reg = gen_reg_rtx (mode);
13828 emit_insn ((*gen_func.mov) (tmp_reg, src));
13829 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
13832 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
13835 for (i = 0; i < num_reg; i++)
13836 emit_insn (stores[i]);
13840 if (mode == BLKmode)
13842 /* Move the address into scratch registers. The movmemsi
13843 patterns require zero offset. */
13844 if (!REG_P (XEXP (src, 0)))
13846 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
13847 src = replace_equiv_address (src, src_reg);
13849 set_mem_size (src, GEN_INT (move_bytes));
13851 if (!REG_P (XEXP (dest, 0)))
13853 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
13854 dest = replace_equiv_address (dest, dest_reg);
13856 set_mem_size (dest, GEN_INT (move_bytes));
13858 emit_insn ((*gen_func.movmemsi) (dest, src,
13859 GEN_INT (move_bytes & 31),
13868 /* Return a string to perform a load_multiple operation.
13869 operands[0] is the vector.
13870 operands[1] is the source address.
13871 operands[2] is the first destination register. */
13874 rs6000_output_load_multiple (rtx operands[3])
13876 /* We have to handle the case where the pseudo used to contain the address
13877 is assigned to one of the output registers. */
13879 int words = XVECLEN (operands[0], 0);
13882 if (XVECLEN (operands[0], 0) == 1)
13883 return "{l|lwz} %2,0(%1)";
13885 for (i = 0; i < words; i++)
13886 if (refers_to_regno_p (REGNO (operands[2]) + i,
13887 REGNO (operands[2]) + i + 1, operands[1], 0))
13891 xop[0] = GEN_INT (4 * (words-1));
13892 xop[1] = operands[1];
13893 xop[2] = operands[2];
13894 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
13899 xop[0] = GEN_INT (4 * (words-1));
13900 xop[1] = operands[1];
13901 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
13902 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);
13907 for (j = 0; j < words; j++)
13910 xop[0] = GEN_INT (j * 4);
13911 xop[1] = operands[1];
13912 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
13913 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
13915 xop[0] = GEN_INT (i * 4);
13916 xop[1] = operands[1];
13917 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
13922 return "{lsi|lswi} %2,%1,%N0";
13926 /* A validation routine: say whether CODE, a condition code, and MODE
13927 match. The other alternatives either don't make sense or should
13928 never be generated. */
13931 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
13933 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
13934 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
13935 && GET_MODE_CLASS (mode) == MODE_CC);
13937 /* These don't make sense. */
13938 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
13939 || mode != CCUNSmode);
13941 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
13942 || mode == CCUNSmode);
13944 gcc_assert (mode == CCFPmode
13945 || (code != ORDERED && code != UNORDERED
13946 && code != UNEQ && code != LTGT
13947 && code != UNGT && code != UNLT
13948 && code != UNGE && code != UNLE));
13950 /* These should never be generated except for
13951 flag_finite_math_only. */
13952 gcc_assert (mode != CCFPmode
13953 || flag_finite_math_only
13954 || (code != LE && code != GE
13955 && code != UNEQ && code != LTGT
13956 && code != UNGT && code != UNLT));
13958 /* These are invalid; the information is not there. */
13959 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
13963 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
13964 mask required to convert the result of a rotate insn into a shift
13965 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
13968 includes_lshift_p (rtx shiftop, rtx andop)
13970 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13972 shift_mask <<= INTVAL (shiftop);
13974 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13977 /* Similar, but for right shift. */
13980 includes_rshift_p (rtx shiftop, rtx andop)
13982 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
13984 shift_mask >>= INTVAL (shiftop);
13986 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
13989 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
13990 to perform a left shift. It must have exactly SHIFTOP least
13991 significant 0's, then one or more 1's, then zero or more 0's. */
13994 includes_rldic_lshift_p (rtx shiftop, rtx andop)
13996 if (GET_CODE (andop) == CONST_INT)
13998 HOST_WIDE_INT c, lsb, shift_mask;
14000 c = INTVAL (andop);
14001 if (c == 0 || c == ~0)
14005 shift_mask <<= INTVAL (shiftop);
14007 /* Find the least significant one bit. */
14010 /* It must coincide with the LSB of the shift mask. */
14011 if (-lsb != shift_mask)
14014 /* Invert to look for the next transition (if any). */
14017 /* Remove the low group of ones (originally low group of zeros). */
14020 /* Again find the lsb, and check we have all 1's above. */
14024 else if (GET_CODE (andop) == CONST_DOUBLE
14025 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14027 HOST_WIDE_INT low, high, lsb;
14028 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14030 low = CONST_DOUBLE_LOW (andop);
14031 if (HOST_BITS_PER_WIDE_INT < 64)
14032 high = CONST_DOUBLE_HIGH (andop);
14034 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14035 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14038 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14040 shift_mask_high = ~0;
14041 if (INTVAL (shiftop) > 32)
14042 shift_mask_high <<= INTVAL (shiftop) - 32;
14044 lsb = high & -high;
14046 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14052 lsb = high & -high;
14053 return high == -lsb;
14056 shift_mask_low = ~0;
14057 shift_mask_low <<= INTVAL (shiftop);
14061 if (-lsb != shift_mask_low)
14064 if (HOST_BITS_PER_WIDE_INT < 64)
14069 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14071 lsb = high & -high;
14072 return high == -lsb;
14076 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14082 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14083 to perform a left shift. It must have SHIFTOP or more least
14084 significant 0's, with the remainder of the word 1's. */
14087 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14089 if (GET_CODE (andop) == CONST_INT)
14091 HOST_WIDE_INT c, lsb, shift_mask;
14094 shift_mask <<= INTVAL (shiftop);
14095 c = INTVAL (andop);
14097 /* Find the least significant one bit. */
14100 /* It must be covered by the shift mask.
14101 This test also rejects c == 0. */
14102 if ((lsb & shift_mask) == 0)
14105 /* Check we have all 1's above the transition, and reject all 1's. */
14106 return c == -lsb && lsb != 1;
14108 else if (GET_CODE (andop) == CONST_DOUBLE
14109 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14111 HOST_WIDE_INT low, lsb, shift_mask_low;
14113 low = CONST_DOUBLE_LOW (andop);
14115 if (HOST_BITS_PER_WIDE_INT < 64)
14117 HOST_WIDE_INT high, shift_mask_high;
14119 high = CONST_DOUBLE_HIGH (andop);
14123 shift_mask_high = ~0;
14124 if (INTVAL (shiftop) > 32)
14125 shift_mask_high <<= INTVAL (shiftop) - 32;
14127 lsb = high & -high;
14129 if ((lsb & shift_mask_high) == 0)
14132 return high == -lsb;
14138 shift_mask_low = ~0;
14139 shift_mask_low <<= INTVAL (shiftop);
14143 if ((lsb & shift_mask_low) == 0)
14146 return low == -lsb && lsb != 1;
14152 /* Return 1 if operands will generate a valid arguments to rlwimi
14153 instruction for insert with right shift in 64-bit mode. The mask may
14154 not start on the first bit or stop on the last bit because wrap-around
14155 effects of instruction do not correspond to semantics of RTL insn. */
14158 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14160 if (INTVAL (startop) > 32
14161 && INTVAL (startop) < 64
14162 && INTVAL (sizeop) > 1
14163 && INTVAL (sizeop) + INTVAL (startop) < 64
14164 && INTVAL (shiftop) > 0
14165 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14166 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14172 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14173 for lfq and stfq insns iff the registers are hard registers. */
14176 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14178 /* We might have been passed a SUBREG. */
14179 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14182 /* We might have been passed non floating point registers. */
14183 if (!FP_REGNO_P (REGNO (reg1))
14184 || !FP_REGNO_P (REGNO (reg2)))
14187 return (REGNO (reg1) == REGNO (reg2) - 1);
14190 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14191 addr1 and addr2 must be in consecutive memory locations
14192 (addr2 == addr1 + 8). */
14195 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14198 unsigned int reg1, reg2;
14199 int offset1, offset2;
14201 /* The mems cannot be volatile. */
14202 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14205 addr1 = XEXP (mem1, 0);
14206 addr2 = XEXP (mem2, 0);
14208 /* Extract an offset (if used) from the first addr. */
14209 if (GET_CODE (addr1) == PLUS)
14211 /* If not a REG, return zero. */
14212 if (GET_CODE (XEXP (addr1, 0)) != REG)
14216 reg1 = REGNO (XEXP (addr1, 0));
14217 /* The offset must be constant! */
14218 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14220 offset1 = INTVAL (XEXP (addr1, 1));
14223 else if (GET_CODE (addr1) != REG)
14227 reg1 = REGNO (addr1);
14228 /* This was a simple (mem (reg)) expression. Offset is 0. */
14232 /* And now for the second addr. */
14233 if (GET_CODE (addr2) == PLUS)
14235 /* If not a REG, return zero. */
14236 if (GET_CODE (XEXP (addr2, 0)) != REG)
14240 reg2 = REGNO (XEXP (addr2, 0));
14241 /* The offset must be constant. */
14242 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14244 offset2 = INTVAL (XEXP (addr2, 1));
14247 else if (GET_CODE (addr2) != REG)
14251 reg2 = REGNO (addr2);
14252 /* This was a simple (mem (reg)) expression. Offset is 0. */
14256 /* Both of these must have the same base register. */
14260 /* The offset for the second addr must be 8 more than the first addr. */
14261 if (offset2 != offset1 + 8)
14264 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14271 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14273 static bool eliminated = false;
14276 if (mode != SDmode)
14277 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14280 rtx mem = cfun->machine->sdmode_stack_slot;
14281 gcc_assert (mem != NULL_RTX);
14285 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14286 cfun->machine->sdmode_stack_slot = mem;
14292 if (TARGET_DEBUG_ADDR)
14294 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14295 GET_MODE_NAME (mode));
14297 fprintf (stderr, "\tNULL_RTX\n");
14306 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14308 /* Don't walk into types. */
14309 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14311 *walk_subtrees = 0;
14315 switch (TREE_CODE (*tp))
14324 case VIEW_CONVERT_EXPR:
14325 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14335 enum reload_reg_type {
14337 VECTOR_REGISTER_TYPE,
14338 OTHER_REGISTER_TYPE
14341 static enum reload_reg_type
14342 rs6000_reload_register_type (enum reg_class rclass)
14348 return GPR_REGISTER_TYPE;
14353 return VECTOR_REGISTER_TYPE;
14356 return OTHER_REGISTER_TYPE;
14360 /* Inform reload about cases where moving X with a mode MODE to a register in
14361 RCLASS requires an extra scratch or immediate register. Return the class
14362 needed for the immediate register.
14364 For VSX and Altivec, we may need a register to convert sp+offset into
14368 rs6000_secondary_reload (bool in_p,
14370 reg_class_t rclass_i,
14371 enum machine_mode mode,
14372 secondary_reload_info *sri)
14374 enum reg_class rclass = (enum reg_class) rclass_i;
14375 reg_class_t ret = ALL_REGS;
14376 enum insn_code icode;
14377 bool default_p = false;
14379 sri->icode = CODE_FOR_nothing;
14381 /* Convert vector loads and stores into gprs to use an additional base
14383 icode = rs6000_vector_reload[mode][in_p != false];
14384 if (icode != CODE_FOR_nothing)
14387 sri->icode = CODE_FOR_nothing;
14388 sri->extra_cost = 0;
14390 if (GET_CODE (x) == MEM)
14392 rtx addr = XEXP (x, 0);
14394 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14395 an extra register in that case, but it would need an extra
14396 register if the addressing is reg+reg or (reg+reg)&(-16). */
14397 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14399 if (!legitimate_indirect_address_p (addr, false)
14400 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14402 sri->icode = icode;
14403 /* account for splitting the loads, and converting the
14404 address from reg+reg to reg. */
14405 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14406 + ((GET_CODE (addr) == AND) ? 1 : 0));
14409 /* Loads to and stores from vector registers can only do reg+reg
14410 addressing. Altivec registers can also do (reg+reg)&(-16). */
14411 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14412 || rclass == FLOAT_REGS || rclass == NO_REGS)
14414 if (!VECTOR_MEM_ALTIVEC_P (mode)
14415 && GET_CODE (addr) == AND
14416 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14417 && INTVAL (XEXP (addr, 1)) == -16
14418 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14419 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14421 sri->icode = icode;
14422 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14425 else if (!legitimate_indirect_address_p (addr, false)
14426 && (rclass == NO_REGS
14427 || !legitimate_indexed_address_p (addr, false)))
14429 sri->icode = icode;
14430 sri->extra_cost = 1;
14433 icode = CODE_FOR_nothing;
14435 /* Any other loads, including to pseudo registers which haven't been
14436 assigned to a register yet, default to require a scratch
14440 sri->icode = icode;
14441 sri->extra_cost = 2;
14444 else if (REG_P (x))
14446 int regno = true_regnum (x);
14448 icode = CODE_FOR_nothing;
14449 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14453 enum reg_class xclass = REGNO_REG_CLASS (regno);
14454 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14455 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14457 /* If memory is needed, use default_secondary_reload to create the
14459 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14472 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14474 gcc_assert (ret != ALL_REGS);
14476 if (TARGET_DEBUG_ADDR)
14479 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14481 reg_class_names[ret],
14482 in_p ? "true" : "false",
14483 reg_class_names[rclass],
14484 GET_MODE_NAME (mode));
14487 fprintf (stderr, ", default secondary reload");
14489 if (sri->icode != CODE_FOR_nothing)
14490 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14491 insn_data[sri->icode].name, sri->extra_cost);
14493 fprintf (stderr, "\n");
14501 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14502 to SP+reg addressing. */
14505 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14507 int regno = true_regnum (reg);
14508 enum machine_mode mode = GET_MODE (reg);
14509 enum reg_class rclass;
14511 rtx and_op2 = NULL_RTX;
14514 rtx scratch_or_premodify = scratch;
14518 if (TARGET_DEBUG_ADDR)
14520 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14521 store_p ? "store" : "load");
14522 fprintf (stderr, "reg:\n");
14524 fprintf (stderr, "mem:\n");
14526 fprintf (stderr, "scratch:\n");
14527 debug_rtx (scratch);
14530 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14531 gcc_assert (GET_CODE (mem) == MEM);
14532 rclass = REGNO_REG_CLASS (regno);
14533 addr = XEXP (mem, 0);
14537 /* GPRs can handle reg + small constant, all other addresses need to use
14538 the scratch register. */
14541 if (GET_CODE (addr) == AND)
14543 and_op2 = XEXP (addr, 1);
14544 addr = XEXP (addr, 0);
14547 if (GET_CODE (addr) == PRE_MODIFY)
14549 scratch_or_premodify = XEXP (addr, 0);
14550 gcc_assert (REG_P (scratch_or_premodify));
14551 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14552 addr = XEXP (addr, 1);
14555 if (GET_CODE (addr) == PLUS
14556 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14557 || and_op2 != NULL_RTX))
14559 addr_op1 = XEXP (addr, 0);
14560 addr_op2 = XEXP (addr, 1);
14561 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
14563 if (!REG_P (addr_op2)
14564 && (GET_CODE (addr_op2) != CONST_INT
14565 || !satisfies_constraint_I (addr_op2)))
14567 if (TARGET_DEBUG_ADDR)
14570 "\nMove plus addr to register %s, mode = %s: ",
14571 rs6000_reg_names[REGNO (scratch)],
14572 GET_MODE_NAME (mode));
14573 debug_rtx (addr_op2);
14575 rs6000_emit_move (scratch, addr_op2, Pmode);
14576 addr_op2 = scratch;
14579 emit_insn (gen_rtx_SET (VOIDmode,
14580 scratch_or_premodify,
14581 gen_rtx_PLUS (Pmode,
14585 addr = scratch_or_premodify;
14586 scratch_or_premodify = scratch;
14588 else if (!legitimate_indirect_address_p (addr, false)
14589 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14591 if (TARGET_DEBUG_ADDR)
14593 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14594 rs6000_reg_names[REGNO (scratch_or_premodify)],
14595 GET_MODE_NAME (mode));
14598 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14599 addr = scratch_or_premodify;
14600 scratch_or_premodify = scratch;
14604 /* Float/Altivec registers can only handle reg+reg addressing. Move
14605 other addresses into a scratch register. */
14610 /* With float regs, we need to handle the AND ourselves, since we can't
14611 use the Altivec instruction with an implicit AND -16. Allow scalar
14612 loads to float registers to use reg+offset even if VSX. */
14613 if (GET_CODE (addr) == AND
14614 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
14615 || GET_CODE (XEXP (addr, 1)) != CONST_INT
14616 || INTVAL (XEXP (addr, 1)) != -16
14617 || !VECTOR_MEM_ALTIVEC_P (mode)))
14619 and_op2 = XEXP (addr, 1);
14620 addr = XEXP (addr, 0);
14623 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
14624 as the address later. */
14625 if (GET_CODE (addr) == PRE_MODIFY
14626 && (!VECTOR_MEM_VSX_P (mode)
14627 || and_op2 != NULL_RTX
14628 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
14630 scratch_or_premodify = XEXP (addr, 0);
14631 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
14633 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14634 addr = XEXP (addr, 1);
14637 if (legitimate_indirect_address_p (addr, false) /* reg */
14638 || legitimate_indexed_address_p (addr, false) /* reg+reg */
14639 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
14640 || (GET_CODE (addr) == AND /* Altivec memory */
14641 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14642 && INTVAL (XEXP (addr, 1)) == -16
14643 && VECTOR_MEM_ALTIVEC_P (mode))
14644 || (rclass == FLOAT_REGS /* legacy float mem */
14645 && GET_MODE_SIZE (mode) == 8
14646 && and_op2 == NULL_RTX
14647 && scratch_or_premodify == scratch
14648 && rs6000_legitimate_offset_address_p (mode, addr, false)))
14651 else if (GET_CODE (addr) == PLUS)
14653 addr_op1 = XEXP (addr, 0);
14654 addr_op2 = XEXP (addr, 1);
14655 gcc_assert (REG_P (addr_op1));
14657 if (TARGET_DEBUG_ADDR)
14659 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
14660 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14661 debug_rtx (addr_op2);
14663 rs6000_emit_move (scratch, addr_op2, Pmode);
14664 emit_insn (gen_rtx_SET (VOIDmode,
14665 scratch_or_premodify,
14666 gen_rtx_PLUS (Pmode,
14669 addr = scratch_or_premodify;
14670 scratch_or_premodify = scratch;
14673 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
14674 || GET_CODE (addr) == CONST_INT || REG_P (addr))
14676 if (TARGET_DEBUG_ADDR)
14678 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
14679 rs6000_reg_names[REGNO (scratch_or_premodify)],
14680 GET_MODE_NAME (mode));
14684 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
14685 addr = scratch_or_premodify;
14686 scratch_or_premodify = scratch;
14690 gcc_unreachable ();
14695 gcc_unreachable ();
14698 /* If the original address involved a pre-modify that we couldn't use the VSX
14699 memory instruction with update, and we haven't taken care of already,
14700 store the address in the pre-modify register and use that as the
14702 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
14704 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
14705 addr = scratch_or_premodify;
14708 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
14709 memory instruction, recreate the AND now, including the clobber which is
14710 generated by the general ANDSI3/ANDDI3 patterns for the
14711 andi. instruction. */
14712 if (and_op2 != NULL_RTX)
14714 if (! legitimate_indirect_address_p (addr, false))
14716 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
14720 if (TARGET_DEBUG_ADDR)
14722 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
14723 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
14724 debug_rtx (and_op2);
14727 and_rtx = gen_rtx_SET (VOIDmode,
14729 gen_rtx_AND (Pmode,
14733 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
14734 emit_insn (gen_rtx_PARALLEL (VOIDmode,
14735 gen_rtvec (2, and_rtx, cc_clobber)));
14739 /* Adjust the address if it changed. */
14740 if (addr != XEXP (mem, 0))
14742 mem = change_address (mem, mode, addr);
14743 if (TARGET_DEBUG_ADDR)
14744 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
14747 /* Now create the move. */
14749 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
14751 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
14756 /* Target hook to return the cover classes for Integrated Register Allocator.
14757 Cover classes is a set of non-intersected register classes covering all hard
14758 registers used for register allocation purpose. Any move between two
14759 registers of a cover class should be cheaper than load or store of the
14760 registers. The value is array of register classes with LIM_REG_CLASSES used
14763 We need two IRA_COVER_CLASSES, one for pre-VSX, and the other for VSX to
14764 account for the Altivec and Floating registers being subsets of the VSX
14765 register set under VSX, but distinct register sets on pre-VSX machines. */
14767 static const reg_class_t *
14768 rs6000_ira_cover_classes (void)
14770 static const reg_class_t cover_pre_vsx[] = IRA_COVER_CLASSES_PRE_VSX;
14771 static const reg_class_t cover_vsx[] = IRA_COVER_CLASSES_VSX;
14773 return (TARGET_VSX) ? cover_vsx : cover_pre_vsx;
14776 /* Allocate a 64-bit stack slot to be used for copying SDmode
14777 values through if this function has any SDmode references. */
14780 rs6000_alloc_sdmode_stack_slot (void)
14784 gimple_stmt_iterator gsi;
14786 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
14789 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
14791 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
14794 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14795 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14801 /* Check for any SDmode parameters of the function. */
14802 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
14804 if (TREE_TYPE (t) == error_mark_node)
14807 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
14808 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
14810 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
14811 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
14819 rs6000_instantiate_decls (void)
14821 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
14822 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
14825 /* Given an rtx X being reloaded into a reg required to be
14826 in class CLASS, return the class of reg to actually use.
14827 In general this is just CLASS; but on some machines
14828 in some cases it is preferable to use a more restrictive class.
14830 On the RS/6000, we have to return NO_REGS when we want to reload a
14831 floating-point CONST_DOUBLE to force it to be copied to memory.
14833 We also don't want to reload integer values into floating-point
14834 registers if we can at all help it. In fact, this can
14835 cause reload to die, if it tries to generate a reload of CTR
14836 into a FP register and discovers it doesn't have the memory location
14839 ??? Would it be a good idea to have reload do the converse, that is
14840 try to reload floating modes into FP registers if possible?
14843 static enum reg_class
14844 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
14846 enum machine_mode mode = GET_MODE (x);
14848 if (VECTOR_UNIT_VSX_P (mode)
14849 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
14852 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
14853 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
14854 && easy_vector_constant (x, mode))
14855 return ALTIVEC_REGS;
14857 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
14860 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
14861 return GENERAL_REGS;
14863 /* For VSX, prefer the traditional registers for 64-bit values because we can
14864 use the non-VSX loads. Prefer the Altivec registers if Altivec is
14865 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
14866 prefer Altivec loads.. */
14867 if (rclass == VSX_REGS)
14869 if (GET_MODE_SIZE (mode) <= 8)
14872 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
14873 return ALTIVEC_REGS;
14881 /* Debug version of rs6000_preferred_reload_class. */
14882 static enum reg_class
14883 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
14885 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
14888 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
14890 reg_class_names[ret], reg_class_names[rclass],
14891 GET_MODE_NAME (GET_MODE (x)));
14897 /* If we are copying between FP or AltiVec registers and anything else, we need
14898 a memory location. The exception is when we are targeting ppc64 and the
14899 move to/from fpr to gpr instructions are available. Also, under VSX, you
14900 can copy vector registers from the FP register set to the Altivec register
14901 set and vice versa. */
14904 rs6000_secondary_memory_needed (enum reg_class class1,
14905 enum reg_class class2,
14906 enum machine_mode mode)
14908 if (class1 == class2)
14911 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
14912 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
14913 between these classes. But we need memory for other things that can go in
14914 FLOAT_REGS like SFmode. */
14916 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
14917 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
14918 || class1 == FLOAT_REGS))
14919 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
14920 && class2 != FLOAT_REGS);
14922 if (class1 == VSX_REGS || class2 == VSX_REGS)
14925 if (class1 == FLOAT_REGS
14926 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14927 || ((mode != DFmode)
14928 && (mode != DDmode)
14929 && (mode != DImode))))
14932 if (class2 == FLOAT_REGS
14933 && (!TARGET_MFPGPR || !TARGET_POWERPC64
14934 || ((mode != DFmode)
14935 && (mode != DDmode)
14936 && (mode != DImode))))
14939 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
14945 /* Debug version of rs6000_secondary_memory_needed. */
14947 rs6000_debug_secondary_memory_needed (enum reg_class class1,
14948 enum reg_class class2,
14949 enum machine_mode mode)
14951 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
14954 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
14955 "class2 = %s, mode = %s\n",
14956 ret ? "true" : "false", reg_class_names[class1],
14957 reg_class_names[class2], GET_MODE_NAME (mode));
14962 /* Return the register class of a scratch register needed to copy IN into
14963 or out of a register in RCLASS in MODE. If it can be done directly,
14964 NO_REGS is returned. */
14966 static enum reg_class
14967 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
14972 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
14974 && MACHOPIC_INDIRECT
14978 /* We cannot copy a symbolic operand directly into anything
14979 other than BASE_REGS for TARGET_ELF. So indicate that a
14980 register from BASE_REGS is needed as an intermediate
14983 On Darwin, pic addresses require a load from memory, which
14984 needs a base register. */
14985 if (rclass != BASE_REGS
14986 && (GET_CODE (in) == SYMBOL_REF
14987 || GET_CODE (in) == HIGH
14988 || GET_CODE (in) == LABEL_REF
14989 || GET_CODE (in) == CONST))
14993 if (GET_CODE (in) == REG)
14995 regno = REGNO (in);
14996 if (regno >= FIRST_PSEUDO_REGISTER)
14998 regno = true_regnum (in);
14999 if (regno >= FIRST_PSEUDO_REGISTER)
15003 else if (GET_CODE (in) == SUBREG)
15005 regno = true_regnum (in);
15006 if (regno >= FIRST_PSEUDO_REGISTER)
15012 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15014 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15015 || (regno >= 0 && INT_REGNO_P (regno)))
15018 /* Constants, memory, and FP registers can go into FP registers. */
15019 if ((regno == -1 || FP_REGNO_P (regno))
15020 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15021 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15023 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15026 && (regno == -1 || VSX_REGNO_P (regno))
15027 && VSX_REG_CLASS_P (rclass))
15030 /* Memory, and AltiVec registers can go into AltiVec registers. */
15031 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15032 && rclass == ALTIVEC_REGS)
15035 /* We can copy among the CR registers. */
15036 if ((rclass == CR_REGS || rclass == CR0_REGS)
15037 && regno >= 0 && CR_REGNO_P (regno))
15040 /* Otherwise, we need GENERAL_REGS. */
15041 return GENERAL_REGS;
15044 /* Debug version of rs6000_secondary_reload_class. */
15045 static enum reg_class
15046 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15047 enum machine_mode mode, rtx in)
15049 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15051 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15052 "mode = %s, input rtx:\n",
15053 reg_class_names[ret], reg_class_names[rclass],
15054 GET_MODE_NAME (mode));
15060 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15063 rs6000_cannot_change_mode_class (enum machine_mode from,
15064 enum machine_mode to,
15065 enum reg_class rclass)
15067 unsigned from_size = GET_MODE_SIZE (from);
15068 unsigned to_size = GET_MODE_SIZE (to);
15070 if (from_size != to_size)
15072 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15073 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15074 && reg_classes_intersect_p (xclass, rclass));
15077 if (TARGET_E500_DOUBLE
15078 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15079 || (((to) == TFmode) + ((from) == TFmode)) == 1
15080 || (((to) == DDmode) + ((from) == DDmode)) == 1
15081 || (((to) == TDmode) + ((from) == TDmode)) == 1
15082 || (((to) == DImode) + ((from) == DImode)) == 1))
15085 /* Since the VSX register set includes traditional floating point registers
15086 and altivec registers, just check for the size being different instead of
15087 trying to check whether the modes are vector modes. Otherwise it won't
15088 allow say DF and DI to change classes. */
15089 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15090 return (from_size != 8 && from_size != 16);
15092 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15093 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15096 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15097 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15103 /* Debug version of rs6000_cannot_change_mode_class. */
15105 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15106 enum machine_mode to,
15107 enum reg_class rclass)
15109 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15112 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15113 "to = %s, rclass = %s\n",
15114 ret ? "true" : "false",
15115 GET_MODE_NAME (from), GET_MODE_NAME (to),
15116 reg_class_names[rclass]);
15121 /* Given a comparison operation, return the bit number in CCR to test. We
15122 know this is a valid comparison.
15124 SCC_P is 1 if this is for an scc. That means that %D will have been
15125 used instead of %C, so the bits will be in different places.
15127 Return -1 if OP isn't a valid comparison for some reason. */
15130 ccr_bit (rtx op, int scc_p)
15132 enum rtx_code code = GET_CODE (op);
15133 enum machine_mode cc_mode;
15138 if (!COMPARISON_P (op))
15141 reg = XEXP (op, 0);
15143 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15145 cc_mode = GET_MODE (reg);
15146 cc_regnum = REGNO (reg);
15147 base_bit = 4 * (cc_regnum - CR0_REGNO);
15149 validate_condition_mode (code, cc_mode);
15151 /* When generating a sCOND operation, only positive conditions are
15154 || code == EQ || code == GT || code == LT || code == UNORDERED
15155 || code == GTU || code == LTU);
15160 return scc_p ? base_bit + 3 : base_bit + 2;
15162 return base_bit + 2;
15163 case GT: case GTU: case UNLE:
15164 return base_bit + 1;
15165 case LT: case LTU: case UNGE:
15167 case ORDERED: case UNORDERED:
15168 return base_bit + 3;
15171 /* If scc, we will have done a cror to put the bit in the
15172 unordered position. So test that bit. For integer, this is ! LT
15173 unless this is an scc insn. */
15174 return scc_p ? base_bit + 3 : base_bit;
15177 return scc_p ? base_bit + 3 : base_bit + 1;
15180 gcc_unreachable ();
15184 /* Return the GOT register. */
15187 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15189 /* The second flow pass currently (June 1999) can't update
15190 regs_ever_live without disturbing other parts of the compiler, so
15191 update it here to make the prolog/epilogue code happy. */
15192 if (!can_create_pseudo_p ()
15193 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15194 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15196 crtl->uses_pic_offset_table = 1;
15198 return pic_offset_table_rtx;
15201 static rs6000_stack_t stack_info;
15203 /* Function to init struct machine_function.
15204 This will be called, via a pointer variable,
15205 from push_function_context. */
15207 static struct machine_function *
15208 rs6000_init_machine_status (void)
15210 stack_info.reload_completed = 0;
15211 return ggc_alloc_cleared_machine_function ();
15214 /* These macros test for integers and extract the low-order bits. */
15216 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15217 && GET_MODE (X) == VOIDmode)
15219 #define INT_LOWPART(X) \
15220 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15223 extract_MB (rtx op)
15226 unsigned long val = INT_LOWPART (op);
15228 /* If the high bit is zero, the value is the first 1 bit we find
15230 if ((val & 0x80000000) == 0)
15232 gcc_assert (val & 0xffffffff);
15235 while (((val <<= 1) & 0x80000000) == 0)
15240 /* If the high bit is set and the low bit is not, or the mask is all
15241 1's, the value is zero. */
15242 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15245 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15248 while (((val >>= 1) & 1) != 0)
15255 extract_ME (rtx op)
15258 unsigned long val = INT_LOWPART (op);
15260 /* If the low bit is zero, the value is the first 1 bit we find from
15262 if ((val & 1) == 0)
15264 gcc_assert (val & 0xffffffff);
15267 while (((val >>= 1) & 1) == 0)
15273 /* If the low bit is set and the high bit is not, or the mask is all
15274 1's, the value is 31. */
15275 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15278 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15281 while (((val <<= 1) & 0x80000000) != 0)
15287 /* Locate some local-dynamic symbol still in use by this function
15288 so that we can print its name in some tls_ld pattern. */
15290 static const char *
15291 rs6000_get_some_local_dynamic_name (void)
15295 if (cfun->machine->some_ld_name)
15296 return cfun->machine->some_ld_name;
15298 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15300 && for_each_rtx (&PATTERN (insn),
15301 rs6000_get_some_local_dynamic_name_1, 0))
15302 return cfun->machine->some_ld_name;
15304 gcc_unreachable ();
15307 /* Helper function for rs6000_get_some_local_dynamic_name. */
15310 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15314 if (GET_CODE (x) == SYMBOL_REF)
15316 const char *str = XSTR (x, 0);
15317 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15319 cfun->machine->some_ld_name = str;
15327 /* Write out a function code label. */
15330 rs6000_output_function_entry (FILE *file, const char *fname)
15332 if (fname[0] != '.')
15334 switch (DEFAULT_ABI)
15337 gcc_unreachable ();
15343 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15352 RS6000_OUTPUT_BASENAME (file, fname);
15355 /* Print an operand. Recognize special options, documented below. */
15358 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15359 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15361 #define SMALL_DATA_RELOC "sda21"
15362 #define SMALL_DATA_REG 0
15366 print_operand (FILE *file, rtx x, int code)
15370 unsigned HOST_WIDE_INT uval;
15375 /* Write out an instruction after the call which may be replaced
15376 with glue code by the loader. This depends on the AIX version. */
15377 asm_fprintf (file, RS6000_CALL_GLUE);
15380 /* %a is output_address. */
15383 /* If X is a constant integer whose low-order 5 bits are zero,
15384 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15385 in the AIX assembler where "sri" with a zero shift count
15386 writes a trash instruction. */
15387 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15394 /* If constant, low-order 16 bits of constant, unsigned.
15395 Otherwise, write normally. */
15397 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15399 print_operand (file, x, 0);
15403 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15404 for 64-bit mask direction. */
15405 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15408 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15412 /* X is a CR register. Print the number of the GT bit of the CR. */
15413 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15414 output_operand_lossage ("invalid %%c value");
15416 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15420 /* Like 'J' but get to the GT bit only. */
15421 gcc_assert (GET_CODE (x) == REG);
15423 /* Bit 1 is GT bit. */
15424 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15426 /* Add one for shift count in rlinm for scc. */
15427 fprintf (file, "%d", i + 1);
15431 /* X is a CR register. Print the number of the EQ bit of the CR */
15432 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15433 output_operand_lossage ("invalid %%E value");
15435 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15439 /* X is a CR register. Print the shift count needed to move it
15440 to the high-order four bits. */
15441 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15442 output_operand_lossage ("invalid %%f value");
15444 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15448 /* Similar, but print the count for the rotate in the opposite
15450 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15451 output_operand_lossage ("invalid %%F value");
15453 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15457 /* X is a constant integer. If it is negative, print "m",
15458 otherwise print "z". This is to make an aze or ame insn. */
15459 if (GET_CODE (x) != CONST_INT)
15460 output_operand_lossage ("invalid %%G value");
15461 else if (INTVAL (x) >= 0)
15468 /* If constant, output low-order five bits. Otherwise, write
15471 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15473 print_operand (file, x, 0);
15477 /* If constant, output low-order six bits. Otherwise, write
15480 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15482 print_operand (file, x, 0);
15486 /* Print `i' if this is a constant, else nothing. */
15492 /* Write the bit number in CCR for jump. */
15493 i = ccr_bit (x, 0);
15495 output_operand_lossage ("invalid %%j code");
15497 fprintf (file, "%d", i);
15501 /* Similar, but add one for shift count in rlinm for scc and pass
15502 scc flag to `ccr_bit'. */
15503 i = ccr_bit (x, 1);
15505 output_operand_lossage ("invalid %%J code");
15507 /* If we want bit 31, write a shift count of zero, not 32. */
15508 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15512 /* X must be a constant. Write the 1's complement of the
15515 output_operand_lossage ("invalid %%k value");
15517 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15521 /* X must be a symbolic constant on ELF. Write an
15522 expression suitable for an 'addi' that adds in the low 16
15523 bits of the MEM. */
15524 if (GET_CODE (x) == CONST)
15526 if (GET_CODE (XEXP (x, 0)) != PLUS
15527 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15528 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15529 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
15530 output_operand_lossage ("invalid %%K value");
15532 print_operand_address (file, x);
15533 fputs ("@l", file);
15536 /* %l is output_asm_label. */
15539 /* Write second word of DImode or DFmode reference. Works on register
15540 or non-indexed memory only. */
15541 if (GET_CODE (x) == REG)
15542 fputs (reg_names[REGNO (x) + 1], file);
15543 else if (GET_CODE (x) == MEM)
15545 /* Handle possible auto-increment. Since it is pre-increment and
15546 we have already done it, we can just use an offset of word. */
15547 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15548 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15549 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15551 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15552 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
15555 output_address (XEXP (adjust_address_nv (x, SImode,
15559 if (small_data_operand (x, GET_MODE (x)))
15560 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15561 reg_names[SMALL_DATA_REG]);
15566 /* MB value for a mask operand. */
15567 if (! mask_operand (x, SImode))
15568 output_operand_lossage ("invalid %%m value");
15570 fprintf (file, "%d", extract_MB (x));
15574 /* ME value for a mask operand. */
15575 if (! mask_operand (x, SImode))
15576 output_operand_lossage ("invalid %%M value");
15578 fprintf (file, "%d", extract_ME (x));
15581 /* %n outputs the negative of its operand. */
15584 /* Write the number of elements in the vector times 4. */
15585 if (GET_CODE (x) != PARALLEL)
15586 output_operand_lossage ("invalid %%N value");
15588 fprintf (file, "%d", XVECLEN (x, 0) * 4);
15592 /* Similar, but subtract 1 first. */
15593 if (GET_CODE (x) != PARALLEL)
15594 output_operand_lossage ("invalid %%O value");
15596 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
15600 /* X is a CONST_INT that is a power of two. Output the logarithm. */
15602 || INT_LOWPART (x) < 0
15603 || (i = exact_log2 (INT_LOWPART (x))) < 0)
15604 output_operand_lossage ("invalid %%p value");
15606 fprintf (file, "%d", i);
15610 /* The operand must be an indirect memory reference. The result
15611 is the register name. */
15612 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
15613 || REGNO (XEXP (x, 0)) >= 32)
15614 output_operand_lossage ("invalid %%P value");
15616 fputs (reg_names[REGNO (XEXP (x, 0))], file);
15620 /* This outputs the logical code corresponding to a boolean
15621 expression. The expression may have one or both operands
15622 negated (if one, only the first one). For condition register
15623 logical operations, it will also treat the negated
15624 CR codes as NOTs, but not handle NOTs of them. */
15626 const char *const *t = 0;
15628 enum rtx_code code = GET_CODE (x);
15629 static const char * const tbl[3][3] = {
15630 { "and", "andc", "nor" },
15631 { "or", "orc", "nand" },
15632 { "xor", "eqv", "xor" } };
15636 else if (code == IOR)
15638 else if (code == XOR)
15641 output_operand_lossage ("invalid %%q value");
15643 if (GET_CODE (XEXP (x, 0)) != NOT)
15647 if (GET_CODE (XEXP (x, 1)) == NOT)
15665 /* X is a CR register. Print the mask for `mtcrf'. */
15666 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15667 output_operand_lossage ("invalid %%R value");
15669 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
15673 /* Low 5 bits of 32 - value */
15675 output_operand_lossage ("invalid %%s value");
15677 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
15681 /* PowerPC64 mask position. All 0's is excluded.
15682 CONST_INT 32-bit mask is considered sign-extended so any
15683 transition must occur within the CONST_INT, not on the boundary. */
15684 if (! mask64_operand (x, DImode))
15685 output_operand_lossage ("invalid %%S value");
15687 uval = INT_LOWPART (x);
15689 if (uval & 1) /* Clear Left */
15691 #if HOST_BITS_PER_WIDE_INT > 64
15692 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15696 else /* Clear Right */
15699 #if HOST_BITS_PER_WIDE_INT > 64
15700 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
15706 gcc_assert (i >= 0);
15707 fprintf (file, "%d", i);
15711 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
15712 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
15714 /* Bit 3 is OV bit. */
15715 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
15717 /* If we want bit 31, write a shift count of zero, not 32. */
15718 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15722 /* Print the symbolic name of a branch target register. */
15723 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
15724 && REGNO (x) != CTR_REGNO))
15725 output_operand_lossage ("invalid %%T value");
15726 else if (REGNO (x) == LR_REGNO)
15727 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
15729 fputs ("ctr", file);
15733 /* High-order 16 bits of constant for use in unsigned operand. */
15735 output_operand_lossage ("invalid %%u value");
15737 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15738 (INT_LOWPART (x) >> 16) & 0xffff);
15742 /* High-order 16 bits of constant for use in signed operand. */
15744 output_operand_lossage ("invalid %%v value");
15746 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
15747 (INT_LOWPART (x) >> 16) & 0xffff);
15751 /* Print `u' if this has an auto-increment or auto-decrement. */
15752 if (GET_CODE (x) == MEM
15753 && (GET_CODE (XEXP (x, 0)) == PRE_INC
15754 || GET_CODE (XEXP (x, 0)) == PRE_DEC
15755 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
15760 /* Print the trap code for this operand. */
15761 switch (GET_CODE (x))
15764 fputs ("eq", file); /* 4 */
15767 fputs ("ne", file); /* 24 */
15770 fputs ("lt", file); /* 16 */
15773 fputs ("le", file); /* 20 */
15776 fputs ("gt", file); /* 8 */
15779 fputs ("ge", file); /* 12 */
15782 fputs ("llt", file); /* 2 */
15785 fputs ("lle", file); /* 6 */
15788 fputs ("lgt", file); /* 1 */
15791 fputs ("lge", file); /* 5 */
15794 gcc_unreachable ();
15799 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
15802 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
15803 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
15805 print_operand (file, x, 0);
15809 /* MB value for a PowerPC64 rldic operand. */
15810 val = (GET_CODE (x) == CONST_INT
15811 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
15816 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
15817 if ((val <<= 1) < 0)
15820 #if HOST_BITS_PER_WIDE_INT == 32
15821 if (GET_CODE (x) == CONST_INT && i >= 0)
15822 i += 32; /* zero-extend high-part was all 0's */
15823 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
15825 val = CONST_DOUBLE_LOW (x);
15831 for ( ; i < 64; i++)
15832 if ((val <<= 1) < 0)
15837 fprintf (file, "%d", i + 1);
15841 /* X is a FPR or Altivec register used in a VSX context. */
15842 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
15843 output_operand_lossage ("invalid %%x value");
15846 int reg = REGNO (x);
15847 int vsx_reg = (FP_REGNO_P (reg)
15849 : reg - FIRST_ALTIVEC_REGNO + 32);
15851 #ifdef TARGET_REGNAMES
15852 if (TARGET_REGNAMES)
15853 fprintf (file, "%%vs%d", vsx_reg);
15856 fprintf (file, "%d", vsx_reg);
15861 if (GET_CODE (x) == MEM
15862 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
15863 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
15864 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
15869 /* Like 'L', for third word of TImode */
15870 if (GET_CODE (x) == REG)
15871 fputs (reg_names[REGNO (x) + 2], file);
15872 else if (GET_CODE (x) == MEM)
15874 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15875 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15876 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15877 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15878 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
15880 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
15881 if (small_data_operand (x, GET_MODE (x)))
15882 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15883 reg_names[SMALL_DATA_REG]);
15888 /* X is a SYMBOL_REF. Write out the name preceded by a
15889 period and without any trailing data in brackets. Used for function
15890 names. If we are configured for System V (or the embedded ABI) on
15891 the PowerPC, do not emit the period, since those systems do not use
15892 TOCs and the like. */
15893 gcc_assert (GET_CODE (x) == SYMBOL_REF);
15895 /* Mark the decl as referenced so that cgraph will output the
15897 if (SYMBOL_REF_DECL (x))
15898 mark_decl_referenced (SYMBOL_REF_DECL (x));
15900 /* For macho, check to see if we need a stub. */
15903 const char *name = XSTR (x, 0);
15905 if (darwin_emit_branch_islands
15906 && MACHOPIC_INDIRECT
15907 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
15908 name = machopic_indirection_name (x, /*stub_p=*/true);
15910 assemble_name (file, name);
15912 else if (!DOT_SYMBOLS)
15913 assemble_name (file, XSTR (x, 0));
15915 rs6000_output_function_entry (file, XSTR (x, 0));
15919 /* Like 'L', for last word of TImode. */
15920 if (GET_CODE (x) == REG)
15921 fputs (reg_names[REGNO (x) + 3], file);
15922 else if (GET_CODE (x) == MEM)
15924 if (GET_CODE (XEXP (x, 0)) == PRE_INC
15925 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
15926 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15927 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
15928 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
15930 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
15931 if (small_data_operand (x, GET_MODE (x)))
15932 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
15933 reg_names[SMALL_DATA_REG]);
15937 /* Print AltiVec or SPE memory operand. */
15942 gcc_assert (GET_CODE (x) == MEM);
15946 /* Ugly hack because %y is overloaded. */
15947 if ((TARGET_SPE || TARGET_E500_DOUBLE)
15948 && (GET_MODE_SIZE (GET_MODE (x)) == 8
15949 || GET_MODE (x) == TFmode
15950 || GET_MODE (x) == TImode))
15952 /* Handle [reg]. */
15953 if (GET_CODE (tmp) == REG)
15955 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
15958 /* Handle [reg+UIMM]. */
15959 else if (GET_CODE (tmp) == PLUS &&
15960 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
15964 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
15966 x = INTVAL (XEXP (tmp, 1));
15967 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
15971 /* Fall through. Must be [reg+reg]. */
15973 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
15974 && GET_CODE (tmp) == AND
15975 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
15976 && INTVAL (XEXP (tmp, 1)) == -16)
15977 tmp = XEXP (tmp, 0);
15978 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
15979 && GET_CODE (tmp) == PRE_MODIFY)
15980 tmp = XEXP (tmp, 1);
15981 if (GET_CODE (tmp) == REG)
15982 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
15985 if (!GET_CODE (tmp) == PLUS
15986 || !REG_P (XEXP (tmp, 0))
15987 || !REG_P (XEXP (tmp, 1)))
15989 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
15993 if (REGNO (XEXP (tmp, 0)) == 0)
15994 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
15995 reg_names[ REGNO (XEXP (tmp, 0)) ]);
15997 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
15998 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16004 if (GET_CODE (x) == REG)
16005 fprintf (file, "%s", reg_names[REGNO (x)]);
16006 else if (GET_CODE (x) == MEM)
16008 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16009 know the width from the mode. */
16010 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
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_DEC)
16014 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16015 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16016 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16017 output_address (XEXP (XEXP (x, 0), 1));
16019 output_address (XEXP (x, 0));
16022 output_addr_const (file, x);
16026 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16030 output_operand_lossage ("invalid %%xn code");
16034 /* Print the address of an operand. */
16037 print_operand_address (FILE *file, rtx x)
16039 if (GET_CODE (x) == REG)
16040 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16041 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16042 || GET_CODE (x) == LABEL_REF)
16044 output_addr_const (file, x);
16045 if (small_data_operand (x, GET_MODE (x)))
16046 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16047 reg_names[SMALL_DATA_REG]);
16049 gcc_assert (!TARGET_TOC);
16051 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16053 gcc_assert (REG_P (XEXP (x, 0)));
16054 if (REGNO (XEXP (x, 0)) == 0)
16055 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16056 reg_names[ REGNO (XEXP (x, 0)) ]);
16058 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16059 reg_names[ REGNO (XEXP (x, 1)) ]);
16061 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16062 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16063 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16065 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16066 && CONSTANT_P (XEXP (x, 1)))
16068 fprintf (file, "lo16(");
16069 output_addr_const (file, XEXP (x, 1));
16070 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16073 else if (legitimate_constant_pool_address_p (x, true))
16075 /* This hack along with a corresponding hack in
16076 rs6000_output_addr_const_extra arranges to output addends
16077 where the assembler expects to find them. eg.
16079 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16080 without this hack would be output as "x@toc+8@l(9)". We
16081 want "x+8@toc@l(9)". */
16082 output_addr_const (file, tocrel_base);
16083 if (GET_CODE (x) == LO_SUM)
16084 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16086 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16089 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16090 && CONSTANT_P (XEXP (x, 1)))
16092 output_addr_const (file, XEXP (x, 1));
16093 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16097 gcc_unreachable ();
16100 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16103 rs6000_output_addr_const_extra (FILE *file, rtx x)
16105 if (GET_CODE (x) == UNSPEC)
16106 switch (XINT (x, 1))
16108 case UNSPEC_TOCREL:
16109 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16110 output_addr_const (file, XVECEXP (x, 0, 0));
16111 if (x == tocrel_base && tocrel_offset != const0_rtx)
16113 if (INTVAL (tocrel_offset) >= 0)
16114 fprintf (file, "+");
16115 output_addr_const (file, tocrel_offset);
16117 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16120 assemble_name (file, toc_label_name);
16122 else if (TARGET_ELF)
16123 fputs ("@toc", file);
16127 case UNSPEC_MACHOPIC_OFFSET:
16128 output_addr_const (file, XVECEXP (x, 0, 0));
16130 machopic_output_function_base_name (file);
16137 /* Target hook for assembling integer objects. The PowerPC version has
16138 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16139 is defined. It also needs to handle DI-mode objects on 64-bit
16143 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16145 #ifdef RELOCATABLE_NEEDS_FIXUP
16146 /* Special handling for SI values. */
16147 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16149 static int recurse = 0;
16151 /* For -mrelocatable, we mark all addresses that need to be fixed up
16152 in the .fixup section. */
16153 if (TARGET_RELOCATABLE
16154 && in_section != toc_section
16155 && in_section != text_section
16156 && !unlikely_text_section_p (in_section)
16158 && GET_CODE (x) != CONST_INT
16159 && GET_CODE (x) != CONST_DOUBLE
16165 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16167 ASM_OUTPUT_LABEL (asm_out_file, buf);
16168 fprintf (asm_out_file, "\t.long\t(");
16169 output_addr_const (asm_out_file, x);
16170 fprintf (asm_out_file, ")@fixup\n");
16171 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16172 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16173 fprintf (asm_out_file, "\t.long\t");
16174 assemble_name (asm_out_file, buf);
16175 fprintf (asm_out_file, "\n\t.previous\n");
16179 /* Remove initial .'s to turn a -mcall-aixdesc function
16180 address into the address of the descriptor, not the function
16182 else if (GET_CODE (x) == SYMBOL_REF
16183 && XSTR (x, 0)[0] == '.'
16184 && DEFAULT_ABI == ABI_AIX)
16186 const char *name = XSTR (x, 0);
16187 while (*name == '.')
16190 fprintf (asm_out_file, "\t.long\t%s\n", name);
16194 #endif /* RELOCATABLE_NEEDS_FIXUP */
16195 return default_assemble_integer (x, size, aligned_p);
16198 #ifdef HAVE_GAS_HIDDEN
16199 /* Emit an assembler directive to set symbol visibility for DECL to
16200 VISIBILITY_TYPE. */
16203 rs6000_assemble_visibility (tree decl, int vis)
16205 /* Functions need to have their entry point symbol visibility set as
16206 well as their descriptor symbol visibility. */
16207 if (DEFAULT_ABI == ABI_AIX
16209 && TREE_CODE (decl) == FUNCTION_DECL)
16211 static const char * const visibility_types[] = {
16212 NULL, "internal", "hidden", "protected"
16215 const char *name, *type;
16217 name = ((* targetm.strip_name_encoding)
16218 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16219 type = visibility_types[vis];
16221 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16222 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16225 default_assemble_visibility (decl, vis);
16230 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16232 /* Reversal of FP compares takes care -- an ordered compare
16233 becomes an unordered compare and vice versa. */
16234 if (mode == CCFPmode
16235 && (!flag_finite_math_only
16236 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16237 || code == UNEQ || code == LTGT))
16238 return reverse_condition_maybe_unordered (code);
16240 return reverse_condition (code);
16243 /* Generate a compare for CODE. Return a brand-new rtx that
16244 represents the result of the compare. */
16247 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16249 enum machine_mode comp_mode;
16250 rtx compare_result;
16251 enum rtx_code code = GET_CODE (cmp);
16252 rtx op0 = XEXP (cmp, 0);
16253 rtx op1 = XEXP (cmp, 1);
16255 if (FLOAT_MODE_P (mode))
16256 comp_mode = CCFPmode;
16257 else if (code == GTU || code == LTU
16258 || code == GEU || code == LEU)
16259 comp_mode = CCUNSmode;
16260 else if ((code == EQ || code == NE)
16261 && GET_CODE (op0) == SUBREG
16262 && GET_CODE (op1) == SUBREG
16263 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16264 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16265 /* These are unsigned values, perhaps there will be a later
16266 ordering compare that can be shared with this one.
16267 Unfortunately we cannot detect the signedness of the operands
16268 for non-subregs. */
16269 comp_mode = CCUNSmode;
16271 comp_mode = CCmode;
16273 /* First, the compare. */
16274 compare_result = gen_reg_rtx (comp_mode);
16276 /* E500 FP compare instructions on the GPRs. Yuck! */
16277 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16278 && FLOAT_MODE_P (mode))
16280 rtx cmp, or_result, compare_result2;
16281 enum machine_mode op_mode = GET_MODE (op0);
16283 if (op_mode == VOIDmode)
16284 op_mode = GET_MODE (op1);
16286 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16287 This explains the following mess. */
16291 case EQ: case UNEQ: case NE: case LTGT:
16295 cmp = (flag_finite_math_only && !flag_trapping_math)
16296 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16297 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16301 cmp = (flag_finite_math_only && !flag_trapping_math)
16302 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16303 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16307 cmp = (flag_finite_math_only && !flag_trapping_math)
16308 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16309 : gen_cmptfeq_gpr (compare_result, op0, op1);
16313 gcc_unreachable ();
16317 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16321 cmp = (flag_finite_math_only && !flag_trapping_math)
16322 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16323 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16327 cmp = (flag_finite_math_only && !flag_trapping_math)
16328 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16329 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16333 cmp = (flag_finite_math_only && !flag_trapping_math)
16334 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16335 : gen_cmptfgt_gpr (compare_result, op0, op1);
16339 gcc_unreachable ();
16343 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16347 cmp = (flag_finite_math_only && !flag_trapping_math)
16348 ? gen_tstsflt_gpr (compare_result, op0, op1)
16349 : gen_cmpsflt_gpr (compare_result, op0, op1);
16353 cmp = (flag_finite_math_only && !flag_trapping_math)
16354 ? gen_tstdflt_gpr (compare_result, op0, op1)
16355 : gen_cmpdflt_gpr (compare_result, op0, op1);
16359 cmp = (flag_finite_math_only && !flag_trapping_math)
16360 ? gen_tsttflt_gpr (compare_result, op0, op1)
16361 : gen_cmptflt_gpr (compare_result, op0, op1);
16365 gcc_unreachable ();
16369 gcc_unreachable ();
16372 /* Synthesize LE and GE from LT/GT || EQ. */
16373 if (code == LE || code == GE || code == LEU || code == GEU)
16379 case LE: code = LT; break;
16380 case GE: code = GT; break;
16381 case LEU: code = LT; break;
16382 case GEU: code = GT; break;
16383 default: gcc_unreachable ();
16386 compare_result2 = gen_reg_rtx (CCFPmode);
16392 cmp = (flag_finite_math_only && !flag_trapping_math)
16393 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16394 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16398 cmp = (flag_finite_math_only && !flag_trapping_math)
16399 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16400 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16404 cmp = (flag_finite_math_only && !flag_trapping_math)
16405 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16406 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16410 gcc_unreachable ();
16414 /* OR them together. */
16415 or_result = gen_reg_rtx (CCFPmode);
16416 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16418 compare_result = or_result;
16423 if (code == NE || code == LTGT)
16433 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16434 CLOBBERs to match cmptf_internal2 pattern. */
16435 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16436 && GET_MODE (op0) == TFmode
16437 && !TARGET_IEEEQUAD
16438 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16439 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16441 gen_rtx_SET (VOIDmode,
16443 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 (DFmode)),
16450 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16451 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16452 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16453 else if (GET_CODE (op1) == UNSPEC
16454 && XINT (op1, 1) == UNSPEC_SP_TEST)
16456 rtx op1b = XVECEXP (op1, 0, 0);
16457 comp_mode = CCEQmode;
16458 compare_result = gen_reg_rtx (CCEQmode);
16460 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16462 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16465 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16466 gen_rtx_COMPARE (comp_mode, op0, op1)));
16469 /* Some kinds of FP comparisons need an OR operation;
16470 under flag_finite_math_only we don't bother. */
16471 if (FLOAT_MODE_P (mode)
16472 && !flag_finite_math_only
16473 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16474 && (code == LE || code == GE
16475 || code == UNEQ || code == LTGT
16476 || code == UNGT || code == UNLT))
16478 enum rtx_code or1, or2;
16479 rtx or1_rtx, or2_rtx, compare2_rtx;
16480 rtx or_result = gen_reg_rtx (CCEQmode);
16484 case LE: or1 = LT; or2 = EQ; break;
16485 case GE: or1 = GT; or2 = EQ; break;
16486 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16487 case LTGT: or1 = LT; or2 = GT; break;
16488 case UNGT: or1 = UNORDERED; or2 = GT; break;
16489 case UNLT: or1 = UNORDERED; or2 = LT; break;
16490 default: gcc_unreachable ();
16492 validate_condition_mode (or1, comp_mode);
16493 validate_condition_mode (or2, comp_mode);
16494 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16495 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16496 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16497 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16499 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16501 compare_result = or_result;
16505 validate_condition_mode (code, GET_MODE (compare_result));
16507 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16511 /* Emit the RTL for an sISEL pattern. */
16514 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16516 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
16520 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
16523 enum machine_mode op_mode;
16524 enum rtx_code cond_code;
16525 rtx result = operands[0];
16527 if (TARGET_ISEL && (mode == SImode || mode == DImode))
16529 rs6000_emit_sISEL (mode, operands);
16533 condition_rtx = rs6000_generate_compare (operands[1], mode);
16534 cond_code = GET_CODE (condition_rtx);
16536 if (FLOAT_MODE_P (mode)
16537 && !TARGET_FPRS && TARGET_HARD_FLOAT)
16541 PUT_MODE (condition_rtx, SImode);
16542 t = XEXP (condition_rtx, 0);
16544 gcc_assert (cond_code == NE || cond_code == EQ);
16546 if (cond_code == NE)
16547 emit_insn (gen_e500_flip_gt_bit (t, t));
16549 emit_insn (gen_move_from_CR_gt_bit (result, t));
16553 if (cond_code == NE
16554 || cond_code == GE || cond_code == LE
16555 || cond_code == GEU || cond_code == LEU
16556 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
16558 rtx not_result = gen_reg_rtx (CCEQmode);
16559 rtx not_op, rev_cond_rtx;
16560 enum machine_mode cc_mode;
16562 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
16564 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
16565 SImode, XEXP (condition_rtx, 0), const0_rtx);
16566 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
16567 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
16568 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
16571 op_mode = GET_MODE (XEXP (operands[1], 0));
16572 if (op_mode == VOIDmode)
16573 op_mode = GET_MODE (XEXP (operands[1], 1));
16575 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
16577 PUT_MODE (condition_rtx, DImode);
16578 convert_move (result, condition_rtx, 0);
16582 PUT_MODE (condition_rtx, SImode);
16583 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
16587 /* Emit a branch of kind CODE to location LOC. */
16590 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
16592 rtx condition_rtx, loc_ref;
16594 condition_rtx = rs6000_generate_compare (operands[0], mode);
16595 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
16596 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
16597 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
16598 loc_ref, pc_rtx)));
16601 /* Return the string to output a conditional branch to LABEL, which is
16602 the operand number of the label, or -1 if the branch is really a
16603 conditional return.
16605 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
16606 condition code register and its mode specifies what kind of
16607 comparison we made.
16609 REVERSED is nonzero if we should reverse the sense of the comparison.
16611 INSN is the insn. */
16614 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
16616 static char string[64];
16617 enum rtx_code code = GET_CODE (op);
16618 rtx cc_reg = XEXP (op, 0);
16619 enum machine_mode mode = GET_MODE (cc_reg);
16620 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
16621 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
16622 int really_reversed = reversed ^ need_longbranch;
16628 validate_condition_mode (code, mode);
16630 /* Work out which way this really branches. We could use
16631 reverse_condition_maybe_unordered here always but this
16632 makes the resulting assembler clearer. */
16633 if (really_reversed)
16635 /* Reversal of FP compares takes care -- an ordered compare
16636 becomes an unordered compare and vice versa. */
16637 if (mode == CCFPmode)
16638 code = reverse_condition_maybe_unordered (code);
16640 code = reverse_condition (code);
16643 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
16645 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
16650 /* Opposite of GT. */
16659 gcc_unreachable ();
16665 /* Not all of these are actually distinct opcodes, but
16666 we distinguish them for clarity of the resulting assembler. */
16667 case NE: case LTGT:
16668 ccode = "ne"; break;
16669 case EQ: case UNEQ:
16670 ccode = "eq"; break;
16672 ccode = "ge"; break;
16673 case GT: case GTU: case UNGT:
16674 ccode = "gt"; break;
16676 ccode = "le"; break;
16677 case LT: case LTU: case UNLT:
16678 ccode = "lt"; break;
16679 case UNORDERED: ccode = "un"; break;
16680 case ORDERED: ccode = "nu"; break;
16681 case UNGE: ccode = "nl"; break;
16682 case UNLE: ccode = "ng"; break;
16684 gcc_unreachable ();
16687 /* Maybe we have a guess as to how likely the branch is.
16688 The old mnemonics don't have a way to specify this information. */
16690 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
16691 if (note != NULL_RTX)
16693 /* PROB is the difference from 50%. */
16694 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
16696 /* Only hint for highly probable/improbable branches on newer
16697 cpus as static prediction overrides processor dynamic
16698 prediction. For older cpus we may as well always hint, but
16699 assume not taken for branches that are very close to 50% as a
16700 mispredicted taken branch is more expensive than a
16701 mispredicted not-taken branch. */
16702 if (rs6000_always_hint
16703 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
16704 && br_prob_note_reliable_p (note)))
16706 if (abs (prob) > REG_BR_PROB_BASE / 20
16707 && ((prob > 0) ^ need_longbranch))
16715 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
16717 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
16719 /* We need to escape any '%' characters in the reg_names string.
16720 Assume they'd only be the first character.... */
16721 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
16723 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
16727 /* If the branch distance was too far, we may have to use an
16728 unconditional branch to go the distance. */
16729 if (need_longbranch)
16730 s += sprintf (s, ",$+8\n\tb %s", label);
16732 s += sprintf (s, ",%s", label);
16738 /* Return the string to flip the GT bit on a CR. */
16740 output_e500_flip_gt_bit (rtx dst, rtx src)
16742 static char string[64];
16745 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
16746 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
16749 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
16750 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
16752 sprintf (string, "crnot %d,%d", a, b);
16756 /* Return insn for VSX or Altivec comparisons. */
16759 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
16762 enum machine_mode mode = GET_MODE (op0);
16770 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
16776 mask = gen_reg_rtx (mode);
16777 emit_insn (gen_rtx_SET (VOIDmode,
16779 gen_rtx_fmt_ee (code, mode, op0, op1)));
16786 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
16787 DMODE is expected destination mode. This is a recursive function. */
16790 rs6000_emit_vector_compare (enum rtx_code rcode,
16792 enum machine_mode dmode)
16795 bool swap_operands = false;
16796 bool try_again = false;
16798 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
16799 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
16801 /* See if the comparison works as is. */
16802 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16810 swap_operands = true;
16815 swap_operands = true;
16823 /* Invert condition and try again.
16824 e.g., A != B becomes ~(A==B). */
16826 enum rtx_code rev_code;
16827 enum insn_code nor_code;
16830 rev_code = reverse_condition_maybe_unordered (rcode);
16831 if (rev_code == UNKNOWN)
16834 nor_code = optab_handler (one_cmpl_optab, dmode);
16835 if (nor_code == CODE_FOR_nothing)
16838 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
16842 mask = gen_reg_rtx (dmode);
16843 emit_insn (GEN_FCN (nor_code) (mask, mask2));
16851 /* Try GT/GTU/LT/LTU OR EQ */
16854 enum insn_code ior_code;
16855 enum rtx_code new_code;
16876 gcc_unreachable ();
16879 ior_code = optab_handler (ior_optab, dmode);
16880 if (ior_code == CODE_FOR_nothing)
16883 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
16887 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
16891 mask = gen_reg_rtx (dmode);
16892 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
16910 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
16915 /* You only get two chances. */
16919 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
16920 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
16921 operands for the relation operation COND. */
16924 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
16925 rtx cond, rtx cc_op0, rtx cc_op1)
16927 enum machine_mode dest_mode = GET_MODE (dest);
16928 enum rtx_code rcode = GET_CODE (cond);
16929 enum machine_mode cc_mode = CCmode;
16933 bool invert_move = false;
16935 if (VECTOR_UNIT_NONE_P (dest_mode))
16940 /* Swap operands if we can, and fall back to doing the operation as
16941 specified, and doing a NOR to invert the test. */
16947 /* Invert condition and try again.
16948 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
16949 invert_move = true;
16950 rcode = reverse_condition_maybe_unordered (rcode);
16951 if (rcode == UNKNOWN)
16955 /* Mark unsigned tests with CCUNSmode. */
16960 cc_mode = CCUNSmode;
16967 /* Get the vector mask for the given relational operations. */
16968 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
16976 op_true = op_false;
16980 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
16981 emit_insn (gen_rtx_SET (VOIDmode,
16983 gen_rtx_IF_THEN_ELSE (dest_mode,
16990 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
16991 operands of the last comparison is nonzero/true, FALSE_COND if it
16992 is zero/false. Return 0 if the hardware has no such operation. */
16995 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
16997 enum rtx_code code = GET_CODE (op);
16998 rtx op0 = XEXP (op, 0);
16999 rtx op1 = XEXP (op, 1);
17000 REAL_VALUE_TYPE c1;
17001 enum machine_mode compare_mode = GET_MODE (op0);
17002 enum machine_mode result_mode = GET_MODE (dest);
17004 bool is_against_zero;
17006 /* These modes should always match. */
17007 if (GET_MODE (op1) != compare_mode
17008 /* In the isel case however, we can use a compare immediate, so
17009 op1 may be a small constant. */
17010 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17012 if (GET_MODE (true_cond) != result_mode)
17014 if (GET_MODE (false_cond) != result_mode)
17017 /* First, work out if the hardware can do this at all, or
17018 if it's too slow.... */
17019 if (!FLOAT_MODE_P (compare_mode))
17022 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17025 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17026 && SCALAR_FLOAT_MODE_P (compare_mode))
17029 is_against_zero = op1 == CONST0_RTX (compare_mode);
17031 /* A floating-point subtract might overflow, underflow, or produce
17032 an inexact result, thus changing the floating-point flags, so it
17033 can't be generated if we care about that. It's safe if one side
17034 of the construct is zero, since then no subtract will be
17036 if (SCALAR_FLOAT_MODE_P (compare_mode)
17037 && flag_trapping_math && ! is_against_zero)
17040 /* Eliminate half of the comparisons by switching operands, this
17041 makes the remaining code simpler. */
17042 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17043 || code == LTGT || code == LT || code == UNLE)
17045 code = reverse_condition_maybe_unordered (code);
17047 true_cond = false_cond;
17051 /* UNEQ and LTGT take four instructions for a comparison with zero,
17052 it'll probably be faster to use a branch here too. */
17053 if (code == UNEQ && HONOR_NANS (compare_mode))
17056 if (GET_CODE (op1) == CONST_DOUBLE)
17057 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17059 /* We're going to try to implement comparisons by performing
17060 a subtract, then comparing against zero. Unfortunately,
17061 Inf - Inf is NaN which is not zero, and so if we don't
17062 know that the operand is finite and the comparison
17063 would treat EQ different to UNORDERED, we can't do it. */
17064 if (HONOR_INFINITIES (compare_mode)
17065 && code != GT && code != UNGE
17066 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17067 /* Constructs of the form (a OP b ? a : b) are safe. */
17068 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17069 || (! rtx_equal_p (op0, true_cond)
17070 && ! rtx_equal_p (op1, true_cond))))
17073 /* At this point we know we can use fsel. */
17075 /* Reduce the comparison to a comparison against zero. */
17076 if (! is_against_zero)
17078 temp = gen_reg_rtx (compare_mode);
17079 emit_insn (gen_rtx_SET (VOIDmode, temp,
17080 gen_rtx_MINUS (compare_mode, op0, op1)));
17082 op1 = CONST0_RTX (compare_mode);
17085 /* If we don't care about NaNs we can reduce some of the comparisons
17086 down to faster ones. */
17087 if (! HONOR_NANS (compare_mode))
17093 true_cond = false_cond;
17106 /* Now, reduce everything down to a GE. */
17113 temp = gen_reg_rtx (compare_mode);
17114 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17119 temp = gen_reg_rtx (compare_mode);
17120 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17125 temp = gen_reg_rtx (compare_mode);
17126 emit_insn (gen_rtx_SET (VOIDmode, temp,
17127 gen_rtx_NEG (compare_mode,
17128 gen_rtx_ABS (compare_mode, op0))));
17133 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17134 temp = gen_reg_rtx (result_mode);
17135 emit_insn (gen_rtx_SET (VOIDmode, temp,
17136 gen_rtx_IF_THEN_ELSE (result_mode,
17137 gen_rtx_GE (VOIDmode,
17139 true_cond, false_cond)));
17140 false_cond = true_cond;
17143 temp = gen_reg_rtx (compare_mode);
17144 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17149 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17150 temp = gen_reg_rtx (result_mode);
17151 emit_insn (gen_rtx_SET (VOIDmode, temp,
17152 gen_rtx_IF_THEN_ELSE (result_mode,
17153 gen_rtx_GE (VOIDmode,
17155 true_cond, false_cond)));
17156 true_cond = false_cond;
17159 temp = gen_reg_rtx (compare_mode);
17160 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17165 gcc_unreachable ();
17168 emit_insn (gen_rtx_SET (VOIDmode, dest,
17169 gen_rtx_IF_THEN_ELSE (result_mode,
17170 gen_rtx_GE (VOIDmode,
17172 true_cond, false_cond)));
17176 /* Same as above, but for ints (isel). */
17179 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17181 rtx condition_rtx, cr;
17182 enum machine_mode mode = GET_MODE (dest);
17183 enum rtx_code cond_code;
17184 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17187 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17190 /* We still have to do the compare, because isel doesn't do a
17191 compare, it just looks at the CRx bits set by a previous compare
17193 condition_rtx = rs6000_generate_compare (op, mode);
17194 cond_code = GET_CODE (condition_rtx);
17195 cr = XEXP (condition_rtx, 0);
17196 signedp = GET_MODE (cr) == CCmode;
17198 isel_func = (mode == SImode
17199 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17200 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17204 case LT: case GT: case LTU: case GTU: case EQ:
17205 /* isel handles these directly. */
17209 /* We need to swap the sense of the comparison. */
17212 true_cond = false_cond;
17214 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17219 false_cond = force_reg (mode, false_cond);
17220 if (true_cond != const0_rtx)
17221 true_cond = force_reg (mode, true_cond);
17223 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17229 output_isel (rtx *operands)
17231 enum rtx_code code;
17233 code = GET_CODE (operands[1]);
17235 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17237 gcc_assert (GET_CODE (operands[2]) == REG
17238 && GET_CODE (operands[3]) == REG);
17239 PUT_CODE (operands[1], reverse_condition (code));
17240 return "isel %0,%3,%2,%j1";
17243 return "isel %0,%2,%3,%j1";
17247 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17249 enum machine_mode mode = GET_MODE (op0);
17253 /* VSX/altivec have direct min/max insns. */
17254 if ((code == SMAX || code == SMIN)
17255 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17256 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17258 emit_insn (gen_rtx_SET (VOIDmode,
17260 gen_rtx_fmt_ee (code, mode, op0, op1)));
17264 if (code == SMAX || code == SMIN)
17269 if (code == SMAX || code == UMAX)
17270 target = emit_conditional_move (dest, c, op0, op1, mode,
17271 op0, op1, mode, 0);
17273 target = emit_conditional_move (dest, c, op0, op1, mode,
17274 op1, op0, mode, 0);
17275 gcc_assert (target);
17276 if (target != dest)
17277 emit_move_insn (dest, target);
17280 /* Emit instructions to perform a load-reserved/store-conditional operation.
17281 The operation performed is an atomic
17282 (set M (CODE:MODE M OP))
17283 If not NULL, BEFORE is atomically set to M before the operation, and
17284 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17285 If SYNC_P then a memory barrier is emitted before the operation.
17286 Either OP or M may be wrapped in a NOT operation. */
17289 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17290 rtx m, rtx op, rtx before_param, rtx after_param,
17293 enum machine_mode used_mode;
17294 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17297 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17298 rtx shift = NULL_RTX;
17301 emit_insn (gen_lwsync ());
17305 /* If this is smaller than SImode, we'll have to use SImode with
17307 if (mode == QImode || mode == HImode)
17311 if (MEM_ALIGN (used_m) >= 32)
17314 if (BYTES_BIG_ENDIAN)
17315 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17317 shift = GEN_INT (ishift);
17318 used_m = change_address (used_m, SImode, 0);
17322 rtx addrSI, aligned_addr;
17323 int shift_mask = mode == QImode ? 0x18 : 0x10;
17325 addrSI = gen_lowpart_common (SImode,
17326 force_reg (Pmode, XEXP (used_m, 0)));
17327 addrSI = force_reg (SImode, addrSI);
17328 shift = gen_reg_rtx (SImode);
17330 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17331 GEN_INT (shift_mask)));
17332 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17334 aligned_addr = expand_binop (Pmode, and_optab,
17336 GEN_INT (-4), NULL_RTX,
17337 1, OPTAB_LIB_WIDEN);
17338 used_m = change_address (used_m, SImode, aligned_addr);
17339 set_mem_align (used_m, 32);
17341 /* It's safe to keep the old alias set of USED_M, because
17342 the operation is atomic and only affects the original
17346 if (GET_CODE (op) == NOT)
17348 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17349 oldop = gen_rtx_NOT (SImode, oldop);
17352 oldop = lowpart_subreg (SImode, op, mode);
17358 newop = expand_binop (SImode, and_optab,
17359 oldop, GEN_INT (imask), NULL_RTX,
17360 1, OPTAB_LIB_WIDEN);
17361 emit_insn (gen_ashlsi3 (newop, newop, shift));
17364 case NOT: /* NAND */
17365 newop = expand_binop (SImode, ior_optab,
17366 oldop, GEN_INT (~imask), NULL_RTX,
17367 1, OPTAB_LIB_WIDEN);
17368 emit_insn (gen_rotlsi3 (newop, newop, shift));
17372 newop = expand_binop (SImode, ior_optab,
17373 oldop, GEN_INT (~imask), NULL_RTX,
17374 1, OPTAB_LIB_WIDEN);
17375 emit_insn (gen_rotlsi3 (newop, newop, shift));
17383 newop = expand_binop (SImode, and_optab,
17384 oldop, GEN_INT (imask), NULL_RTX,
17385 1, OPTAB_LIB_WIDEN);
17386 emit_insn (gen_ashlsi3 (newop, newop, shift));
17388 mask = gen_reg_rtx (SImode);
17389 emit_move_insn (mask, GEN_INT (imask));
17390 emit_insn (gen_ashlsi3 (mask, mask, shift));
17393 newop = gen_rtx_PLUS (SImode, m, newop);
17395 newop = gen_rtx_MINUS (SImode, m, newop);
17396 newop = gen_rtx_AND (SImode, newop, mask);
17397 newop = gen_rtx_IOR (SImode, newop,
17398 gen_rtx_AND (SImode,
17399 gen_rtx_NOT (SImode, mask),
17405 gcc_unreachable ();
17409 used_mode = SImode;
17410 before = gen_reg_rtx (used_mode);
17411 after = gen_reg_rtx (used_mode);
17416 before = before_param;
17417 after = after_param;
17419 if (before == NULL_RTX)
17420 before = gen_reg_rtx (used_mode);
17421 if (after == NULL_RTX)
17422 after = gen_reg_rtx (used_mode);
17425 if ((code == PLUS || code == MINUS)
17426 && used_mode != mode)
17427 the_op = op; /* Computed above. */
17428 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17429 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17430 else if (code == NOT)
17431 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17432 gen_rtx_NOT (used_mode, m),
17433 gen_rtx_NOT (used_mode, op));
17435 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17437 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17438 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17439 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17440 gen_rtx_UNSPEC (used_mode,
17441 gen_rtvec (1, the_op),
17443 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17445 if ((code == PLUS || code == MINUS) && used_mode != mode)
17446 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17447 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17449 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17450 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17452 /* Shift and mask the return values properly. */
17453 if (used_mode != mode && before_param)
17455 emit_insn (gen_lshrsi3 (before, before, shift));
17456 convert_move (before_param, before, 1);
17459 if (used_mode != mode && after_param)
17461 emit_insn (gen_lshrsi3 (after, after, shift));
17462 convert_move (after_param, after, 1);
17465 /* The previous sequence will end with a branch that's dependent on
17466 the conditional store, so placing an isync will ensure that no
17467 other instructions (especially, no load or store instructions)
17468 can start before the atomic operation completes. */
17470 emit_insn (gen_isync ());
17473 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17474 COND is true. Mark the jump as unlikely to be taken. */
17477 emit_unlikely_jump (rtx cond, rtx label)
17479 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17482 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17483 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17484 add_reg_note (x, REG_BR_PROB, very_unlikely);
17487 /* A subroutine of the atomic operation splitters. Emit a load-locked
17488 instruction in MODE. */
17491 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17493 rtx (*fn) (rtx, rtx) = NULL;
17494 if (mode == SImode)
17495 fn = gen_load_locked_si;
17496 else if (mode == DImode)
17497 fn = gen_load_locked_di;
17498 emit_insn (fn (reg, mem));
17501 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17502 instruction in MODE. */
17505 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17507 rtx (*fn) (rtx, rtx, rtx) = NULL;
17508 if (mode == SImode)
17509 fn = gen_store_conditional_si;
17510 else if (mode == DImode)
17511 fn = gen_store_conditional_di;
17513 /* Emit sync before stwcx. to address PPC405 Erratum. */
17514 if (PPC405_ERRATUM77)
17515 emit_insn (gen_memory_barrier ());
17517 emit_insn (fn (res, mem, val));
17520 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
17521 to perform. MEM is the memory on which to operate. VAL is the second
17522 operand of the binary operator. BEFORE and AFTER are optional locations to
17523 return the value of MEM either before of after the operation. SCRATCH is
17524 a scratch register. */
17527 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
17528 rtx before, rtx after, rtx scratch)
17530 enum machine_mode mode = GET_MODE (mem);
17531 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17533 emit_insn (gen_lwsync ());
17535 label = gen_label_rtx ();
17536 emit_label (label);
17537 label = gen_rtx_LABEL_REF (VOIDmode, label);
17539 if (before == NULL_RTX)
17541 emit_load_locked (mode, before, mem);
17544 x = gen_rtx_IOR (mode,
17545 gen_rtx_NOT (mode, before),
17546 gen_rtx_NOT (mode, val));
17547 else if (code == AND)
17548 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
17550 x = gen_rtx_fmt_ee (code, mode, before, val);
17552 if (after != NULL_RTX)
17553 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
17554 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
17556 emit_store_conditional (mode, cond, mem, scratch);
17558 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17559 emit_unlikely_jump (x, label);
17561 emit_insn (gen_isync ());
17564 /* Expand an atomic compare and swap operation. MEM is the memory on which
17565 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
17566 value to be stored. SCRATCH is a scratch GPR. */
17569 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
17572 enum machine_mode mode = GET_MODE (mem);
17573 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17575 emit_insn (gen_lwsync ());
17577 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17578 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17579 emit_label (XEXP (label1, 0));
17581 emit_load_locked (mode, retval, mem);
17583 x = gen_rtx_COMPARE (CCmode, retval, oldval);
17584 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17586 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17587 emit_unlikely_jump (x, label2);
17589 emit_move_insn (scratch, newval);
17590 emit_store_conditional (mode, cond, mem, scratch);
17592 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17593 emit_unlikely_jump (x, label1);
17595 emit_insn (gen_isync ());
17596 emit_label (XEXP (label2, 0));
17599 /* Expand an atomic test and set operation. MEM is the memory on which
17600 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
17603 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
17605 enum machine_mode mode = GET_MODE (mem);
17606 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17608 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17609 emit_label (XEXP (label, 0));
17611 emit_load_locked (mode, retval, mem);
17612 emit_move_insn (scratch, val);
17613 emit_store_conditional (mode, cond, mem, scratch);
17615 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17616 emit_unlikely_jump (x, label);
17618 emit_insn (gen_isync ());
17622 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
17624 enum machine_mode mode = GET_MODE (mem);
17625 rtx addrSI, align, wdst, shift, mask;
17626 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
17627 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17629 /* Shift amount for subword relative to aligned word. */
17630 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
17631 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
17632 shift = gen_reg_rtx (SImode);
17633 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17634 GEN_INT (shift_mask)));
17635 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17637 /* Shift and mask old value into position within word. */
17638 oldval = convert_modes (SImode, mode, oldval, 1);
17639 oldval = expand_binop (SImode, and_optab,
17640 oldval, GEN_INT (imask), NULL_RTX,
17641 1, OPTAB_LIB_WIDEN);
17642 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
17644 /* Shift and mask new value into position within word. */
17645 newval = convert_modes (SImode, mode, newval, 1);
17646 newval = expand_binop (SImode, and_optab,
17647 newval, GEN_INT (imask), NULL_RTX,
17648 1, OPTAB_LIB_WIDEN);
17649 emit_insn (gen_ashlsi3 (newval, newval, shift));
17651 /* Mask for insertion. */
17652 mask = gen_reg_rtx (SImode);
17653 emit_move_insn (mask, GEN_INT (imask));
17654 emit_insn (gen_ashlsi3 (mask, mask, shift));
17656 /* Address of aligned word containing subword. */
17657 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
17658 NULL_RTX, 1, OPTAB_LIB_WIDEN);
17659 mem = change_address (mem, SImode, align);
17660 set_mem_align (mem, 32);
17661 MEM_VOLATILE_P (mem) = 1;
17663 wdst = gen_reg_rtx (SImode);
17664 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
17665 oldval, newval, mem));
17667 /* Shift the result back. */
17668 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
17670 emit_move_insn (dst, gen_lowpart (mode, wdst));
17674 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
17675 rtx oldval, rtx newval, rtx mem,
17678 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
17680 emit_insn (gen_lwsync ());
17681 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17682 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
17683 emit_label (XEXP (label1, 0));
17685 emit_load_locked (SImode, scratch, mem);
17687 /* Mask subword within loaded value for comparison with oldval.
17688 Use UNSPEC_AND to avoid clobber.*/
17689 emit_insn (gen_rtx_SET (SImode, dest,
17690 gen_rtx_UNSPEC (SImode,
17691 gen_rtvec (2, scratch, mask),
17694 x = gen_rtx_COMPARE (CCmode, dest, oldval);
17695 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
17697 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17698 emit_unlikely_jump (x, label2);
17700 /* Clear subword within loaded value for insertion of new value. */
17701 emit_insn (gen_rtx_SET (SImode, scratch,
17702 gen_rtx_AND (SImode,
17703 gen_rtx_NOT (SImode, mask), scratch)));
17704 emit_insn (gen_iorsi3 (scratch, scratch, newval));
17705 emit_store_conditional (SImode, cond, mem, scratch);
17707 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
17708 emit_unlikely_jump (x, label1);
17710 emit_insn (gen_isync ());
17711 emit_label (XEXP (label2, 0));
17715 /* Emit instructions to move SRC to DST. Called by splitters for
17716 multi-register moves. It will emit at most one instruction for
17717 each register that is accessed; that is, it won't emit li/lis pairs
17718 (or equivalent for 64-bit code). One of SRC or DST must be a hard
17722 rs6000_split_multireg_move (rtx dst, rtx src)
17724 /* The register number of the first register being moved. */
17726 /* The mode that is to be moved. */
17727 enum machine_mode mode;
17728 /* The mode that the move is being done in, and its size. */
17729 enum machine_mode reg_mode;
17731 /* The number of registers that will be moved. */
17734 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
17735 mode = GET_MODE (dst);
17736 nregs = hard_regno_nregs[reg][mode];
17737 if (FP_REGNO_P (reg))
17738 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
17739 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
17740 else if (ALTIVEC_REGNO_P (reg))
17741 reg_mode = V16QImode;
17742 else if (TARGET_E500_DOUBLE && mode == TFmode)
17745 reg_mode = word_mode;
17746 reg_mode_size = GET_MODE_SIZE (reg_mode);
17748 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
17750 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
17752 /* Move register range backwards, if we might have destructive
17755 for (i = nregs - 1; i >= 0; i--)
17756 emit_insn (gen_rtx_SET (VOIDmode,
17757 simplify_gen_subreg (reg_mode, dst, mode,
17758 i * reg_mode_size),
17759 simplify_gen_subreg (reg_mode, src, mode,
17760 i * reg_mode_size)));
17766 bool used_update = false;
17767 rtx restore_basereg = NULL_RTX;
17769 if (MEM_P (src) && INT_REGNO_P (reg))
17773 if (GET_CODE (XEXP (src, 0)) == PRE_INC
17774 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
17777 breg = XEXP (XEXP (src, 0), 0);
17778 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
17779 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
17780 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
17781 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17782 src = replace_equiv_address (src, breg);
17784 else if (! rs6000_offsettable_memref_p (src))
17786 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
17788 rtx basereg = XEXP (XEXP (src, 0), 0);
17791 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
17792 emit_insn (gen_rtx_SET (VOIDmode, ndst,
17793 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
17794 used_update = true;
17797 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17798 XEXP (XEXP (src, 0), 1)));
17799 src = replace_equiv_address (src, basereg);
17803 rtx basereg = gen_rtx_REG (Pmode, reg);
17804 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
17805 src = replace_equiv_address (src, basereg);
17809 breg = XEXP (src, 0);
17810 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
17811 breg = XEXP (breg, 0);
17813 /* If the base register we are using to address memory is
17814 also a destination reg, then change that register last. */
17816 && REGNO (breg) >= REGNO (dst)
17817 && REGNO (breg) < REGNO (dst) + nregs)
17818 j = REGNO (breg) - REGNO (dst);
17820 else if (MEM_P (dst) && INT_REGNO_P (reg))
17824 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
17825 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
17828 breg = XEXP (XEXP (dst, 0), 0);
17829 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
17830 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
17831 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
17833 /* We have to update the breg before doing the store.
17834 Use store with update, if available. */
17838 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17839 emit_insn (TARGET_32BIT
17840 ? (TARGET_POWERPC64
17841 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
17842 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
17843 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
17844 used_update = true;
17847 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
17848 dst = replace_equiv_address (dst, breg);
17850 else if (!rs6000_offsettable_memref_p (dst)
17851 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
17853 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
17855 rtx basereg = XEXP (XEXP (dst, 0), 0);
17858 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
17859 emit_insn (gen_rtx_SET (VOIDmode,
17860 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
17861 used_update = true;
17864 emit_insn (gen_rtx_SET (VOIDmode, basereg,
17865 XEXP (XEXP (dst, 0), 1)));
17866 dst = replace_equiv_address (dst, basereg);
17870 rtx basereg = XEXP (XEXP (dst, 0), 0);
17871 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
17872 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
17874 && REG_P (offsetreg)
17875 && REGNO (basereg) != REGNO (offsetreg));
17876 if (REGNO (basereg) == 0)
17878 rtx tmp = offsetreg;
17879 offsetreg = basereg;
17882 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
17883 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
17884 dst = replace_equiv_address (dst, basereg);
17887 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
17888 gcc_assert (rs6000_offsettable_memref_p (dst));
17891 for (i = 0; i < nregs; i++)
17893 /* Calculate index to next subword. */
17898 /* If compiler already emitted move of first word by
17899 store with update, no need to do anything. */
17900 if (j == 0 && used_update)
17903 emit_insn (gen_rtx_SET (VOIDmode,
17904 simplify_gen_subreg (reg_mode, dst, mode,
17905 j * reg_mode_size),
17906 simplify_gen_subreg (reg_mode, src, mode,
17907 j * reg_mode_size)));
17909 if (restore_basereg != NULL_RTX)
17910 emit_insn (restore_basereg);
17915 /* This page contains routines that are used to determine what the
17916 function prologue and epilogue code will do and write them out. */
17918 /* Return the first fixed-point register that is required to be
17919 saved. 32 if none. */
17922 first_reg_to_save (void)
17926 /* Find lowest numbered live register. */
17927 for (first_reg = 13; first_reg <= 31; first_reg++)
17928 if (df_regs_ever_live_p (first_reg)
17929 && (! call_used_regs[first_reg]
17930 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
17931 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
17932 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
17933 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
17938 && crtl->uses_pic_offset_table
17939 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
17940 return RS6000_PIC_OFFSET_TABLE_REGNUM;
17946 /* Similar, for FP regs. */
17949 first_fp_reg_to_save (void)
17953 /* Find lowest numbered live register. */
17954 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
17955 if (df_regs_ever_live_p (first_reg))
17961 /* Similar, for AltiVec regs. */
17964 first_altivec_reg_to_save (void)
17968 /* Stack frame remains as is unless we are in AltiVec ABI. */
17969 if (! TARGET_ALTIVEC_ABI)
17970 return LAST_ALTIVEC_REGNO + 1;
17972 /* On Darwin, the unwind routines are compiled without
17973 TARGET_ALTIVEC, and use save_world to save/restore the
17974 altivec registers when necessary. */
17975 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
17976 && ! TARGET_ALTIVEC)
17977 return FIRST_ALTIVEC_REGNO + 20;
17979 /* Find lowest numbered live register. */
17980 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
17981 if (df_regs_ever_live_p (i))
17987 /* Return a 32-bit mask of the AltiVec registers we need to set in
17988 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
17989 the 32-bit word is 0. */
17991 static unsigned int
17992 compute_vrsave_mask (void)
17994 unsigned int i, mask = 0;
17996 /* On Darwin, the unwind routines are compiled without
17997 TARGET_ALTIVEC, and use save_world to save/restore the
17998 call-saved altivec registers when necessary. */
17999 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18000 && ! TARGET_ALTIVEC)
18003 /* First, find out if we use _any_ altivec registers. */
18004 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18005 if (df_regs_ever_live_p (i))
18006 mask |= ALTIVEC_REG_BIT (i);
18011 /* Next, remove the argument registers from the set. These must
18012 be in the VRSAVE mask set by the caller, so we don't need to add
18013 them in again. More importantly, the mask we compute here is
18014 used to generate CLOBBERs in the set_vrsave insn, and we do not
18015 wish the argument registers to die. */
18016 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18017 mask &= ~ALTIVEC_REG_BIT (i);
18019 /* Similarly, remove the return value from the set. */
18022 diddle_return_value (is_altivec_return_reg, &yes);
18024 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18030 /* For a very restricted set of circumstances, we can cut down the
18031 size of prologues/epilogues by calling our own save/restore-the-world
18035 compute_save_world_info (rs6000_stack_t *info_ptr)
18037 info_ptr->world_save_p = 1;
18038 info_ptr->world_save_p
18039 = (WORLD_SAVE_P (info_ptr)
18040 && DEFAULT_ABI == ABI_DARWIN
18041 && ! (cfun->calls_setjmp && flag_exceptions)
18042 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18043 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18044 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18045 && info_ptr->cr_save_p);
18047 /* This will not work in conjunction with sibcalls. Make sure there
18048 are none. (This check is expensive, but seldom executed.) */
18049 if (WORLD_SAVE_P (info_ptr))
18052 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18053 if ( GET_CODE (insn) == CALL_INSN
18054 && SIBLING_CALL_P (insn))
18056 info_ptr->world_save_p = 0;
18061 if (WORLD_SAVE_P (info_ptr))
18063 /* Even if we're not touching VRsave, make sure there's room on the
18064 stack for it, if it looks like we're calling SAVE_WORLD, which
18065 will attempt to save it. */
18066 info_ptr->vrsave_size = 4;
18068 /* If we are going to save the world, we need to save the link register too. */
18069 info_ptr->lr_save_p = 1;
18071 /* "Save" the VRsave register too if we're saving the world. */
18072 if (info_ptr->vrsave_mask == 0)
18073 info_ptr->vrsave_mask = compute_vrsave_mask ();
18075 /* Because the Darwin register save/restore routines only handle
18076 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18078 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18079 && (info_ptr->first_altivec_reg_save
18080 >= FIRST_SAVED_ALTIVEC_REGNO));
18087 is_altivec_return_reg (rtx reg, void *xyes)
18089 bool *yes = (bool *) xyes;
18090 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18095 /* Determine the strategy for savings/restoring registers. */
18098 SAVRES_MULTIPLE = 0x1,
18099 SAVE_INLINE_FPRS = 0x2,
18100 SAVE_INLINE_GPRS = 0x4,
18101 REST_INLINE_FPRS = 0x8,
18102 REST_INLINE_GPRS = 0x10,
18103 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18104 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18105 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18109 rs6000_savres_strategy (rs6000_stack_t *info,
18110 bool using_static_chain_p)
18114 if (TARGET_MULTIPLE
18115 && !TARGET_POWERPC64
18116 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18117 && info->first_gp_reg_save < 31
18118 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18119 strategy |= SAVRES_MULTIPLE;
18121 if (crtl->calls_eh_return
18122 || cfun->machine->ra_need_lr
18123 || info->total_size > 32767)
18124 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18125 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18127 if (info->first_fp_reg_save == 64
18128 || FP_SAVE_INLINE (info->first_fp_reg_save)
18129 /* The out-of-line FP routines use double-precision stores;
18130 we can't use those routines if we don't have such stores. */
18131 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18132 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18133 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18135 if (info->first_gp_reg_save == 32
18136 || GP_SAVE_INLINE (info->first_gp_reg_save)
18137 || !((strategy & SAVRES_MULTIPLE)
18138 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18139 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18141 /* Don't bother to try to save things out-of-line if r11 is occupied
18142 by the static chain. It would require too much fiddling and the
18143 static chain is rarely used anyway. */
18144 if (using_static_chain_p)
18145 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18147 /* If we are going to use store multiple, then don't even bother
18148 with the out-of-line routines, since the store-multiple
18149 instruction will always be smaller. */
18150 if ((strategy & SAVRES_MULTIPLE))
18151 strategy |= SAVE_INLINE_GPRS;
18153 /* The situation is more complicated with load multiple. We'd
18154 prefer to use the out-of-line routines for restores, since the
18155 "exit" out-of-line routines can handle the restore of LR and the
18156 frame teardown. However if doesn't make sense to use the
18157 out-of-line routine if that is the only reason we'd need to save
18158 LR, and we can't use the "exit" out-of-line gpr restore if we
18159 have saved some fprs; In those cases it is advantageous to use
18160 load multiple when available. */
18161 if ((strategy & SAVRES_MULTIPLE)
18162 && (!info->lr_save_p
18163 || info->first_fp_reg_save != 64))
18164 strategy |= REST_INLINE_GPRS;
18166 /* We can only use load multiple or the out-of-line routines to
18167 restore if we've used store multiple or out-of-line routines
18168 in the prologue, i.e. if we've saved all the registers from
18169 first_gp_reg_save. Otherwise, we risk loading garbage. */
18170 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18171 strategy |= REST_INLINE_GPRS;
18173 /* Saving CR interferes with the exit routines used on the SPE, so
18176 && info->spe_64bit_regs_used
18177 && info->cr_save_p)
18178 strategy |= REST_INLINE_GPRS;
18180 #ifdef POWERPC_LINUX
18183 if (!(strategy & SAVE_INLINE_FPRS))
18184 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18185 else if (!(strategy & SAVE_INLINE_GPRS)
18186 && info->first_fp_reg_save == 64)
18187 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18190 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18191 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18196 /* Calculate the stack information for the current function. This is
18197 complicated by having two separate calling sequences, the AIX calling
18198 sequence and the V.4 calling sequence.
18200 AIX (and Darwin/Mac OS X) stack frames look like:
18202 SP----> +---------------------------------------+
18203 | back chain to caller | 0 0
18204 +---------------------------------------+
18205 | saved CR | 4 8 (8-11)
18206 +---------------------------------------+
18208 +---------------------------------------+
18209 | reserved for compilers | 12 24
18210 +---------------------------------------+
18211 | reserved for binders | 16 32
18212 +---------------------------------------+
18213 | saved TOC pointer | 20 40
18214 +---------------------------------------+
18215 | Parameter save area (P) | 24 48
18216 +---------------------------------------+
18217 | Alloca space (A) | 24+P etc.
18218 +---------------------------------------+
18219 | Local variable space (L) | 24+P+A
18220 +---------------------------------------+
18221 | Float/int conversion temporary (X) | 24+P+A+L
18222 +---------------------------------------+
18223 | Save area for AltiVec registers (W) | 24+P+A+L+X
18224 +---------------------------------------+
18225 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18226 +---------------------------------------+
18227 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18228 +---------------------------------------+
18229 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18230 +---------------------------------------+
18231 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18232 +---------------------------------------+
18233 old SP->| back chain to caller's caller |
18234 +---------------------------------------+
18236 The required alignment for AIX configurations is two words (i.e., 8
18240 V.4 stack frames look like:
18242 SP----> +---------------------------------------+
18243 | back chain to caller | 0
18244 +---------------------------------------+
18245 | caller's saved LR | 4
18246 +---------------------------------------+
18247 | Parameter save area (P) | 8
18248 +---------------------------------------+
18249 | Alloca space (A) | 8+P
18250 +---------------------------------------+
18251 | Varargs save area (V) | 8+P+A
18252 +---------------------------------------+
18253 | Local variable space (L) | 8+P+A+V
18254 +---------------------------------------+
18255 | Float/int conversion temporary (X) | 8+P+A+V+L
18256 +---------------------------------------+
18257 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18258 +---------------------------------------+
18259 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18260 +---------------------------------------+
18261 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18262 +---------------------------------------+
18263 | SPE: area for 64-bit GP registers |
18264 +---------------------------------------+
18265 | SPE alignment padding |
18266 +---------------------------------------+
18267 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18268 +---------------------------------------+
18269 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18270 +---------------------------------------+
18271 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18272 +---------------------------------------+
18273 old SP->| back chain to caller's caller |
18274 +---------------------------------------+
18276 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18277 given. (But note below and in sysv4.h that we require only 8 and
18278 may round up the size of our stack frame anyways. The historical
18279 reason is early versions of powerpc-linux which didn't properly
18280 align the stack at program startup. A happy side-effect is that
18281 -mno-eabi libraries can be used with -meabi programs.)
18283 The EABI configuration defaults to the V.4 layout. However,
18284 the stack alignment requirements may differ. If -mno-eabi is not
18285 given, the required stack alignment is 8 bytes; if -mno-eabi is
18286 given, the required alignment is 16 bytes. (But see V.4 comment
18289 #ifndef ABI_STACK_BOUNDARY
18290 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18293 static rs6000_stack_t *
18294 rs6000_stack_info (void)
18296 #ifdef ENABLE_CHECKING
18297 static rs6000_stack_t info_save;
18299 rs6000_stack_t *info_ptr = &stack_info;
18300 int reg_size = TARGET_32BIT ? 4 : 8;
18304 HOST_WIDE_INT non_fixed_size;
18305 bool using_static_chain_p;
18307 #ifdef ENABLE_CHECKING
18308 memcpy (&info_save, &stack_info, sizeof stack_info);
18310 if (reload_completed && info_ptr->reload_completed)
18314 memset (&stack_info, 0, sizeof (stack_info));
18315 info_ptr->reload_completed = reload_completed;
18319 /* Cache value so we don't rescan instruction chain over and over. */
18320 if (cfun->machine->insn_chain_scanned_p == 0)
18321 cfun->machine->insn_chain_scanned_p
18322 = spe_func_has_64bit_regs_p () + 1;
18323 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18326 /* Select which calling sequence. */
18327 info_ptr->abi = DEFAULT_ABI;
18329 /* Calculate which registers need to be saved & save area size. */
18330 info_ptr->first_gp_reg_save = first_reg_to_save ();
18331 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18332 even if it currently looks like we won't. Reload may need it to
18333 get at a constant; if so, it will have already created a constant
18334 pool entry for it. */
18335 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18336 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18337 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18338 && crtl->uses_const_pool
18339 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18340 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18342 first_gp = info_ptr->first_gp_reg_save;
18344 info_ptr->gp_size = reg_size * (32 - first_gp);
18346 /* For the SPE, we have an additional upper 32-bits on each GPR.
18347 Ideally we should save the entire 64-bits only when the upper
18348 half is used in SIMD instructions. Since we only record
18349 registers live (not the size they are used in), this proves
18350 difficult because we'd have to traverse the instruction chain at
18351 the right time, taking reload into account. This is a real pain,
18352 so we opt to save the GPRs in 64-bits always if but one register
18353 gets used in 64-bits. Otherwise, all the registers in the frame
18354 get saved in 32-bits.
18356 So... since when we save all GPRs (except the SP) in 64-bits, the
18357 traditional GP save area will be empty. */
18358 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18359 info_ptr->gp_size = 0;
18361 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18362 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18364 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18365 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18366 - info_ptr->first_altivec_reg_save);
18368 /* Does this function call anything? */
18369 info_ptr->calls_p = (! current_function_is_leaf
18370 || cfun->machine->ra_needs_full_frame);
18372 /* Determine if we need to save the condition code registers. */
18373 if (df_regs_ever_live_p (CR2_REGNO)
18374 || df_regs_ever_live_p (CR3_REGNO)
18375 || df_regs_ever_live_p (CR4_REGNO))
18377 info_ptr->cr_save_p = 1;
18378 if (DEFAULT_ABI == ABI_V4)
18379 info_ptr->cr_size = reg_size;
18382 /* If the current function calls __builtin_eh_return, then we need
18383 to allocate stack space for registers that will hold data for
18384 the exception handler. */
18385 if (crtl->calls_eh_return)
18388 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18391 /* SPE saves EH registers in 64-bits. */
18392 ehrd_size = i * (TARGET_SPE_ABI
18393 && info_ptr->spe_64bit_regs_used != 0
18394 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18399 /* Determine various sizes. */
18400 info_ptr->reg_size = reg_size;
18401 info_ptr->fixed_size = RS6000_SAVE_AREA;
18402 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18403 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18404 TARGET_ALTIVEC ? 16 : 8);
18405 if (FRAME_GROWS_DOWNWARD)
18406 info_ptr->vars_size
18407 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18408 + info_ptr->parm_size,
18409 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18410 - (info_ptr->fixed_size + info_ptr->vars_size
18411 + info_ptr->parm_size);
18413 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18414 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18416 info_ptr->spe_gp_size = 0;
18418 if (TARGET_ALTIVEC_ABI)
18419 info_ptr->vrsave_mask = compute_vrsave_mask ();
18421 info_ptr->vrsave_mask = 0;
18423 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18424 info_ptr->vrsave_size = 4;
18426 info_ptr->vrsave_size = 0;
18428 compute_save_world_info (info_ptr);
18430 /* Calculate the offsets. */
18431 switch (DEFAULT_ABI)
18435 gcc_unreachable ();
18439 info_ptr->fp_save_offset = - info_ptr->fp_size;
18440 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18442 if (TARGET_ALTIVEC_ABI)
18444 info_ptr->vrsave_save_offset
18445 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18447 /* Align stack so vector save area is on a quadword boundary.
18448 The padding goes above the vectors. */
18449 if (info_ptr->altivec_size != 0)
18450 info_ptr->altivec_padding_size
18451 = info_ptr->vrsave_save_offset & 0xF;
18453 info_ptr->altivec_padding_size = 0;
18455 info_ptr->altivec_save_offset
18456 = info_ptr->vrsave_save_offset
18457 - info_ptr->altivec_padding_size
18458 - info_ptr->altivec_size;
18459 gcc_assert (info_ptr->altivec_size == 0
18460 || info_ptr->altivec_save_offset % 16 == 0);
18462 /* Adjust for AltiVec case. */
18463 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18466 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18467 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18468 info_ptr->lr_save_offset = 2*reg_size;
18472 info_ptr->fp_save_offset = - info_ptr->fp_size;
18473 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18474 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18476 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18478 /* Align stack so SPE GPR save area is aligned on a
18479 double-word boundary. */
18480 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18481 info_ptr->spe_padding_size
18482 = 8 - (-info_ptr->cr_save_offset % 8);
18484 info_ptr->spe_padding_size = 0;
18486 info_ptr->spe_gp_save_offset
18487 = info_ptr->cr_save_offset
18488 - info_ptr->spe_padding_size
18489 - info_ptr->spe_gp_size;
18491 /* Adjust for SPE case. */
18492 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18494 else if (TARGET_ALTIVEC_ABI)
18496 info_ptr->vrsave_save_offset
18497 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18499 /* Align stack so vector save area is on a quadword boundary. */
18500 if (info_ptr->altivec_size != 0)
18501 info_ptr->altivec_padding_size
18502 = 16 - (-info_ptr->vrsave_save_offset % 16);
18504 info_ptr->altivec_padding_size = 0;
18506 info_ptr->altivec_save_offset
18507 = info_ptr->vrsave_save_offset
18508 - info_ptr->altivec_padding_size
18509 - info_ptr->altivec_size;
18511 /* Adjust for AltiVec case. */
18512 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18515 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18516 info_ptr->ehrd_offset -= ehrd_size;
18517 info_ptr->lr_save_offset = reg_size;
18521 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18522 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18523 + info_ptr->gp_size
18524 + info_ptr->altivec_size
18525 + info_ptr->altivec_padding_size
18526 + info_ptr->spe_gp_size
18527 + info_ptr->spe_padding_size
18529 + info_ptr->cr_size
18530 + info_ptr->vrsave_size,
18533 non_fixed_size = (info_ptr->vars_size
18534 + info_ptr->parm_size
18535 + info_ptr->save_size);
18537 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
18538 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
18540 /* Determine if we need to save the link register. */
18541 if (info_ptr->calls_p
18542 || (DEFAULT_ABI == ABI_AIX
18544 && !TARGET_PROFILE_KERNEL)
18545 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
18546 #ifdef TARGET_RELOCATABLE
18547 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
18549 || rs6000_ra_ever_killed ())
18550 info_ptr->lr_save_p = 1;
18552 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
18553 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
18554 && call_used_regs[STATIC_CHAIN_REGNUM]);
18555 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
18556 using_static_chain_p);
18558 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
18559 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
18560 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
18561 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
18562 info_ptr->lr_save_p = 1;
18564 if (info_ptr->lr_save_p)
18565 df_set_regs_ever_live (LR_REGNO, true);
18567 /* Determine if we need to allocate any stack frame:
18569 For AIX we need to push the stack if a frame pointer is needed
18570 (because the stack might be dynamically adjusted), if we are
18571 debugging, if we make calls, or if the sum of fp_save, gp_save,
18572 and local variables are more than the space needed to save all
18573 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
18574 + 18*8 = 288 (GPR13 reserved).
18576 For V.4 we don't have the stack cushion that AIX uses, but assume
18577 that the debugger can handle stackless frames. */
18579 if (info_ptr->calls_p)
18580 info_ptr->push_p = 1;
18582 else if (DEFAULT_ABI == ABI_V4)
18583 info_ptr->push_p = non_fixed_size != 0;
18585 else if (frame_pointer_needed)
18586 info_ptr->push_p = 1;
18588 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
18589 info_ptr->push_p = 1;
18592 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
18594 /* Zero offsets if we're not saving those registers. */
18595 if (info_ptr->fp_size == 0)
18596 info_ptr->fp_save_offset = 0;
18598 if (info_ptr->gp_size == 0)
18599 info_ptr->gp_save_offset = 0;
18601 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
18602 info_ptr->altivec_save_offset = 0;
18604 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
18605 info_ptr->vrsave_save_offset = 0;
18607 if (! TARGET_SPE_ABI
18608 || info_ptr->spe_64bit_regs_used == 0
18609 || info_ptr->spe_gp_size == 0)
18610 info_ptr->spe_gp_save_offset = 0;
18612 if (! info_ptr->lr_save_p)
18613 info_ptr->lr_save_offset = 0;
18615 if (! info_ptr->cr_save_p)
18616 info_ptr->cr_save_offset = 0;
18618 #ifdef ENABLE_CHECKING
18619 gcc_assert (!(reload_completed && info_save.reload_completed)
18620 || memcmp (&info_save, &stack_info, sizeof stack_info) == 0);
18625 /* Return true if the current function uses any GPRs in 64-bit SIMD
18629 spe_func_has_64bit_regs_p (void)
18633 /* Functions that save and restore all the call-saved registers will
18634 need to save/restore the registers in 64-bits. */
18635 if (crtl->calls_eh_return
18636 || cfun->calls_setjmp
18637 || crtl->has_nonlocal_goto)
18640 insns = get_insns ();
18642 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
18648 /* FIXME: This should be implemented with attributes...
18650 (set_attr "spe64" "true")....then,
18651 if (get_spe64(insn)) return true;
18653 It's the only reliable way to do the stuff below. */
18655 i = PATTERN (insn);
18656 if (GET_CODE (i) == SET)
18658 enum machine_mode mode = GET_MODE (SET_SRC (i));
18660 if (SPE_VECTOR_MODE (mode))
18662 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
18672 debug_stack_info (rs6000_stack_t *info)
18674 const char *abi_string;
18677 info = rs6000_stack_info ();
18679 fprintf (stderr, "\nStack information for function %s:\n",
18680 ((current_function_decl && DECL_NAME (current_function_decl))
18681 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
18686 default: abi_string = "Unknown"; break;
18687 case ABI_NONE: abi_string = "NONE"; break;
18688 case ABI_AIX: abi_string = "AIX"; break;
18689 case ABI_DARWIN: abi_string = "Darwin"; break;
18690 case ABI_V4: abi_string = "V.4"; break;
18693 fprintf (stderr, "\tABI = %5s\n", abi_string);
18695 if (TARGET_ALTIVEC_ABI)
18696 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
18698 if (TARGET_SPE_ABI)
18699 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
18701 if (info->first_gp_reg_save != 32)
18702 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
18704 if (info->first_fp_reg_save != 64)
18705 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
18707 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
18708 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
18709 info->first_altivec_reg_save);
18711 if (info->lr_save_p)
18712 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
18714 if (info->cr_save_p)
18715 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
18717 if (info->vrsave_mask)
18718 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
18721 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
18724 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
18726 if (info->gp_save_offset)
18727 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
18729 if (info->fp_save_offset)
18730 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
18732 if (info->altivec_save_offset)
18733 fprintf (stderr, "\taltivec_save_offset = %5d\n",
18734 info->altivec_save_offset);
18736 if (info->spe_gp_save_offset)
18737 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
18738 info->spe_gp_save_offset);
18740 if (info->vrsave_save_offset)
18741 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
18742 info->vrsave_save_offset);
18744 if (info->lr_save_offset)
18745 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
18747 if (info->cr_save_offset)
18748 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
18750 if (info->varargs_save_offset)
18751 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
18753 if (info->total_size)
18754 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18757 if (info->vars_size)
18758 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
18761 if (info->parm_size)
18762 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
18764 if (info->fixed_size)
18765 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
18768 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
18770 if (info->spe_gp_size)
18771 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
18774 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
18776 if (info->altivec_size)
18777 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
18779 if (info->vrsave_size)
18780 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
18782 if (info->altivec_padding_size)
18783 fprintf (stderr, "\taltivec_padding_size= %5d\n",
18784 info->altivec_padding_size);
18786 if (info->spe_padding_size)
18787 fprintf (stderr, "\tspe_padding_size = %5d\n",
18788 info->spe_padding_size);
18791 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
18793 if (info->save_size)
18794 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
18796 if (info->reg_size != 4)
18797 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
18799 fprintf (stderr, "\n");
18803 rs6000_return_addr (int count, rtx frame)
18805 /* Currently we don't optimize very well between prolog and body
18806 code and for PIC code the code can be actually quite bad, so
18807 don't try to be too clever here. */
18808 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
18810 cfun->machine->ra_needs_full_frame = 1;
18817 plus_constant (copy_to_reg
18818 (gen_rtx_MEM (Pmode,
18819 memory_address (Pmode, frame))),
18820 RETURN_ADDRESS_OFFSET)));
18823 cfun->machine->ra_need_lr = 1;
18824 return get_hard_reg_initial_val (Pmode, LR_REGNO);
18827 /* Say whether a function is a candidate for sibcall handling or not.
18828 We do not allow indirect calls to be optimized into sibling calls.
18829 Also, we can't do it if there are any vector parameters; there's
18830 nowhere to put the VRsave code so it works; note that functions with
18831 vector parameters are required to have a prototype, so the argument
18832 type info must be available here. (The tail recursion case can work
18833 with vector parameters, but there's no way to distinguish here.) */
18835 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
18840 if (TARGET_ALTIVEC_VRSAVE)
18842 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
18843 type; type = TREE_CHAIN (type))
18845 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
18849 if (DEFAULT_ABI == ABI_DARWIN
18850 || ((*targetm.binds_local_p) (decl)
18851 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
18853 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
18855 if (!lookup_attribute ("longcall", attr_list)
18856 || lookup_attribute ("shortcall", attr_list))
18863 /* NULL if INSN insn is valid within a low-overhead loop.
18864 Otherwise return why doloop cannot be applied.
18865 PowerPC uses the COUNT register for branch on table instructions. */
18867 static const char *
18868 rs6000_invalid_within_doloop (const_rtx insn)
18871 return "Function call in the loop.";
18874 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
18875 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
18876 return "Computed branch in the loop.";
18882 rs6000_ra_ever_killed (void)
18888 if (cfun->is_thunk)
18891 if (cfun->machine->lr_save_state)
18892 return cfun->machine->lr_save_state - 1;
18894 /* regs_ever_live has LR marked as used if any sibcalls are present,
18895 but this should not force saving and restoring in the
18896 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
18897 clobbers LR, so that is inappropriate. */
18899 /* Also, the prologue can generate a store into LR that
18900 doesn't really count, like this:
18903 bcl to set PIC register
18907 When we're called from the epilogue, we need to avoid counting
18908 this as a store. */
18910 push_topmost_sequence ();
18911 top = get_insns ();
18912 pop_topmost_sequence ();
18913 reg = gen_rtx_REG (Pmode, LR_REGNO);
18915 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
18921 if (!SIBLING_CALL_P (insn))
18924 else if (find_regno_note (insn, REG_INC, LR_REGNO))
18926 else if (set_of (reg, insn) != NULL_RTX
18927 && !prologue_epilogue_contains (insn))
18934 /* Emit instructions needed to load the TOC register.
18935 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
18936 a constant pool; or for SVR4 -fpic. */
18939 rs6000_emit_load_toc_table (int fromprolog)
18942 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
18944 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
18947 rtx lab, tmp1, tmp2, got;
18949 lab = gen_label_rtx ();
18950 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
18951 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18953 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18955 got = rs6000_got_sym ();
18956 tmp1 = tmp2 = dest;
18959 tmp1 = gen_reg_rtx (Pmode);
18960 tmp2 = gen_reg_rtx (Pmode);
18962 emit_insn (gen_load_toc_v4_PIC_1 (lab));
18963 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
18964 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
18965 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
18967 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
18969 emit_insn (gen_load_toc_v4_pic_si ());
18970 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18972 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
18975 rtx temp0 = (fromprolog
18976 ? gen_rtx_REG (Pmode, 0)
18977 : gen_reg_rtx (Pmode));
18983 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18984 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18986 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
18987 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
18989 emit_insn (gen_load_toc_v4_PIC_1 (symF));
18990 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
18991 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
18997 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
18998 lab = gen_label_rtx ();
18999 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19000 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19001 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19003 emit_insn (gen_addsi3 (dest, temp0, dest));
19005 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19007 /* This is for AIX code running in non-PIC ELF32. */
19010 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19011 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19013 emit_insn (gen_elf_high (dest, realsym));
19014 emit_insn (gen_elf_low (dest, dest, realsym));
19018 gcc_assert (DEFAULT_ABI == ABI_AIX);
19021 emit_insn (gen_load_toc_aix_si (dest));
19023 emit_insn (gen_load_toc_aix_di (dest));
19027 /* Emit instructions to restore the link register after determining where
19028 its value has been stored. */
19031 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19033 rs6000_stack_t *info = rs6000_stack_info ();
19036 operands[0] = source;
19037 operands[1] = scratch;
19039 if (info->lr_save_p)
19041 rtx frame_rtx = stack_pointer_rtx;
19042 HOST_WIDE_INT sp_offset = 0;
19045 if (frame_pointer_needed
19046 || cfun->calls_alloca
19047 || info->total_size > 32767)
19049 tmp = gen_frame_mem (Pmode, frame_rtx);
19050 emit_move_insn (operands[1], tmp);
19051 frame_rtx = operands[1];
19053 else if (info->push_p)
19054 sp_offset = info->total_size;
19056 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19057 tmp = gen_frame_mem (Pmode, tmp);
19058 emit_move_insn (tmp, operands[0]);
19061 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19063 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19064 state of lr_save_p so any change from here on would be a bug. In
19065 particular, stop rs6000_ra_ever_killed from considering the SET
19066 of lr we may have added just above. */
19067 cfun->machine->lr_save_state = info->lr_save_p + 1;
19070 static GTY(()) alias_set_type set = -1;
19073 get_TOC_alias_set (void)
19076 set = new_alias_set ();
19080 /* This returns nonzero if the current function uses the TOC. This is
19081 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19082 is generated by the ABI_V4 load_toc_* patterns. */
19089 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19092 rtx pat = PATTERN (insn);
19095 if (GET_CODE (pat) == PARALLEL)
19096 for (i = 0; i < XVECLEN (pat, 0); i++)
19098 rtx sub = XVECEXP (pat, 0, i);
19099 if (GET_CODE (sub) == USE)
19101 sub = XEXP (sub, 0);
19102 if (GET_CODE (sub) == UNSPEC
19103 && XINT (sub, 1) == UNSPEC_TOC)
19113 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19115 rtx tocrel, tocreg;
19117 if (TARGET_DEBUG_ADDR)
19119 if (GET_CODE (symbol) == SYMBOL_REF)
19120 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19124 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19125 GET_RTX_NAME (GET_CODE (symbol)));
19126 debug_rtx (symbol);
19130 if (!can_create_pseudo_p ())
19131 df_set_regs_ever_live (TOC_REGISTER, true);
19133 tocrel = gen_rtx_CONST (Pmode,
19134 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19136 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19137 if (TARGET_CMODEL != CMODEL_SMALL)
19139 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19140 if (largetoc_reg != NULL)
19142 emit_move_insn (largetoc_reg, hi);
19145 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19148 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19151 /* Issue assembly directives that create a reference to the given DWARF
19152 FRAME_TABLE_LABEL from the current function section. */
19154 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19156 fprintf (asm_out_file, "\t.ref %s\n",
19157 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19160 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19161 and the change to the stack pointer. */
19164 rs6000_emit_stack_tie (void)
19166 rtx mem = gen_frame_mem (BLKmode,
19167 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19169 emit_insn (gen_stack_tie (mem));
19172 /* Emit the correct code for allocating stack space, as insns.
19173 If COPY_REG, make sure a copy of the old frame is left there.
19174 The generated code may use hard register 0 as a temporary. */
19177 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19180 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19181 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19182 rtx todec = gen_int_mode (-size, Pmode);
19185 if (INTVAL (todec) != -size)
19187 warning (0, "stack frame too large");
19188 emit_insn (gen_trap ());
19192 if (crtl->limit_stack)
19194 if (REG_P (stack_limit_rtx)
19195 && REGNO (stack_limit_rtx) > 1
19196 && REGNO (stack_limit_rtx) <= 31)
19198 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19199 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19202 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19204 && DEFAULT_ABI == ABI_V4)
19206 rtx toload = gen_rtx_CONST (VOIDmode,
19207 gen_rtx_PLUS (Pmode,
19211 emit_insn (gen_elf_high (tmp_reg, toload));
19212 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19213 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19217 warning (0, "stack limit expression is not supported");
19221 emit_move_insn (copy_reg, stack_reg);
19225 /* Need a note here so that try_split doesn't get confused. */
19226 if (get_last_insn () == NULL_RTX)
19227 emit_note (NOTE_INSN_DELETED);
19228 insn = emit_move_insn (tmp_reg, todec);
19229 try_split (PATTERN (insn), insn, 0);
19233 insn = emit_insn (TARGET_32BIT
19234 ? gen_movsi_update_stack (stack_reg, stack_reg,
19236 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19237 todec, stack_reg));
19238 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19239 it now and set the alias set/attributes. The above gen_*_update
19240 calls will generate a PARALLEL with the MEM set being the first
19242 par = PATTERN (insn);
19243 gcc_assert (GET_CODE (par) == PARALLEL);
19244 set = XVECEXP (par, 0, 0);
19245 gcc_assert (GET_CODE (set) == SET);
19246 mem = SET_DEST (set);
19247 gcc_assert (MEM_P (mem));
19248 MEM_NOTRAP_P (mem) = 1;
19249 set_mem_alias_set (mem, get_frame_alias_set ());
19251 RTX_FRAME_RELATED_P (insn) = 1;
19252 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19253 gen_rtx_SET (VOIDmode, stack_reg,
19254 gen_rtx_PLUS (Pmode, stack_reg,
19255 GEN_INT (-size))));
19258 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19260 #if PROBE_INTERVAL > 32768
19261 #error Cannot use indexed addressing mode for stack probing
19264 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19265 inclusive. These are offsets from the current stack pointer. */
19268 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19270 /* See if we have a constant small number of probes to generate. If so,
19271 that's the easy case. */
19272 if (first + size <= 32768)
19276 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19277 it exceeds SIZE. If only one probe is needed, this will not
19278 generate any code. Then probe at FIRST + SIZE. */
19279 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19280 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19282 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19285 /* Otherwise, do the same as above, but in a loop. Note that we must be
19286 extra careful with variables wrapping around because we might be at
19287 the very top (or the very bottom) of the address space and we have
19288 to be able to handle this case properly; in particular, we use an
19289 equality test for the loop condition. */
19292 HOST_WIDE_INT rounded_size;
19293 rtx r12 = gen_rtx_REG (Pmode, 12);
19294 rtx r0 = gen_rtx_REG (Pmode, 0);
19296 /* Sanity check for the addressing mode we're going to use. */
19297 gcc_assert (first <= 32768);
19299 /* Step 1: round SIZE to the previous multiple of the interval. */
19301 rounded_size = size & -PROBE_INTERVAL;
19304 /* Step 2: compute initial and final value of the loop counter. */
19306 /* TEST_ADDR = SP + FIRST. */
19307 emit_insn (gen_rtx_SET (VOIDmode, r12,
19308 plus_constant (stack_pointer_rtx, -first)));
19310 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19311 if (rounded_size > 32768)
19313 emit_move_insn (r0, GEN_INT (-rounded_size));
19314 emit_insn (gen_rtx_SET (VOIDmode, r0,
19315 gen_rtx_PLUS (Pmode, r12, r0)));
19318 emit_insn (gen_rtx_SET (VOIDmode, r0,
19319 plus_constant (r12, -rounded_size)));
19322 /* Step 3: the loop
19324 while (TEST_ADDR != LAST_ADDR)
19326 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19330 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19331 until it is equal to ROUNDED_SIZE. */
19334 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19336 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19339 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19340 that SIZE is equal to ROUNDED_SIZE. */
19342 if (size != rounded_size)
19343 emit_stack_probe (plus_constant (r12, rounded_size - size));
19347 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19348 absolute addresses. */
19351 output_probe_stack_range (rtx reg1, rtx reg2)
19353 static int labelno = 0;
19354 char loop_lab[32], end_lab[32];
19357 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19358 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19360 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19362 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19366 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19368 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19370 fputs ("\tbeq 0,", asm_out_file);
19371 assemble_name_raw (asm_out_file, end_lab);
19372 fputc ('\n', asm_out_file);
19374 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19375 xops[1] = GEN_INT (-PROBE_INTERVAL);
19376 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19378 /* Probe at TEST_ADDR and branch. */
19379 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19380 fprintf (asm_out_file, "\tb ");
19381 assemble_name_raw (asm_out_file, loop_lab);
19382 fputc ('\n', asm_out_file);
19384 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19389 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19390 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19391 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19392 deduce these equivalences by itself so it wasn't necessary to hold
19393 its hand so much. */
19396 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19397 rtx reg2, rtx rreg)
19401 /* copy_rtx will not make unique copies of registers, so we need to
19402 ensure we don't have unwanted sharing here. */
19404 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19407 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19409 real = copy_rtx (PATTERN (insn));
19411 if (reg2 != NULL_RTX)
19412 real = replace_rtx (real, reg2, rreg);
19414 real = replace_rtx (real, reg,
19415 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19416 STACK_POINTER_REGNUM),
19419 /* We expect that 'real' is either a SET or a PARALLEL containing
19420 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19421 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19423 if (GET_CODE (real) == SET)
19427 temp = simplify_rtx (SET_SRC (set));
19429 SET_SRC (set) = temp;
19430 temp = simplify_rtx (SET_DEST (set));
19432 SET_DEST (set) = temp;
19433 if (GET_CODE (SET_DEST (set)) == MEM)
19435 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19437 XEXP (SET_DEST (set), 0) = temp;
19444 gcc_assert (GET_CODE (real) == PARALLEL);
19445 for (i = 0; i < XVECLEN (real, 0); i++)
19446 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19448 rtx set = XVECEXP (real, 0, i);
19450 temp = simplify_rtx (SET_SRC (set));
19452 SET_SRC (set) = temp;
19453 temp = simplify_rtx (SET_DEST (set));
19455 SET_DEST (set) = temp;
19456 if (GET_CODE (SET_DEST (set)) == MEM)
19458 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19460 XEXP (SET_DEST (set), 0) = temp;
19462 RTX_FRAME_RELATED_P (set) = 1;
19466 RTX_FRAME_RELATED_P (insn) = 1;
19467 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19470 /* Returns an insn that has a vrsave set operation with the
19471 appropriate CLOBBERs. */
19474 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19477 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19478 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19481 = gen_rtx_SET (VOIDmode,
19483 gen_rtx_UNSPEC_VOLATILE (SImode,
19484 gen_rtvec (2, reg, vrsave),
19485 UNSPECV_SET_VRSAVE));
19489 /* We need to clobber the registers in the mask so the scheduler
19490 does not move sets to VRSAVE before sets of AltiVec registers.
19492 However, if the function receives nonlocal gotos, reload will set
19493 all call saved registers live. We will end up with:
19495 (set (reg 999) (mem))
19496 (parallel [ (set (reg vrsave) (unspec blah))
19497 (clobber (reg 999))])
19499 The clobber will cause the store into reg 999 to be dead, and
19500 flow will attempt to delete an epilogue insn. In this case, we
19501 need an unspec use/set of the register. */
19503 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19504 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19506 if (!epiloguep || call_used_regs [i])
19507 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19508 gen_rtx_REG (V4SImode, i));
19511 rtx reg = gen_rtx_REG (V4SImode, i);
19514 = gen_rtx_SET (VOIDmode,
19516 gen_rtx_UNSPEC (V4SImode,
19517 gen_rtvec (1, reg), 27));
19521 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19523 for (i = 0; i < nclobs; ++i)
19524 XVECEXP (insn, 0, i) = clobs[i];
19529 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
19530 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
19533 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
19534 unsigned int regno, int offset, HOST_WIDE_INT total_size)
19536 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
19537 rtx replacea, replaceb;
19539 int_rtx = GEN_INT (offset);
19541 /* Some cases that need register indexed addressing. */
19542 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
19543 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
19544 || (TARGET_E500_DOUBLE && mode == DFmode)
19546 && SPE_VECTOR_MODE (mode)
19547 && !SPE_CONST_OFFSET_OK (offset)))
19549 /* Whomever calls us must make sure r11 is available in the
19550 flow path of instructions in the prologue. */
19551 offset_rtx = gen_rtx_REG (Pmode, 11);
19552 emit_move_insn (offset_rtx, int_rtx);
19554 replacea = offset_rtx;
19555 replaceb = int_rtx;
19559 offset_rtx = int_rtx;
19560 replacea = NULL_RTX;
19561 replaceb = NULL_RTX;
19564 reg = gen_rtx_REG (mode, regno);
19565 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
19566 mem = gen_frame_mem (mode, addr);
19568 insn = emit_move_insn (mem, reg);
19570 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
19573 /* Emit an offset memory reference suitable for a frame store, while
19574 converting to a valid addressing mode. */
19577 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
19579 rtx int_rtx, offset_rtx;
19581 int_rtx = GEN_INT (offset);
19583 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
19584 || (TARGET_E500_DOUBLE && mode == DFmode))
19586 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
19587 emit_move_insn (offset_rtx, int_rtx);
19590 offset_rtx = int_rtx;
19592 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
19595 /* Look for user-defined global regs. We should not save and restore these,
19596 and cannot use stmw/lmw if there are any in its range. */
19599 no_global_regs_above (int first, bool gpr)
19602 int last = gpr ? 32 : 64;
19603 for (i = first; i < last; i++)
19604 if (global_regs[i])
19609 #ifndef TARGET_FIX_AND_CONTINUE
19610 #define TARGET_FIX_AND_CONTINUE 0
19613 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
19614 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
19615 #define LAST_SAVRES_REGISTER 31
19616 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
19618 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
19620 /* Temporary holding space for an out-of-line register save/restore
19622 static char savres_routine_name[30];
19624 /* Return the name for an out-of-line register save/restore routine.
19625 We are saving/restoring GPRs if GPR is true. */
19628 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
19629 bool savep, bool gpr, bool lr)
19631 const char *prefix = "";
19632 const char *suffix = "";
19634 /* Different targets are supposed to define
19635 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
19636 routine name could be defined with:
19638 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
19640 This is a nice idea in practice, but in reality, things are
19641 complicated in several ways:
19643 - ELF targets have save/restore routines for GPRs.
19645 - SPE targets use different prefixes for 32/64-bit registers, and
19646 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
19648 - PPC64 ELF targets have routines for save/restore of GPRs that
19649 differ in what they do with the link register, so having a set
19650 prefix doesn't work. (We only use one of the save routines at
19651 the moment, though.)
19653 - PPC32 elf targets have "exit" versions of the restore routines
19654 that restore the link register and can save some extra space.
19655 These require an extra suffix. (There are also "tail" versions
19656 of the restore routines and "GOT" versions of the save routines,
19657 but we don't generate those at present. Same problems apply,
19660 We deal with all this by synthesizing our own prefix/suffix and
19661 using that for the simple sprintf call shown above. */
19664 /* No floating point saves on the SPE. */
19668 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
19670 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
19675 else if (DEFAULT_ABI == ABI_V4)
19681 prefix = savep ? "_savegpr_" : "_restgpr_";
19683 prefix = savep ? "_savefpr_" : "_restfpr_";
19688 else if (DEFAULT_ABI == ABI_AIX)
19690 #ifndef POWERPC_LINUX
19691 /* No out-of-line save/restore routines for GPRs on AIX. */
19692 gcc_assert (!TARGET_AIX || !gpr);
19698 ? (lr ? "_savegpr0_" : "_savegpr1_")
19699 : (lr ? "_restgpr0_" : "_restgpr1_"));
19700 #ifdef POWERPC_LINUX
19702 prefix = (savep ? "_savefpr_" : "_restfpr_");
19706 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
19707 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
19710 else if (DEFAULT_ABI == ABI_DARWIN)
19711 sorry ("out-of-line save/restore routines not supported on Darwin");
19713 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
19715 return savres_routine_name;
19718 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
19719 We are saving/restoring GPRs if GPR is true. */
19722 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
19725 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
19727 int select = ((savep ? 1 : 0) << 2
19729 /* On the SPE, we never have any FPRs, but we do have
19730 32/64-bit versions of the routines. */
19731 ? (info->spe_64bit_regs_used ? 1 : 0)
19732 : (gpr ? 1 : 0)) << 1)
19735 /* Don't generate bogus routine names. */
19736 gcc_assert (FIRST_SAVRES_REGISTER <= regno
19737 && regno <= LAST_SAVRES_REGISTER);
19739 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
19745 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
19747 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
19748 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
19749 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
19755 /* Emit a sequence of insns, including a stack tie if needed, for
19756 resetting the stack pointer. If SAVRES is true, then don't reset the
19757 stack pointer, but move the base of the frame into r11 for use by
19758 out-of-line register restore routines. */
19761 rs6000_emit_stack_reset (rs6000_stack_t *info,
19762 rtx sp_reg_rtx, rtx frame_reg_rtx,
19763 int sp_offset, bool savres)
19765 /* This blockage is needed so that sched doesn't decide to move
19766 the sp change before the register restores. */
19767 if (frame_reg_rtx != sp_reg_rtx
19769 && info->spe_64bit_regs_used != 0
19770 && info->first_gp_reg_save != 32))
19771 rs6000_emit_stack_tie ();
19773 if (frame_reg_rtx != sp_reg_rtx)
19775 if (sp_offset != 0)
19777 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
19778 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
19779 GEN_INT (sp_offset)));
19782 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
19784 else if (sp_offset != 0)
19786 /* If we are restoring registers out-of-line, we will be using the
19787 "exit" variants of the restore routines, which will reset the
19788 stack for us. But we do need to point r11 into the right place
19789 for those routines. */
19790 rtx dest_reg = (savres
19791 ? gen_rtx_REG (Pmode, 11)
19794 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
19795 GEN_INT (sp_offset)));
19802 /* Construct a parallel rtx describing the effect of a call to an
19803 out-of-line register save/restore routine. */
19806 rs6000_make_savres_rtx (rs6000_stack_t *info,
19807 rtx frame_reg_rtx, int save_area_offset,
19808 enum machine_mode reg_mode,
19809 bool savep, bool gpr, bool lr)
19812 int offset, start_reg, end_reg, n_regs;
19813 int reg_size = GET_MODE_SIZE (reg_mode);
19819 ? info->first_gp_reg_save
19820 : info->first_fp_reg_save);
19821 end_reg = gpr ? 32 : 64;
19822 n_regs = end_reg - start_reg;
19823 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
19826 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
19828 RTVEC_ELT (p, offset++)
19829 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
19831 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
19832 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
19833 RTVEC_ELT (p, offset++)
19834 = gen_rtx_USE (VOIDmode,
19835 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
19839 for (i = 0; i < end_reg - start_reg; i++)
19841 rtx addr, reg, mem;
19842 reg = gen_rtx_REG (reg_mode, start_reg + i);
19843 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19844 GEN_INT (save_area_offset + reg_size*i));
19845 mem = gen_frame_mem (reg_mode, addr);
19847 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
19849 savep ? reg : mem);
19854 rtx addr, reg, mem;
19855 reg = gen_rtx_REG (Pmode, 0);
19856 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
19857 GEN_INT (info->lr_save_offset));
19858 mem = gen_frame_mem (Pmode, addr);
19859 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
19862 return gen_rtx_PARALLEL (VOIDmode, p);
19865 /* Determine whether the gp REG is really used. */
19868 rs6000_reg_live_or_pic_offset_p (int reg)
19870 /* If the function calls eh_return, claim used all the registers that would
19871 be checked for liveness otherwise. This is required for the PIC offset
19872 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
19873 register allocation purposes in this case. */
19875 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
19876 && (!call_used_regs[reg]
19877 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19878 && TARGET_TOC && TARGET_MINIMAL_TOC)))
19879 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
19880 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
19881 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
19884 /* Emit function prologue as insns. */
19887 rs6000_emit_prologue (void)
19889 rs6000_stack_t *info = rs6000_stack_info ();
19890 enum machine_mode reg_mode = Pmode;
19891 int reg_size = TARGET_32BIT ? 4 : 8;
19892 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19893 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
19894 rtx frame_reg_rtx = sp_reg_rtx;
19895 rtx cr_save_rtx = NULL_RTX;
19898 int saving_FPRs_inline;
19899 int saving_GPRs_inline;
19900 int using_store_multiple;
19901 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19902 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19903 && call_used_regs[STATIC_CHAIN_REGNUM]);
19904 HOST_WIDE_INT sp_offset = 0;
19906 if (flag_stack_usage)
19907 current_function_static_stack_size = info->total_size;
19909 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
19910 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
19912 if (TARGET_FIX_AND_CONTINUE)
19914 /* gdb on darwin arranges to forward a function from the old
19915 address by modifying the first 5 instructions of the function
19916 to branch to the overriding function. This is necessary to
19917 permit function pointers that point to the old function to
19918 actually forward to the new function. */
19919 emit_insn (gen_nop ());
19920 emit_insn (gen_nop ());
19921 emit_insn (gen_nop ());
19922 emit_insn (gen_nop ());
19923 emit_insn (gen_nop ());
19926 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
19928 reg_mode = V2SImode;
19932 strategy = info->savres_strategy;
19933 using_store_multiple = strategy & SAVRES_MULTIPLE;
19934 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
19935 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
19937 /* For V.4, update stack before we do any saving and set back pointer. */
19938 if (! WORLD_SAVE_P (info)
19940 && (DEFAULT_ABI == ABI_V4
19941 || crtl->calls_eh_return))
19943 bool need_r11 = (TARGET_SPE
19944 ? (!saving_GPRs_inline
19945 && info->spe_64bit_regs_used == 0)
19946 : (!saving_FPRs_inline || !saving_GPRs_inline));
19947 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
19949 if (info->total_size < 32767)
19950 sp_offset = info->total_size;
19952 frame_reg_rtx = copy_reg;
19953 else if (info->cr_save_p
19955 || info->first_fp_reg_save < 64
19956 || info->first_gp_reg_save < 32
19957 || info->altivec_size != 0
19958 || info->vrsave_mask != 0
19959 || crtl->calls_eh_return)
19961 copy_reg = frame_ptr_rtx;
19962 frame_reg_rtx = copy_reg;
19966 /* The prologue won't be saving any regs so there is no need
19967 to set up a frame register to access any frame save area.
19968 We also won't be using sp_offset anywhere below, but set
19969 the correct value anyway to protect against future
19970 changes to this function. */
19971 sp_offset = info->total_size;
19973 rs6000_emit_allocate_stack (info->total_size, copy_reg);
19974 if (frame_reg_rtx != sp_reg_rtx)
19975 rs6000_emit_stack_tie ();
19978 /* Handle world saves specially here. */
19979 if (WORLD_SAVE_P (info))
19986 /* save_world expects lr in r0. */
19987 reg0 = gen_rtx_REG (Pmode, 0);
19988 if (info->lr_save_p)
19990 insn = emit_move_insn (reg0,
19991 gen_rtx_REG (Pmode, LR_REGNO));
19992 RTX_FRAME_RELATED_P (insn) = 1;
19995 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
19996 assumptions about the offsets of various bits of the stack
19998 gcc_assert (info->gp_save_offset == -220
19999 && info->fp_save_offset == -144
20000 && info->lr_save_offset == 8
20001 && info->cr_save_offset == 4
20004 && (!crtl->calls_eh_return
20005 || info->ehrd_offset == -432)
20006 && info->vrsave_save_offset == -224
20007 && info->altivec_save_offset == -416);
20009 treg = gen_rtx_REG (SImode, 11);
20010 emit_move_insn (treg, GEN_INT (-info->total_size));
20012 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20013 in R11. It also clobbers R12, so beware! */
20015 /* Preserve CR2 for save_world prologues */
20017 sz += 32 - info->first_gp_reg_save;
20018 sz += 64 - info->first_fp_reg_save;
20019 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20020 p = rtvec_alloc (sz);
20022 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20023 gen_rtx_REG (SImode,
20025 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20026 gen_rtx_SYMBOL_REF (Pmode,
20028 /* We do floats first so that the instruction pattern matches
20030 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20032 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20033 ? DFmode : SFmode),
20034 info->first_fp_reg_save + i);
20035 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20036 GEN_INT (info->fp_save_offset
20037 + sp_offset + 8 * i));
20038 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20039 ? DFmode : SFmode), addr);
20041 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20043 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20045 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20046 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20047 GEN_INT (info->altivec_save_offset
20048 + sp_offset + 16 * i));
20049 rtx mem = gen_frame_mem (V4SImode, addr);
20051 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20053 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20055 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20056 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20057 GEN_INT (info->gp_save_offset
20058 + sp_offset + reg_size * i));
20059 rtx mem = gen_frame_mem (reg_mode, addr);
20061 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20065 /* CR register traditionally saved as CR2. */
20066 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20067 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20068 GEN_INT (info->cr_save_offset
20070 rtx mem = gen_frame_mem (reg_mode, addr);
20072 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20074 /* Explain about use of R0. */
20075 if (info->lr_save_p)
20077 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20078 GEN_INT (info->lr_save_offset
20080 rtx mem = gen_frame_mem (reg_mode, addr);
20082 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20084 /* Explain what happens to the stack pointer. */
20086 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20087 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20090 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20091 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20092 treg, GEN_INT (-info->total_size));
20093 sp_offset = info->total_size;
20096 /* If we use the link register, get it into r0. */
20097 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20099 rtx addr, reg, mem;
20101 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20102 gen_rtx_REG (Pmode, LR_REGNO));
20103 RTX_FRAME_RELATED_P (insn) = 1;
20105 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20106 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20108 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20109 GEN_INT (info->lr_save_offset + sp_offset));
20110 reg = gen_rtx_REG (Pmode, 0);
20111 mem = gen_rtx_MEM (Pmode, addr);
20112 /* This should not be of rs6000_sr_alias_set, because of
20113 __builtin_return_address. */
20115 insn = emit_move_insn (mem, reg);
20116 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20117 NULL_RTX, NULL_RTX);
20121 /* If we need to save CR, put it into r12 or r11. */
20122 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20127 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20129 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20130 RTX_FRAME_RELATED_P (insn) = 1;
20131 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20132 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20133 But that's OK. All we have to do is specify that _one_ condition
20134 code register is saved in this stack slot. The thrower's epilogue
20135 will then restore all the call-saved registers.
20136 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20137 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20138 gen_rtx_REG (SImode, CR2_REGNO));
20139 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20142 /* Do any required saving of fpr's. If only one or two to save, do
20143 it ourselves. Otherwise, call function. */
20144 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20147 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20148 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20149 && ! call_used_regs[info->first_fp_reg_save+i]))
20150 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20151 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20153 info->first_fp_reg_save + i,
20154 info->fp_save_offset + sp_offset + 8 * i,
20157 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20161 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20162 info->fp_save_offset + sp_offset,
20164 /*savep=*/true, /*gpr=*/false,
20166 & SAVE_NOINLINE_FPRS_SAVES_LR)
20168 insn = emit_insn (par);
20169 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20170 NULL_RTX, NULL_RTX);
20173 /* Save GPRs. This is done as a PARALLEL if we are using
20174 the store-multiple instructions. */
20175 if (!WORLD_SAVE_P (info)
20177 && info->spe_64bit_regs_used != 0
20178 && info->first_gp_reg_save != 32)
20181 rtx spe_save_area_ptr;
20183 /* Determine whether we can address all of the registers that need
20184 to be saved with an offset from the stack pointer that fits in
20185 the small const field for SPE memory instructions. */
20186 int spe_regs_addressable_via_sp
20187 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20188 + (32 - info->first_gp_reg_save - 1) * reg_size)
20189 && saving_GPRs_inline);
20192 if (spe_regs_addressable_via_sp)
20194 spe_save_area_ptr = frame_reg_rtx;
20195 spe_offset = info->spe_gp_save_offset + sp_offset;
20199 /* Make r11 point to the start of the SPE save area. We need
20200 to be careful here if r11 is holding the static chain. If
20201 it is, then temporarily save it in r0. We would use r0 as
20202 our base register here, but using r0 as a base register in
20203 loads and stores means something different from what we
20205 int ool_adjust = (saving_GPRs_inline
20207 : (info->first_gp_reg_save
20208 - (FIRST_SAVRES_REGISTER+1))*8);
20209 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20210 + sp_offset - ool_adjust);
20212 if (using_static_chain_p)
20214 rtx r0 = gen_rtx_REG (Pmode, 0);
20215 gcc_assert (info->first_gp_reg_save > 11);
20217 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20220 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20221 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20223 GEN_INT (offset)));
20224 /* We need to make sure the move to r11 gets noted for
20225 properly outputting unwind information. */
20226 if (!saving_GPRs_inline)
20227 rs6000_frame_related (insn, frame_reg_rtx, offset,
20228 NULL_RTX, NULL_RTX);
20232 if (saving_GPRs_inline)
20234 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20235 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20237 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20238 rtx offset, addr, mem;
20240 /* We're doing all this to ensure that the offset fits into
20241 the immediate offset of 'evstdd'. */
20242 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20244 offset = GEN_INT (reg_size * i + spe_offset);
20245 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20246 mem = gen_rtx_MEM (V2SImode, addr);
20248 insn = emit_move_insn (mem, reg);
20250 rs6000_frame_related (insn, spe_save_area_ptr,
20251 info->spe_gp_save_offset
20252 + sp_offset + reg_size * i,
20253 offset, const0_rtx);
20260 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20262 /*savep=*/true, /*gpr=*/true,
20264 insn = emit_insn (par);
20265 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20266 NULL_RTX, NULL_RTX);
20270 /* Move the static chain pointer back. */
20271 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20272 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20274 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20278 /* Need to adjust r11 (r12) if we saved any FPRs. */
20279 if (info->first_fp_reg_save != 64)
20281 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20283 rtx offset = GEN_INT (sp_offset
20284 + (-8 * (64-info->first_fp_reg_save)));
20285 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20288 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20289 info->gp_save_offset + sp_offset,
20291 /*savep=*/true, /*gpr=*/true,
20293 & SAVE_NOINLINE_GPRS_SAVES_LR)
20295 insn = emit_insn (par);
20296 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20297 NULL_RTX, NULL_RTX);
20299 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20303 p = rtvec_alloc (32 - info->first_gp_reg_save);
20304 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20306 rtx addr, reg, mem;
20307 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20308 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20309 GEN_INT (info->gp_save_offset
20312 mem = gen_frame_mem (reg_mode, addr);
20314 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20316 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20317 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20318 NULL_RTX, NULL_RTX);
20320 else if (!WORLD_SAVE_P (info))
20323 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20324 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20326 rtx addr, reg, mem;
20327 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20329 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20330 GEN_INT (info->gp_save_offset
20333 mem = gen_frame_mem (reg_mode, addr);
20335 insn = emit_move_insn (mem, reg);
20336 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20337 NULL_RTX, NULL_RTX);
20341 /* ??? There's no need to emit actual instructions here, but it's the
20342 easiest way to get the frame unwind information emitted. */
20343 if (crtl->calls_eh_return)
20345 unsigned int i, regno;
20349 regno = EH_RETURN_DATA_REGNO (i);
20350 if (regno == INVALID_REGNUM)
20353 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20354 info->ehrd_offset + sp_offset
20355 + reg_size * (int) i,
20360 /* In AIX ABI we need to make sure r2 is really saved. */
20361 if (TARGET_AIX && crtl->calls_eh_return)
20363 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20364 long toc_restore_insn;
20366 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20367 || frame_reg_rtx == sp_reg_rtx);
20368 tmp_reg = gen_rtx_REG (Pmode, 11);
20369 tmp_reg_si = gen_rtx_REG (SImode, 11);
20370 if (using_static_chain_p)
20371 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20372 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20373 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20374 /* Peek at instruction to which this function returns. If it's
20375 restoring r2, then we know we've already saved r2. We can't
20376 unconditionally save r2 because the value we have will already
20377 be updated if we arrived at this function via a plt call or
20378 toc adjusting stub. */
20379 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20380 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20381 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20382 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20383 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20384 validate_condition_mode (EQ, CCUNSmode);
20385 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20386 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20387 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20388 toc_save_done = gen_label_rtx ();
20389 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20390 gen_rtx_EQ (VOIDmode, compare_result,
20392 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20394 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20395 JUMP_LABEL (jump) = toc_save_done;
20396 LABEL_NUSES (toc_save_done) += 1;
20398 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20399 sp_offset + 5 * reg_size, info->total_size);
20400 emit_label (toc_save_done);
20401 if (using_static_chain_p)
20402 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20405 /* Save CR if we use any that must be preserved. */
20406 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20408 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20409 GEN_INT (info->cr_save_offset + sp_offset));
20410 rtx mem = gen_frame_mem (SImode, addr);
20411 /* See the large comment above about why CR2_REGNO is used. */
20412 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20414 /* If r12 was used to hold the original sp, copy cr into r0 now
20416 if (REGNO (frame_reg_rtx) == 12)
20420 cr_save_rtx = gen_rtx_REG (SImode, 0);
20421 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20422 RTX_FRAME_RELATED_P (insn) = 1;
20423 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20424 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20426 insn = emit_move_insn (mem, cr_save_rtx);
20428 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20429 NULL_RTX, NULL_RTX);
20432 /* Update stack and set back pointer unless this is V.4,
20433 for which it was done previously. */
20434 if (!WORLD_SAVE_P (info) && info->push_p
20435 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20437 rtx copy_reg = NULL;
20439 if (info->total_size < 32767)
20440 sp_offset = info->total_size;
20441 else if (info->altivec_size != 0
20442 || info->vrsave_mask != 0)
20444 copy_reg = frame_ptr_rtx;
20445 frame_reg_rtx = copy_reg;
20448 sp_offset = info->total_size;
20449 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20450 if (frame_reg_rtx != sp_reg_rtx)
20451 rs6000_emit_stack_tie ();
20454 /* Set frame pointer, if needed. */
20455 if (frame_pointer_needed)
20457 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20459 RTX_FRAME_RELATED_P (insn) = 1;
20462 /* Save AltiVec registers if needed. Save here because the red zone does
20463 not include AltiVec registers. */
20464 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20468 /* There should be a non inline version of this, for when we
20469 are saving lots of vector registers. */
20470 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20471 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20473 rtx areg, savereg, mem;
20476 offset = info->altivec_save_offset + sp_offset
20477 + 16 * (i - info->first_altivec_reg_save);
20479 savereg = gen_rtx_REG (V4SImode, i);
20481 areg = gen_rtx_REG (Pmode, 0);
20482 emit_move_insn (areg, GEN_INT (offset));
20484 /* AltiVec addressing mode is [reg+reg]. */
20485 mem = gen_frame_mem (V4SImode,
20486 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20488 insn = emit_move_insn (mem, savereg);
20490 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20491 areg, GEN_INT (offset));
20495 /* VRSAVE is a bit vector representing which AltiVec registers
20496 are used. The OS uses this to determine which vector
20497 registers to save on a context switch. We need to save
20498 VRSAVE on the stack frame, add whatever AltiVec registers we
20499 used in this function, and do the corresponding magic in the
20502 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20503 && info->vrsave_mask != 0)
20505 rtx reg, mem, vrsave;
20508 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20509 as frame_reg_rtx and r11 as the static chain pointer for
20510 nested functions. */
20511 reg = gen_rtx_REG (SImode, 0);
20512 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20514 emit_insn (gen_get_vrsave_internal (reg));
20516 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20518 if (!WORLD_SAVE_P (info))
20521 offset = info->vrsave_save_offset + sp_offset;
20522 mem = gen_frame_mem (SImode,
20523 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20524 GEN_INT (offset)));
20525 insn = emit_move_insn (mem, reg);
20528 /* Include the registers in the mask. */
20529 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
20531 insn = emit_insn (generate_set_vrsave (reg, info, 0));
20534 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
20535 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
20536 || (DEFAULT_ABI == ABI_V4
20537 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
20538 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
20540 /* If emit_load_toc_table will use the link register, we need to save
20541 it. We use R12 for this purpose because emit_load_toc_table
20542 can use register 0. This allows us to use a plain 'blr' to return
20543 from the procedure more often. */
20544 int save_LR_around_toc_setup = (TARGET_ELF
20545 && DEFAULT_ABI != ABI_AIX
20547 && ! info->lr_save_p
20548 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
20549 if (save_LR_around_toc_setup)
20551 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20553 insn = emit_move_insn (frame_ptr_rtx, lr);
20554 RTX_FRAME_RELATED_P (insn) = 1;
20556 rs6000_emit_load_toc_table (TRUE);
20558 insn = emit_move_insn (lr, frame_ptr_rtx);
20559 RTX_FRAME_RELATED_P (insn) = 1;
20562 rs6000_emit_load_toc_table (TRUE);
20566 if (DEFAULT_ABI == ABI_DARWIN
20567 && flag_pic && crtl->uses_pic_offset_table)
20569 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
20570 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
20572 /* Save and restore LR locally around this call (in R0). */
20573 if (!info->lr_save_p)
20574 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
20576 emit_insn (gen_load_macho_picbase (src));
20578 emit_move_insn (gen_rtx_REG (Pmode,
20579 RS6000_PIC_OFFSET_TABLE_REGNUM),
20582 if (!info->lr_save_p)
20583 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
20588 /* Write function prologue. */
20591 rs6000_output_function_prologue (FILE *file,
20592 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
20594 rs6000_stack_t *info = rs6000_stack_info ();
20596 if (TARGET_DEBUG_STACK)
20597 debug_stack_info (info);
20599 /* Write .extern for any function we will call to save and restore
20601 if (info->first_fp_reg_save < 64)
20604 int regno = info->first_fp_reg_save - 32;
20606 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
20608 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
20609 /*gpr=*/false, /*lr=*/false);
20610 fprintf (file, "\t.extern %s\n", name);
20612 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
20614 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
20615 /*gpr=*/false, /*lr=*/true);
20616 fprintf (file, "\t.extern %s\n", name);
20620 /* Write .extern for AIX common mode routines, if needed. */
20621 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
20623 fputs ("\t.extern __mulh\n", file);
20624 fputs ("\t.extern __mull\n", file);
20625 fputs ("\t.extern __divss\n", file);
20626 fputs ("\t.extern __divus\n", file);
20627 fputs ("\t.extern __quoss\n", file);
20628 fputs ("\t.extern __quous\n", file);
20629 common_mode_defined = 1;
20632 if (! HAVE_prologue)
20638 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
20639 the "toplevel" insn chain. */
20640 emit_note (NOTE_INSN_DELETED);
20641 rs6000_emit_prologue ();
20642 emit_note (NOTE_INSN_DELETED);
20644 /* Expand INSN_ADDRESSES so final() doesn't crash. */
20648 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
20650 INSN_ADDRESSES_NEW (insn, addr);
20655 prologue = get_insns ();
20658 if (TARGET_DEBUG_STACK)
20659 debug_rtx_list (prologue, 100);
20661 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
20665 rs6000_pic_labelno++;
20668 /* Non-zero if vmx regs are restored before the frame pop, zero if
20669 we restore after the pop when possible. */
20670 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
20672 /* Reload CR from REG. */
20675 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
20680 if (using_mfcr_multiple)
20682 for (i = 0; i < 8; i++)
20683 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20685 gcc_assert (count);
20688 if (using_mfcr_multiple && count > 1)
20693 p = rtvec_alloc (count);
20696 for (i = 0; i < 8; i++)
20697 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20699 rtvec r = rtvec_alloc (2);
20700 RTVEC_ELT (r, 0) = reg;
20701 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
20702 RTVEC_ELT (p, ndx) =
20703 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
20704 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
20707 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20708 gcc_assert (ndx == count);
20711 for (i = 0; i < 8; i++)
20712 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
20714 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
20720 /* Return true if OFFSET from stack pointer can be clobbered by signals.
20721 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
20722 below stack pointer not cloberred by signals. */
20725 offset_below_red_zone_p (HOST_WIDE_INT offset)
20727 return offset < (DEFAULT_ABI == ABI_V4
20729 : TARGET_32BIT ? -220 : -288);
20732 /* Emit function epilogue as insns. */
20735 rs6000_emit_epilogue (int sibcall)
20737 rs6000_stack_t *info;
20738 int restoring_GPRs_inline;
20739 int restoring_FPRs_inline;
20740 int using_load_multiple;
20741 int using_mtcr_multiple;
20742 int use_backchain_to_restore_sp;
20746 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
20747 rtx frame_reg_rtx = sp_reg_rtx;
20748 rtx cfa_restores = NULL_RTX;
20750 rtx cr_save_reg = NULL_RTX;
20751 enum machine_mode reg_mode = Pmode;
20752 int reg_size = TARGET_32BIT ? 4 : 8;
20755 info = rs6000_stack_info ();
20757 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20759 reg_mode = V2SImode;
20763 strategy = info->savres_strategy;
20764 using_load_multiple = strategy & SAVRES_MULTIPLE;
20765 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
20766 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
20767 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
20768 || rs6000_cpu == PROCESSOR_PPC603
20769 || rs6000_cpu == PROCESSOR_PPC750
20771 /* Restore via the backchain when we have a large frame, since this
20772 is more efficient than an addis, addi pair. The second condition
20773 here will not trigger at the moment; We don't actually need a
20774 frame pointer for alloca, but the generic parts of the compiler
20775 give us one anyway. */
20776 use_backchain_to_restore_sp = (info->total_size > 32767
20777 || info->total_size
20778 + (info->lr_save_p ? info->lr_save_offset : 0)
20780 || (cfun->calls_alloca
20781 && !frame_pointer_needed));
20782 restore_lr = (info->lr_save_p
20783 && (restoring_FPRs_inline
20784 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
20785 && (restoring_GPRs_inline
20786 || info->first_fp_reg_save < 64));
20788 if (WORLD_SAVE_P (info))
20792 const char *alloc_rname;
20795 /* eh_rest_world_r10 will return to the location saved in the LR
20796 stack slot (which is not likely to be our caller.)
20797 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
20798 rest_world is similar, except any R10 parameter is ignored.
20799 The exception-handling stuff that was here in 2.95 is no
20800 longer necessary. */
20804 + 32 - info->first_gp_reg_save
20805 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
20806 + 63 + 1 - info->first_fp_reg_save);
20808 strcpy (rname, ((crtl->calls_eh_return) ?
20809 "*eh_rest_world_r10" : "*rest_world"));
20810 alloc_rname = ggc_strdup (rname);
20813 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
20814 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20815 gen_rtx_REG (Pmode,
20818 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
20819 /* The instruction pattern requires a clobber here;
20820 it is shared with the restVEC helper. */
20822 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
20825 /* CR register traditionally saved as CR2. */
20826 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20827 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20828 GEN_INT (info->cr_save_offset));
20829 rtx mem = gen_frame_mem (reg_mode, addr);
20831 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20834 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20836 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20837 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20838 GEN_INT (info->gp_save_offset
20840 rtx mem = gen_frame_mem (reg_mode, addr);
20842 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20844 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20846 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20847 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20848 GEN_INT (info->altivec_save_offset
20850 rtx mem = gen_frame_mem (V4SImode, addr);
20852 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20854 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
20856 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20857 ? DFmode : SFmode),
20858 info->first_fp_reg_save + i);
20859 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20860 GEN_INT (info->fp_save_offset
20862 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20863 ? DFmode : SFmode), addr);
20865 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
20868 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
20870 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
20872 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
20874 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
20876 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
20877 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
20882 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
20884 sp_offset = info->total_size;
20886 /* Restore AltiVec registers if we must do so before adjusting the
20888 if (TARGET_ALTIVEC_ABI
20889 && info->altivec_size != 0
20890 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20891 || (DEFAULT_ABI != ABI_V4
20892 && offset_below_red_zone_p (info->altivec_save_offset))))
20896 if (use_backchain_to_restore_sp)
20898 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20899 emit_move_insn (frame_reg_rtx,
20900 gen_rtx_MEM (Pmode, sp_reg_rtx));
20903 else if (frame_pointer_needed)
20904 frame_reg_rtx = hard_frame_pointer_rtx;
20906 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20907 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20909 rtx addr, areg, mem, reg;
20911 areg = gen_rtx_REG (Pmode, 0);
20913 (areg, GEN_INT (info->altivec_save_offset
20915 + 16 * (i - info->first_altivec_reg_save)));
20917 /* AltiVec addressing mode is [reg+reg]. */
20918 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
20919 mem = gen_frame_mem (V4SImode, addr);
20921 reg = gen_rtx_REG (V4SImode, i);
20922 emit_move_insn (reg, mem);
20923 if (offset_below_red_zone_p (info->altivec_save_offset
20924 + (i - info->first_altivec_reg_save)
20926 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
20931 /* Restore VRSAVE if we must do so before adjusting the stack. */
20933 && TARGET_ALTIVEC_VRSAVE
20934 && info->vrsave_mask != 0
20935 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20936 || (DEFAULT_ABI != ABI_V4
20937 && offset_below_red_zone_p (info->vrsave_save_offset))))
20939 rtx addr, mem, reg;
20941 if (frame_reg_rtx == sp_reg_rtx)
20943 if (use_backchain_to_restore_sp)
20945 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20946 emit_move_insn (frame_reg_rtx,
20947 gen_rtx_MEM (Pmode, sp_reg_rtx));
20950 else if (frame_pointer_needed)
20951 frame_reg_rtx = hard_frame_pointer_rtx;
20954 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20955 GEN_INT (info->vrsave_save_offset + sp_offset));
20956 mem = gen_frame_mem (SImode, addr);
20957 reg = gen_rtx_REG (SImode, 12);
20958 emit_move_insn (reg, mem);
20960 emit_insn (generate_set_vrsave (reg, info, 1));
20964 /* If we have a large stack frame, restore the old stack pointer
20965 using the backchain. */
20966 if (use_backchain_to_restore_sp)
20968 if (frame_reg_rtx == sp_reg_rtx)
20970 /* Under V.4, don't reset the stack pointer until after we're done
20971 loading the saved registers. */
20972 if (DEFAULT_ABI == ABI_V4)
20973 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20975 insn = emit_move_insn (frame_reg_rtx,
20976 gen_rtx_MEM (Pmode, sp_reg_rtx));
20979 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
20980 && DEFAULT_ABI == ABI_V4)
20981 /* frame_reg_rtx has been set up by the altivec restore. */
20985 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20986 frame_reg_rtx = sp_reg_rtx;
20989 /* If we have a frame pointer, we can restore the old stack pointer
20991 else if (frame_pointer_needed)
20993 frame_reg_rtx = sp_reg_rtx;
20994 if (DEFAULT_ABI == ABI_V4)
20995 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
20996 /* Prevent reordering memory accesses against stack pointer restore. */
20997 else if (cfun->calls_alloca
20998 || offset_below_red_zone_p (-info->total_size))
21000 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21001 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21002 MEM_NOTRAP_P (mem1) = 1;
21003 MEM_NOTRAP_P (mem2) = 1;
21004 emit_insn (gen_frame_tie (mem1, mem2));
21007 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21008 GEN_INT (info->total_size)));
21011 else if (info->push_p
21012 && DEFAULT_ABI != ABI_V4
21013 && !crtl->calls_eh_return)
21015 /* Prevent reordering memory accesses against stack pointer restore. */
21016 if (cfun->calls_alloca
21017 || offset_below_red_zone_p (-info->total_size))
21019 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21020 MEM_NOTRAP_P (mem) = 1;
21021 emit_insn (gen_stack_tie (mem));
21023 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21024 GEN_INT (info->total_size)));
21027 if (insn && frame_reg_rtx == sp_reg_rtx)
21031 REG_NOTES (insn) = cfa_restores;
21032 cfa_restores = NULL_RTX;
21034 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21035 RTX_FRAME_RELATED_P (insn) = 1;
21038 /* Restore AltiVec registers if we have not done so already. */
21039 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21040 && TARGET_ALTIVEC_ABI
21041 && info->altivec_size != 0
21042 && (DEFAULT_ABI == ABI_V4
21043 || !offset_below_red_zone_p (info->altivec_save_offset)))
21047 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21048 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21050 rtx addr, areg, mem, reg;
21052 areg = gen_rtx_REG (Pmode, 0);
21054 (areg, GEN_INT (info->altivec_save_offset
21056 + 16 * (i - info->first_altivec_reg_save)));
21058 /* AltiVec addressing mode is [reg+reg]. */
21059 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21060 mem = gen_frame_mem (V4SImode, addr);
21062 reg = gen_rtx_REG (V4SImode, i);
21063 emit_move_insn (reg, mem);
21064 if (DEFAULT_ABI == ABI_V4)
21065 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21070 /* Restore VRSAVE if we have not done so already. */
21071 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21073 && TARGET_ALTIVEC_VRSAVE
21074 && info->vrsave_mask != 0
21075 && (DEFAULT_ABI == ABI_V4
21076 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21078 rtx addr, mem, reg;
21080 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21081 GEN_INT (info->vrsave_save_offset + sp_offset));
21082 mem = gen_frame_mem (SImode, addr);
21083 reg = gen_rtx_REG (SImode, 12);
21084 emit_move_insn (reg, mem);
21086 emit_insn (generate_set_vrsave (reg, info, 1));
21089 /* Get the old lr if we saved it. If we are restoring registers
21090 out-of-line, then the out-of-line routines can do this for us. */
21091 if (restore_lr && restoring_GPRs_inline)
21093 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21094 info->lr_save_offset + sp_offset);
21096 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21099 /* Get the old cr if we saved it. */
21100 if (info->cr_save_p)
21102 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21103 GEN_INT (info->cr_save_offset + sp_offset));
21104 rtx mem = gen_frame_mem (SImode, addr);
21106 cr_save_reg = gen_rtx_REG (SImode,
21107 DEFAULT_ABI == ABI_AIX
21108 && !restoring_GPRs_inline
21109 && info->first_fp_reg_save < 64
21111 emit_move_insn (cr_save_reg, mem);
21114 /* Set LR here to try to overlap restores below. LR is always saved
21115 above incoming stack, so it never needs REG_CFA_RESTORE. */
21116 if (restore_lr && restoring_GPRs_inline)
21117 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21118 gen_rtx_REG (Pmode, 0));
21120 /* Load exception handler data registers, if needed. */
21121 if (crtl->calls_eh_return)
21123 unsigned int i, regno;
21127 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21128 GEN_INT (sp_offset + 5 * reg_size));
21129 rtx mem = gen_frame_mem (reg_mode, addr);
21131 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21138 regno = EH_RETURN_DATA_REGNO (i);
21139 if (regno == INVALID_REGNUM)
21142 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21143 info->ehrd_offset + sp_offset
21144 + reg_size * (int) i);
21146 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21150 /* Restore GPRs. This is done as a PARALLEL if we are using
21151 the load-multiple instructions. */
21153 && info->spe_64bit_regs_used != 0
21154 && info->first_gp_reg_save != 32)
21156 /* Determine whether we can address all of the registers that need
21157 to be saved with an offset from the stack pointer that fits in
21158 the small const field for SPE memory instructions. */
21159 int spe_regs_addressable_via_sp
21160 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21161 + (32 - info->first_gp_reg_save - 1) * reg_size)
21162 && restoring_GPRs_inline);
21165 if (spe_regs_addressable_via_sp)
21166 spe_offset = info->spe_gp_save_offset + sp_offset;
21169 rtx old_frame_reg_rtx = frame_reg_rtx;
21170 /* Make r11 point to the start of the SPE save area. We worried about
21171 not clobbering it when we were saving registers in the prologue.
21172 There's no need to worry here because the static chain is passed
21173 anew to every function. */
21174 int ool_adjust = (restoring_GPRs_inline
21176 : (info->first_gp_reg_save
21177 - (FIRST_SAVRES_REGISTER+1))*8);
21179 if (frame_reg_rtx == sp_reg_rtx)
21180 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21181 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21182 GEN_INT (info->spe_gp_save_offset
21185 /* Keep the invariant that frame_reg_rtx + sp_offset points
21186 at the top of the stack frame. */
21187 sp_offset = -info->spe_gp_save_offset;
21192 if (restoring_GPRs_inline)
21194 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21195 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21197 rtx offset, addr, mem, reg;
21199 /* We're doing all this to ensure that the immediate offset
21200 fits into the immediate field of 'evldd'. */
21201 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21203 offset = GEN_INT (spe_offset + reg_size * i);
21204 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21205 mem = gen_rtx_MEM (V2SImode, addr);
21206 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21208 insn = emit_move_insn (reg, mem);
21209 if (DEFAULT_ABI == ABI_V4)
21211 if (frame_pointer_needed
21212 && info->first_gp_reg_save + i
21213 == HARD_FRAME_POINTER_REGNUM)
21215 add_reg_note (insn, REG_CFA_DEF_CFA,
21216 plus_constant (frame_reg_rtx,
21218 RTX_FRAME_RELATED_P (insn) = 1;
21221 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21230 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21232 /*savep=*/false, /*gpr=*/true,
21234 emit_jump_insn (par);
21235 /* We don't want anybody else emitting things after we jumped
21240 else if (!restoring_GPRs_inline)
21242 /* We are jumping to an out-of-line function. */
21243 bool can_use_exit = info->first_fp_reg_save == 64;
21246 /* Emit stack reset code if we need it. */
21248 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21249 sp_offset, can_use_exit);
21252 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21255 GEN_INT (sp_offset - info->fp_size)));
21256 if (REGNO (frame_reg_rtx) == 11)
21257 sp_offset += info->fp_size;
21260 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21261 info->gp_save_offset, reg_mode,
21262 /*savep=*/false, /*gpr=*/true,
21263 /*lr=*/can_use_exit);
21267 if (info->cr_save_p)
21269 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21270 if (DEFAULT_ABI == ABI_V4)
21272 = alloc_reg_note (REG_CFA_RESTORE,
21273 gen_rtx_REG (SImode, CR2_REGNO),
21277 emit_jump_insn (par);
21279 /* We don't want anybody else emitting things after we jumped
21284 insn = emit_insn (par);
21285 if (DEFAULT_ABI == ABI_V4)
21287 if (frame_pointer_needed)
21289 add_reg_note (insn, REG_CFA_DEF_CFA,
21290 plus_constant (frame_reg_rtx, sp_offset));
21291 RTX_FRAME_RELATED_P (insn) = 1;
21294 for (i = info->first_gp_reg_save; i < 32; i++)
21296 = alloc_reg_note (REG_CFA_RESTORE,
21297 gen_rtx_REG (reg_mode, i), cfa_restores);
21300 else if (using_load_multiple)
21303 p = rtvec_alloc (32 - info->first_gp_reg_save);
21304 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21306 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21307 GEN_INT (info->gp_save_offset
21310 rtx mem = gen_frame_mem (reg_mode, addr);
21311 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21313 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21314 if (DEFAULT_ABI == ABI_V4)
21315 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21318 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21319 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21321 add_reg_note (insn, REG_CFA_DEF_CFA,
21322 plus_constant (frame_reg_rtx, sp_offset));
21323 RTX_FRAME_RELATED_P (insn) = 1;
21328 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21329 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21331 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21332 GEN_INT (info->gp_save_offset
21335 rtx mem = gen_frame_mem (reg_mode, addr);
21336 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21338 insn = emit_move_insn (reg, mem);
21339 if (DEFAULT_ABI == ABI_V4)
21341 if (frame_pointer_needed
21342 && info->first_gp_reg_save + i
21343 == HARD_FRAME_POINTER_REGNUM)
21345 add_reg_note (insn, REG_CFA_DEF_CFA,
21346 plus_constant (frame_reg_rtx, sp_offset));
21347 RTX_FRAME_RELATED_P (insn) = 1;
21350 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21356 if (restore_lr && !restoring_GPRs_inline)
21358 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21359 info->lr_save_offset + sp_offset);
21361 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21362 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21363 gen_rtx_REG (Pmode, 0));
21366 /* Restore fpr's if we need to do it without calling a function. */
21367 if (restoring_FPRs_inline)
21368 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21369 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21370 && ! call_used_regs[info->first_fp_reg_save+i]))
21372 rtx addr, mem, reg;
21373 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21374 GEN_INT (info->fp_save_offset
21377 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21378 ? DFmode : SFmode), addr);
21379 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21380 ? DFmode : SFmode),
21381 info->first_fp_reg_save + i);
21383 emit_move_insn (reg, mem);
21384 if (DEFAULT_ABI == ABI_V4)
21385 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21389 /* If we saved cr, restore it here. Just those that were used. */
21390 if (info->cr_save_p)
21392 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21393 if (DEFAULT_ABI == ABI_V4)
21395 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21399 /* If this is V.4, unwind the stack pointer after all of the loads
21401 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21402 sp_offset, !restoring_FPRs_inline);
21407 REG_NOTES (insn) = cfa_restores;
21408 cfa_restores = NULL_RTX;
21410 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21411 RTX_FRAME_RELATED_P (insn) = 1;
21414 if (crtl->calls_eh_return)
21416 rtx sa = EH_RETURN_STACKADJ_RTX;
21417 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21423 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21424 if (! restoring_FPRs_inline)
21425 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21427 p = rtvec_alloc (2);
21429 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21430 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21431 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21432 : gen_rtx_CLOBBER (VOIDmode,
21433 gen_rtx_REG (Pmode, 65)));
21435 /* If we have to restore more than two FP registers, branch to the
21436 restore function. It will return to our caller. */
21437 if (! restoring_FPRs_inline)
21442 sym = rs6000_savres_routine_sym (info,
21446 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21447 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21448 gen_rtx_REG (Pmode,
21449 DEFAULT_ABI == ABI_AIX
21451 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21454 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21455 GEN_INT (info->fp_save_offset + 8*i));
21456 mem = gen_frame_mem (DFmode, addr);
21458 RTVEC_ELT (p, i+4) =
21459 gen_rtx_SET (VOIDmode,
21460 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21465 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21469 /* Write function epilogue. */
21472 rs6000_output_function_epilogue (FILE *file,
21473 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21475 if (! HAVE_epilogue)
21477 rtx insn = get_last_insn ();
21478 /* If the last insn was a BARRIER, we don't have to write anything except
21479 the trace table. */
21480 if (GET_CODE (insn) == NOTE)
21481 insn = prev_nonnote_insn (insn);
21482 if (insn == 0 || GET_CODE (insn) != BARRIER)
21484 /* This is slightly ugly, but at least we don't have two
21485 copies of the epilogue-emitting code. */
21488 /* A NOTE_INSN_DELETED is supposed to be at the start
21489 and end of the "toplevel" insn chain. */
21490 emit_note (NOTE_INSN_DELETED);
21491 rs6000_emit_epilogue (FALSE);
21492 emit_note (NOTE_INSN_DELETED);
21494 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21498 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21500 INSN_ADDRESSES_NEW (insn, addr);
21505 if (TARGET_DEBUG_STACK)
21506 debug_rtx_list (get_insns (), 100);
21507 final (get_insns (), file, FALSE);
21513 macho_branch_islands ();
21514 /* Mach-O doesn't support labels at the end of objects, so if
21515 it looks like we might want one, insert a NOP. */
21517 rtx insn = get_last_insn ();
21520 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21521 insn = PREV_INSN (insn);
21525 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
21526 fputs ("\tnop\n", file);
21530 /* Output a traceback table here. See /usr/include/sys/debug.h for info
21533 We don't output a traceback table if -finhibit-size-directive was
21534 used. The documentation for -finhibit-size-directive reads
21535 ``don't output a @code{.size} assembler directive, or anything
21536 else that would cause trouble if the function is split in the
21537 middle, and the two halves are placed at locations far apart in
21538 memory.'' The traceback table has this property, since it
21539 includes the offset from the start of the function to the
21540 traceback table itself.
21542 System V.4 Powerpc's (and the embedded ABI derived from it) use a
21543 different traceback table. */
21544 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
21545 && rs6000_traceback != traceback_none && !cfun->is_thunk)
21547 const char *fname = NULL;
21548 const char *language_string = lang_hooks.name;
21549 int fixed_parms = 0, float_parms = 0, parm_info = 0;
21551 int optional_tbtab;
21552 rs6000_stack_t *info = rs6000_stack_info ();
21554 if (rs6000_traceback == traceback_full)
21555 optional_tbtab = 1;
21556 else if (rs6000_traceback == traceback_part)
21557 optional_tbtab = 0;
21559 optional_tbtab = !optimize_size && !TARGET_ELF;
21561 if (optional_tbtab)
21563 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
21564 while (*fname == '.') /* V.4 encodes . in the name */
21567 /* Need label immediately before tbtab, so we can compute
21568 its offset from the function start. */
21569 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21570 ASM_OUTPUT_LABEL (file, fname);
21573 /* The .tbtab pseudo-op can only be used for the first eight
21574 expressions, since it can't handle the possibly variable
21575 length fields that follow. However, if you omit the optional
21576 fields, the assembler outputs zeros for all optional fields
21577 anyways, giving each variable length field is minimum length
21578 (as defined in sys/debug.h). Thus we can not use the .tbtab
21579 pseudo-op at all. */
21581 /* An all-zero word flags the start of the tbtab, for debuggers
21582 that have to find it by searching forward from the entry
21583 point or from the current pc. */
21584 fputs ("\t.long 0\n", file);
21586 /* Tbtab format type. Use format type 0. */
21587 fputs ("\t.byte 0,", file);
21589 /* Language type. Unfortunately, there does not seem to be any
21590 official way to discover the language being compiled, so we
21591 use language_string.
21592 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
21593 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
21594 a number, so for now use 9. LTO isn't assigned a number either,
21595 so for now use 0. */
21596 if (! strcmp (language_string, "GNU C")
21597 || ! strcmp (language_string, "GNU GIMPLE"))
21599 else if (! strcmp (language_string, "GNU F77")
21600 || ! strcmp (language_string, "GNU Fortran"))
21602 else if (! strcmp (language_string, "GNU Pascal"))
21604 else if (! strcmp (language_string, "GNU Ada"))
21606 else if (! strcmp (language_string, "GNU C++")
21607 || ! strcmp (language_string, "GNU Objective-C++"))
21609 else if (! strcmp (language_string, "GNU Java"))
21611 else if (! strcmp (language_string, "GNU Objective-C"))
21614 gcc_unreachable ();
21615 fprintf (file, "%d,", i);
21617 /* 8 single bit fields: global linkage (not set for C extern linkage,
21618 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
21619 from start of procedure stored in tbtab, internal function, function
21620 has controlled storage, function has no toc, function uses fp,
21621 function logs/aborts fp operations. */
21622 /* Assume that fp operations are used if any fp reg must be saved. */
21623 fprintf (file, "%d,",
21624 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
21626 /* 6 bitfields: function is interrupt handler, name present in
21627 proc table, function calls alloca, on condition directives
21628 (controls stack walks, 3 bits), saves condition reg, saves
21630 /* The `function calls alloca' bit seems to be set whenever reg 31 is
21631 set up as a frame pointer, even when there is no alloca call. */
21632 fprintf (file, "%d,",
21633 ((optional_tbtab << 6)
21634 | ((optional_tbtab & frame_pointer_needed) << 5)
21635 | (info->cr_save_p << 1)
21636 | (info->lr_save_p)));
21638 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
21640 fprintf (file, "%d,",
21641 (info->push_p << 7) | (64 - info->first_fp_reg_save));
21643 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
21644 fprintf (file, "%d,", (32 - first_reg_to_save ()));
21646 if (optional_tbtab)
21648 /* Compute the parameter info from the function decl argument
21651 int next_parm_info_bit = 31;
21653 for (decl = DECL_ARGUMENTS (current_function_decl);
21654 decl; decl = DECL_CHAIN (decl))
21656 rtx parameter = DECL_INCOMING_RTL (decl);
21657 enum machine_mode mode = GET_MODE (parameter);
21659 if (GET_CODE (parameter) == REG)
21661 if (SCALAR_FLOAT_MODE_P (mode))
21682 gcc_unreachable ();
21685 /* If only one bit will fit, don't or in this entry. */
21686 if (next_parm_info_bit > 0)
21687 parm_info |= (bits << (next_parm_info_bit - 1));
21688 next_parm_info_bit -= 2;
21692 fixed_parms += ((GET_MODE_SIZE (mode)
21693 + (UNITS_PER_WORD - 1))
21695 next_parm_info_bit -= 1;
21701 /* Number of fixed point parameters. */
21702 /* This is actually the number of words of fixed point parameters; thus
21703 an 8 byte struct counts as 2; and thus the maximum value is 8. */
21704 fprintf (file, "%d,", fixed_parms);
21706 /* 2 bitfields: number of floating point parameters (7 bits), parameters
21708 /* This is actually the number of fp registers that hold parameters;
21709 and thus the maximum value is 13. */
21710 /* Set parameters on stack bit if parameters are not in their original
21711 registers, regardless of whether they are on the stack? Xlc
21712 seems to set the bit when not optimizing. */
21713 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
21715 if (! optional_tbtab)
21718 /* Optional fields follow. Some are variable length. */
21720 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
21721 11 double float. */
21722 /* There is an entry for each parameter in a register, in the order that
21723 they occur in the parameter list. Any intervening arguments on the
21724 stack are ignored. If the list overflows a long (max possible length
21725 34 bits) then completely leave off all elements that don't fit. */
21726 /* Only emit this long if there was at least one parameter. */
21727 if (fixed_parms || float_parms)
21728 fprintf (file, "\t.long %d\n", parm_info);
21730 /* Offset from start of code to tb table. */
21731 fputs ("\t.long ", file);
21732 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
21733 RS6000_OUTPUT_BASENAME (file, fname);
21735 rs6000_output_function_entry (file, fname);
21738 /* Interrupt handler mask. */
21739 /* Omit this long, since we never set the interrupt handler bit
21742 /* Number of CTL (controlled storage) anchors. */
21743 /* Omit this long, since the has_ctl bit is never set above. */
21745 /* Displacement into stack of each CTL anchor. */
21746 /* Omit this list of longs, because there are no CTL anchors. */
21748 /* Length of function name. */
21751 fprintf (file, "\t.short %d\n", (int) strlen (fname));
21753 /* Function name. */
21754 assemble_string (fname, strlen (fname));
21756 /* Register for alloca automatic storage; this is always reg 31.
21757 Only emit this if the alloca bit was set above. */
21758 if (frame_pointer_needed)
21759 fputs ("\t.byte 31\n", file);
21761 fputs ("\t.align 2\n", file);
21765 /* A C compound statement that outputs the assembler code for a thunk
21766 function, used to implement C++ virtual function calls with
21767 multiple inheritance. The thunk acts as a wrapper around a virtual
21768 function, adjusting the implicit object parameter before handing
21769 control off to the real function.
21771 First, emit code to add the integer DELTA to the location that
21772 contains the incoming first argument. Assume that this argument
21773 contains a pointer, and is the one used to pass the `this' pointer
21774 in C++. This is the incoming argument *before* the function
21775 prologue, e.g. `%o0' on a sparc. The addition must preserve the
21776 values of all other incoming arguments.
21778 After the addition, emit code to jump to FUNCTION, which is a
21779 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
21780 not touch the return address. Hence returning from FUNCTION will
21781 return to whoever called the current `thunk'.
21783 The effect must be as if FUNCTION had been called directly with the
21784 adjusted first argument. This macro is responsible for emitting
21785 all of the code for a thunk function; output_function_prologue()
21786 and output_function_epilogue() are not invoked.
21788 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
21789 been extracted from it.) It might possibly be useful on some
21790 targets, but probably not.
21792 If you do not define this macro, the target-independent code in the
21793 C++ frontend will generate a less efficient heavyweight thunk that
21794 calls FUNCTION instead of jumping to it. The generic approach does
21795 not support varargs. */
21798 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
21799 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
21802 rtx this_rtx, insn, funexp;
21804 reload_completed = 1;
21805 epilogue_completed = 1;
21807 /* Mark the end of the (empty) prologue. */
21808 emit_note (NOTE_INSN_PROLOGUE_END);
21810 /* Find the "this" pointer. If the function returns a structure,
21811 the structure return pointer is in r3. */
21812 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
21813 this_rtx = gen_rtx_REG (Pmode, 4);
21815 this_rtx = gen_rtx_REG (Pmode, 3);
21817 /* Apply the constant offset, if required. */
21819 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
21821 /* Apply the offset from the vtable, if required. */
21824 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
21825 rtx tmp = gen_rtx_REG (Pmode, 12);
21827 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
21828 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
21830 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
21831 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
21835 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
21837 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
21839 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
21842 /* Generate a tail call to the target function. */
21843 if (!TREE_USED (function))
21845 assemble_external (function);
21846 TREE_USED (function) = 1;
21848 funexp = XEXP (DECL_RTL (function), 0);
21849 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
21852 if (MACHOPIC_INDIRECT)
21853 funexp = machopic_indirect_call_target (funexp);
21856 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
21857 generate sibcall RTL explicitly. */
21858 insn = emit_call_insn (
21859 gen_rtx_PARALLEL (VOIDmode,
21861 gen_rtx_CALL (VOIDmode,
21862 funexp, const0_rtx),
21863 gen_rtx_USE (VOIDmode, const0_rtx),
21864 gen_rtx_USE (VOIDmode,
21865 gen_rtx_REG (SImode,
21867 gen_rtx_RETURN (VOIDmode))));
21868 SIBLING_CALL_P (insn) = 1;
21871 /* Run just enough of rest_of_compilation to get the insns emitted.
21872 There's not really enough bulk here to make other passes such as
21873 instruction scheduling worth while. Note that use_thunk calls
21874 assemble_start_function and assemble_end_function. */
21875 insn = get_insns ();
21876 insn_locators_alloc ();
21877 shorten_branches (insn);
21878 final_start_function (insn, file, 1);
21879 final (insn, file, 1);
21880 final_end_function ();
21882 reload_completed = 0;
21883 epilogue_completed = 0;
21886 /* A quick summary of the various types of 'constant-pool tables'
21889 Target Flags Name One table per
21890 AIX (none) AIX TOC object file
21891 AIX -mfull-toc AIX TOC object file
21892 AIX -mminimal-toc AIX minimal TOC translation unit
21893 SVR4/EABI (none) SVR4 SDATA object file
21894 SVR4/EABI -fpic SVR4 pic object file
21895 SVR4/EABI -fPIC SVR4 PIC translation unit
21896 SVR4/EABI -mrelocatable EABI TOC function
21897 SVR4/EABI -maix AIX TOC object file
21898 SVR4/EABI -maix -mminimal-toc
21899 AIX minimal TOC translation unit
21901 Name Reg. Set by entries contains:
21902 made by addrs? fp? sum?
21904 AIX TOC 2 crt0 as Y option option
21905 AIX minimal TOC 30 prolog gcc Y Y option
21906 SVR4 SDATA 13 crt0 gcc N Y N
21907 SVR4 pic 30 prolog ld Y not yet N
21908 SVR4 PIC 30 prolog gcc Y option option
21909 EABI TOC 30 prolog gcc Y option option
21913 /* Hash functions for the hash table. */
21916 rs6000_hash_constant (rtx k)
21918 enum rtx_code code = GET_CODE (k);
21919 enum machine_mode mode = GET_MODE (k);
21920 unsigned result = (code << 3) ^ mode;
21921 const char *format;
21924 format = GET_RTX_FORMAT (code);
21925 flen = strlen (format);
21931 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
21934 if (mode != VOIDmode)
21935 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
21947 for (; fidx < flen; fidx++)
21948 switch (format[fidx])
21953 const char *str = XSTR (k, fidx);
21954 len = strlen (str);
21955 result = result * 613 + len;
21956 for (i = 0; i < len; i++)
21957 result = result * 613 + (unsigned) str[i];
21962 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
21966 result = result * 613 + (unsigned) XINT (k, fidx);
21969 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
21970 result = result * 613 + (unsigned) XWINT (k, fidx);
21974 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
21975 result = result * 613 + (unsigned) (XWINT (k, fidx)
21982 gcc_unreachable ();
21989 toc_hash_function (const void *hash_entry)
21991 const struct toc_hash_struct *thc =
21992 (const struct toc_hash_struct *) hash_entry;
21993 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
21996 /* Compare H1 and H2 for equivalence. */
21999 toc_hash_eq (const void *h1, const void *h2)
22001 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22002 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22004 if (((const struct toc_hash_struct *) h1)->key_mode
22005 != ((const struct toc_hash_struct *) h2)->key_mode)
22008 return rtx_equal_p (r1, r2);
22011 /* These are the names given by the C++ front-end to vtables, and
22012 vtable-like objects. Ideally, this logic should not be here;
22013 instead, there should be some programmatic way of inquiring as
22014 to whether or not an object is a vtable. */
22016 #define VTABLE_NAME_P(NAME) \
22017 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22018 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22019 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22020 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22021 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22023 #ifdef NO_DOLLAR_IN_LABEL
22024 /* Return a GGC-allocated character string translating dollar signs in
22025 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22028 rs6000_xcoff_strip_dollar (const char *name)
22033 p = strchr (name, '$');
22035 if (p == 0 || p == name)
22038 len = strlen (name);
22039 strip = (char *) alloca (len + 1);
22040 strcpy (strip, name);
22041 p = strchr (strip, '$');
22045 p = strchr (p + 1, '$');
22048 return ggc_alloc_string (strip, len);
22053 rs6000_output_symbol_ref (FILE *file, rtx x)
22055 /* Currently C++ toc references to vtables can be emitted before it
22056 is decided whether the vtable is public or private. If this is
22057 the case, then the linker will eventually complain that there is
22058 a reference to an unknown section. Thus, for vtables only,
22059 we emit the TOC reference to reference the symbol and not the
22061 const char *name = XSTR (x, 0);
22063 if (VTABLE_NAME_P (name))
22065 RS6000_OUTPUT_BASENAME (file, name);
22068 assemble_name (file, name);
22071 /* Output a TOC entry. We derive the entry name from what is being
22075 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22078 const char *name = buf;
22080 HOST_WIDE_INT offset = 0;
22082 gcc_assert (!TARGET_NO_TOC);
22084 /* When the linker won't eliminate them, don't output duplicate
22085 TOC entries (this happens on AIX if there is any kind of TOC,
22086 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22088 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22090 struct toc_hash_struct *h;
22093 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22094 time because GGC is not initialized at that point. */
22095 if (toc_hash_table == NULL)
22096 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22097 toc_hash_eq, NULL);
22099 h = ggc_alloc_toc_hash_struct ();
22101 h->key_mode = mode;
22102 h->labelno = labelno;
22104 found = htab_find_slot (toc_hash_table, h, INSERT);
22105 if (*found == NULL)
22107 else /* This is indeed a duplicate.
22108 Set this label equal to that label. */
22110 fputs ("\t.set ", file);
22111 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22112 fprintf (file, "%d,", labelno);
22113 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22114 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22120 /* If we're going to put a double constant in the TOC, make sure it's
22121 aligned properly when strict alignment is on. */
22122 if (GET_CODE (x) == CONST_DOUBLE
22123 && STRICT_ALIGNMENT
22124 && GET_MODE_BITSIZE (mode) >= 64
22125 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22126 ASM_OUTPUT_ALIGN (file, 3);
22129 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22131 /* Handle FP constants specially. Note that if we have a minimal
22132 TOC, things we put here aren't actually in the TOC, so we can allow
22134 if (GET_CODE (x) == CONST_DOUBLE &&
22135 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22137 REAL_VALUE_TYPE rv;
22140 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22141 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22142 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22144 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22148 if (TARGET_MINIMAL_TOC)
22149 fputs (DOUBLE_INT_ASM_OP, file);
22151 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22152 k[0] & 0xffffffff, k[1] & 0xffffffff,
22153 k[2] & 0xffffffff, k[3] & 0xffffffff);
22154 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22155 k[0] & 0xffffffff, k[1] & 0xffffffff,
22156 k[2] & 0xffffffff, k[3] & 0xffffffff);
22161 if (TARGET_MINIMAL_TOC)
22162 fputs ("\t.long ", file);
22164 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22165 k[0] & 0xffffffff, k[1] & 0xffffffff,
22166 k[2] & 0xffffffff, k[3] & 0xffffffff);
22167 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22168 k[0] & 0xffffffff, k[1] & 0xffffffff,
22169 k[2] & 0xffffffff, k[3] & 0xffffffff);
22173 else if (GET_CODE (x) == CONST_DOUBLE &&
22174 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22176 REAL_VALUE_TYPE rv;
22179 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22181 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22182 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22184 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22188 if (TARGET_MINIMAL_TOC)
22189 fputs (DOUBLE_INT_ASM_OP, file);
22191 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22192 k[0] & 0xffffffff, k[1] & 0xffffffff);
22193 fprintf (file, "0x%lx%08lx\n",
22194 k[0] & 0xffffffff, k[1] & 0xffffffff);
22199 if (TARGET_MINIMAL_TOC)
22200 fputs ("\t.long ", file);
22202 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22203 k[0] & 0xffffffff, k[1] & 0xffffffff);
22204 fprintf (file, "0x%lx,0x%lx\n",
22205 k[0] & 0xffffffff, k[1] & 0xffffffff);
22209 else if (GET_CODE (x) == CONST_DOUBLE &&
22210 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22212 REAL_VALUE_TYPE rv;
22215 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22216 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22217 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22219 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22223 if (TARGET_MINIMAL_TOC)
22224 fputs (DOUBLE_INT_ASM_OP, file);
22226 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22227 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22232 if (TARGET_MINIMAL_TOC)
22233 fputs ("\t.long ", file);
22235 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22236 fprintf (file, "0x%lx\n", l & 0xffffffff);
22240 else if (GET_MODE (x) == VOIDmode
22241 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22243 unsigned HOST_WIDE_INT low;
22244 HOST_WIDE_INT high;
22246 if (GET_CODE (x) == CONST_DOUBLE)
22248 low = CONST_DOUBLE_LOW (x);
22249 high = CONST_DOUBLE_HIGH (x);
22252 #if HOST_BITS_PER_WIDE_INT == 32
22255 high = (low & 0x80000000) ? ~0 : 0;
22259 low = INTVAL (x) & 0xffffffff;
22260 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22264 /* TOC entries are always Pmode-sized, but since this
22265 is a bigendian machine then if we're putting smaller
22266 integer constants in the TOC we have to pad them.
22267 (This is still a win over putting the constants in
22268 a separate constant pool, because then we'd have
22269 to have both a TOC entry _and_ the actual constant.)
22271 For a 32-bit target, CONST_INT values are loaded and shifted
22272 entirely within `low' and can be stored in one TOC entry. */
22274 /* It would be easy to make this work, but it doesn't now. */
22275 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22277 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22279 #if HOST_BITS_PER_WIDE_INT == 32
22280 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22281 POINTER_SIZE, &low, &high, 0);
22284 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22285 high = (HOST_WIDE_INT) low >> 32;
22292 if (TARGET_MINIMAL_TOC)
22293 fputs (DOUBLE_INT_ASM_OP, file);
22295 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22296 (long) high & 0xffffffff, (long) low & 0xffffffff);
22297 fprintf (file, "0x%lx%08lx\n",
22298 (long) high & 0xffffffff, (long) low & 0xffffffff);
22303 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22305 if (TARGET_MINIMAL_TOC)
22306 fputs ("\t.long ", file);
22308 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22309 (long) high & 0xffffffff, (long) low & 0xffffffff);
22310 fprintf (file, "0x%lx,0x%lx\n",
22311 (long) high & 0xffffffff, (long) low & 0xffffffff);
22315 if (TARGET_MINIMAL_TOC)
22316 fputs ("\t.long ", file);
22318 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22319 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22325 if (GET_CODE (x) == CONST)
22327 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22328 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22330 base = XEXP (XEXP (x, 0), 0);
22331 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22334 switch (GET_CODE (base))
22337 name = XSTR (base, 0);
22341 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22342 CODE_LABEL_NUMBER (XEXP (base, 0)));
22346 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22350 gcc_unreachable ();
22353 if (TARGET_MINIMAL_TOC)
22354 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22357 fputs ("\t.tc ", file);
22358 RS6000_OUTPUT_BASENAME (file, name);
22361 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22363 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22365 fputs ("[TC],", file);
22368 /* Currently C++ toc references to vtables can be emitted before it
22369 is decided whether the vtable is public or private. If this is
22370 the case, then the linker will eventually complain that there is
22371 a TOC reference to an unknown section. Thus, for vtables only,
22372 we emit the TOC reference to reference the symbol and not the
22374 if (VTABLE_NAME_P (name))
22376 RS6000_OUTPUT_BASENAME (file, name);
22378 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22379 else if (offset > 0)
22380 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22383 output_addr_const (file, x);
22387 /* Output an assembler pseudo-op to write an ASCII string of N characters
22388 starting at P to FILE.
22390 On the RS/6000, we have to do this using the .byte operation and
22391 write out special characters outside the quoted string.
22392 Also, the assembler is broken; very long strings are truncated,
22393 so we must artificially break them up early. */
22396 output_ascii (FILE *file, const char *p, int n)
22399 int i, count_string;
22400 const char *for_string = "\t.byte \"";
22401 const char *for_decimal = "\t.byte ";
22402 const char *to_close = NULL;
22405 for (i = 0; i < n; i++)
22408 if (c >= ' ' && c < 0177)
22411 fputs (for_string, file);
22414 /* Write two quotes to get one. */
22422 for_decimal = "\"\n\t.byte ";
22426 if (count_string >= 512)
22428 fputs (to_close, file);
22430 for_string = "\t.byte \"";
22431 for_decimal = "\t.byte ";
22439 fputs (for_decimal, file);
22440 fprintf (file, "%d", c);
22442 for_string = "\n\t.byte \"";
22443 for_decimal = ", ";
22449 /* Now close the string if we have written one. Then end the line. */
22451 fputs (to_close, file);
22454 /* Generate a unique section name for FILENAME for a section type
22455 represented by SECTION_DESC. Output goes into BUF.
22457 SECTION_DESC can be any string, as long as it is different for each
22458 possible section type.
22460 We name the section in the same manner as xlc. The name begins with an
22461 underscore followed by the filename (after stripping any leading directory
22462 names) with the last period replaced by the string SECTION_DESC. If
22463 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22467 rs6000_gen_section_name (char **buf, const char *filename,
22468 const char *section_desc)
22470 const char *q, *after_last_slash, *last_period = 0;
22474 after_last_slash = filename;
22475 for (q = filename; *q; q++)
22478 after_last_slash = q + 1;
22479 else if (*q == '.')
22483 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22484 *buf = (char *) xmalloc (len);
22489 for (q = after_last_slash; *q; q++)
22491 if (q == last_period)
22493 strcpy (p, section_desc);
22494 p += strlen (section_desc);
22498 else if (ISALNUM (*q))
22502 if (last_period == 0)
22503 strcpy (p, section_desc);
22508 /* Emit profile function. */
22511 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22513 /* Non-standard profiling for kernels, which just saves LR then calls
22514 _mcount without worrying about arg saves. The idea is to change
22515 the function prologue as little as possible as it isn't easy to
22516 account for arg save/restore code added just for _mcount. */
22517 if (TARGET_PROFILE_KERNEL)
22520 if (DEFAULT_ABI == ABI_AIX)
22522 #ifndef NO_PROFILE_COUNTERS
22523 # define NO_PROFILE_COUNTERS 0
22525 if (NO_PROFILE_COUNTERS)
22526 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22527 LCT_NORMAL, VOIDmode, 0);
22531 const char *label_name;
22534 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22535 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
22536 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
22538 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
22539 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
22542 else if (DEFAULT_ABI == ABI_DARWIN)
22544 const char *mcount_name = RS6000_MCOUNT;
22545 int caller_addr_regno = LR_REGNO;
22547 /* Be conservative and always set this, at least for now. */
22548 crtl->uses_pic_offset_table = 1;
22551 /* For PIC code, set up a stub and collect the caller's address
22552 from r0, which is where the prologue puts it. */
22553 if (MACHOPIC_INDIRECT
22554 && crtl->uses_pic_offset_table)
22555 caller_addr_regno = 0;
22557 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
22558 LCT_NORMAL, VOIDmode, 1,
22559 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
22563 /* Write function profiler code. */
22566 output_function_profiler (FILE *file, int labelno)
22570 switch (DEFAULT_ABI)
22573 gcc_unreachable ();
22578 warning (0, "no profiling of 64-bit code for this ABI");
22581 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
22582 fprintf (file, "\tmflr %s\n", reg_names[0]);
22583 if (NO_PROFILE_COUNTERS)
22585 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22586 reg_names[0], reg_names[1]);
22588 else if (TARGET_SECURE_PLT && flag_pic)
22590 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
22591 reg_names[0], reg_names[1]);
22592 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22593 asm_fprintf (file, "\t{cau|addis} %s,%s,",
22594 reg_names[12], reg_names[12]);
22595 assemble_name (file, buf);
22596 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
22597 assemble_name (file, buf);
22598 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
22600 else if (flag_pic == 1)
22602 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
22603 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22604 reg_names[0], reg_names[1]);
22605 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
22606 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
22607 assemble_name (file, buf);
22608 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
22610 else if (flag_pic > 1)
22612 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22613 reg_names[0], reg_names[1]);
22614 /* Now, we need to get the address of the label. */
22615 fputs ("\tbcl 20,31,1f\n\t.long ", file);
22616 assemble_name (file, buf);
22617 fputs ("-.\n1:", file);
22618 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
22619 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
22620 reg_names[0], reg_names[11]);
22621 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
22622 reg_names[0], reg_names[0], reg_names[11]);
22626 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
22627 assemble_name (file, buf);
22628 fputs ("@ha\n", file);
22629 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
22630 reg_names[0], reg_names[1]);
22631 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
22632 assemble_name (file, buf);
22633 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
22636 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
22637 fprintf (file, "\tbl %s%s\n",
22638 RS6000_MCOUNT, flag_pic ? "@plt" : "");
22643 if (!TARGET_PROFILE_KERNEL)
22645 /* Don't do anything, done in output_profile_hook (). */
22649 gcc_assert (!TARGET_32BIT);
22651 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
22652 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
22654 if (cfun->static_chain_decl != NULL)
22656 asm_fprintf (file, "\tstd %s,24(%s)\n",
22657 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22658 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22659 asm_fprintf (file, "\tld %s,24(%s)\n",
22660 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
22663 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
22671 /* The following variable value is the last issued insn. */
22673 static rtx last_scheduled_insn;
22675 /* The following variable helps to balance issuing of load and
22676 store instructions */
22678 static int load_store_pendulum;
22680 /* Power4 load update and store update instructions are cracked into a
22681 load or store and an integer insn which are executed in the same cycle.
22682 Branches have their own dispatch slot which does not count against the
22683 GCC issue rate, but it changes the program flow so there are no other
22684 instructions to issue in this cycle. */
22687 rs6000_variable_issue_1 (rtx insn, int more)
22689 last_scheduled_insn = insn;
22690 if (GET_CODE (PATTERN (insn)) == USE
22691 || GET_CODE (PATTERN (insn)) == CLOBBER)
22693 cached_can_issue_more = more;
22694 return cached_can_issue_more;
22697 if (insn_terminates_group_p (insn, current_group))
22699 cached_can_issue_more = 0;
22700 return cached_can_issue_more;
22703 /* If no reservation, but reach here */
22704 if (recog_memoized (insn) < 0)
22707 if (rs6000_sched_groups)
22709 if (is_microcoded_insn (insn))
22710 cached_can_issue_more = 0;
22711 else if (is_cracked_insn (insn))
22712 cached_can_issue_more = more > 2 ? more - 2 : 0;
22714 cached_can_issue_more = more - 1;
22716 return cached_can_issue_more;
22719 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
22722 cached_can_issue_more = more - 1;
22723 return cached_can_issue_more;
22727 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
22729 int r = rs6000_variable_issue_1 (insn, more);
22731 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
22735 /* Adjust the cost of a scheduling dependency. Return the new cost of
22736 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
22739 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
22741 enum attr_type attr_type;
22743 if (! recog_memoized (insn))
22746 switch (REG_NOTE_KIND (link))
22750 /* Data dependency; DEP_INSN writes a register that INSN reads
22751 some cycles later. */
22753 /* Separate a load from a narrower, dependent store. */
22754 if (rs6000_sched_groups
22755 && GET_CODE (PATTERN (insn)) == SET
22756 && GET_CODE (PATTERN (dep_insn)) == SET
22757 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
22758 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
22759 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
22760 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
22763 attr_type = get_attr_type (insn);
22768 /* Tell the first scheduling pass about the latency between
22769 a mtctr and bctr (and mtlr and br/blr). The first
22770 scheduling pass will not know about this latency since
22771 the mtctr instruction, which has the latency associated
22772 to it, will be generated by reload. */
22773 return TARGET_POWER ? 5 : 4;
22775 /* Leave some extra cycles between a compare and its
22776 dependent branch, to inhibit expensive mispredicts. */
22777 if ((rs6000_cpu_attr == CPU_PPC603
22778 || rs6000_cpu_attr == CPU_PPC604
22779 || rs6000_cpu_attr == CPU_PPC604E
22780 || rs6000_cpu_attr == CPU_PPC620
22781 || rs6000_cpu_attr == CPU_PPC630
22782 || rs6000_cpu_attr == CPU_PPC750
22783 || rs6000_cpu_attr == CPU_PPC7400
22784 || rs6000_cpu_attr == CPU_PPC7450
22785 || rs6000_cpu_attr == CPU_POWER4
22786 || rs6000_cpu_attr == CPU_POWER5
22787 || rs6000_cpu_attr == CPU_POWER7
22788 || rs6000_cpu_attr == CPU_CELL)
22789 && recog_memoized (dep_insn)
22790 && (INSN_CODE (dep_insn) >= 0))
22792 switch (get_attr_type (dep_insn))
22796 case TYPE_DELAYED_COMPARE:
22797 case TYPE_IMUL_COMPARE:
22798 case TYPE_LMUL_COMPARE:
22799 case TYPE_FPCOMPARE:
22800 case TYPE_CR_LOGICAL:
22801 case TYPE_DELAYED_CR:
22810 case TYPE_STORE_UX:
22812 case TYPE_FPSTORE_U:
22813 case TYPE_FPSTORE_UX:
22814 if ((rs6000_cpu == PROCESSOR_POWER6)
22815 && recog_memoized (dep_insn)
22816 && (INSN_CODE (dep_insn) >= 0))
22819 if (GET_CODE (PATTERN (insn)) != SET)
22820 /* If this happens, we have to extend this to schedule
22821 optimally. Return default for now. */
22824 /* Adjust the cost for the case where the value written
22825 by a fixed point operation is used as the address
22826 gen value on a store. */
22827 switch (get_attr_type (dep_insn))
22834 if (! store_data_bypass_p (dep_insn, insn))
22838 case TYPE_LOAD_EXT:
22839 case TYPE_LOAD_EXT_U:
22840 case TYPE_LOAD_EXT_UX:
22841 case TYPE_VAR_SHIFT_ROTATE:
22842 case TYPE_VAR_DELAYED_COMPARE:
22844 if (! store_data_bypass_p (dep_insn, insn))
22850 case TYPE_FAST_COMPARE:
22853 case TYPE_INSERT_WORD:
22854 case TYPE_INSERT_DWORD:
22855 case TYPE_FPLOAD_U:
22856 case TYPE_FPLOAD_UX:
22858 case TYPE_STORE_UX:
22859 case TYPE_FPSTORE_U:
22860 case TYPE_FPSTORE_UX:
22862 if (! store_data_bypass_p (dep_insn, insn))
22870 case TYPE_IMUL_COMPARE:
22871 case TYPE_LMUL_COMPARE:
22873 if (! store_data_bypass_p (dep_insn, insn))
22879 if (! store_data_bypass_p (dep_insn, insn))
22885 if (! store_data_bypass_p (dep_insn, insn))
22898 case TYPE_LOAD_EXT:
22899 case TYPE_LOAD_EXT_U:
22900 case TYPE_LOAD_EXT_UX:
22901 if ((rs6000_cpu == PROCESSOR_POWER6)
22902 && recog_memoized (dep_insn)
22903 && (INSN_CODE (dep_insn) >= 0))
22906 /* Adjust the cost for the case where the value written
22907 by a fixed point instruction is used within the address
22908 gen portion of a subsequent load(u)(x) */
22909 switch (get_attr_type (dep_insn))
22916 if (set_to_load_agen (dep_insn, insn))
22920 case TYPE_LOAD_EXT:
22921 case TYPE_LOAD_EXT_U:
22922 case TYPE_LOAD_EXT_UX:
22923 case TYPE_VAR_SHIFT_ROTATE:
22924 case TYPE_VAR_DELAYED_COMPARE:
22926 if (set_to_load_agen (dep_insn, insn))
22932 case TYPE_FAST_COMPARE:
22935 case TYPE_INSERT_WORD:
22936 case TYPE_INSERT_DWORD:
22937 case TYPE_FPLOAD_U:
22938 case TYPE_FPLOAD_UX:
22940 case TYPE_STORE_UX:
22941 case TYPE_FPSTORE_U:
22942 case TYPE_FPSTORE_UX:
22944 if (set_to_load_agen (dep_insn, insn))
22952 case TYPE_IMUL_COMPARE:
22953 case TYPE_LMUL_COMPARE:
22955 if (set_to_load_agen (dep_insn, insn))
22961 if (set_to_load_agen (dep_insn, insn))
22967 if (set_to_load_agen (dep_insn, insn))
22978 if ((rs6000_cpu == PROCESSOR_POWER6)
22979 && recog_memoized (dep_insn)
22980 && (INSN_CODE (dep_insn) >= 0)
22981 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
22988 /* Fall out to return default cost. */
22992 case REG_DEP_OUTPUT:
22993 /* Output dependency; DEP_INSN writes a register that INSN writes some
22995 if ((rs6000_cpu == PROCESSOR_POWER6)
22996 && recog_memoized (dep_insn)
22997 && (INSN_CODE (dep_insn) >= 0))
22999 attr_type = get_attr_type (insn);
23004 if (get_attr_type (dep_insn) == TYPE_FP)
23008 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23016 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23021 gcc_unreachable ();
23027 /* Debug version of rs6000_adjust_cost. */
23030 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23032 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23038 switch (REG_NOTE_KIND (link))
23040 default: dep = "unknown depencency"; break;
23041 case REG_DEP_TRUE: dep = "data dependency"; break;
23042 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23043 case REG_DEP_ANTI: dep = "anti depencency"; break;
23047 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23048 "%s, insn:\n", ret, cost, dep);
23056 /* The function returns a true if INSN is microcoded.
23057 Return false otherwise. */
23060 is_microcoded_insn (rtx insn)
23062 if (!insn || !NONDEBUG_INSN_P (insn)
23063 || GET_CODE (PATTERN (insn)) == USE
23064 || GET_CODE (PATTERN (insn)) == CLOBBER)
23067 if (rs6000_cpu_attr == CPU_CELL)
23068 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23070 if (rs6000_sched_groups)
23072 enum attr_type type = get_attr_type (insn);
23073 if (type == TYPE_LOAD_EXT_U
23074 || type == TYPE_LOAD_EXT_UX
23075 || type == TYPE_LOAD_UX
23076 || type == TYPE_STORE_UX
23077 || type == TYPE_MFCR)
23084 /* The function returns true if INSN is cracked into 2 instructions
23085 by the processor (and therefore occupies 2 issue slots). */
23088 is_cracked_insn (rtx insn)
23090 if (!insn || !NONDEBUG_INSN_P (insn)
23091 || GET_CODE (PATTERN (insn)) == USE
23092 || GET_CODE (PATTERN (insn)) == CLOBBER)
23095 if (rs6000_sched_groups)
23097 enum attr_type type = get_attr_type (insn);
23098 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23099 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23100 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23101 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23102 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23103 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23104 || type == TYPE_IDIV || type == TYPE_LDIV
23105 || type == TYPE_INSERT_WORD)
23112 /* The function returns true if INSN can be issued only from
23113 the branch slot. */
23116 is_branch_slot_insn (rtx insn)
23118 if (!insn || !NONDEBUG_INSN_P (insn)
23119 || GET_CODE (PATTERN (insn)) == USE
23120 || GET_CODE (PATTERN (insn)) == CLOBBER)
23123 if (rs6000_sched_groups)
23125 enum attr_type type = get_attr_type (insn);
23126 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23134 /* The function returns true if out_inst sets a value that is
23135 used in the address generation computation of in_insn */
23137 set_to_load_agen (rtx out_insn, rtx in_insn)
23139 rtx out_set, in_set;
23141 /* For performance reasons, only handle the simple case where
23142 both loads are a single_set. */
23143 out_set = single_set (out_insn);
23146 in_set = single_set (in_insn);
23148 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23154 /* The function returns true if the target storage location of
23155 out_insn is adjacent to the target storage location of in_insn */
23156 /* Return 1 if memory locations are adjacent. */
23159 adjacent_mem_locations (rtx insn1, rtx insn2)
23162 rtx a = get_store_dest (PATTERN (insn1));
23163 rtx b = get_store_dest (PATTERN (insn2));
23165 if ((GET_CODE (XEXP (a, 0)) == REG
23166 || (GET_CODE (XEXP (a, 0)) == PLUS
23167 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23168 && (GET_CODE (XEXP (b, 0)) == REG
23169 || (GET_CODE (XEXP (b, 0)) == PLUS
23170 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23172 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23175 if (GET_CODE (XEXP (a, 0)) == PLUS)
23177 reg0 = XEXP (XEXP (a, 0), 0);
23178 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23181 reg0 = XEXP (a, 0);
23183 if (GET_CODE (XEXP (b, 0)) == PLUS)
23185 reg1 = XEXP (XEXP (b, 0), 0);
23186 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23189 reg1 = XEXP (b, 0);
23191 val_diff = val1 - val0;
23193 return ((REGNO (reg0) == REGNO (reg1))
23194 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23195 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23201 /* A C statement (sans semicolon) to update the integer scheduling
23202 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23203 INSN earlier, reduce the priority to execute INSN later. Do not
23204 define this macro if you do not need to adjust the scheduling
23205 priorities of insns. */
23208 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23210 /* On machines (like the 750) which have asymmetric integer units,
23211 where one integer unit can do multiply and divides and the other
23212 can't, reduce the priority of multiply/divide so it is scheduled
23213 before other integer operations. */
23216 if (! INSN_P (insn))
23219 if (GET_CODE (PATTERN (insn)) == USE)
23222 switch (rs6000_cpu_attr) {
23224 switch (get_attr_type (insn))
23231 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23232 priority, priority);
23233 if (priority >= 0 && priority < 0x01000000)
23240 if (insn_must_be_first_in_group (insn)
23241 && reload_completed
23242 && current_sched_info->sched_max_insns_priority
23243 && rs6000_sched_restricted_insns_priority)
23246 /* Prioritize insns that can be dispatched only in the first
23248 if (rs6000_sched_restricted_insns_priority == 1)
23249 /* Attach highest priority to insn. This means that in
23250 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23251 precede 'priority' (critical path) considerations. */
23252 return current_sched_info->sched_max_insns_priority;
23253 else if (rs6000_sched_restricted_insns_priority == 2)
23254 /* Increase priority of insn by a minimal amount. This means that in
23255 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23256 considerations precede dispatch-slot restriction considerations. */
23257 return (priority + 1);
23260 if (rs6000_cpu == PROCESSOR_POWER6
23261 && ((load_store_pendulum == -2 && is_load_insn (insn))
23262 || (load_store_pendulum == 2 && is_store_insn (insn))))
23263 /* Attach highest priority to insn if the scheduler has just issued two
23264 stores and this instruction is a load, or two loads and this instruction
23265 is a store. Power6 wants loads and stores scheduled alternately
23267 return current_sched_info->sched_max_insns_priority;
23272 /* Return true if the instruction is nonpipelined on the Cell. */
23274 is_nonpipeline_insn (rtx insn)
23276 enum attr_type type;
23277 if (!insn || !NONDEBUG_INSN_P (insn)
23278 || GET_CODE (PATTERN (insn)) == USE
23279 || GET_CODE (PATTERN (insn)) == CLOBBER)
23282 type = get_attr_type (insn);
23283 if (type == TYPE_IMUL
23284 || type == TYPE_IMUL2
23285 || type == TYPE_IMUL3
23286 || type == TYPE_LMUL
23287 || type == TYPE_IDIV
23288 || type == TYPE_LDIV
23289 || type == TYPE_SDIV
23290 || type == TYPE_DDIV
23291 || type == TYPE_SSQRT
23292 || type == TYPE_DSQRT
23293 || type == TYPE_MFCR
23294 || type == TYPE_MFCRF
23295 || type == TYPE_MFJMPR)
23303 /* Return how many instructions the machine can issue per cycle. */
23306 rs6000_issue_rate (void)
23308 /* Unless scheduling for register pressure, use issue rate of 1 for
23309 first scheduling pass to decrease degradation. */
23310 if (!reload_completed && !flag_sched_pressure)
23313 switch (rs6000_cpu_attr) {
23314 case CPU_RIOS1: /* ? */
23316 case CPU_PPC601: /* ? */
23325 case CPU_PPCE300C2:
23326 case CPU_PPCE300C3:
23327 case CPU_PPCE500MC:
23328 case CPU_PPCE500MC64:
23348 /* Return how many instructions to look ahead for better insn
23352 rs6000_use_sched_lookahead (void)
23354 if (rs6000_cpu_attr == CPU_PPC8540)
23356 if (rs6000_cpu_attr == CPU_CELL)
23357 return (reload_completed ? 8 : 0);
23361 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23363 rs6000_use_sched_lookahead_guard (rtx insn)
23365 if (rs6000_cpu_attr != CPU_CELL)
23368 if (insn == NULL_RTX || !INSN_P (insn))
23371 if (!reload_completed
23372 || is_nonpipeline_insn (insn)
23373 || is_microcoded_insn (insn))
23379 /* Determine is PAT refers to memory. */
23382 is_mem_ref (rtx pat)
23388 /* stack_tie does not produce any real memory traffic. */
23389 if (GET_CODE (pat) == UNSPEC
23390 && XINT (pat, 1) == UNSPEC_TIE)
23393 if (GET_CODE (pat) == MEM)
23396 /* Recursively process the pattern. */
23397 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23399 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23402 ret |= is_mem_ref (XEXP (pat, i));
23403 else if (fmt[i] == 'E')
23404 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23405 ret |= is_mem_ref (XVECEXP (pat, i, j));
23411 /* Determine if PAT is a PATTERN of a load insn. */
23414 is_load_insn1 (rtx pat)
23416 if (!pat || pat == NULL_RTX)
23419 if (GET_CODE (pat) == SET)
23420 return is_mem_ref (SET_SRC (pat));
23422 if (GET_CODE (pat) == PARALLEL)
23426 for (i = 0; i < XVECLEN (pat, 0); i++)
23427 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23434 /* Determine if INSN loads from memory. */
23437 is_load_insn (rtx insn)
23439 if (!insn || !INSN_P (insn))
23442 if (GET_CODE (insn) == CALL_INSN)
23445 return is_load_insn1 (PATTERN (insn));
23448 /* Determine if PAT is a PATTERN of a store insn. */
23451 is_store_insn1 (rtx pat)
23453 if (!pat || pat == NULL_RTX)
23456 if (GET_CODE (pat) == SET)
23457 return is_mem_ref (SET_DEST (pat));
23459 if (GET_CODE (pat) == PARALLEL)
23463 for (i = 0; i < XVECLEN (pat, 0); i++)
23464 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23471 /* Determine if INSN stores to memory. */
23474 is_store_insn (rtx insn)
23476 if (!insn || !INSN_P (insn))
23479 return is_store_insn1 (PATTERN (insn));
23482 /* Return the dest of a store insn. */
23485 get_store_dest (rtx pat)
23487 gcc_assert (is_store_insn1 (pat));
23489 if (GET_CODE (pat) == SET)
23490 return SET_DEST (pat);
23491 else if (GET_CODE (pat) == PARALLEL)
23495 for (i = 0; i < XVECLEN (pat, 0); i++)
23497 rtx inner_pat = XVECEXP (pat, 0, i);
23498 if (GET_CODE (inner_pat) == SET
23499 && is_mem_ref (SET_DEST (inner_pat)))
23503 /* We shouldn't get here, because we should have either a simple
23504 store insn or a store with update which are covered above. */
23508 /* Returns whether the dependence between INSN and NEXT is considered
23509 costly by the given target. */
23512 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23517 /* If the flag is not enabled - no dependence is considered costly;
23518 allow all dependent insns in the same group.
23519 This is the most aggressive option. */
23520 if (rs6000_sched_costly_dep == no_dep_costly)
23523 /* If the flag is set to 1 - a dependence is always considered costly;
23524 do not allow dependent instructions in the same group.
23525 This is the most conservative option. */
23526 if (rs6000_sched_costly_dep == all_deps_costly)
23529 insn = DEP_PRO (dep);
23530 next = DEP_CON (dep);
23532 if (rs6000_sched_costly_dep == store_to_load_dep_costly
23533 && is_load_insn (next)
23534 && is_store_insn (insn))
23535 /* Prevent load after store in the same group. */
23538 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
23539 && is_load_insn (next)
23540 && is_store_insn (insn)
23541 && DEP_TYPE (dep) == REG_DEP_TRUE)
23542 /* Prevent load after store in the same group if it is a true
23546 /* The flag is set to X; dependences with latency >= X are considered costly,
23547 and will not be scheduled in the same group. */
23548 if (rs6000_sched_costly_dep <= max_dep_latency
23549 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
23555 /* Return the next insn after INSN that is found before TAIL is reached,
23556 skipping any "non-active" insns - insns that will not actually occupy
23557 an issue slot. Return NULL_RTX if such an insn is not found. */
23560 get_next_active_insn (rtx insn, rtx tail)
23562 if (insn == NULL_RTX || insn == tail)
23567 insn = NEXT_INSN (insn);
23568 if (insn == NULL_RTX || insn == tail)
23573 || (NONJUMP_INSN_P (insn)
23574 && GET_CODE (PATTERN (insn)) != USE
23575 && GET_CODE (PATTERN (insn)) != CLOBBER
23576 && INSN_CODE (insn) != CODE_FOR_stack_tie))
23582 /* We are about to begin issuing insns for this clock cycle. */
23585 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
23586 rtx *ready ATTRIBUTE_UNUSED,
23587 int *pn_ready ATTRIBUTE_UNUSED,
23588 int clock_var ATTRIBUTE_UNUSED)
23590 int n_ready = *pn_ready;
23593 fprintf (dump, "// rs6000_sched_reorder :\n");
23595 /* Reorder the ready list, if the second to last ready insn
23596 is a nonepipeline insn. */
23597 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
23599 if (is_nonpipeline_insn (ready[n_ready - 1])
23600 && (recog_memoized (ready[n_ready - 2]) > 0))
23601 /* Simply swap first two insns. */
23603 rtx tmp = ready[n_ready - 1];
23604 ready[n_ready - 1] = ready[n_ready - 2];
23605 ready[n_ready - 2] = tmp;
23609 if (rs6000_cpu == PROCESSOR_POWER6)
23610 load_store_pendulum = 0;
23612 return rs6000_issue_rate ();
23615 /* Like rs6000_sched_reorder, but called after issuing each insn. */
23618 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
23619 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
23622 fprintf (dump, "// rs6000_sched_reorder2 :\n");
23624 /* For Power6, we need to handle some special cases to try and keep the
23625 store queue from overflowing and triggering expensive flushes.
23627 This code monitors how load and store instructions are being issued
23628 and skews the ready list one way or the other to increase the likelihood
23629 that a desired instruction is issued at the proper time.
23631 A couple of things are done. First, we maintain a "load_store_pendulum"
23632 to track the current state of load/store issue.
23634 - If the pendulum is at zero, then no loads or stores have been
23635 issued in the current cycle so we do nothing.
23637 - If the pendulum is 1, then a single load has been issued in this
23638 cycle and we attempt to locate another load in the ready list to
23641 - If the pendulum is -2, then two stores have already been
23642 issued in this cycle, so we increase the priority of the first load
23643 in the ready list to increase it's likelihood of being chosen first
23646 - If the pendulum is -1, then a single store has been issued in this
23647 cycle and we attempt to locate another store in the ready list to
23648 issue with it, preferring a store to an adjacent memory location to
23649 facilitate store pairing in the store queue.
23651 - If the pendulum is 2, then two loads have already been
23652 issued in this cycle, so we increase the priority of the first store
23653 in the ready list to increase it's likelihood of being chosen first
23656 - If the pendulum < -2 or > 2, then do nothing.
23658 Note: This code covers the most common scenarios. There exist non
23659 load/store instructions which make use of the LSU and which
23660 would need to be accounted for to strictly model the behavior
23661 of the machine. Those instructions are currently unaccounted
23662 for to help minimize compile time overhead of this code.
23664 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
23670 if (is_store_insn (last_scheduled_insn))
23671 /* Issuing a store, swing the load_store_pendulum to the left */
23672 load_store_pendulum--;
23673 else if (is_load_insn (last_scheduled_insn))
23674 /* Issuing a load, swing the load_store_pendulum to the right */
23675 load_store_pendulum++;
23677 return cached_can_issue_more;
23679 /* If the pendulum is balanced, or there is only one instruction on
23680 the ready list, then all is well, so return. */
23681 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
23682 return cached_can_issue_more;
23684 if (load_store_pendulum == 1)
23686 /* A load has been issued in this cycle. Scan the ready list
23687 for another load to issue with it */
23692 if (is_load_insn (ready[pos]))
23694 /* Found a load. Move it to the head of the ready list,
23695 and adjust it's priority so that it is more likely to
23698 for (i=pos; i<*pn_ready-1; i++)
23699 ready[i] = ready[i + 1];
23700 ready[*pn_ready-1] = tmp;
23702 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23703 INSN_PRIORITY (tmp)++;
23709 else if (load_store_pendulum == -2)
23711 /* Two stores have been issued in this cycle. Increase the
23712 priority of the first load in the ready list to favor it for
23713 issuing in the next cycle. */
23718 if (is_load_insn (ready[pos])
23720 && INSN_PRIORITY_KNOWN (ready[pos]))
23722 INSN_PRIORITY (ready[pos])++;
23724 /* Adjust the pendulum to account for the fact that a load
23725 was found and increased in priority. This is to prevent
23726 increasing the priority of multiple loads */
23727 load_store_pendulum--;
23734 else if (load_store_pendulum == -1)
23736 /* A store has been issued in this cycle. Scan the ready list for
23737 another store to issue with it, preferring a store to an adjacent
23739 int first_store_pos = -1;
23745 if (is_store_insn (ready[pos]))
23747 /* Maintain the index of the first store found on the
23749 if (first_store_pos == -1)
23750 first_store_pos = pos;
23752 if (is_store_insn (last_scheduled_insn)
23753 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
23755 /* Found an adjacent store. Move it to the head of the
23756 ready list, and adjust it's priority so that it is
23757 more likely to stay there */
23759 for (i=pos; i<*pn_ready-1; i++)
23760 ready[i] = ready[i + 1];
23761 ready[*pn_ready-1] = tmp;
23763 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23764 INSN_PRIORITY (tmp)++;
23766 first_store_pos = -1;
23774 if (first_store_pos >= 0)
23776 /* An adjacent store wasn't found, but a non-adjacent store was,
23777 so move the non-adjacent store to the front of the ready
23778 list, and adjust its priority so that it is more likely to
23780 tmp = ready[first_store_pos];
23781 for (i=first_store_pos; i<*pn_ready-1; i++)
23782 ready[i] = ready[i + 1];
23783 ready[*pn_ready-1] = tmp;
23784 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
23785 INSN_PRIORITY (tmp)++;
23788 else if (load_store_pendulum == 2)
23790 /* Two loads have been issued in this cycle. Increase the priority
23791 of the first store in the ready list to favor it for issuing in
23797 if (is_store_insn (ready[pos])
23799 && INSN_PRIORITY_KNOWN (ready[pos]))
23801 INSN_PRIORITY (ready[pos])++;
23803 /* Adjust the pendulum to account for the fact that a store
23804 was found and increased in priority. This is to prevent
23805 increasing the priority of multiple stores */
23806 load_store_pendulum++;
23815 return cached_can_issue_more;
23818 /* Return whether the presence of INSN causes a dispatch group termination
23819 of group WHICH_GROUP.
23821 If WHICH_GROUP == current_group, this function will return true if INSN
23822 causes the termination of the current group (i.e, the dispatch group to
23823 which INSN belongs). This means that INSN will be the last insn in the
23824 group it belongs to.
23826 If WHICH_GROUP == previous_group, this function will return true if INSN
23827 causes the termination of the previous group (i.e, the dispatch group that
23828 precedes the group to which INSN belongs). This means that INSN will be
23829 the first insn in the group it belongs to). */
23832 insn_terminates_group_p (rtx insn, enum group_termination which_group)
23839 first = insn_must_be_first_in_group (insn);
23840 last = insn_must_be_last_in_group (insn);
23845 if (which_group == current_group)
23847 else if (which_group == previous_group)
23855 insn_must_be_first_in_group (rtx insn)
23857 enum attr_type type;
23860 || GET_CODE (insn) == NOTE
23861 || DEBUG_INSN_P (insn)
23862 || GET_CODE (PATTERN (insn)) == USE
23863 || GET_CODE (PATTERN (insn)) == CLOBBER)
23866 switch (rs6000_cpu)
23868 case PROCESSOR_POWER5:
23869 if (is_cracked_insn (insn))
23871 case PROCESSOR_POWER4:
23872 if (is_microcoded_insn (insn))
23875 if (!rs6000_sched_groups)
23878 type = get_attr_type (insn);
23885 case TYPE_DELAYED_CR:
23886 case TYPE_CR_LOGICAL:
23900 case PROCESSOR_POWER6:
23901 type = get_attr_type (insn);
23905 case TYPE_INSERT_DWORD:
23909 case TYPE_VAR_SHIFT_ROTATE:
23916 case TYPE_INSERT_WORD:
23917 case TYPE_DELAYED_COMPARE:
23918 case TYPE_IMUL_COMPARE:
23919 case TYPE_LMUL_COMPARE:
23920 case TYPE_FPCOMPARE:
23931 case TYPE_LOAD_EXT_UX:
23933 case TYPE_STORE_UX:
23934 case TYPE_FPLOAD_U:
23935 case TYPE_FPLOAD_UX:
23936 case TYPE_FPSTORE_U:
23937 case TYPE_FPSTORE_UX:
23943 case PROCESSOR_POWER7:
23944 type = get_attr_type (insn);
23948 case TYPE_CR_LOGICAL:
23955 case TYPE_DELAYED_COMPARE:
23956 case TYPE_VAR_DELAYED_COMPARE:
23962 case TYPE_LOAD_EXT:
23963 case TYPE_LOAD_EXT_U:
23964 case TYPE_LOAD_EXT_UX:
23966 case TYPE_STORE_UX:
23967 case TYPE_FPLOAD_U:
23968 case TYPE_FPLOAD_UX:
23969 case TYPE_FPSTORE_U:
23970 case TYPE_FPSTORE_UX:
23986 insn_must_be_last_in_group (rtx insn)
23988 enum attr_type type;
23991 || GET_CODE (insn) == NOTE
23992 || DEBUG_INSN_P (insn)
23993 || GET_CODE (PATTERN (insn)) == USE
23994 || GET_CODE (PATTERN (insn)) == CLOBBER)
23997 switch (rs6000_cpu) {
23998 case PROCESSOR_POWER4:
23999 case PROCESSOR_POWER5:
24000 if (is_microcoded_insn (insn))
24003 if (is_branch_slot_insn (insn))
24007 case PROCESSOR_POWER6:
24008 type = get_attr_type (insn);
24015 case TYPE_VAR_SHIFT_ROTATE:
24022 case TYPE_DELAYED_COMPARE:
24023 case TYPE_IMUL_COMPARE:
24024 case TYPE_LMUL_COMPARE:
24025 case TYPE_FPCOMPARE:
24039 case PROCESSOR_POWER7:
24040 type = get_attr_type (insn);
24048 case TYPE_LOAD_EXT_U:
24049 case TYPE_LOAD_EXT_UX:
24050 case TYPE_STORE_UX:
24063 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24064 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24067 is_costly_group (rtx *group_insns, rtx next_insn)
24070 int issue_rate = rs6000_issue_rate ();
24072 for (i = 0; i < issue_rate; i++)
24074 sd_iterator_def sd_it;
24076 rtx insn = group_insns[i];
24081 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24083 rtx next = DEP_CON (dep);
24085 if (next == next_insn
24086 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24094 /* Utility of the function redefine_groups.
24095 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24096 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24097 to keep it "far" (in a separate group) from GROUP_INSNS, following
24098 one of the following schemes, depending on the value of the flag
24099 -minsert_sched_nops = X:
24100 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24101 in order to force NEXT_INSN into a separate group.
24102 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24103 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24104 insertion (has a group just ended, how many vacant issue slots remain in the
24105 last group, and how many dispatch groups were encountered so far). */
24108 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24109 rtx next_insn, bool *group_end, int can_issue_more,
24114 int issue_rate = rs6000_issue_rate ();
24115 bool end = *group_end;
24118 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24119 return can_issue_more;
24121 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24122 return can_issue_more;
24124 force = is_costly_group (group_insns, next_insn);
24126 return can_issue_more;
24128 if (sched_verbose > 6)
24129 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24130 *group_count ,can_issue_more);
24132 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24135 can_issue_more = 0;
24137 /* Since only a branch can be issued in the last issue_slot, it is
24138 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24139 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24140 in this case the last nop will start a new group and the branch
24141 will be forced to the new group. */
24142 if (can_issue_more && !is_branch_slot_insn (next_insn))
24145 while (can_issue_more > 0)
24148 emit_insn_before (nop, next_insn);
24156 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24158 int n_nops = rs6000_sched_insert_nops;
24160 /* Nops can't be issued from the branch slot, so the effective
24161 issue_rate for nops is 'issue_rate - 1'. */
24162 if (can_issue_more == 0)
24163 can_issue_more = issue_rate;
24165 if (can_issue_more == 0)
24167 can_issue_more = issue_rate - 1;
24170 for (i = 0; i < issue_rate; i++)
24172 group_insns[i] = 0;
24179 emit_insn_before (nop, next_insn);
24180 if (can_issue_more == issue_rate - 1) /* new group begins */
24183 if (can_issue_more == 0)
24185 can_issue_more = issue_rate - 1;
24188 for (i = 0; i < issue_rate; i++)
24190 group_insns[i] = 0;
24196 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24199 /* Is next_insn going to start a new group? */
24202 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24203 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24204 || (can_issue_more < issue_rate &&
24205 insn_terminates_group_p (next_insn, previous_group)));
24206 if (*group_end && end)
24209 if (sched_verbose > 6)
24210 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24211 *group_count, can_issue_more);
24212 return can_issue_more;
24215 return can_issue_more;
24218 /* This function tries to synch the dispatch groups that the compiler "sees"
24219 with the dispatch groups that the processor dispatcher is expected to
24220 form in practice. It tries to achieve this synchronization by forcing the
24221 estimated processor grouping on the compiler (as opposed to the function
24222 'pad_goups' which tries to force the scheduler's grouping on the processor).
24224 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24225 examines the (estimated) dispatch groups that will be formed by the processor
24226 dispatcher. It marks these group boundaries to reflect the estimated
24227 processor grouping, overriding the grouping that the scheduler had marked.
24228 Depending on the value of the flag '-minsert-sched-nops' this function can
24229 force certain insns into separate groups or force a certain distance between
24230 them by inserting nops, for example, if there exists a "costly dependence"
24233 The function estimates the group boundaries that the processor will form as
24234 follows: It keeps track of how many vacant issue slots are available after
24235 each insn. A subsequent insn will start a new group if one of the following
24237 - no more vacant issue slots remain in the current dispatch group.
24238 - only the last issue slot, which is the branch slot, is vacant, but the next
24239 insn is not a branch.
24240 - only the last 2 or less issue slots, including the branch slot, are vacant,
24241 which means that a cracked insn (which occupies two issue slots) can't be
24242 issued in this group.
24243 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24244 start a new group. */
24247 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24249 rtx insn, next_insn;
24251 int can_issue_more;
24254 int group_count = 0;
24258 issue_rate = rs6000_issue_rate ();
24259 group_insns = XALLOCAVEC (rtx, issue_rate);
24260 for (i = 0; i < issue_rate; i++)
24262 group_insns[i] = 0;
24264 can_issue_more = issue_rate;
24266 insn = get_next_active_insn (prev_head_insn, tail);
24269 while (insn != NULL_RTX)
24271 slot = (issue_rate - can_issue_more);
24272 group_insns[slot] = insn;
24274 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24275 if (insn_terminates_group_p (insn, current_group))
24276 can_issue_more = 0;
24278 next_insn = get_next_active_insn (insn, tail);
24279 if (next_insn == NULL_RTX)
24280 return group_count + 1;
24282 /* Is next_insn going to start a new group? */
24284 = (can_issue_more == 0
24285 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24286 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24287 || (can_issue_more < issue_rate &&
24288 insn_terminates_group_p (next_insn, previous_group)));
24290 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24291 next_insn, &group_end, can_issue_more,
24297 can_issue_more = 0;
24298 for (i = 0; i < issue_rate; i++)
24300 group_insns[i] = 0;
24304 if (GET_MODE (next_insn) == TImode && can_issue_more)
24305 PUT_MODE (next_insn, VOIDmode);
24306 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24307 PUT_MODE (next_insn, TImode);
24310 if (can_issue_more == 0)
24311 can_issue_more = issue_rate;
24314 return group_count;
24317 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24318 dispatch group boundaries that the scheduler had marked. Pad with nops
24319 any dispatch groups which have vacant issue slots, in order to force the
24320 scheduler's grouping on the processor dispatcher. The function
24321 returns the number of dispatch groups found. */
24324 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24326 rtx insn, next_insn;
24329 int can_issue_more;
24331 int group_count = 0;
24333 /* Initialize issue_rate. */
24334 issue_rate = rs6000_issue_rate ();
24335 can_issue_more = issue_rate;
24337 insn = get_next_active_insn (prev_head_insn, tail);
24338 next_insn = get_next_active_insn (insn, tail);
24340 while (insn != NULL_RTX)
24343 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24345 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24347 if (next_insn == NULL_RTX)
24352 /* If the scheduler had marked group termination at this location
24353 (between insn and next_insn), and neither insn nor next_insn will
24354 force group termination, pad the group with nops to force group
24357 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24358 && !insn_terminates_group_p (insn, current_group)
24359 && !insn_terminates_group_p (next_insn, previous_group))
24361 if (!is_branch_slot_insn (next_insn))
24364 while (can_issue_more)
24367 emit_insn_before (nop, next_insn);
24372 can_issue_more = issue_rate;
24377 next_insn = get_next_active_insn (insn, tail);
24380 return group_count;
24383 /* We're beginning a new block. Initialize data structures as necessary. */
24386 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24387 int sched_verbose ATTRIBUTE_UNUSED,
24388 int max_ready ATTRIBUTE_UNUSED)
24390 last_scheduled_insn = NULL_RTX;
24391 load_store_pendulum = 0;
24394 /* The following function is called at the end of scheduling BB.
24395 After reload, it inserts nops at insn group bundling. */
24398 rs6000_sched_finish (FILE *dump, int sched_verbose)
24403 fprintf (dump, "=== Finishing schedule.\n");
24405 if (reload_completed && rs6000_sched_groups)
24407 /* Do not run sched_finish hook when selective scheduling enabled. */
24408 if (sel_sched_p ())
24411 if (rs6000_sched_insert_nops == sched_finish_none)
24414 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24415 n_groups = pad_groups (dump, sched_verbose,
24416 current_sched_info->prev_head,
24417 current_sched_info->next_tail);
24419 n_groups = redefine_groups (dump, sched_verbose,
24420 current_sched_info->prev_head,
24421 current_sched_info->next_tail);
24423 if (sched_verbose >= 6)
24425 fprintf (dump, "ngroups = %d\n", n_groups);
24426 print_rtl (dump, current_sched_info->prev_head);
24427 fprintf (dump, "Done finish_sched\n");
24432 struct _rs6000_sched_context
24434 short cached_can_issue_more;
24435 rtx last_scheduled_insn;
24436 int load_store_pendulum;
24439 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24440 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24442 /* Allocate store for new scheduling context. */
24444 rs6000_alloc_sched_context (void)
24446 return xmalloc (sizeof (rs6000_sched_context_def));
24449 /* If CLEAN_P is true then initializes _SC with clean data,
24450 and from the global context otherwise. */
24452 rs6000_init_sched_context (void *_sc, bool clean_p)
24454 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24458 sc->cached_can_issue_more = 0;
24459 sc->last_scheduled_insn = NULL_RTX;
24460 sc->load_store_pendulum = 0;
24464 sc->cached_can_issue_more = cached_can_issue_more;
24465 sc->last_scheduled_insn = last_scheduled_insn;
24466 sc->load_store_pendulum = load_store_pendulum;
24470 /* Sets the global scheduling context to the one pointed to by _SC. */
24472 rs6000_set_sched_context (void *_sc)
24474 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24476 gcc_assert (sc != NULL);
24478 cached_can_issue_more = sc->cached_can_issue_more;
24479 last_scheduled_insn = sc->last_scheduled_insn;
24480 load_store_pendulum = sc->load_store_pendulum;
24485 rs6000_free_sched_context (void *_sc)
24487 gcc_assert (_sc != NULL);
24493 /* Length in units of the trampoline for entering a nested function. */
24496 rs6000_trampoline_size (void)
24500 switch (DEFAULT_ABI)
24503 gcc_unreachable ();
24506 ret = (TARGET_32BIT) ? 12 : 24;
24511 ret = (TARGET_32BIT) ? 40 : 48;
24518 /* Emit RTL insns to initialize the variable parts of a trampoline.
24519 FNADDR is an RTX for the address of the function's pure code.
24520 CXT is an RTX for the static chain value for the function. */
24523 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
24525 int regsize = (TARGET_32BIT) ? 4 : 8;
24526 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
24527 rtx ctx_reg = force_reg (Pmode, cxt);
24528 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
24530 switch (DEFAULT_ABI)
24533 gcc_unreachable ();
24535 /* Under AIX, just build the 3 word function descriptor */
24538 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
24539 rtx fn_reg = gen_reg_rtx (Pmode);
24540 rtx toc_reg = gen_reg_rtx (Pmode);
24542 /* Macro to shorten the code expansions below. */
24543 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
24545 m_tramp = replace_equiv_address (m_tramp, addr);
24547 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
24548 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
24549 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
24550 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
24551 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
24557 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
24560 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
24561 LCT_NORMAL, VOIDmode, 4,
24563 GEN_INT (rs6000_trampoline_size ()), SImode,
24571 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
24572 identifier as an argument, so the front end shouldn't look it up. */
24575 rs6000_attribute_takes_identifier_p (const_tree attr_id)
24577 return is_attribute_p ("altivec", attr_id);
24580 /* Handle the "altivec" attribute. The attribute may have
24581 arguments as follows:
24583 __attribute__((altivec(vector__)))
24584 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
24585 __attribute__((altivec(bool__))) (always followed by 'unsigned')
24587 and may appear more than once (e.g., 'vector bool char') in a
24588 given declaration. */
24591 rs6000_handle_altivec_attribute (tree *node,
24592 tree name ATTRIBUTE_UNUSED,
24594 int flags ATTRIBUTE_UNUSED,
24595 bool *no_add_attrs)
24597 tree type = *node, result = NULL_TREE;
24598 enum machine_mode mode;
24601 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
24602 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
24603 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
24606 while (POINTER_TYPE_P (type)
24607 || TREE_CODE (type) == FUNCTION_TYPE
24608 || TREE_CODE (type) == METHOD_TYPE
24609 || TREE_CODE (type) == ARRAY_TYPE)
24610 type = TREE_TYPE (type);
24612 mode = TYPE_MODE (type);
24614 /* Check for invalid AltiVec type qualifiers. */
24615 if (type == long_double_type_node)
24616 error ("use of %<long double%> in AltiVec types is invalid");
24617 else if (type == boolean_type_node)
24618 error ("use of boolean types in AltiVec types is invalid");
24619 else if (TREE_CODE (type) == COMPLEX_TYPE)
24620 error ("use of %<complex%> in AltiVec types is invalid");
24621 else if (DECIMAL_FLOAT_MODE_P (mode))
24622 error ("use of decimal floating point types in AltiVec types is invalid");
24623 else if (!TARGET_VSX)
24625 if (type == long_unsigned_type_node || type == long_integer_type_node)
24628 error ("use of %<long%> in AltiVec types is invalid for "
24629 "64-bit code without -mvsx");
24630 else if (rs6000_warn_altivec_long)
24631 warning (0, "use of %<long%> in AltiVec types is deprecated; "
24634 else if (type == long_long_unsigned_type_node
24635 || type == long_long_integer_type_node)
24636 error ("use of %<long long%> in AltiVec types is invalid without "
24638 else if (type == double_type_node)
24639 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
24642 switch (altivec_type)
24645 unsigned_p = TYPE_UNSIGNED (type);
24649 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
24652 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
24655 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
24658 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
24660 case SFmode: result = V4SF_type_node; break;
24661 case DFmode: result = V2DF_type_node; break;
24662 /* If the user says 'vector int bool', we may be handed the 'bool'
24663 attribute _before_ the 'vector' attribute, and so select the
24664 proper type in the 'b' case below. */
24665 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
24666 case V2DImode: case V2DFmode:
24674 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
24675 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
24676 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
24677 case QImode: case V16QImode: result = bool_V16QI_type_node;
24684 case V8HImode: result = pixel_V8HI_type_node;
24690 /* Propagate qualifiers attached to the element type
24691 onto the vector type. */
24692 if (result && result != type && TYPE_QUALS (type))
24693 result = build_qualified_type (result, TYPE_QUALS (type));
24695 *no_add_attrs = true; /* No need to hang on to the attribute. */
24698 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
24703 /* AltiVec defines four built-in scalar types that serve as vector
24704 elements; we must teach the compiler how to mangle them. */
24706 static const char *
24707 rs6000_mangle_type (const_tree type)
24709 type = TYPE_MAIN_VARIANT (type);
24711 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24712 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24715 if (type == bool_char_type_node) return "U6__boolc";
24716 if (type == bool_short_type_node) return "U6__bools";
24717 if (type == pixel_type_node) return "u7__pixel";
24718 if (type == bool_int_type_node) return "U6__booli";
24719 if (type == bool_long_type_node) return "U6__booll";
24721 /* Mangle IBM extended float long double as `g' (__float128) on
24722 powerpc*-linux where long-double-64 previously was the default. */
24723 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
24725 && TARGET_LONG_DOUBLE_128
24726 && !TARGET_IEEEQUAD)
24729 /* For all other types, use normal C++ mangling. */
24733 /* Handle a "longcall" or "shortcall" attribute; arguments as in
24734 struct attribute_spec.handler. */
24737 rs6000_handle_longcall_attribute (tree *node, tree name,
24738 tree args ATTRIBUTE_UNUSED,
24739 int flags ATTRIBUTE_UNUSED,
24740 bool *no_add_attrs)
24742 if (TREE_CODE (*node) != FUNCTION_TYPE
24743 && TREE_CODE (*node) != FIELD_DECL
24744 && TREE_CODE (*node) != TYPE_DECL)
24746 warning (OPT_Wattributes, "%qE attribute only applies to functions",
24748 *no_add_attrs = true;
24754 /* Set longcall attributes on all functions declared when
24755 rs6000_default_long_calls is true. */
24757 rs6000_set_default_type_attributes (tree type)
24759 if (rs6000_default_long_calls
24760 && (TREE_CODE (type) == FUNCTION_TYPE
24761 || TREE_CODE (type) == METHOD_TYPE))
24762 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
24764 TYPE_ATTRIBUTES (type));
24767 darwin_set_default_type_attributes (type);
24771 /* Return a reference suitable for calling a function with the
24772 longcall attribute. */
24775 rs6000_longcall_ref (rtx call_ref)
24777 const char *call_name;
24780 if (GET_CODE (call_ref) != SYMBOL_REF)
24783 /* System V adds '.' to the internal name, so skip them. */
24784 call_name = XSTR (call_ref, 0);
24785 if (*call_name == '.')
24787 while (*call_name == '.')
24790 node = get_identifier (call_name);
24791 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
24794 return force_reg (Pmode, call_ref);
24797 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
24798 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
24801 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
24802 struct attribute_spec.handler. */
24804 rs6000_handle_struct_attribute (tree *node, tree name,
24805 tree args ATTRIBUTE_UNUSED,
24806 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
24809 if (DECL_P (*node))
24811 if (TREE_CODE (*node) == TYPE_DECL)
24812 type = &TREE_TYPE (*node);
24817 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
24818 || TREE_CODE (*type) == UNION_TYPE)))
24820 warning (OPT_Wattributes, "%qE attribute ignored", name);
24821 *no_add_attrs = true;
24824 else if ((is_attribute_p ("ms_struct", name)
24825 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
24826 || ((is_attribute_p ("gcc_struct", name)
24827 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
24829 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
24831 *no_add_attrs = true;
24838 rs6000_ms_bitfield_layout_p (const_tree record_type)
24840 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
24841 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
24842 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
24845 #ifdef USING_ELFOS_H
24847 /* A get_unnamed_section callback, used for switching to toc_section. */
24850 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
24852 if (DEFAULT_ABI == ABI_AIX
24853 && TARGET_MINIMAL_TOC
24854 && !TARGET_RELOCATABLE)
24856 if (!toc_initialized)
24858 toc_initialized = 1;
24859 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24860 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
24861 fprintf (asm_out_file, "\t.tc ");
24862 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
24863 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24864 fprintf (asm_out_file, "\n");
24866 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24867 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24868 fprintf (asm_out_file, " = .+32768\n");
24871 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24873 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
24874 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
24877 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
24878 if (!toc_initialized)
24880 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
24881 fprintf (asm_out_file, " = .+32768\n");
24882 toc_initialized = 1;
24887 /* Implement TARGET_ASM_INIT_SECTIONS. */
24890 rs6000_elf_asm_init_sections (void)
24893 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
24896 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
24897 SDATA2_SECTION_ASM_OP);
24900 /* Implement TARGET_SELECT_RTX_SECTION. */
24903 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
24904 unsigned HOST_WIDE_INT align)
24906 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
24907 return toc_section;
24909 return default_elf_select_rtx_section (mode, x, align);
24912 /* For a SYMBOL_REF, set generic flags and then perform some
24913 target-specific processing.
24915 When the AIX ABI is requested on a non-AIX system, replace the
24916 function name with the real name (with a leading .) rather than the
24917 function descriptor name. This saves a lot of overriding code to
24918 read the prefixes. */
24921 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
24923 default_encode_section_info (decl, rtl, first);
24926 && TREE_CODE (decl) == FUNCTION_DECL
24928 && DEFAULT_ABI == ABI_AIX)
24930 rtx sym_ref = XEXP (rtl, 0);
24931 size_t len = strlen (XSTR (sym_ref, 0));
24932 char *str = XALLOCAVEC (char, len + 2);
24934 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
24935 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
24940 compare_section_name (const char *section, const char *templ)
24944 len = strlen (templ);
24945 return (strncmp (section, templ, len) == 0
24946 && (section[len] == 0 || section[len] == '.'));
24950 rs6000_elf_in_small_data_p (const_tree decl)
24952 if (rs6000_sdata == SDATA_NONE)
24955 /* We want to merge strings, so we never consider them small data. */
24956 if (TREE_CODE (decl) == STRING_CST)
24959 /* Functions are never in the small data area. */
24960 if (TREE_CODE (decl) == FUNCTION_DECL)
24963 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
24965 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
24966 if (compare_section_name (section, ".sdata")
24967 || compare_section_name (section, ".sdata2")
24968 || compare_section_name (section, ".gnu.linkonce.s")
24969 || compare_section_name (section, ".sbss")
24970 || compare_section_name (section, ".sbss2")
24971 || compare_section_name (section, ".gnu.linkonce.sb")
24972 || strcmp (section, ".PPC.EMB.sdata0") == 0
24973 || strcmp (section, ".PPC.EMB.sbss0") == 0)
24978 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
24981 && size <= g_switch_value
24982 /* If it's not public, and we're not going to reference it there,
24983 there's no need to put it in the small data section. */
24984 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
24991 #endif /* USING_ELFOS_H */
24993 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
24996 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
24998 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25001 /* Return a REG that occurs in ADDR with coefficient 1.
25002 ADDR can be effectively incremented by incrementing REG.
25004 r0 is special and we must not select it as an address
25005 register by this routine since our caller will try to
25006 increment the returned register via an "la" instruction. */
25009 find_addr_reg (rtx addr)
25011 while (GET_CODE (addr) == PLUS)
25013 if (GET_CODE (XEXP (addr, 0)) == REG
25014 && REGNO (XEXP (addr, 0)) != 0)
25015 addr = XEXP (addr, 0);
25016 else if (GET_CODE (XEXP (addr, 1)) == REG
25017 && REGNO (XEXP (addr, 1)) != 0)
25018 addr = XEXP (addr, 1);
25019 else if (CONSTANT_P (XEXP (addr, 0)))
25020 addr = XEXP (addr, 1);
25021 else if (CONSTANT_P (XEXP (addr, 1)))
25022 addr = XEXP (addr, 0);
25024 gcc_unreachable ();
25026 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25031 rs6000_fatal_bad_address (rtx op)
25033 fatal_insn ("bad address", op);
25038 typedef struct branch_island_d {
25039 tree function_name;
25044 DEF_VEC_O(branch_island);
25045 DEF_VEC_ALLOC_O(branch_island,gc);
25047 static VEC(branch_island,gc) *branch_islands;
25049 /* Remember to generate a branch island for far calls to the given
25053 add_compiler_branch_island (tree label_name, tree function_name,
25056 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25058 bi->function_name = function_name;
25059 bi->label_name = label_name;
25060 bi->line_number = line_number;
25063 /* Generate far-jump branch islands for everything recorded in
25064 branch_islands. Invoked immediately after the last instruction of
25065 the epilogue has been emitted; the branch islands must be appended
25066 to, and contiguous with, the function body. Mach-O stubs are
25067 generated in machopic_output_stub(). */
25070 macho_branch_islands (void)
25074 while (!VEC_empty (branch_island, branch_islands))
25076 branch_island *bi = VEC_last (branch_island, branch_islands);
25077 const char *label = IDENTIFIER_POINTER (bi->label_name);
25078 const char *name = IDENTIFIER_POINTER (bi->function_name);
25079 char name_buf[512];
25080 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25081 if (name[0] == '*' || name[0] == '&')
25082 strcpy (name_buf, name+1);
25086 strcpy (name_buf+1, name);
25088 strcpy (tmp_buf, "\n");
25089 strcat (tmp_buf, label);
25090 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25091 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25092 dbxout_stabd (N_SLINE, bi->line_number);
25093 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25096 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25097 strcat (tmp_buf, label);
25098 strcat (tmp_buf, "_pic\n");
25099 strcat (tmp_buf, label);
25100 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25102 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25103 strcat (tmp_buf, name_buf);
25104 strcat (tmp_buf, " - ");
25105 strcat (tmp_buf, label);
25106 strcat (tmp_buf, "_pic)\n");
25108 strcat (tmp_buf, "\tmtlr r0\n");
25110 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25111 strcat (tmp_buf, name_buf);
25112 strcat (tmp_buf, " - ");
25113 strcat (tmp_buf, label);
25114 strcat (tmp_buf, "_pic)\n");
25116 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25120 strcat (tmp_buf, ":\nlis r12,hi16(");
25121 strcat (tmp_buf, name_buf);
25122 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25123 strcat (tmp_buf, name_buf);
25124 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25126 output_asm_insn (tmp_buf, 0);
25127 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25128 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25129 dbxout_stabd (N_SLINE, bi->line_number);
25130 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25131 VEC_pop (branch_island, branch_islands);
25135 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25136 already there or not. */
25139 no_previous_def (tree function_name)
25144 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25145 if (function_name == bi->function_name)
25150 /* GET_PREV_LABEL gets the label name from the previous definition of
25154 get_prev_label (tree function_name)
25159 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25160 if (function_name == bi->function_name)
25161 return bi->label_name;
25165 /* INSN is either a function call or a millicode call. It may have an
25166 unconditional jump in its delay slot.
25168 CALL_DEST is the routine we are calling. */
25171 output_call (rtx insn, rtx *operands, int dest_operand_number,
25172 int cookie_operand_number)
25174 static char buf[256];
25175 if (darwin_emit_branch_islands
25176 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25177 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25180 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25182 if (no_previous_def (funname))
25184 rtx label_rtx = gen_label_rtx ();
25185 char *label_buf, temp_buf[256];
25186 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25187 CODE_LABEL_NUMBER (label_rtx));
25188 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25189 labelname = get_identifier (label_buf);
25190 add_compiler_branch_island (labelname, funname, insn_line (insn));
25193 labelname = get_prev_label (funname);
25195 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25196 instruction will reach 'foo', otherwise link as 'bl L42'".
25197 "L42" should be a 'branch island', that will do a far jump to
25198 'foo'. Branch islands are generated in
25199 macho_branch_islands(). */
25200 sprintf (buf, "jbsr %%z%d,%.246s",
25201 dest_operand_number, IDENTIFIER_POINTER (labelname));
25204 sprintf (buf, "bl %%z%d", dest_operand_number);
25208 /* Generate PIC and indirect symbol stubs. */
25211 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25213 unsigned int length;
25214 char *symbol_name, *lazy_ptr_name;
25215 char *local_label_0;
25216 static int label = 0;
25218 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25219 symb = (*targetm.strip_name_encoding) (symb);
25222 length = strlen (symb);
25223 symbol_name = XALLOCAVEC (char, length + 32);
25224 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25226 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25227 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25230 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25232 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25236 fprintf (file, "\t.align 5\n");
25238 fprintf (file, "%s:\n", stub);
25239 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25242 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25243 sprintf (local_label_0, "\"L%011d$spb\"", label);
25245 fprintf (file, "\tmflr r0\n");
25246 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25247 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25248 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25249 lazy_ptr_name, local_label_0);
25250 fprintf (file, "\tmtlr r0\n");
25251 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25252 (TARGET_64BIT ? "ldu" : "lwzu"),
25253 lazy_ptr_name, local_label_0);
25254 fprintf (file, "\tmtctr r12\n");
25255 fprintf (file, "\tbctr\n");
25259 fprintf (file, "\t.align 4\n");
25261 fprintf (file, "%s:\n", stub);
25262 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25264 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25265 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25266 (TARGET_64BIT ? "ldu" : "lwzu"),
25268 fprintf (file, "\tmtctr r12\n");
25269 fprintf (file, "\tbctr\n");
25272 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25273 fprintf (file, "%s:\n", lazy_ptr_name);
25274 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25275 fprintf (file, "%sdyld_stub_binding_helper\n",
25276 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25279 /* Legitimize PIC addresses. If the address is already
25280 position-independent, we return ORIG. Newly generated
25281 position-independent addresses go into a reg. This is REG if non
25282 zero, otherwise we allocate register(s) as necessary. */
25284 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25287 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25292 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25293 reg = gen_reg_rtx (Pmode);
25295 if (GET_CODE (orig) == CONST)
25299 if (GET_CODE (XEXP (orig, 0)) == PLUS
25300 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25303 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25305 /* Use a different reg for the intermediate value, as
25306 it will be marked UNCHANGING. */
25307 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25308 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25311 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25314 if (GET_CODE (offset) == CONST_INT)
25316 if (SMALL_INT (offset))
25317 return plus_constant (base, INTVAL (offset));
25318 else if (! reload_in_progress && ! reload_completed)
25319 offset = force_reg (Pmode, offset);
25322 rtx mem = force_const_mem (Pmode, orig);
25323 return machopic_legitimize_pic_address (mem, Pmode, reg);
25326 return gen_rtx_PLUS (Pmode, base, offset);
25329 /* Fall back on generic machopic code. */
25330 return machopic_legitimize_pic_address (orig, mode, reg);
25333 /* Output a .machine directive for the Darwin assembler, and call
25334 the generic start_file routine. */
25337 rs6000_darwin_file_start (void)
25339 static const struct
25345 { "ppc64", "ppc64", MASK_64BIT },
25346 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25347 { "power4", "ppc970", 0 },
25348 { "G5", "ppc970", 0 },
25349 { "7450", "ppc7450", 0 },
25350 { "7400", "ppc7400", MASK_ALTIVEC },
25351 { "G4", "ppc7400", 0 },
25352 { "750", "ppc750", 0 },
25353 { "740", "ppc750", 0 },
25354 { "G3", "ppc750", 0 },
25355 { "604e", "ppc604e", 0 },
25356 { "604", "ppc604", 0 },
25357 { "603e", "ppc603", 0 },
25358 { "603", "ppc603", 0 },
25359 { "601", "ppc601", 0 },
25360 { NULL, "ppc", 0 } };
25361 const char *cpu_id = "";
25364 rs6000_file_start ();
25365 darwin_file_start ();
25367 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25368 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25369 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25370 && rs6000_select[i].string[0] != '\0')
25371 cpu_id = rs6000_select[i].string;
25373 /* Look through the mapping array. Pick the first name that either
25374 matches the argument, has a bit set in IF_SET that is also set
25375 in the target flags, or has a NULL name. */
25378 while (mapping[i].arg != NULL
25379 && strcmp (mapping[i].arg, cpu_id) != 0
25380 && (mapping[i].if_set & target_flags) == 0)
25383 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25386 #endif /* TARGET_MACHO */
25390 rs6000_elf_reloc_rw_mask (void)
25394 else if (DEFAULT_ABI == ABI_AIX)
25400 /* Record an element in the table of global constructors. SYMBOL is
25401 a SYMBOL_REF of the function to be called; PRIORITY is a number
25402 between 0 and MAX_INIT_PRIORITY.
25404 This differs from default_named_section_asm_out_constructor in
25405 that we have special handling for -mrelocatable. */
25408 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25410 const char *section = ".ctors";
25413 if (priority != DEFAULT_INIT_PRIORITY)
25415 sprintf (buf, ".ctors.%.5u",
25416 /* Invert the numbering so the linker puts us in the proper
25417 order; constructors are run from right to left, and the
25418 linker sorts in increasing order. */
25419 MAX_INIT_PRIORITY - priority);
25423 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25424 assemble_align (POINTER_SIZE);
25426 if (TARGET_RELOCATABLE)
25428 fputs ("\t.long (", asm_out_file);
25429 output_addr_const (asm_out_file, symbol);
25430 fputs (")@fixup\n", asm_out_file);
25433 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25437 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25439 const char *section = ".dtors";
25442 if (priority != DEFAULT_INIT_PRIORITY)
25444 sprintf (buf, ".dtors.%.5u",
25445 /* Invert the numbering so the linker puts us in the proper
25446 order; constructors are run from right to left, and the
25447 linker sorts in increasing order. */
25448 MAX_INIT_PRIORITY - priority);
25452 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25453 assemble_align (POINTER_SIZE);
25455 if (TARGET_RELOCATABLE)
25457 fputs ("\t.long (", asm_out_file);
25458 output_addr_const (asm_out_file, symbol);
25459 fputs (")@fixup\n", asm_out_file);
25462 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25466 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25470 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25471 ASM_OUTPUT_LABEL (file, name);
25472 fputs (DOUBLE_INT_ASM_OP, file);
25473 rs6000_output_function_entry (file, name);
25474 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25477 fputs ("\t.size\t", file);
25478 assemble_name (file, name);
25479 fputs (",24\n\t.type\t.", file);
25480 assemble_name (file, name);
25481 fputs (",@function\n", file);
25482 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25484 fputs ("\t.globl\t.", file);
25485 assemble_name (file, name);
25490 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25491 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25492 rs6000_output_function_entry (file, name);
25493 fputs (":\n", file);
25497 if (TARGET_RELOCATABLE
25498 && !TARGET_SECURE_PLT
25499 && (get_pool_size () != 0 || crtl->profile)
25504 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25506 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25507 fprintf (file, "\t.long ");
25508 assemble_name (file, buf);
25510 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25511 assemble_name (file, buf);
25515 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25516 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25518 if (DEFAULT_ABI == ABI_AIX)
25520 const char *desc_name, *orig_name;
25522 orig_name = (*targetm.strip_name_encoding) (name);
25523 desc_name = orig_name;
25524 while (*desc_name == '.')
25527 if (TREE_PUBLIC (decl))
25528 fprintf (file, "\t.globl %s\n", desc_name);
25530 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25531 fprintf (file, "%s:\n", desc_name);
25532 fprintf (file, "\t.long %s\n", orig_name);
25533 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
25534 if (DEFAULT_ABI == ABI_AIX)
25535 fputs ("\t.long 0\n", file);
25536 fprintf (file, "\t.previous\n");
25538 ASM_OUTPUT_LABEL (file, name);
25542 rs6000_elf_end_indicate_exec_stack (void)
25545 file_end_indicate_exec_stack ();
25551 rs6000_xcoff_asm_output_anchor (rtx symbol)
25555 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
25556 SYMBOL_REF_BLOCK_OFFSET (symbol));
25557 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
25561 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
25563 fputs (GLOBAL_ASM_OP, stream);
25564 RS6000_OUTPUT_BASENAME (stream, name);
25565 putc ('\n', stream);
25568 /* A get_unnamed_decl callback, used for read-only sections. PTR
25569 points to the section string variable. */
25572 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
25574 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
25575 *(const char *const *) directive,
25576 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25579 /* Likewise for read-write sections. */
25582 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
25584 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
25585 *(const char *const *) directive,
25586 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
25589 /* A get_unnamed_section callback, used for switching to toc_section. */
25592 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25594 if (TARGET_MINIMAL_TOC)
25596 /* toc_section is always selected at least once from
25597 rs6000_xcoff_file_start, so this is guaranteed to
25598 always be defined once and only once in each file. */
25599 if (!toc_initialized)
25601 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
25602 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
25603 toc_initialized = 1;
25605 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
25606 (TARGET_32BIT ? "" : ",3"));
25609 fputs ("\t.toc\n", asm_out_file);
25612 /* Implement TARGET_ASM_INIT_SECTIONS. */
25615 rs6000_xcoff_asm_init_sections (void)
25617 read_only_data_section
25618 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25619 &xcoff_read_only_section_name);
25621 private_data_section
25622 = get_unnamed_section (SECTION_WRITE,
25623 rs6000_xcoff_output_readwrite_section_asm_op,
25624 &xcoff_private_data_section_name);
25626 read_only_private_data_section
25627 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
25628 &xcoff_private_data_section_name);
25631 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
25633 readonly_data_section = read_only_data_section;
25634 exception_section = data_section;
25638 rs6000_xcoff_reloc_rw_mask (void)
25644 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
25645 tree decl ATTRIBUTE_UNUSED)
25648 static const char * const suffix[3] = { "PR", "RO", "RW" };
25650 if (flags & SECTION_CODE)
25652 else if (flags & SECTION_WRITE)
25657 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
25658 (flags & SECTION_CODE) ? "." : "",
25659 name, suffix[smclass], flags & SECTION_ENTSIZE);
25663 rs6000_xcoff_select_section (tree decl, int reloc,
25664 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25666 if (decl_readonly_section (decl, reloc))
25668 if (TREE_PUBLIC (decl))
25669 return read_only_data_section;
25671 return read_only_private_data_section;
25675 if (TREE_PUBLIC (decl))
25676 return data_section;
25678 return private_data_section;
25683 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
25687 /* Use select_section for private and uninitialized data. */
25688 if (!TREE_PUBLIC (decl)
25689 || DECL_COMMON (decl)
25690 || DECL_INITIAL (decl) == NULL_TREE
25691 || DECL_INITIAL (decl) == error_mark_node
25692 || (flag_zero_initialized_in_bss
25693 && initializer_zerop (DECL_INITIAL (decl))))
25696 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
25697 name = (*targetm.strip_name_encoding) (name);
25698 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
25701 /* Select section for constant in constant pool.
25703 On RS/6000, all constants are in the private read-only data area.
25704 However, if this is being placed in the TOC it must be output as a
25708 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
25709 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
25711 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25712 return toc_section;
25714 return read_only_private_data_section;
25717 /* Remove any trailing [DS] or the like from the symbol name. */
25719 static const char *
25720 rs6000_xcoff_strip_name_encoding (const char *name)
25725 len = strlen (name);
25726 if (name[len - 1] == ']')
25727 return ggc_alloc_string (name, len - 4);
25732 /* Section attributes. AIX is always PIC. */
25734 static unsigned int
25735 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
25737 unsigned int align;
25738 unsigned int flags = default_section_type_flags (decl, name, reloc);
25740 /* Align to at least UNIT size. */
25741 if (flags & SECTION_CODE)
25742 align = MIN_UNITS_PER_WORD;
25744 /* Increase alignment of large objects if not already stricter. */
25745 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
25746 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
25747 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
25749 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
25752 /* Output at beginning of assembler file.
25754 Initialize the section names for the RS/6000 at this point.
25756 Specify filename, including full path, to assembler.
25758 We want to go into the TOC section so at least one .toc will be emitted.
25759 Also, in order to output proper .bs/.es pairs, we need at least one static
25760 [RW] section emitted.
25762 Finally, declare mcount when profiling to make the assembler happy. */
25765 rs6000_xcoff_file_start (void)
25767 rs6000_gen_section_name (&xcoff_bss_section_name,
25768 main_input_filename, ".bss_");
25769 rs6000_gen_section_name (&xcoff_private_data_section_name,
25770 main_input_filename, ".rw_");
25771 rs6000_gen_section_name (&xcoff_read_only_section_name,
25772 main_input_filename, ".ro_");
25774 fputs ("\t.file\t", asm_out_file);
25775 output_quoted_string (asm_out_file, main_input_filename);
25776 fputc ('\n', asm_out_file);
25777 if (write_symbols != NO_DEBUG)
25778 switch_to_section (private_data_section);
25779 switch_to_section (text_section);
25781 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
25782 rs6000_file_start ();
25785 /* Output at end of assembler file.
25786 On the RS/6000, referencing data should automatically pull in text. */
25789 rs6000_xcoff_file_end (void)
25791 switch_to_section (text_section);
25792 fputs ("_section_.text:\n", asm_out_file);
25793 switch_to_section (data_section);
25794 fputs (TARGET_32BIT
25795 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
25798 #endif /* TARGET_XCOFF */
25800 /* Compute a (partial) cost for rtx X. Return true if the complete
25801 cost has been computed, and false if subexpressions should be
25802 scanned. In either case, *TOTAL contains the cost result. */
25805 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
25808 enum machine_mode mode = GET_MODE (x);
25812 /* On the RS/6000, if it is valid in the insn, it is free. */
25814 if (((outer_code == SET
25815 || outer_code == PLUS
25816 || outer_code == MINUS)
25817 && (satisfies_constraint_I (x)
25818 || satisfies_constraint_L (x)))
25819 || (outer_code == AND
25820 && (satisfies_constraint_K (x)
25822 ? satisfies_constraint_L (x)
25823 : satisfies_constraint_J (x))
25824 || mask_operand (x, mode)
25826 && mask64_operand (x, DImode))))
25827 || ((outer_code == IOR || outer_code == XOR)
25828 && (satisfies_constraint_K (x)
25830 ? satisfies_constraint_L (x)
25831 : satisfies_constraint_J (x))))
25832 || outer_code == ASHIFT
25833 || outer_code == ASHIFTRT
25834 || outer_code == LSHIFTRT
25835 || outer_code == ROTATE
25836 || outer_code == ROTATERT
25837 || outer_code == ZERO_EXTRACT
25838 || (outer_code == MULT
25839 && satisfies_constraint_I (x))
25840 || ((outer_code == DIV || outer_code == UDIV
25841 || outer_code == MOD || outer_code == UMOD)
25842 && exact_log2 (INTVAL (x)) >= 0)
25843 || (outer_code == COMPARE
25844 && (satisfies_constraint_I (x)
25845 || satisfies_constraint_K (x)))
25846 || ((outer_code == EQ || outer_code == NE)
25847 && (satisfies_constraint_I (x)
25848 || satisfies_constraint_K (x)
25850 ? satisfies_constraint_L (x)
25851 : satisfies_constraint_J (x))))
25852 || (outer_code == GTU
25853 && satisfies_constraint_I (x))
25854 || (outer_code == LTU
25855 && satisfies_constraint_P (x)))
25860 else if ((outer_code == PLUS
25861 && reg_or_add_cint_operand (x, VOIDmode))
25862 || (outer_code == MINUS
25863 && reg_or_sub_cint_operand (x, VOIDmode))
25864 || ((outer_code == SET
25865 || outer_code == IOR
25866 || outer_code == XOR)
25868 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
25870 *total = COSTS_N_INSNS (1);
25876 if (mode == DImode && code == CONST_DOUBLE)
25878 if ((outer_code == IOR || outer_code == XOR)
25879 && CONST_DOUBLE_HIGH (x) == 0
25880 && (CONST_DOUBLE_LOW (x)
25881 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
25886 else if ((outer_code == AND && and64_2_operand (x, DImode))
25887 || ((outer_code == SET
25888 || outer_code == IOR
25889 || outer_code == XOR)
25890 && CONST_DOUBLE_HIGH (x) == 0))
25892 *total = COSTS_N_INSNS (1);
25902 /* When optimizing for size, MEM should be slightly more expensive
25903 than generating address, e.g., (plus (reg) (const)).
25904 L1 cache latency is about two instructions. */
25905 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
25913 if (mode == DFmode)
25915 if (GET_CODE (XEXP (x, 0)) == MULT)
25917 /* FNMA accounted in outer NEG. */
25918 if (outer_code == NEG)
25919 *total = rs6000_cost->dmul - rs6000_cost->fp;
25921 *total = rs6000_cost->dmul;
25924 *total = rs6000_cost->fp;
25926 else if (mode == SFmode)
25928 /* FNMA accounted in outer NEG. */
25929 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25932 *total = rs6000_cost->fp;
25935 *total = COSTS_N_INSNS (1);
25939 if (mode == DFmode)
25941 if (GET_CODE (XEXP (x, 0)) == MULT
25942 || GET_CODE (XEXP (x, 1)) == MULT)
25944 /* FNMA accounted in outer NEG. */
25945 if (outer_code == NEG)
25946 *total = rs6000_cost->dmul - rs6000_cost->fp;
25948 *total = rs6000_cost->dmul;
25951 *total = rs6000_cost->fp;
25953 else if (mode == SFmode)
25955 /* FNMA accounted in outer NEG. */
25956 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
25959 *total = rs6000_cost->fp;
25962 *total = COSTS_N_INSNS (1);
25966 if (GET_CODE (XEXP (x, 1)) == CONST_INT
25967 && satisfies_constraint_I (XEXP (x, 1)))
25969 if (INTVAL (XEXP (x, 1)) >= -256
25970 && INTVAL (XEXP (x, 1)) <= 255)
25971 *total = rs6000_cost->mulsi_const9;
25973 *total = rs6000_cost->mulsi_const;
25975 /* FMA accounted in outer PLUS/MINUS. */
25976 else if ((mode == DFmode || mode == SFmode)
25977 && (outer_code == PLUS || outer_code == MINUS))
25979 else if (mode == DFmode)
25980 *total = rs6000_cost->dmul;
25981 else if (mode == SFmode)
25982 *total = rs6000_cost->fp;
25983 else if (mode == DImode)
25984 *total = rs6000_cost->muldi;
25986 *total = rs6000_cost->mulsi;
25991 if (FLOAT_MODE_P (mode))
25993 *total = mode == DFmode ? rs6000_cost->ddiv
25994 : rs6000_cost->sdiv;
26001 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26002 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26004 if (code == DIV || code == MOD)
26006 *total = COSTS_N_INSNS (2);
26009 *total = COSTS_N_INSNS (1);
26013 if (GET_MODE (XEXP (x, 1)) == DImode)
26014 *total = rs6000_cost->divdi;
26016 *total = rs6000_cost->divsi;
26018 /* Add in shift and subtract for MOD. */
26019 if (code == MOD || code == UMOD)
26020 *total += COSTS_N_INSNS (2);
26025 *total = COSTS_N_INSNS (4);
26029 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26033 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26037 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26049 *total = COSTS_N_INSNS (1);
26057 /* Handle mul_highpart. */
26058 if (outer_code == TRUNCATE
26059 && GET_CODE (XEXP (x, 0)) == MULT)
26061 if (mode == DImode)
26062 *total = rs6000_cost->muldi;
26064 *total = rs6000_cost->mulsi;
26067 else if (outer_code == AND)
26070 *total = COSTS_N_INSNS (1);
26075 if (GET_CODE (XEXP (x, 0)) == MEM)
26078 *total = COSTS_N_INSNS (1);
26084 if (!FLOAT_MODE_P (mode))
26086 *total = COSTS_N_INSNS (1);
26092 case UNSIGNED_FLOAT:
26095 case FLOAT_TRUNCATE:
26096 *total = rs6000_cost->fp;
26100 if (mode == DFmode)
26103 *total = rs6000_cost->fp;
26107 switch (XINT (x, 1))
26110 *total = rs6000_cost->fp;
26122 *total = COSTS_N_INSNS (1);
26125 else if (FLOAT_MODE_P (mode)
26126 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26128 *total = rs6000_cost->fp;
26136 /* Carry bit requires mode == Pmode.
26137 NEG or PLUS already counted so only add one. */
26139 && (outer_code == NEG || outer_code == PLUS))
26141 *total = COSTS_N_INSNS (1);
26144 if (outer_code == SET)
26146 if (XEXP (x, 1) == const0_rtx)
26148 if (TARGET_ISEL && !TARGET_MFCRF)
26149 *total = COSTS_N_INSNS (8);
26151 *total = COSTS_N_INSNS (2);
26154 else if (mode == Pmode)
26156 *total = COSTS_N_INSNS (3);
26165 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26167 if (TARGET_ISEL && !TARGET_MFCRF)
26168 *total = COSTS_N_INSNS (8);
26170 *total = COSTS_N_INSNS (2);
26174 if (outer_code == COMPARE)
26188 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26191 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26194 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26197 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26198 "total = %d, speed = %s, x:\n",
26199 ret ? "complete" : "scan inner",
26200 GET_RTX_NAME (code),
26201 GET_RTX_NAME (outer_code),
26203 speed ? "true" : "false");
26210 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26213 rs6000_debug_address_cost (rtx x, bool speed)
26215 int ret = TARGET_ADDRESS_COST (x, speed);
26217 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26218 ret, speed ? "true" : "false");
26225 /* A C expression returning the cost of moving data from a register of class
26226 CLASS1 to one of CLASS2. */
26229 rs6000_register_move_cost (enum machine_mode mode,
26230 reg_class_t from, reg_class_t to)
26234 /* Moves from/to GENERAL_REGS. */
26235 if (reg_classes_intersect_p (to, GENERAL_REGS)
26236 || reg_classes_intersect_p (from, GENERAL_REGS))
26238 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26241 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26242 ret = (rs6000_memory_move_cost (mode, from, false)
26243 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26245 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26247 else if (from == CR_REGS)
26250 /* Power6 has slower LR/CTR moves so make them more expensive than
26251 memory in order to bias spills to memory .*/
26252 else if (rs6000_cpu == PROCESSOR_POWER6
26253 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26254 ret = 6 * hard_regno_nregs[0][mode];
26257 /* A move will cost one instruction per GPR moved. */
26258 ret = 2 * hard_regno_nregs[0][mode];
26261 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26262 else if (VECTOR_UNIT_VSX_P (mode)
26263 && reg_classes_intersect_p (to, VSX_REGS)
26264 && reg_classes_intersect_p (from, VSX_REGS))
26265 ret = 2 * hard_regno_nregs[32][mode];
26267 /* Moving between two similar registers is just one instruction. */
26268 else if (reg_classes_intersect_p (to, from))
26269 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26271 /* Everything else has to go through GENERAL_REGS. */
26273 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26274 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26276 if (TARGET_DEBUG_COST)
26278 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26279 ret, GET_MODE_NAME (mode), reg_class_names[from],
26280 reg_class_names[to]);
26285 /* A C expressions returning the cost of moving data of MODE from a register to
26289 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26290 bool in ATTRIBUTE_UNUSED)
26294 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26295 ret = 4 * hard_regno_nregs[0][mode];
26296 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26297 ret = 4 * hard_regno_nregs[32][mode];
26298 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26299 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26301 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26303 if (TARGET_DEBUG_COST)
26305 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26306 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26311 /* Returns a code for a target-specific builtin that implements
26312 reciprocal of the function, or NULL_TREE if not available. */
26315 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26316 bool sqrt ATTRIBUTE_UNUSED)
26318 if (optimize_insn_for_size_p ())
26324 case VSX_BUILTIN_XVSQRTDP:
26325 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26328 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26330 case VSX_BUILTIN_XVSQRTSP:
26331 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26334 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26343 case BUILT_IN_SQRT:
26344 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26347 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26349 case BUILT_IN_SQRTF:
26350 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26353 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26360 /* Load up a constant. If the mode is a vector mode, splat the value across
26361 all of the vector elements. */
26364 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26368 if (mode == SFmode || mode == DFmode)
26370 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26371 reg = force_reg (mode, d);
26373 else if (mode == V4SFmode)
26375 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26376 rtvec v = gen_rtvec (4, d, d, d, d);
26377 reg = gen_reg_rtx (mode);
26378 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26380 else if (mode == V2DFmode)
26382 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26383 rtvec v = gen_rtvec (2, d, d);
26384 reg = gen_reg_rtx (mode);
26385 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26388 gcc_unreachable ();
26393 /* Generate a FMADD instruction:
26394 dst = (m1 * m2) + a
26396 generating different RTL based on the fused multiply/add switch. */
26399 rs6000_emit_madd (rtx dst, rtx m1, rtx m2, rtx a)
26401 enum machine_mode mode = GET_MODE (dst);
26403 if (!TARGET_FUSED_MADD)
26405 /* For the simple ops, use the generator function, rather than assuming
26406 that the RTL is standard. */
26407 enum insn_code mcode = optab_handler (smul_optab, mode);
26408 enum insn_code acode = optab_handler (add_optab, mode);
26409 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26410 gen_2arg_fn_t gen_add = (gen_2arg_fn_t) GEN_FCN (acode);
26411 rtx mreg = gen_reg_rtx (mode);
26413 gcc_assert (mcode != CODE_FOR_nothing && acode != CODE_FOR_nothing);
26414 emit_insn (gen_mul (mreg, m1, m2));
26415 emit_insn (gen_add (dst, mreg, a));
26419 emit_insn (gen_rtx_SET (VOIDmode, dst,
26420 gen_rtx_PLUS (mode,
26421 gen_rtx_MULT (mode, m1, m2),
26425 /* Generate a FMSUB instruction:
26426 dst = (m1 * m2) - a
26428 generating different RTL based on the fused multiply/add switch. */
26431 rs6000_emit_msub (rtx dst, rtx m1, rtx m2, rtx a)
26433 enum machine_mode mode = GET_MODE (dst);
26435 if (!TARGET_FUSED_MADD
26436 || (mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (V4SFmode)))
26438 /* For the simple ops, use the generator function, rather than assuming
26439 that the RTL is standard. */
26440 enum insn_code mcode = optab_handler (smul_optab, mode);
26441 enum insn_code scode = optab_handler (add_optab, mode);
26442 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26443 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26444 rtx mreg = gen_reg_rtx (mode);
26446 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26447 emit_insn (gen_mul (mreg, m1, m2));
26448 emit_insn (gen_sub (dst, mreg, a));
26452 emit_insn (gen_rtx_SET (VOIDmode, dst,
26453 gen_rtx_MINUS (mode,
26454 gen_rtx_MULT (mode, m1, m2),
26458 /* Generate a FNMSUB instruction:
26459 dst = - ((m1 * m2) - a)
26461 Which is equivalent to (except in the prescence of -0.0):
26462 dst = a - (m1 * m2)
26464 generating different RTL based on the fast-math and fused multiply/add
26468 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26470 enum machine_mode mode = GET_MODE (dst);
26472 if (!TARGET_FUSED_MADD)
26474 /* For the simple ops, use the generator function, rather than assuming
26475 that the RTL is standard. */
26476 enum insn_code mcode = optab_handler (smul_optab, mode);
26477 enum insn_code scode = optab_handler (sub_optab, mode);
26478 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (mcode);
26479 gen_2arg_fn_t gen_sub = (gen_2arg_fn_t) GEN_FCN (scode);
26480 rtx mreg = gen_reg_rtx (mode);
26482 gcc_assert (mcode != CODE_FOR_nothing && scode != CODE_FOR_nothing);
26483 emit_insn (gen_mul (mreg, m1, m2));
26484 emit_insn (gen_sub (dst, a, mreg));
26489 rtx m = gen_rtx_MULT (mode, m1, m2);
26491 if (!HONOR_SIGNED_ZEROS (mode))
26492 emit_insn (gen_rtx_SET (VOIDmode, dst, gen_rtx_MINUS (mode, a, m)));
26495 emit_insn (gen_rtx_SET (VOIDmode, dst,
26497 gen_rtx_MINUS (mode, m, a))));
26501 /* Newton-Raphson approximation of floating point divide with just 2 passes
26502 (either single precision floating point, or newer machines with higher
26503 accuracy estimates). Support both scalar and vector divide. Assumes no
26504 trapping math and finite arguments. */
26507 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26509 enum machine_mode mode = GET_MODE (dst);
26510 rtx x0, e0, e1, y1, u0, v0;
26511 enum insn_code code = optab_handler (smul_optab, mode);
26512 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26513 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26515 gcc_assert (code != CODE_FOR_nothing);
26517 /* x0 = 1./d estimate */
26518 x0 = gen_reg_rtx (mode);
26519 emit_insn (gen_rtx_SET (VOIDmode, x0,
26520 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26523 e0 = gen_reg_rtx (mode);
26524 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26526 e1 = gen_reg_rtx (mode);
26527 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26529 y1 = gen_reg_rtx (mode);
26530 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26532 u0 = gen_reg_rtx (mode);
26533 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26535 v0 = gen_reg_rtx (mode);
26536 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26538 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26541 /* Newton-Raphson approximation of floating point divide that has a low
26542 precision estimate. Assumes no trapping math and finite arguments. */
26545 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26547 enum machine_mode mode = GET_MODE (dst);
26548 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26549 enum insn_code code = optab_handler (smul_optab, mode);
26550 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26552 gcc_assert (code != CODE_FOR_nothing);
26554 one = rs6000_load_constant_and_splat (mode, dconst1);
26556 /* x0 = 1./d estimate */
26557 x0 = gen_reg_rtx (mode);
26558 emit_insn (gen_rtx_SET (VOIDmode, x0,
26559 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26562 e0 = gen_reg_rtx (mode);
26563 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26565 y1 = gen_reg_rtx (mode);
26566 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26568 e1 = gen_reg_rtx (mode);
26569 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26571 y2 = gen_reg_rtx (mode);
26572 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26574 e2 = gen_reg_rtx (mode);
26575 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26577 y3 = gen_reg_rtx (mode);
26578 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26580 u0 = gen_reg_rtx (mode);
26581 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26583 v0 = gen_reg_rtx (mode);
26584 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26586 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26589 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26590 add a reg_note saying that this was a division. Support both scalar and
26591 vector divide. Assumes no trapping math and finite arguments. */
26594 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
26596 enum machine_mode mode = GET_MODE (dst);
26598 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
26599 rs6000_emit_swdiv_high_precision (dst, n, d);
26601 rs6000_emit_swdiv_low_precision (dst, n, d);
26604 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
26607 /* Newton-Raphson approximation of single/double-precision floating point
26608 rsqrt. Assumes no trapping math and finite arguments. */
26611 rs6000_emit_swrsqrt (rtx dst, rtx src)
26613 enum machine_mode mode = GET_MODE (src);
26614 rtx x0 = gen_reg_rtx (mode);
26615 rtx y = gen_reg_rtx (mode);
26616 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
26617 REAL_VALUE_TYPE dconst3_2;
26620 enum insn_code code = optab_handler (smul_optab, mode);
26621 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26623 gcc_assert (code != CODE_FOR_nothing);
26625 /* Load up the constant 1.5 either as a scalar, or as a vector. */
26626 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
26627 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
26629 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
26631 /* x0 = rsqrt estimate */
26632 emit_insn (gen_rtx_SET (VOIDmode, x0,
26633 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
26636 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
26637 rs6000_emit_msub (y, src, halfthree, src);
26639 for (i = 0; i < passes; i++)
26641 rtx x1 = gen_reg_rtx (mode);
26642 rtx u = gen_reg_rtx (mode);
26643 rtx v = gen_reg_rtx (mode);
26645 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
26646 emit_insn (gen_mul (u, x0, x0));
26647 rs6000_emit_nmsub (v, y, u, halfthree);
26648 emit_insn (gen_mul (x1, x0, v));
26652 emit_move_insn (dst, x0);
26656 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
26657 (Power7) targets. DST is the target, and SRC is the argument operand. */
26660 rs6000_emit_popcount (rtx dst, rtx src)
26662 enum machine_mode mode = GET_MODE (dst);
26665 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
26666 if (TARGET_POPCNTD)
26668 if (mode == SImode)
26669 emit_insn (gen_popcntdsi2 (dst, src));
26671 emit_insn (gen_popcntddi2 (dst, src));
26675 tmp1 = gen_reg_rtx (mode);
26677 if (mode == SImode)
26679 emit_insn (gen_popcntbsi2 (tmp1, src));
26680 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
26682 tmp2 = force_reg (SImode, tmp2);
26683 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
26687 emit_insn (gen_popcntbdi2 (tmp1, src));
26688 tmp2 = expand_mult (DImode, tmp1,
26689 GEN_INT ((HOST_WIDE_INT)
26690 0x01010101 << 32 | 0x01010101),
26692 tmp2 = force_reg (DImode, tmp2);
26693 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
26698 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
26699 target, and SRC is the argument operand. */
26702 rs6000_emit_parity (rtx dst, rtx src)
26704 enum machine_mode mode = GET_MODE (dst);
26707 tmp = gen_reg_rtx (mode);
26709 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
26712 if (mode == SImode)
26714 emit_insn (gen_popcntbsi2 (tmp, src));
26715 emit_insn (gen_paritysi2_cmpb (dst, tmp));
26719 emit_insn (gen_popcntbdi2 (tmp, src));
26720 emit_insn (gen_paritydi2_cmpb (dst, tmp));
26725 if (mode == SImode)
26727 /* Is mult+shift >= shift+xor+shift+xor? */
26728 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
26730 rtx tmp1, tmp2, tmp3, tmp4;
26732 tmp1 = gen_reg_rtx (SImode);
26733 emit_insn (gen_popcntbsi2 (tmp1, src));
26735 tmp2 = gen_reg_rtx (SImode);
26736 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
26737 tmp3 = gen_reg_rtx (SImode);
26738 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
26740 tmp4 = gen_reg_rtx (SImode);
26741 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
26742 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
26745 rs6000_emit_popcount (tmp, src);
26746 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
26750 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
26751 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
26753 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
26755 tmp1 = gen_reg_rtx (DImode);
26756 emit_insn (gen_popcntbdi2 (tmp1, src));
26758 tmp2 = gen_reg_rtx (DImode);
26759 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
26760 tmp3 = gen_reg_rtx (DImode);
26761 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
26763 tmp4 = gen_reg_rtx (DImode);
26764 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
26765 tmp5 = gen_reg_rtx (DImode);
26766 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
26768 tmp6 = gen_reg_rtx (DImode);
26769 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
26770 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
26773 rs6000_emit_popcount (tmp, src);
26774 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
26778 /* Return an RTX representing where to find the function value of a
26779 function returning MODE. */
26781 rs6000_complex_function_value (enum machine_mode mode)
26783 unsigned int regno;
26785 enum machine_mode inner = GET_MODE_INNER (mode);
26786 unsigned int inner_bytes = GET_MODE_SIZE (inner);
26788 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26789 regno = FP_ARG_RETURN;
26792 regno = GP_ARG_RETURN;
26794 /* 32-bit is OK since it'll go in r3/r4. */
26795 if (TARGET_32BIT && inner_bytes >= 4)
26796 return gen_rtx_REG (mode, regno);
26799 if (inner_bytes >= 8)
26800 return gen_rtx_REG (mode, regno);
26802 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
26804 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
26805 GEN_INT (inner_bytes));
26806 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
26809 /* Target hook for TARGET_FUNCTION_VALUE.
26811 On the SPE, both FPs and vectors are returned in r3.
26813 On RS/6000 an integer value is in r3 and a floating-point value is in
26814 fp1, unless -msoft-float. */
26817 rs6000_function_value (const_tree valtype,
26818 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
26819 bool outgoing ATTRIBUTE_UNUSED)
26821 enum machine_mode mode;
26822 unsigned int regno;
26824 /* Special handling for structs in darwin64. */
26826 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
26828 CUMULATIVE_ARGS valcum;
26832 valcum.fregno = FP_ARG_MIN_REG;
26833 valcum.vregno = ALTIVEC_ARG_MIN_REG;
26834 /* Do a trial code generation as if this were going to be passed as
26835 an argument; if any part goes in memory, we return NULL. */
26836 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, true);
26839 /* Otherwise fall through to standard ABI rules. */
26842 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
26844 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26845 return gen_rtx_PARALLEL (DImode,
26847 gen_rtx_EXPR_LIST (VOIDmode,
26848 gen_rtx_REG (SImode, GP_ARG_RETURN),
26850 gen_rtx_EXPR_LIST (VOIDmode,
26851 gen_rtx_REG (SImode,
26852 GP_ARG_RETURN + 1),
26855 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
26857 return gen_rtx_PARALLEL (DCmode,
26859 gen_rtx_EXPR_LIST (VOIDmode,
26860 gen_rtx_REG (SImode, GP_ARG_RETURN),
26862 gen_rtx_EXPR_LIST (VOIDmode,
26863 gen_rtx_REG (SImode,
26864 GP_ARG_RETURN + 1),
26866 gen_rtx_EXPR_LIST (VOIDmode,
26867 gen_rtx_REG (SImode,
26868 GP_ARG_RETURN + 2),
26870 gen_rtx_EXPR_LIST (VOIDmode,
26871 gen_rtx_REG (SImode,
26872 GP_ARG_RETURN + 3),
26876 mode = TYPE_MODE (valtype);
26877 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
26878 || POINTER_TYPE_P (valtype))
26879 mode = TARGET_32BIT ? SImode : DImode;
26881 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26882 /* _Decimal128 must use an even/odd register pair. */
26883 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26884 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
26885 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
26886 regno = FP_ARG_RETURN;
26887 else if (TREE_CODE (valtype) == COMPLEX_TYPE
26888 && targetm.calls.split_complex_arg)
26889 return rs6000_complex_function_value (mode);
26890 else if (TREE_CODE (valtype) == VECTOR_TYPE
26891 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
26892 && ALTIVEC_VECTOR_MODE (mode))
26893 regno = ALTIVEC_ARG_RETURN;
26894 else if (TREE_CODE (valtype) == VECTOR_TYPE
26895 && TARGET_VSX && TARGET_ALTIVEC_ABI
26896 && VSX_VECTOR_MODE (mode))
26897 regno = ALTIVEC_ARG_RETURN;
26898 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26899 && (mode == DFmode || mode == DCmode
26900 || mode == TFmode || mode == TCmode))
26901 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26903 regno = GP_ARG_RETURN;
26905 return gen_rtx_REG (mode, regno);
26908 /* Define how to find the value returned by a library function
26909 assuming the value has mode MODE. */
26911 rs6000_libcall_value (enum machine_mode mode)
26913 unsigned int regno;
26915 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
26917 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
26918 return gen_rtx_PARALLEL (DImode,
26920 gen_rtx_EXPR_LIST (VOIDmode,
26921 gen_rtx_REG (SImode, GP_ARG_RETURN),
26923 gen_rtx_EXPR_LIST (VOIDmode,
26924 gen_rtx_REG (SImode,
26925 GP_ARG_RETURN + 1),
26929 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
26930 /* _Decimal128 must use an even/odd register pair. */
26931 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
26932 else if (SCALAR_FLOAT_MODE_P (mode)
26933 && TARGET_HARD_FLOAT && TARGET_FPRS
26934 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
26935 regno = FP_ARG_RETURN;
26936 else if (ALTIVEC_VECTOR_MODE (mode)
26937 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
26938 regno = ALTIVEC_ARG_RETURN;
26939 else if (VSX_VECTOR_MODE (mode)
26940 && TARGET_VSX && TARGET_ALTIVEC_ABI)
26941 regno = ALTIVEC_ARG_RETURN;
26942 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
26943 return rs6000_complex_function_value (mode);
26944 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
26945 && (mode == DFmode || mode == DCmode
26946 || mode == TFmode || mode == TCmode))
26947 return spe_build_register_parallel (mode, GP_ARG_RETURN);
26949 regno = GP_ARG_RETURN;
26951 return gen_rtx_REG (mode, regno);
26955 /* Given FROM and TO register numbers, say whether this elimination is allowed.
26956 Frame pointer elimination is automatically handled.
26958 For the RS/6000, if frame pointer elimination is being done, we would like
26959 to convert ap into fp, not sp.
26961 We need r30 if -mminimal-toc was specified, and there are constant pool
26965 rs6000_can_eliminate (const int from, const int to)
26967 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
26968 ? ! frame_pointer_needed
26969 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
26970 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
26974 /* Define the offset between two registers, FROM to be eliminated and its
26975 replacement TO, at the start of a routine. */
26977 rs6000_initial_elimination_offset (int from, int to)
26979 rs6000_stack_t *info = rs6000_stack_info ();
26980 HOST_WIDE_INT offset;
26982 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26983 offset = info->push_p ? 0 : -info->total_size;
26984 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26986 offset = info->push_p ? 0 : -info->total_size;
26987 if (FRAME_GROWS_DOWNWARD)
26988 offset += info->fixed_size + info->vars_size + info->parm_size;
26990 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26991 offset = FRAME_GROWS_DOWNWARD
26992 ? info->fixed_size + info->vars_size + info->parm_size
26994 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
26995 offset = info->total_size;
26996 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
26997 offset = info->push_p ? info->total_size : 0;
26998 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27001 gcc_unreachable ();
27007 rs6000_dwarf_register_span (rtx reg)
27011 unsigned regno = REGNO (reg);
27012 enum machine_mode mode = GET_MODE (reg);
27016 && (SPE_VECTOR_MODE (GET_MODE (reg))
27017 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27018 && mode != SFmode && mode != SDmode && mode != SCmode)))
27023 regno = REGNO (reg);
27025 /* The duality of the SPE register size wreaks all kinds of havoc.
27026 This is a way of distinguishing r0 in 32-bits from r0 in
27028 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27029 gcc_assert (words <= 4);
27030 for (i = 0; i < words; i++, regno++)
27032 if (BYTES_BIG_ENDIAN)
27034 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27035 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27039 parts[2 * i] = gen_rtx_REG (SImode, regno);
27040 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27044 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27047 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27050 rs6000_init_dwarf_reg_sizes_extra (tree address)
27055 enum machine_mode mode = TYPE_MODE (char_type_node);
27056 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27057 rtx mem = gen_rtx_MEM (BLKmode, addr);
27058 rtx value = gen_int_mode (4, mode);
27060 for (i = 1201; i < 1232; i++)
27062 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27063 HOST_WIDE_INT offset
27064 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27066 emit_move_insn (adjust_address (mem, mode, offset), value);
27071 /* Map internal gcc register numbers to DWARF2 register numbers. */
27074 rs6000_dbx_register_number (unsigned int regno)
27076 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27078 if (regno == MQ_REGNO)
27080 if (regno == LR_REGNO)
27082 if (regno == CTR_REGNO)
27084 if (CR_REGNO_P (regno))
27085 return regno - CR0_REGNO + 86;
27086 if (regno == CA_REGNO)
27087 return 101; /* XER */
27088 if (ALTIVEC_REGNO_P (regno))
27089 return regno - FIRST_ALTIVEC_REGNO + 1124;
27090 if (regno == VRSAVE_REGNO)
27092 if (regno == VSCR_REGNO)
27094 if (regno == SPE_ACC_REGNO)
27096 if (regno == SPEFSCR_REGNO)
27098 /* SPE high reg number. We get these values of regno from
27099 rs6000_dwarf_register_span. */
27100 gcc_assert (regno >= 1200 && regno < 1232);
27104 /* target hook eh_return_filter_mode */
27105 static enum machine_mode
27106 rs6000_eh_return_filter_mode (void)
27108 return TARGET_32BIT ? SImode : word_mode;
27111 /* Target hook for scalar_mode_supported_p. */
27113 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27115 if (DECIMAL_FLOAT_MODE_P (mode))
27116 return default_decimal_float_supported_p ();
27118 return default_scalar_mode_supported_p (mode);
27121 /* Target hook for vector_mode_supported_p. */
27123 rs6000_vector_mode_supported_p (enum machine_mode mode)
27126 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27129 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27132 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27139 /* Target hook for invalid_arg_for_unprototyped_fn. */
27140 static const char *
27141 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27143 return (!rs6000_darwin64_abi
27145 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27146 && (funcdecl == NULL_TREE
27147 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27148 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27149 ? N_("AltiVec argument passed to unprototyped function")
27153 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27154 setup by using __stack_chk_fail_local hidden function instead of
27155 calling __stack_chk_fail directly. Otherwise it is better to call
27156 __stack_chk_fail directly. */
27159 rs6000_stack_protect_fail (void)
27161 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27162 ? default_hidden_stack_protect_fail ()
27163 : default_external_stack_protect_fail ();
27167 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27168 int num_operands ATTRIBUTE_UNUSED)
27170 if (rs6000_warn_cell_microcode)
27173 int insn_code_number = recog_memoized (insn);
27174 location_t location = locator_location (INSN_LOCATOR (insn));
27176 /* Punt on insns we cannot recognize. */
27177 if (insn_code_number < 0)
27180 temp = get_insn_template (insn_code_number, insn);
27182 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27183 warning_at (location, OPT_mwarn_cell_microcode,
27184 "emitting microcode insn %s\t[%s] #%d",
27185 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27186 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27187 warning_at (location, OPT_mwarn_cell_microcode,
27188 "emitting conditional microcode insn %s\t[%s] #%d",
27189 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27194 /* Allocate a stack temp and fixup the address so it meets the particular
27195 memory requirements (either offetable or REG+REG addressing). */
27198 rs6000_allocate_stack_temp (enum machine_mode mode,
27199 bool offsettable_p,
27202 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
27203 rtx addr = XEXP (stack, 0);
27204 int strict_p = (reload_in_progress || reload_completed);
27206 if (!legitimate_indirect_address_p (addr, strict_p))
27209 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
27210 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27212 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
27213 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
27219 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
27220 to such a form to deal with memory reference instructions like STFIWX that
27221 only take reg+reg addressing. */
27224 rs6000_address_for_fpconvert (rtx x)
27226 int strict_p = (reload_in_progress || reload_completed);
27229 gcc_assert (MEM_P (x));
27230 addr = XEXP (x, 0);
27231 if (! legitimate_indirect_address_p (addr, strict_p)
27232 && ! legitimate_indexed_address_p (addr, strict_p))
27234 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
27236 rtx reg = XEXP (addr, 0);
27237 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
27238 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
27239 gcc_assert (REG_P (reg));
27240 emit_insn (gen_add3_insn (reg, reg, size_rtx));
27243 else if (GET_CODE (addr) == PRE_MODIFY)
27245 rtx reg = XEXP (addr, 0);
27246 rtx expr = XEXP (addr, 1);
27247 gcc_assert (REG_P (reg));
27248 gcc_assert (GET_CODE (expr) == PLUS);
27249 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
27253 x = replace_equiv_address (x, copy_addr_to_reg (addr));
27259 #include "gt-rs6000.h"