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, 2011
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"
63 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
66 #include "gstab.h" /* for N_SLINE */
69 #ifndef TARGET_NO_PROTOTYPE
70 #define TARGET_NO_PROTOTYPE 0
73 #define min(A,B) ((A) < (B) ? (A) : (B))
74 #define max(A,B) ((A) > (B) ? (A) : (B))
76 /* Structure used to define the rs6000 stack */
77 typedef struct rs6000_stack {
78 int reload_completed; /* stack info won't change from here on */
79 int first_gp_reg_save; /* first callee saved GP register used */
80 int first_fp_reg_save; /* first callee saved FP register used */
81 int first_altivec_reg_save; /* first callee saved AltiVec register used */
82 int lr_save_p; /* true if the link reg needs to be saved */
83 int cr_save_p; /* true if the CR reg needs to be saved */
84 unsigned int vrsave_mask; /* mask of vec registers to save */
85 int push_p; /* true if we need to allocate stack space */
86 int calls_p; /* true if the function makes any calls */
87 int world_save_p; /* true if we're saving *everything*:
88 r13-r31, cr, f14-f31, vrsave, v20-v31 */
89 enum rs6000_abi abi; /* which ABI to use */
90 int gp_save_offset; /* offset to save GP regs from initial SP */
91 int fp_save_offset; /* offset to save FP regs from initial SP */
92 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
93 int lr_save_offset; /* offset to save LR from initial SP */
94 int cr_save_offset; /* offset to save CR from initial SP */
95 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
96 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
97 int varargs_save_offset; /* offset to save the varargs registers */
98 int ehrd_offset; /* offset to EH return data */
99 int reg_size; /* register size (4 or 8) */
100 HOST_WIDE_INT vars_size; /* variable save area size */
101 int parm_size; /* outgoing parameter size */
102 int save_size; /* save area size */
103 int fixed_size; /* fixed size of stack frame */
104 int gp_size; /* size of saved GP registers */
105 int fp_size; /* size of saved FP registers */
106 int altivec_size; /* size of saved AltiVec registers */
107 int cr_size; /* size to hold CR if not in save_size */
108 int vrsave_size; /* size to hold VRSAVE if not in save_size */
109 int altivec_padding_size; /* size of altivec alignment padding if
111 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
112 int spe_padding_size;
113 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
114 int spe_64bit_regs_used;
118 /* A C structure for machine-specific, per-function data.
119 This is added to the cfun structure. */
120 typedef struct GTY(()) machine_function
122 /* Some local-dynamic symbol. */
123 const char *some_ld_name;
124 /* Whether the instruction chain has been scanned already. */
125 int insn_chain_scanned_p;
126 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
127 int ra_needs_full_frame;
128 /* Flags if __builtin_return_address (0) was used. */
130 /* Cache lr_save_p after expansion of builtin_eh_return. */
132 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
133 varargs save area. */
134 HOST_WIDE_INT varargs_save_offset;
135 /* Temporary stack slot to use for SDmode copies. This slot is
136 64-bits wide and is allocated early enough so that the offset
137 does not overflow the 16-bit load/store offset field. */
138 rtx sdmode_stack_slot;
141 /* Target cpu type */
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 /* String variables to hold the various options. */
152 static const char *rs6000_sched_insert_nops_str;
153 static const char *rs6000_sched_costly_dep_str;
154 static const char *rs6000_recip_name;
157 static const char *rs6000_abi_name;
158 static const char *rs6000_sdata_name;
161 /* Support targetm.vectorize.builtin_mask_for_load. */
162 static GTY(()) tree altivec_builtin_mask_for_load;
164 /* Set to nonzero once AIX common-mode calls have been defined. */
165 static GTY(()) int common_mode_defined;
167 /* Label number of label created for -mrelocatable, to call to so we can
168 get the address of the GOT section */
169 static int rs6000_pic_labelno;
172 /* Counter for labels which are to be placed in .fixup. */
173 int fixuplabelno = 0;
176 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
179 /* Specify the machine mode that pointers have. After generation of rtl, the
180 compiler makes no further distinction between pointers and any other objects
181 of this machine mode. The type is unsigned since not all things that
182 include rs6000.h also include machmode.h. */
183 unsigned rs6000_pmode;
185 /* Width in bits of a pointer. */
186 unsigned rs6000_pointer_size;
188 #ifdef HAVE_AS_GNU_ATTRIBUTE
189 /* Flag whether floating point values have been passed/returned. */
190 static bool rs6000_passes_float;
191 /* Flag whether vector values have been passed/returned. */
192 static bool rs6000_passes_vector;
193 /* Flag whether small (<= 8 byte) structures have been returned. */
194 static bool rs6000_returns_struct;
197 /* Value is TRUE if register/mode pair is acceptable. */
198 bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
200 /* Maximum number of registers needed for a given register class and mode. */
201 unsigned char rs6000_class_max_nregs[NUM_MACHINE_MODES][LIM_REG_CLASSES];
203 /* How many registers are needed for a given register and mode. */
204 unsigned char rs6000_hard_regno_nregs[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
206 /* Map register number to register class. */
207 enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
209 /* Reload functions based on the type and the vector unit. */
210 static enum insn_code rs6000_vector_reload[NUM_MACHINE_MODES][2];
212 /* Built in types. */
213 tree rs6000_builtin_types[RS6000_BTI_MAX];
214 tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
216 /* Flag to say the TOC is initialized */
218 char toc_label_name[10];
220 /* Cached value of rs6000_variable_issue. This is cached in
221 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
222 static short cached_can_issue_more;
224 static GTY(()) section *read_only_data_section;
225 static GTY(()) section *private_data_section;
226 static GTY(()) section *read_only_private_data_section;
227 static GTY(()) section *sdata2_section;
228 static GTY(()) section *toc_section;
230 /* True for any options that were explicitly set. */
232 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
233 bool alignment; /* True if -malign- was used. */
234 bool spe_abi; /* True if -mabi=spe/no-spe was used. */
235 bool altivec_abi; /* True if -mabi=altivec/no-altivec used. */
236 bool spe; /* True if -mspe= was used. */
237 bool float_gprs; /* True if -mfloat-gprs= was used. */
238 bool long_double; /* True if -mlong-double- was used. */
239 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
240 bool vrsave; /* True if -mvrsave was used. */
241 bool cmodel; /* True if -mcmodel was used. */
242 } rs6000_explicit_options;
244 struct builtin_description
246 /* mask is not const because we're going to alter it below. This
247 nonsense will go away when we rewrite the -march infrastructure
248 to give us more target flag bits. */
250 const enum insn_code icode;
251 const char *const name;
252 const enum rs6000_builtins code;
255 /* Describe the vector unit used for modes. */
256 enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
257 enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
259 /* Register classes for various constraints that are based on the target
261 enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
263 /* Describe the alignment of a vector. */
264 int rs6000_vector_align[NUM_MACHINE_MODES];
266 /* Map selected modes to types for builtins. */
267 static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
269 /* What modes to automatically generate reciprocal divide estimate (fre) and
270 reciprocal sqrt (frsqrte) for. */
271 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
273 /* Masks to determine which reciprocal esitmate instructions to generate
275 enum rs6000_recip_mask {
276 RECIP_SF_DIV = 0x001, /* Use divide estimate */
277 RECIP_DF_DIV = 0x002,
278 RECIP_V4SF_DIV = 0x004,
279 RECIP_V2DF_DIV = 0x008,
281 RECIP_SF_RSQRT = 0x010, /* Use reciprocal sqrt estimate. */
282 RECIP_DF_RSQRT = 0x020,
283 RECIP_V4SF_RSQRT = 0x040,
284 RECIP_V2DF_RSQRT = 0x080,
286 /* Various combination of flags for -mrecip=xxx. */
288 RECIP_ALL = (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
289 | RECIP_V2DF_DIV | RECIP_SF_RSQRT | RECIP_DF_RSQRT
290 | RECIP_V4SF_RSQRT | RECIP_V2DF_RSQRT),
292 RECIP_HIGH_PRECISION = RECIP_ALL,
294 /* On low precision machines like the power5, don't enable double precision
295 reciprocal square root estimate, since it isn't accurate enough. */
296 RECIP_LOW_PRECISION = (RECIP_ALL & ~(RECIP_DF_RSQRT | RECIP_V2DF_RSQRT))
299 /* -mrecip options. */
302 const char *string; /* option name */
303 unsigned int mask; /* mask bits to set */
304 } recip_options[] = {
305 { "all", RECIP_ALL },
306 { "none", RECIP_NONE },
307 { "div", (RECIP_SF_DIV | RECIP_DF_DIV | RECIP_V4SF_DIV
309 { "divf", (RECIP_SF_DIV | RECIP_V4SF_DIV) },
310 { "divd", (RECIP_DF_DIV | RECIP_V2DF_DIV) },
311 { "rsqrt", (RECIP_SF_RSQRT | RECIP_DF_RSQRT | RECIP_V4SF_RSQRT
312 | RECIP_V2DF_RSQRT) },
313 { "rsqrtf", (RECIP_SF_RSQRT | RECIP_V4SF_RSQRT) },
314 { "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
317 /* 2 argument gen function typedef. */
318 typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
321 /* Target cpu costs. */
323 struct processor_costs {
324 const int mulsi; /* cost of SImode multiplication. */
325 const int mulsi_const; /* cost of SImode multiplication by constant. */
326 const int mulsi_const9; /* cost of SImode mult by short constant. */
327 const int muldi; /* cost of DImode multiplication. */
328 const int divsi; /* cost of SImode division. */
329 const int divdi; /* cost of DImode division. */
330 const int fp; /* cost of simple SFmode and DFmode insns. */
331 const int dmul; /* cost of DFmode multiplication (and fmadd). */
332 const int sdiv; /* cost of SFmode division (fdivs). */
333 const int ddiv; /* cost of DFmode division (fdiv). */
334 const int cache_line_size; /* cache line size in bytes. */
335 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
336 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
337 const int simultaneous_prefetches; /* number of parallel prefetch
341 const struct processor_costs *rs6000_cost;
343 /* Processor costs (relative to an add) */
345 /* Instruction size costs on 32bit processors. */
347 struct processor_costs size32_cost = {
348 COSTS_N_INSNS (1), /* mulsi */
349 COSTS_N_INSNS (1), /* mulsi_const */
350 COSTS_N_INSNS (1), /* mulsi_const9 */
351 COSTS_N_INSNS (1), /* muldi */
352 COSTS_N_INSNS (1), /* divsi */
353 COSTS_N_INSNS (1), /* divdi */
354 COSTS_N_INSNS (1), /* fp */
355 COSTS_N_INSNS (1), /* dmul */
356 COSTS_N_INSNS (1), /* sdiv */
357 COSTS_N_INSNS (1), /* ddiv */
364 /* Instruction size costs on 64bit processors. */
366 struct processor_costs size64_cost = {
367 COSTS_N_INSNS (1), /* mulsi */
368 COSTS_N_INSNS (1), /* mulsi_const */
369 COSTS_N_INSNS (1), /* mulsi_const9 */
370 COSTS_N_INSNS (1), /* muldi */
371 COSTS_N_INSNS (1), /* divsi */
372 COSTS_N_INSNS (1), /* divdi */
373 COSTS_N_INSNS (1), /* fp */
374 COSTS_N_INSNS (1), /* dmul */
375 COSTS_N_INSNS (1), /* sdiv */
376 COSTS_N_INSNS (1), /* ddiv */
383 /* Instruction costs on RIOS1 processors. */
385 struct processor_costs rios1_cost = {
386 COSTS_N_INSNS (5), /* mulsi */
387 COSTS_N_INSNS (4), /* mulsi_const */
388 COSTS_N_INSNS (3), /* mulsi_const9 */
389 COSTS_N_INSNS (5), /* muldi */
390 COSTS_N_INSNS (19), /* divsi */
391 COSTS_N_INSNS (19), /* divdi */
392 COSTS_N_INSNS (2), /* fp */
393 COSTS_N_INSNS (2), /* dmul */
394 COSTS_N_INSNS (19), /* sdiv */
395 COSTS_N_INSNS (19), /* ddiv */
396 128, /* cache line size */
402 /* Instruction costs on RIOS2 processors. */
404 struct processor_costs rios2_cost = {
405 COSTS_N_INSNS (2), /* mulsi */
406 COSTS_N_INSNS (2), /* mulsi_const */
407 COSTS_N_INSNS (2), /* mulsi_const9 */
408 COSTS_N_INSNS (2), /* muldi */
409 COSTS_N_INSNS (13), /* divsi */
410 COSTS_N_INSNS (13), /* divdi */
411 COSTS_N_INSNS (2), /* fp */
412 COSTS_N_INSNS (2), /* dmul */
413 COSTS_N_INSNS (17), /* sdiv */
414 COSTS_N_INSNS (17), /* ddiv */
415 256, /* cache line size */
421 /* Instruction costs on RS64A processors. */
423 struct processor_costs rs64a_cost = {
424 COSTS_N_INSNS (20), /* mulsi */
425 COSTS_N_INSNS (12), /* mulsi_const */
426 COSTS_N_INSNS (8), /* mulsi_const9 */
427 COSTS_N_INSNS (34), /* muldi */
428 COSTS_N_INSNS (65), /* divsi */
429 COSTS_N_INSNS (67), /* divdi */
430 COSTS_N_INSNS (4), /* fp */
431 COSTS_N_INSNS (4), /* dmul */
432 COSTS_N_INSNS (31), /* sdiv */
433 COSTS_N_INSNS (31), /* ddiv */
434 128, /* cache line size */
440 /* Instruction costs on MPCCORE processors. */
442 struct processor_costs mpccore_cost = {
443 COSTS_N_INSNS (2), /* mulsi */
444 COSTS_N_INSNS (2), /* mulsi_const */
445 COSTS_N_INSNS (2), /* mulsi_const9 */
446 COSTS_N_INSNS (2), /* muldi */
447 COSTS_N_INSNS (6), /* divsi */
448 COSTS_N_INSNS (6), /* divdi */
449 COSTS_N_INSNS (4), /* fp */
450 COSTS_N_INSNS (5), /* dmul */
451 COSTS_N_INSNS (10), /* sdiv */
452 COSTS_N_INSNS (17), /* ddiv */
453 32, /* cache line size */
459 /* Instruction costs on PPC403 processors. */
461 struct processor_costs ppc403_cost = {
462 COSTS_N_INSNS (4), /* mulsi */
463 COSTS_N_INSNS (4), /* mulsi_const */
464 COSTS_N_INSNS (4), /* mulsi_const9 */
465 COSTS_N_INSNS (4), /* muldi */
466 COSTS_N_INSNS (33), /* divsi */
467 COSTS_N_INSNS (33), /* divdi */
468 COSTS_N_INSNS (11), /* fp */
469 COSTS_N_INSNS (11), /* dmul */
470 COSTS_N_INSNS (11), /* sdiv */
471 COSTS_N_INSNS (11), /* ddiv */
472 32, /* cache line size */
478 /* Instruction costs on PPC405 processors. */
480 struct processor_costs ppc405_cost = {
481 COSTS_N_INSNS (5), /* mulsi */
482 COSTS_N_INSNS (4), /* mulsi_const */
483 COSTS_N_INSNS (3), /* mulsi_const9 */
484 COSTS_N_INSNS (5), /* muldi */
485 COSTS_N_INSNS (35), /* divsi */
486 COSTS_N_INSNS (35), /* divdi */
487 COSTS_N_INSNS (11), /* fp */
488 COSTS_N_INSNS (11), /* dmul */
489 COSTS_N_INSNS (11), /* sdiv */
490 COSTS_N_INSNS (11), /* ddiv */
491 32, /* cache line size */
497 /* Instruction costs on PPC440 processors. */
499 struct processor_costs ppc440_cost = {
500 COSTS_N_INSNS (3), /* mulsi */
501 COSTS_N_INSNS (2), /* mulsi_const */
502 COSTS_N_INSNS (2), /* mulsi_const9 */
503 COSTS_N_INSNS (3), /* muldi */
504 COSTS_N_INSNS (34), /* divsi */
505 COSTS_N_INSNS (34), /* divdi */
506 COSTS_N_INSNS (5), /* fp */
507 COSTS_N_INSNS (5), /* dmul */
508 COSTS_N_INSNS (19), /* sdiv */
509 COSTS_N_INSNS (33), /* ddiv */
510 32, /* cache line size */
516 /* Instruction costs on PPC476 processors. */
518 struct processor_costs ppc476_cost = {
519 COSTS_N_INSNS (4), /* mulsi */
520 COSTS_N_INSNS (4), /* mulsi_const */
521 COSTS_N_INSNS (4), /* mulsi_const9 */
522 COSTS_N_INSNS (4), /* muldi */
523 COSTS_N_INSNS (11), /* divsi */
524 COSTS_N_INSNS (11), /* divdi */
525 COSTS_N_INSNS (6), /* fp */
526 COSTS_N_INSNS (6), /* dmul */
527 COSTS_N_INSNS (19), /* sdiv */
528 COSTS_N_INSNS (33), /* ddiv */
529 32, /* l1 cache line size */
535 /* Instruction costs on PPC601 processors. */
537 struct processor_costs ppc601_cost = {
538 COSTS_N_INSNS (5), /* mulsi */
539 COSTS_N_INSNS (5), /* mulsi_const */
540 COSTS_N_INSNS (5), /* mulsi_const9 */
541 COSTS_N_INSNS (5), /* muldi */
542 COSTS_N_INSNS (36), /* divsi */
543 COSTS_N_INSNS (36), /* divdi */
544 COSTS_N_INSNS (4), /* fp */
545 COSTS_N_INSNS (5), /* dmul */
546 COSTS_N_INSNS (17), /* sdiv */
547 COSTS_N_INSNS (31), /* ddiv */
548 32, /* cache line size */
554 /* Instruction costs on PPC603 processors. */
556 struct processor_costs ppc603_cost = {
557 COSTS_N_INSNS (5), /* mulsi */
558 COSTS_N_INSNS (3), /* mulsi_const */
559 COSTS_N_INSNS (2), /* mulsi_const9 */
560 COSTS_N_INSNS (5), /* muldi */
561 COSTS_N_INSNS (37), /* divsi */
562 COSTS_N_INSNS (37), /* divdi */
563 COSTS_N_INSNS (3), /* fp */
564 COSTS_N_INSNS (4), /* dmul */
565 COSTS_N_INSNS (18), /* sdiv */
566 COSTS_N_INSNS (33), /* ddiv */
567 32, /* cache line size */
573 /* Instruction costs on PPC604 processors. */
575 struct processor_costs ppc604_cost = {
576 COSTS_N_INSNS (4), /* mulsi */
577 COSTS_N_INSNS (4), /* mulsi_const */
578 COSTS_N_INSNS (4), /* mulsi_const9 */
579 COSTS_N_INSNS (4), /* muldi */
580 COSTS_N_INSNS (20), /* divsi */
581 COSTS_N_INSNS (20), /* divdi */
582 COSTS_N_INSNS (3), /* fp */
583 COSTS_N_INSNS (3), /* dmul */
584 COSTS_N_INSNS (18), /* sdiv */
585 COSTS_N_INSNS (32), /* ddiv */
586 32, /* cache line size */
592 /* Instruction costs on PPC604e processors. */
594 struct processor_costs ppc604e_cost = {
595 COSTS_N_INSNS (2), /* mulsi */
596 COSTS_N_INSNS (2), /* mulsi_const */
597 COSTS_N_INSNS (2), /* mulsi_const9 */
598 COSTS_N_INSNS (2), /* muldi */
599 COSTS_N_INSNS (20), /* divsi */
600 COSTS_N_INSNS (20), /* divdi */
601 COSTS_N_INSNS (3), /* fp */
602 COSTS_N_INSNS (3), /* dmul */
603 COSTS_N_INSNS (18), /* sdiv */
604 COSTS_N_INSNS (32), /* ddiv */
605 32, /* cache line size */
611 /* Instruction costs on PPC620 processors. */
613 struct processor_costs ppc620_cost = {
614 COSTS_N_INSNS (5), /* mulsi */
615 COSTS_N_INSNS (4), /* mulsi_const */
616 COSTS_N_INSNS (3), /* mulsi_const9 */
617 COSTS_N_INSNS (7), /* muldi */
618 COSTS_N_INSNS (21), /* divsi */
619 COSTS_N_INSNS (37), /* divdi */
620 COSTS_N_INSNS (3), /* fp */
621 COSTS_N_INSNS (3), /* dmul */
622 COSTS_N_INSNS (18), /* sdiv */
623 COSTS_N_INSNS (32), /* ddiv */
624 128, /* cache line size */
630 /* Instruction costs on PPC630 processors. */
632 struct processor_costs ppc630_cost = {
633 COSTS_N_INSNS (5), /* mulsi */
634 COSTS_N_INSNS (4), /* mulsi_const */
635 COSTS_N_INSNS (3), /* mulsi_const9 */
636 COSTS_N_INSNS (7), /* muldi */
637 COSTS_N_INSNS (21), /* divsi */
638 COSTS_N_INSNS (37), /* divdi */
639 COSTS_N_INSNS (3), /* fp */
640 COSTS_N_INSNS (3), /* dmul */
641 COSTS_N_INSNS (17), /* sdiv */
642 COSTS_N_INSNS (21), /* ddiv */
643 128, /* cache line size */
649 /* Instruction costs on Cell processor. */
650 /* COSTS_N_INSNS (1) ~ one add. */
652 struct processor_costs ppccell_cost = {
653 COSTS_N_INSNS (9/2)+2, /* mulsi */
654 COSTS_N_INSNS (6/2), /* mulsi_const */
655 COSTS_N_INSNS (6/2), /* mulsi_const9 */
656 COSTS_N_INSNS (15/2)+2, /* muldi */
657 COSTS_N_INSNS (38/2), /* divsi */
658 COSTS_N_INSNS (70/2), /* divdi */
659 COSTS_N_INSNS (10/2), /* fp */
660 COSTS_N_INSNS (10/2), /* dmul */
661 COSTS_N_INSNS (74/2), /* sdiv */
662 COSTS_N_INSNS (74/2), /* ddiv */
663 128, /* cache line size */
669 /* Instruction costs on PPC750 and PPC7400 processors. */
671 struct processor_costs ppc750_cost = {
672 COSTS_N_INSNS (5), /* mulsi */
673 COSTS_N_INSNS (3), /* mulsi_const */
674 COSTS_N_INSNS (2), /* mulsi_const9 */
675 COSTS_N_INSNS (5), /* muldi */
676 COSTS_N_INSNS (17), /* divsi */
677 COSTS_N_INSNS (17), /* divdi */
678 COSTS_N_INSNS (3), /* fp */
679 COSTS_N_INSNS (3), /* dmul */
680 COSTS_N_INSNS (17), /* sdiv */
681 COSTS_N_INSNS (31), /* ddiv */
682 32, /* cache line size */
688 /* Instruction costs on PPC7450 processors. */
690 struct processor_costs ppc7450_cost = {
691 COSTS_N_INSNS (4), /* mulsi */
692 COSTS_N_INSNS (3), /* mulsi_const */
693 COSTS_N_INSNS (3), /* mulsi_const9 */
694 COSTS_N_INSNS (4), /* muldi */
695 COSTS_N_INSNS (23), /* divsi */
696 COSTS_N_INSNS (23), /* divdi */
697 COSTS_N_INSNS (5), /* fp */
698 COSTS_N_INSNS (5), /* dmul */
699 COSTS_N_INSNS (21), /* sdiv */
700 COSTS_N_INSNS (35), /* ddiv */
701 32, /* cache line size */
707 /* Instruction costs on PPC8540 processors. */
709 struct processor_costs ppc8540_cost = {
710 COSTS_N_INSNS (4), /* mulsi */
711 COSTS_N_INSNS (4), /* mulsi_const */
712 COSTS_N_INSNS (4), /* mulsi_const9 */
713 COSTS_N_INSNS (4), /* muldi */
714 COSTS_N_INSNS (19), /* divsi */
715 COSTS_N_INSNS (19), /* divdi */
716 COSTS_N_INSNS (4), /* fp */
717 COSTS_N_INSNS (4), /* dmul */
718 COSTS_N_INSNS (29), /* sdiv */
719 COSTS_N_INSNS (29), /* ddiv */
720 32, /* cache line size */
723 1, /* prefetch streams /*/
726 /* Instruction costs on E300C2 and E300C3 cores. */
728 struct processor_costs ppce300c2c3_cost = {
729 COSTS_N_INSNS (4), /* mulsi */
730 COSTS_N_INSNS (4), /* mulsi_const */
731 COSTS_N_INSNS (4), /* mulsi_const9 */
732 COSTS_N_INSNS (4), /* muldi */
733 COSTS_N_INSNS (19), /* divsi */
734 COSTS_N_INSNS (19), /* divdi */
735 COSTS_N_INSNS (3), /* fp */
736 COSTS_N_INSNS (4), /* dmul */
737 COSTS_N_INSNS (18), /* sdiv */
738 COSTS_N_INSNS (33), /* ddiv */
742 1, /* prefetch streams /*/
745 /* Instruction costs on PPCE500MC processors. */
747 struct processor_costs ppce500mc_cost = {
748 COSTS_N_INSNS (4), /* mulsi */
749 COSTS_N_INSNS (4), /* mulsi_const */
750 COSTS_N_INSNS (4), /* mulsi_const9 */
751 COSTS_N_INSNS (4), /* muldi */
752 COSTS_N_INSNS (14), /* divsi */
753 COSTS_N_INSNS (14), /* divdi */
754 COSTS_N_INSNS (8), /* fp */
755 COSTS_N_INSNS (10), /* dmul */
756 COSTS_N_INSNS (36), /* sdiv */
757 COSTS_N_INSNS (66), /* ddiv */
758 64, /* cache line size */
761 1, /* prefetch streams /*/
764 /* Instruction costs on PPCE500MC64 processors. */
766 struct processor_costs ppce500mc64_cost = {
767 COSTS_N_INSNS (4), /* mulsi */
768 COSTS_N_INSNS (4), /* mulsi_const */
769 COSTS_N_INSNS (4), /* mulsi_const9 */
770 COSTS_N_INSNS (4), /* muldi */
771 COSTS_N_INSNS (14), /* divsi */
772 COSTS_N_INSNS (14), /* divdi */
773 COSTS_N_INSNS (4), /* fp */
774 COSTS_N_INSNS (10), /* dmul */
775 COSTS_N_INSNS (36), /* sdiv */
776 COSTS_N_INSNS (66), /* ddiv */
777 64, /* cache line size */
780 1, /* prefetch streams /*/
783 /* Instruction costs on AppliedMicro Titan processors. */
785 struct processor_costs titan_cost = {
786 COSTS_N_INSNS (5), /* mulsi */
787 COSTS_N_INSNS (5), /* mulsi_const */
788 COSTS_N_INSNS (5), /* mulsi_const9 */
789 COSTS_N_INSNS (5), /* muldi */
790 COSTS_N_INSNS (18), /* divsi */
791 COSTS_N_INSNS (18), /* divdi */
792 COSTS_N_INSNS (10), /* fp */
793 COSTS_N_INSNS (10), /* dmul */
794 COSTS_N_INSNS (46), /* sdiv */
795 COSTS_N_INSNS (72), /* ddiv */
796 32, /* cache line size */
799 1, /* prefetch streams /*/
802 /* Instruction costs on POWER4 and POWER5 processors. */
804 struct processor_costs power4_cost = {
805 COSTS_N_INSNS (3), /* mulsi */
806 COSTS_N_INSNS (2), /* mulsi_const */
807 COSTS_N_INSNS (2), /* mulsi_const9 */
808 COSTS_N_INSNS (4), /* muldi */
809 COSTS_N_INSNS (18), /* divsi */
810 COSTS_N_INSNS (34), /* divdi */
811 COSTS_N_INSNS (3), /* fp */
812 COSTS_N_INSNS (3), /* dmul */
813 COSTS_N_INSNS (17), /* sdiv */
814 COSTS_N_INSNS (17), /* ddiv */
815 128, /* cache line size */
818 8, /* prefetch streams /*/
821 /* Instruction costs on POWER6 processors. */
823 struct processor_costs power6_cost = {
824 COSTS_N_INSNS (8), /* mulsi */
825 COSTS_N_INSNS (8), /* mulsi_const */
826 COSTS_N_INSNS (8), /* mulsi_const9 */
827 COSTS_N_INSNS (8), /* muldi */
828 COSTS_N_INSNS (22), /* divsi */
829 COSTS_N_INSNS (28), /* divdi */
830 COSTS_N_INSNS (3), /* fp */
831 COSTS_N_INSNS (3), /* dmul */
832 COSTS_N_INSNS (13), /* sdiv */
833 COSTS_N_INSNS (16), /* ddiv */
834 128, /* cache line size */
837 16, /* prefetch streams */
840 /* Instruction costs on POWER7 processors. */
842 struct processor_costs power7_cost = {
843 COSTS_N_INSNS (2), /* mulsi */
844 COSTS_N_INSNS (2), /* mulsi_const */
845 COSTS_N_INSNS (2), /* mulsi_const9 */
846 COSTS_N_INSNS (2), /* muldi */
847 COSTS_N_INSNS (18), /* divsi */
848 COSTS_N_INSNS (34), /* divdi */
849 COSTS_N_INSNS (3), /* fp */
850 COSTS_N_INSNS (3), /* dmul */
851 COSTS_N_INSNS (13), /* sdiv */
852 COSTS_N_INSNS (16), /* ddiv */
853 128, /* cache line size */
856 12, /* prefetch streams */
859 /* Instruction costs on POWER A2 processors. */
861 struct processor_costs ppca2_cost = {
862 COSTS_N_INSNS (16), /* mulsi */
863 COSTS_N_INSNS (16), /* mulsi_const */
864 COSTS_N_INSNS (16), /* mulsi_const9 */
865 COSTS_N_INSNS (16), /* muldi */
866 COSTS_N_INSNS (22), /* divsi */
867 COSTS_N_INSNS (28), /* divdi */
868 COSTS_N_INSNS (3), /* fp */
869 COSTS_N_INSNS (3), /* dmul */
870 COSTS_N_INSNS (59), /* sdiv */
871 COSTS_N_INSNS (72), /* ddiv */
875 16, /* prefetch streams */
879 /* Table that classifies rs6000 builtin functions (pure, const, etc.). */
880 #undef RS6000_BUILTIN
881 #undef RS6000_BUILTIN_EQUATE
882 #define RS6000_BUILTIN(NAME, TYPE) TYPE,
883 #define RS6000_BUILTIN_EQUATE(NAME, VALUE)
885 static const enum rs6000_btc builtin_classify[(int)RS6000_BUILTIN_COUNT] =
887 #include "rs6000-builtin.def"
890 #undef RS6000_BUILTIN
891 #undef RS6000_BUILTIN_EQUATE
893 /* Support for -mveclibabi=<xxx> to control which vector library to use. */
894 static tree (*rs6000_veclib_handler) (tree, tree, tree);
897 static bool rs6000_function_ok_for_sibcall (tree, tree);
898 static const char *rs6000_invalid_within_doloop (const_rtx);
899 static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool);
900 static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool);
901 static rtx rs6000_generate_compare (rtx, enum machine_mode);
902 static void rs6000_emit_stack_tie (void);
903 static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
904 static bool spe_func_has_64bit_regs_p (void);
905 static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
907 static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
908 static unsigned rs6000_hash_constant (rtx);
909 static unsigned toc_hash_function (const void *);
910 static int toc_hash_eq (const void *, const void *);
911 static bool reg_offset_addressing_ok_p (enum machine_mode);
912 static bool virtual_stack_registers_memory_p (rtx);
913 static bool constant_pool_expr_p (rtx);
914 static bool legitimate_small_data_p (enum machine_mode, rtx);
915 static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
916 static struct machine_function * rs6000_init_machine_status (void);
917 static bool rs6000_assemble_integer (rtx, unsigned int, int);
918 static bool no_global_regs_above (int, bool);
919 #ifdef HAVE_GAS_HIDDEN
920 static void rs6000_assemble_visibility (tree, int);
922 static int rs6000_ra_ever_killed (void);
923 static bool rs6000_attribute_takes_identifier_p (const_tree);
924 static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
925 static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
926 static bool rs6000_ms_bitfield_layout_p (const_tree);
927 static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
928 static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
929 static const char *rs6000_mangle_type (const_tree);
930 static void rs6000_set_default_type_attributes (tree);
931 static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool);
932 static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool);
933 static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int,
934 enum machine_mode, bool, bool, bool);
935 static bool rs6000_reg_live_or_pic_offset_p (int);
936 static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
937 static tree rs6000_builtin_vectorized_function (tree, tree, tree);
938 static void rs6000_restore_saved_cr (rtx, int);
939 static bool rs6000_output_addr_const_extra (FILE *, rtx);
940 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
941 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
942 static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
944 static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
945 static bool rs6000_return_in_memory (const_tree, const_tree);
946 static rtx rs6000_function_value (const_tree, const_tree, bool);
947 static void rs6000_file_start (void);
949 static int rs6000_elf_reloc_rw_mask (void);
950 static void rs6000_elf_asm_out_constructor (rtx, int) ATTRIBUTE_UNUSED;
951 static void rs6000_elf_asm_out_destructor (rtx, int) ATTRIBUTE_UNUSED;
952 static void rs6000_elf_file_end (void) ATTRIBUTE_UNUSED;
953 static void rs6000_elf_asm_init_sections (void);
954 static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
955 unsigned HOST_WIDE_INT);
956 static void rs6000_elf_encode_section_info (tree, rtx, int)
959 static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
960 static void rs6000_alloc_sdmode_stack_slot (void);
961 static void rs6000_instantiate_decls (void);
963 static void rs6000_xcoff_asm_output_anchor (rtx);
964 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
965 static void rs6000_xcoff_asm_init_sections (void);
966 static int rs6000_xcoff_reloc_rw_mask (void);
967 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
968 static section *rs6000_xcoff_select_section (tree, int,
969 unsigned HOST_WIDE_INT);
970 static void rs6000_xcoff_unique_section (tree, int);
971 static section *rs6000_xcoff_select_rtx_section
972 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
973 static const char * rs6000_xcoff_strip_name_encoding (const char *);
974 static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
975 static void rs6000_xcoff_file_start (void);
976 static void rs6000_xcoff_file_end (void);
978 static int rs6000_variable_issue (FILE *, int, rtx, int);
979 static int rs6000_register_move_cost (enum machine_mode,
980 reg_class_t, reg_class_t);
981 static int rs6000_memory_move_cost (enum machine_mode, reg_class_t, bool);
982 static bool rs6000_rtx_costs (rtx, int, int, int *, bool);
983 static bool rs6000_debug_rtx_costs (rtx, int, int, int *, bool);
984 static int rs6000_debug_address_cost (rtx, bool);
985 static int rs6000_adjust_cost (rtx, rtx, rtx, int);
986 static int rs6000_debug_adjust_cost (rtx, rtx, rtx, int);
987 static void rs6000_sched_init (FILE *, int, int);
988 static bool is_microcoded_insn (rtx);
989 static bool is_nonpipeline_insn (rtx);
990 static bool is_cracked_insn (rtx);
991 static bool is_branch_slot_insn (rtx);
992 static bool is_load_insn (rtx);
993 static rtx get_store_dest (rtx pat);
994 static bool is_store_insn (rtx);
995 static bool set_to_load_agen (rtx,rtx);
996 static bool adjacent_mem_locations (rtx,rtx);
997 static int rs6000_adjust_priority (rtx, int);
998 static int rs6000_issue_rate (void);
999 static bool rs6000_is_costly_dependence (dep_t, int, int);
1000 static rtx get_next_active_insn (rtx, rtx);
1001 static bool insn_terminates_group_p (rtx , enum group_termination);
1002 static bool insn_must_be_first_in_group (rtx);
1003 static bool insn_must_be_last_in_group (rtx);
1004 static bool is_costly_group (rtx *, rtx);
1005 static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
1006 static int redefine_groups (FILE *, int, rtx, rtx);
1007 static int pad_groups (FILE *, int, rtx, rtx);
1008 static void rs6000_sched_finish (FILE *, int);
1009 static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
1010 static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
1011 static int rs6000_use_sched_lookahead (void);
1012 static int rs6000_use_sched_lookahead_guard (rtx);
1013 static void * rs6000_alloc_sched_context (void);
1014 static void rs6000_init_sched_context (void *, bool);
1015 static void rs6000_set_sched_context (void *);
1016 static void rs6000_free_sched_context (void *);
1017 static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
1018 static tree rs6000_builtin_mask_for_load (void);
1019 static tree rs6000_builtin_mul_widen_even (tree);
1020 static tree rs6000_builtin_mul_widen_odd (tree);
1021 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
1022 static tree rs6000_builtin_vec_perm (tree, tree *);
1023 static bool rs6000_builtin_support_vector_misalignment (enum
1027 static int rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt,
1029 static enum machine_mode rs6000_preferred_simd_mode (enum machine_mode);
1031 static void def_builtin (int, const char *, tree, int);
1032 static bool rs6000_vector_alignment_reachable (const_tree, bool);
1033 static void rs6000_init_builtins (void);
1034 static tree rs6000_builtin_decl (unsigned, bool);
1036 static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
1037 static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
1038 static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
1039 static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1040 static void altivec_init_builtins (void);
1041 static unsigned builtin_hash_function (const void *);
1042 static int builtin_hash_eq (const void *, const void *);
1043 static tree builtin_function_type (enum machine_mode, enum machine_mode,
1044 enum machine_mode, enum machine_mode,
1045 enum rs6000_builtins, const char *name);
1046 static void rs6000_common_init_builtins (void);
1047 static void rs6000_init_libfuncs (void);
1049 static void paired_init_builtins (void);
1050 static rtx paired_expand_builtin (tree, rtx, bool *);
1051 static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
1052 static rtx paired_expand_stv_builtin (enum insn_code, tree);
1053 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
1055 static void enable_mask_for_builtins (struct builtin_description *, int,
1056 enum rs6000_builtins,
1057 enum rs6000_builtins);
1058 static void spe_init_builtins (void);
1059 static rtx spe_expand_builtin (tree, rtx, bool *);
1060 static rtx spe_expand_stv_builtin (enum insn_code, tree);
1061 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
1062 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
1063 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
1064 static rs6000_stack_t *rs6000_stack_info (void);
1065 static void debug_stack_info (rs6000_stack_t *);
1067 static rtx altivec_expand_builtin (tree, rtx, bool *);
1068 static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
1069 static rtx altivec_expand_st_builtin (tree, rtx, bool *);
1070 static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
1071 static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
1072 static rtx altivec_expand_predicate_builtin (enum insn_code, tree, rtx);
1073 static rtx altivec_expand_stv_builtin (enum insn_code, tree);
1074 static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
1075 static rtx altivec_expand_vec_set_builtin (tree);
1076 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
1077 static int get_element_number (tree, tree);
1078 static void rs6000_option_override (void);
1079 static void rs6000_option_init_struct (struct gcc_options *);
1080 static void rs6000_option_default_params (void);
1081 static bool rs6000_handle_option (struct gcc_options *, struct gcc_options *,
1082 const struct cl_decoded_option *,
1084 static int rs6000_loop_align_max_skip (rtx);
1085 static int first_altivec_reg_to_save (void);
1086 static unsigned int compute_vrsave_mask (void);
1087 static void compute_save_world_info (rs6000_stack_t *info_ptr);
1088 static void is_altivec_return_reg (rtx, void *);
1089 static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
1090 int easy_vector_constant (rtx, enum machine_mode);
1091 static rtx rs6000_dwarf_register_span (rtx);
1092 static void rs6000_init_dwarf_reg_sizes_extra (tree);
1093 static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
1094 static rtx rs6000_debug_legitimize_address (rtx, rtx, enum machine_mode);
1095 static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
1096 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
1097 static rtx rs6000_delegitimize_address (rtx);
1098 static rtx rs6000_tls_get_addr (void);
1099 static rtx rs6000_got_sym (void);
1100 static int rs6000_tls_symbol_ref_1 (rtx *, void *);
1101 static const char *rs6000_get_some_local_dynamic_name (void);
1102 static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
1103 static rtx rs6000_complex_function_value (enum machine_mode);
1104 static rtx rs6000_spe_function_arg (const CUMULATIVE_ARGS *,
1105 enum machine_mode, const_tree);
1106 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
1107 HOST_WIDE_INT, int);
1108 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
1111 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
1114 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
1115 const_tree, HOST_WIDE_INT,
1117 static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, bool, bool);
1118 static rtx rs6000_mixed_function_arg (enum machine_mode, const_tree, int);
1119 static void rs6000_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
1121 static rtx rs6000_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
1123 static unsigned int rs6000_function_arg_boundary (enum machine_mode,
1125 static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
1126 static void setup_incoming_varargs (CUMULATIVE_ARGS *,
1127 enum machine_mode, tree,
1129 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
1131 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
1133 static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
1135 static void macho_branch_islands (void);
1136 static int no_previous_def (tree function_name);
1137 static tree get_prev_label (tree function_name);
1138 static void rs6000_darwin_file_start (void);
1141 static tree rs6000_build_builtin_va_list (void);
1142 static void rs6000_va_start (tree, rtx);
1143 static tree rs6000_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
1144 static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
1145 static bool rs6000_scalar_mode_supported_p (enum machine_mode);
1146 static bool rs6000_vector_mode_supported_p (enum machine_mode);
1147 static rtx rs6000_emit_vector_compare_inner (enum rtx_code, rtx, rtx);
1148 static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
1150 static tree rs6000_stack_protect_fail (void);
1152 static rtx rs6000_legitimize_reload_address (rtx, enum machine_mode, int, int,
1155 static rtx rs6000_debug_legitimize_reload_address (rtx, enum machine_mode, int,
1158 rtx (*rs6000_legitimize_reload_address_ptr) (rtx, enum machine_mode, int, int,
1160 = rs6000_legitimize_reload_address;
1162 static bool rs6000_mode_dependent_address_p (const_rtx);
1163 static bool rs6000_mode_dependent_address (const_rtx);
1164 static bool rs6000_debug_mode_dependent_address (const_rtx);
1165 static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
1166 = rs6000_mode_dependent_address;
1168 static enum reg_class rs6000_secondary_reload_class (enum reg_class,
1169 enum machine_mode, rtx);
1170 static enum reg_class rs6000_debug_secondary_reload_class (enum reg_class,
1173 enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
1174 enum machine_mode, rtx)
1175 = rs6000_secondary_reload_class;
1177 static enum reg_class rs6000_preferred_reload_class (rtx, enum reg_class);
1178 static enum reg_class rs6000_debug_preferred_reload_class (rtx,
1180 enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx, enum reg_class)
1181 = rs6000_preferred_reload_class;
1183 static bool rs6000_secondary_memory_needed (enum reg_class, enum reg_class,
1186 static bool rs6000_debug_secondary_memory_needed (enum reg_class,
1190 bool (*rs6000_secondary_memory_needed_ptr) (enum reg_class, enum reg_class,
1192 = rs6000_secondary_memory_needed;
1194 static bool rs6000_cannot_change_mode_class (enum machine_mode,
1197 static bool rs6000_debug_cannot_change_mode_class (enum machine_mode,
1201 bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
1204 = rs6000_cannot_change_mode_class;
1206 static reg_class_t rs6000_secondary_reload (bool, rtx, reg_class_t,
1208 struct secondary_reload_info *);
1210 const int INSN_NOT_AVAILABLE = -1;
1211 static enum machine_mode rs6000_eh_return_filter_mode (void);
1212 static bool rs6000_can_eliminate (const int, const int);
1213 static void rs6000_conditional_register_usage (void);
1214 static void rs6000_trampoline_init (rtx, tree, rtx);
1216 /* Hash table stuff for keeping track of TOC entries. */
1218 struct GTY(()) toc_hash_struct
1220 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1221 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1223 enum machine_mode key_mode;
1227 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1229 /* Hash table to keep track of the argument types for builtin functions. */
1231 struct GTY(()) builtin_hash_struct
1234 enum machine_mode mode[4]; /* return value + 3 arguments. */
1235 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1238 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1240 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1241 static void rs6000_function_specific_save (struct cl_target_option *);
1242 static void rs6000_function_specific_restore (struct cl_target_option *);
1243 static void rs6000_function_specific_print (FILE *, int,
1244 struct cl_target_option *);
1245 static bool rs6000_can_inline_p (tree, tree);
1246 static void rs6000_set_current_function (tree);
1249 /* Default register names. */
1250 char rs6000_reg_names[][8] =
1252 "0", "1", "2", "3", "4", "5", "6", "7",
1253 "8", "9", "10", "11", "12", "13", "14", "15",
1254 "16", "17", "18", "19", "20", "21", "22", "23",
1255 "24", "25", "26", "27", "28", "29", "30", "31",
1256 "0", "1", "2", "3", "4", "5", "6", "7",
1257 "8", "9", "10", "11", "12", "13", "14", "15",
1258 "16", "17", "18", "19", "20", "21", "22", "23",
1259 "24", "25", "26", "27", "28", "29", "30", "31",
1260 "mq", "lr", "ctr","ap",
1261 "0", "1", "2", "3", "4", "5", "6", "7",
1263 /* AltiVec registers. */
1264 "0", "1", "2", "3", "4", "5", "6", "7",
1265 "8", "9", "10", "11", "12", "13", "14", "15",
1266 "16", "17", "18", "19", "20", "21", "22", "23",
1267 "24", "25", "26", "27", "28", "29", "30", "31",
1269 /* SPE registers. */
1270 "spe_acc", "spefscr",
1271 /* Soft frame pointer. */
1275 #ifdef TARGET_REGNAMES
1276 static const char alt_reg_names[][8] =
1278 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1279 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1280 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1281 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1282 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1283 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1284 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1285 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1286 "mq", "lr", "ctr", "ap",
1287 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1289 /* AltiVec registers. */
1290 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1291 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1292 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1293 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1295 /* SPE registers. */
1296 "spe_acc", "spefscr",
1297 /* Soft frame pointer. */
1302 /* Table of valid machine attributes. */
1304 static const struct attribute_spec rs6000_attribute_table[] =
1306 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1307 affects_type_identity } */
1308 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1310 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1312 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1314 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1316 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1318 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1319 SUBTARGET_ATTRIBUTE_TABLE,
1321 { NULL, 0, 0, false, false, false, NULL, false }
1324 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1325 static const struct default_options rs6000_option_optimization_table[] =
1327 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1328 { OPT_LEVELS_NONE, 0, NULL, 0 }
1331 #ifndef MASK_STRICT_ALIGN
1332 #define MASK_STRICT_ALIGN 0
1334 #ifndef TARGET_PROFILE_KERNEL
1335 #define TARGET_PROFILE_KERNEL 0
1338 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1339 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1341 /* Initialize the GCC target structure. */
1342 #undef TARGET_ATTRIBUTE_TABLE
1343 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1344 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1345 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1346 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1347 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1349 #undef TARGET_ASM_ALIGNED_DI_OP
1350 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1352 /* Default unaligned ops are only provided for ELF. Find the ops needed
1353 for non-ELF systems. */
1354 #ifndef OBJECT_FORMAT_ELF
1356 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1358 #undef TARGET_ASM_UNALIGNED_HI_OP
1359 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1360 #undef TARGET_ASM_UNALIGNED_SI_OP
1361 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1362 #undef TARGET_ASM_UNALIGNED_DI_OP
1363 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1366 #undef TARGET_ASM_UNALIGNED_HI_OP
1367 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1368 #undef TARGET_ASM_UNALIGNED_SI_OP
1369 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1370 #undef TARGET_ASM_UNALIGNED_DI_OP
1371 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1372 #undef TARGET_ASM_ALIGNED_DI_OP
1373 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1377 /* This hook deals with fixups for relocatable code and DI-mode objects
1379 #undef TARGET_ASM_INTEGER
1380 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1382 #ifdef HAVE_GAS_HIDDEN
1383 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1384 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1387 #undef TARGET_HAVE_TLS
1388 #define TARGET_HAVE_TLS HAVE_AS_TLS
1390 #undef TARGET_CANNOT_FORCE_CONST_MEM
1391 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
1393 #undef TARGET_DELEGITIMIZE_ADDRESS
1394 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1396 #undef TARGET_ASM_FUNCTION_PROLOGUE
1397 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1398 #undef TARGET_ASM_FUNCTION_EPILOGUE
1399 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1401 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1402 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1404 #undef TARGET_LEGITIMIZE_ADDRESS
1405 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1407 #undef TARGET_SCHED_VARIABLE_ISSUE
1408 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1410 #undef TARGET_SCHED_ISSUE_RATE
1411 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1412 #undef TARGET_SCHED_ADJUST_COST
1413 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1414 #undef TARGET_SCHED_ADJUST_PRIORITY
1415 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1416 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1417 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1418 #undef TARGET_SCHED_INIT
1419 #define TARGET_SCHED_INIT rs6000_sched_init
1420 #undef TARGET_SCHED_FINISH
1421 #define TARGET_SCHED_FINISH rs6000_sched_finish
1422 #undef TARGET_SCHED_REORDER
1423 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1424 #undef TARGET_SCHED_REORDER2
1425 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1427 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1428 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1430 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1431 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1433 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1434 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1435 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1436 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1437 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1438 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1439 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1440 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1442 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1443 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1444 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1445 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1446 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1447 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1448 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1449 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1450 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1451 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1452 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1453 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1454 rs6000_builtin_support_vector_misalignment
1455 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1456 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1457 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1458 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1459 rs6000_builtin_vectorization_cost
1460 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1461 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1462 rs6000_preferred_simd_mode
1464 #undef TARGET_INIT_BUILTINS
1465 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1466 #undef TARGET_BUILTIN_DECL
1467 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1469 #undef TARGET_EXPAND_BUILTIN
1470 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1472 #undef TARGET_MANGLE_TYPE
1473 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1475 #undef TARGET_INIT_LIBFUNCS
1476 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1479 #undef TARGET_BINDS_LOCAL_P
1480 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1483 #undef TARGET_MS_BITFIELD_LAYOUT_P
1484 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1486 #undef TARGET_ASM_OUTPUT_MI_THUNK
1487 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1489 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1490 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1492 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1493 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1495 #undef TARGET_INVALID_WITHIN_DOLOOP
1496 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1498 #undef TARGET_REGISTER_MOVE_COST
1499 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1500 #undef TARGET_MEMORY_MOVE_COST
1501 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1502 #undef TARGET_RTX_COSTS
1503 #define TARGET_RTX_COSTS rs6000_rtx_costs
1504 #undef TARGET_ADDRESS_COST
1505 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1507 #undef TARGET_DWARF_REGISTER_SPAN
1508 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1510 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1511 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1513 /* On rs6000, function arguments are promoted, as are function return
1515 #undef TARGET_PROMOTE_FUNCTION_MODE
1516 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1518 #undef TARGET_RETURN_IN_MEMORY
1519 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1521 #undef TARGET_SETUP_INCOMING_VARARGS
1522 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1524 /* Always strict argument naming on rs6000. */
1525 #undef TARGET_STRICT_ARGUMENT_NAMING
1526 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1527 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1528 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1529 #undef TARGET_SPLIT_COMPLEX_ARG
1530 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1531 #undef TARGET_MUST_PASS_IN_STACK
1532 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1533 #undef TARGET_PASS_BY_REFERENCE
1534 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1535 #undef TARGET_ARG_PARTIAL_BYTES
1536 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1537 #undef TARGET_FUNCTION_ARG_ADVANCE
1538 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1539 #undef TARGET_FUNCTION_ARG
1540 #define TARGET_FUNCTION_ARG rs6000_function_arg
1541 #undef TARGET_FUNCTION_ARG_BOUNDARY
1542 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1544 #undef TARGET_BUILD_BUILTIN_VA_LIST
1545 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1547 #undef TARGET_EXPAND_BUILTIN_VA_START
1548 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1550 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1551 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1553 #undef TARGET_EH_RETURN_FILTER_MODE
1554 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1556 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1557 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1559 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1560 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1562 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1563 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1565 #undef TARGET_HANDLE_OPTION
1566 #define TARGET_HANDLE_OPTION rs6000_handle_option
1568 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1569 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1571 #undef TARGET_OPTION_OVERRIDE
1572 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1574 #undef TARGET_OPTION_INIT_STRUCT
1575 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1577 #undef TARGET_OPTION_DEFAULT_PARAMS
1578 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1580 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1581 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1583 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1584 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1585 rs6000_builtin_vectorized_function
1587 #undef TARGET_DEFAULT_TARGET_FLAGS
1588 #define TARGET_DEFAULT_TARGET_FLAGS \
1591 #undef TARGET_STACK_PROTECT_FAIL
1592 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1594 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1595 The PowerPC architecture requires only weak consistency among
1596 processors--that is, memory accesses between processors need not be
1597 sequentially consistent and memory accesses among processors can occur
1598 in any order. The ability to order memory accesses weakly provides
1599 opportunities for more efficient use of the system bus. Unless a
1600 dependency exists, the 604e allows read operations to precede store
1602 #undef TARGET_RELAXED_ORDERING
1603 #define TARGET_RELAXED_ORDERING true
1606 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1607 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1610 /* Use a 32-bit anchor range. This leads to sequences like:
1612 addis tmp,anchor,high
1615 where tmp itself acts as an anchor, and can be shared between
1616 accesses to the same 64k page. */
1617 #undef TARGET_MIN_ANCHOR_OFFSET
1618 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1619 #undef TARGET_MAX_ANCHOR_OFFSET
1620 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1621 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1622 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1624 #undef TARGET_BUILTIN_RECIPROCAL
1625 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1627 #undef TARGET_EXPAND_TO_RTL_HOOK
1628 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1630 #undef TARGET_INSTANTIATE_DECLS
1631 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1633 #undef TARGET_SECONDARY_RELOAD
1634 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1636 #undef TARGET_LEGITIMATE_ADDRESS_P
1637 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1639 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1640 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1642 #undef TARGET_CAN_ELIMINATE
1643 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1645 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1646 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1648 #undef TARGET_TRAMPOLINE_INIT
1649 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1651 #undef TARGET_FUNCTION_VALUE
1652 #define TARGET_FUNCTION_VALUE rs6000_function_value
1654 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1655 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1657 #undef TARGET_OPTION_SAVE
1658 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1660 #undef TARGET_OPTION_RESTORE
1661 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1663 #undef TARGET_OPTION_PRINT
1664 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1666 #undef TARGET_CAN_INLINE_P
1667 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1669 #undef TARGET_SET_CURRENT_FUNCTION
1670 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1672 struct gcc_target targetm = TARGET_INITIALIZER;
1675 /* Simplifications for entries below. */
1678 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1679 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1682 /* Some OSs don't support saving the high part of 64-bit registers on context
1683 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1684 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1685 either, the user must explicitly specify them and we won't interfere with
1686 the user's specification. */
1689 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1690 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1691 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1692 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1693 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1694 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1695 | MASK_RECIP_PRECISION)
1698 /* Masks for instructions set at various powerpc ISAs. */
1700 ISA_2_1_MASKS = MASK_MFCRF,
1701 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1702 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1704 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1705 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1706 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1707 server and embedded. */
1708 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1709 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1710 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1712 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1713 altivec is a win so enable it. */
1714 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1715 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1719 /* This table occasionally claims that a processor does not support a
1720 particular feature even though it does, but the feature is slower than the
1721 alternative. Thus, it shouldn't be relied on as a complete description of
1722 the processor's support.
1724 Please keep this list in order, and don't forget to update the documentation
1725 in invoke.texi when adding a new processor or flag. */
1729 const char *const name; /* Canonical processor name. */
1730 const enum processor_type processor; /* Processor type enum value. */
1731 const int target_enable; /* Target flags to enable. */
1734 static struct rs6000_ptt const processor_target_table[] =
1736 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1737 {"403", PROCESSOR_PPC403,
1738 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1739 {"405", PROCESSOR_PPC405,
1740 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1741 {"405fp", PROCESSOR_PPC405,
1742 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1743 {"440", PROCESSOR_PPC440,
1744 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1745 {"440fp", PROCESSOR_PPC440,
1746 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1747 {"464", PROCESSOR_PPC440,
1748 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1749 {"464fp", PROCESSOR_PPC440,
1750 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1751 {"476", PROCESSOR_PPC476,
1752 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1753 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1754 {"476fp", PROCESSOR_PPC476,
1755 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1756 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1757 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1758 {"601", PROCESSOR_PPC601,
1759 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1760 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1761 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1763 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1764 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1765 {"620", PROCESSOR_PPC620,
1766 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1767 {"630", PROCESSOR_PPC630,
1768 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1769 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1770 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1771 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1772 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1773 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1774 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1775 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1776 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1778 /* 8548 has a dummy entry for now. */
1779 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1781 {"a2", PROCESSOR_PPCA2,
1782 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1783 | MASK_CMPB | MASK_NO_UPDATE },
1784 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1785 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1786 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1788 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1789 | MASK_PPC_GFXOPT | MASK_ISEL},
1790 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1791 {"970", PROCESSOR_POWER4,
1792 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1793 {"cell", PROCESSOR_CELL,
1794 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1795 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1796 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1797 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1798 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1799 {"G5", PROCESSOR_POWER4,
1800 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1801 {"titan", PROCESSOR_TITAN,
1802 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1803 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1804 {"power2", PROCESSOR_POWER,
1805 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1806 {"power3", PROCESSOR_PPC630,
1807 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1808 {"power4", PROCESSOR_POWER4,
1809 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1811 {"power5", PROCESSOR_POWER5,
1812 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1813 | MASK_MFCRF | MASK_POPCNTB},
1814 {"power5+", PROCESSOR_POWER5,
1815 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1816 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1817 {"power6", PROCESSOR_POWER6,
1818 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1819 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1820 | MASK_RECIP_PRECISION},
1821 {"power6x", PROCESSOR_POWER6,
1822 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1823 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1824 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1825 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1826 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1827 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1828 | MASK_VSX | MASK_RECIP_PRECISION},
1829 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1830 {"powerpc64", PROCESSOR_POWERPC64,
1831 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1832 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1833 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1834 {"rios2", PROCESSOR_RIOS2,
1835 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1836 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1837 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1838 {"rs64", PROCESSOR_RS64A,
1839 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1842 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1846 rs6000_cpu_name_lookup (const char *name)
1852 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1853 if (! strcmp (name, processor_target_table[i].name))
1861 /* Return number of consecutive hard regs needed starting at reg REGNO
1862 to hold something of mode MODE.
1863 This is ordinarily the length in words of a value of mode MODE
1864 but can be less for certain modes in special long registers.
1866 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1867 scalar instructions. The upper 32 bits are only available to the
1870 POWER and PowerPC GPRs hold 32 bits worth;
1871 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1874 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1876 unsigned HOST_WIDE_INT reg_size;
1878 if (FP_REGNO_P (regno))
1879 reg_size = (VECTOR_MEM_VSX_P (mode)
1880 ? UNITS_PER_VSX_WORD
1881 : UNITS_PER_FP_WORD);
1883 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1884 reg_size = UNITS_PER_SPE_WORD;
1886 else if (ALTIVEC_REGNO_P (regno))
1887 reg_size = UNITS_PER_ALTIVEC_WORD;
1889 /* The value returned for SCmode in the E500 double case is 2 for
1890 ABI compatibility; storing an SCmode value in a single register
1891 would require function_arg and rs6000_spe_function_arg to handle
1892 SCmode so as to pass the value correctly in a pair of
1894 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1895 && !DECIMAL_FLOAT_MODE_P (mode))
1896 reg_size = UNITS_PER_FP_WORD;
1899 reg_size = UNITS_PER_WORD;
1901 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1904 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1907 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1909 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1911 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1912 implementations. Don't allow an item to be split between a FP register
1913 and an Altivec register. */
1914 if (VECTOR_MEM_VSX_P (mode))
1916 if (FP_REGNO_P (regno))
1917 return FP_REGNO_P (last_regno);
1919 if (ALTIVEC_REGNO_P (regno))
1920 return ALTIVEC_REGNO_P (last_regno);
1923 /* The GPRs can hold any mode, but values bigger than one register
1924 cannot go past R31. */
1925 if (INT_REGNO_P (regno))
1926 return INT_REGNO_P (last_regno);
1928 /* The float registers (except for VSX vector modes) can only hold floating
1929 modes and DImode. This excludes the 32-bit decimal float mode for
1931 if (FP_REGNO_P (regno))
1933 if (SCALAR_FLOAT_MODE_P (mode)
1934 && (mode != TDmode || (regno % 2) == 0)
1935 && FP_REGNO_P (last_regno))
1938 if (GET_MODE_CLASS (mode) == MODE_INT
1939 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1942 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1943 && PAIRED_VECTOR_MODE (mode))
1949 /* The CR register can only hold CC modes. */
1950 if (CR_REGNO_P (regno))
1951 return GET_MODE_CLASS (mode) == MODE_CC;
1953 if (CA_REGNO_P (regno))
1954 return mode == BImode;
1956 /* AltiVec only in AldyVec registers. */
1957 if (ALTIVEC_REGNO_P (regno))
1958 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1960 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1961 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1964 /* We cannot put TImode anywhere except general register and it must be able
1965 to fit within the register set. In the future, allow TImode in the
1966 Altivec or VSX registers. */
1968 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1971 /* Print interesting facts about registers. */
1973 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1977 for (r = first_regno; r <= last_regno; ++r)
1979 const char *comma = "";
1982 if (first_regno == last_regno)
1983 fprintf (stderr, "%s:\t", reg_name);
1985 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1988 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1989 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1993 fprintf (stderr, ",\n\t");
1998 if (rs6000_hard_regno_nregs[m][r] > 1)
1999 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
2000 rs6000_hard_regno_nregs[m][r]);
2002 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2007 if (call_used_regs[r])
2011 fprintf (stderr, ",\n\t");
2016 len += fprintf (stderr, "%s%s", comma, "call-used");
2024 fprintf (stderr, ",\n\t");
2029 len += fprintf (stderr, "%s%s", comma, "fixed");
2035 fprintf (stderr, ",\n\t");
2039 fprintf (stderr, "%sregno = %d\n", comma, r);
2043 #define DEBUG_FMT_D "%-32s= %d\n"
2044 #define DEBUG_FMT_S "%-32s= %s\n"
2046 /* Print various interesting information with -mdebug=reg. */
2048 rs6000_debug_reg_global (void)
2050 static const char *const tf[2] = { "false", "true" };
2051 const char *nl = (const char *)0;
2053 char costly_num[20];
2055 const char *costly_str;
2056 const char *nop_str;
2057 const char *trace_str;
2058 const char *abi_str;
2059 const char *cmodel_str;
2061 /* Map enum rs6000_vector to string. */
2062 static const char *rs6000_debug_vector_unit[] = {
2071 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2072 LAST_VIRTUAL_REGISTER);
2073 rs6000_debug_reg_print (0, 31, "gr");
2074 rs6000_debug_reg_print (32, 63, "fp");
2075 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2078 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2079 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2080 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2081 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2082 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2083 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2084 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2085 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2086 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2090 "d reg_class = %s\n"
2091 "f reg_class = %s\n"
2092 "v reg_class = %s\n"
2093 "wa reg_class = %s\n"
2094 "wd reg_class = %s\n"
2095 "wf reg_class = %s\n"
2096 "ws reg_class = %s\n\n",
2097 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2101 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2102 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2103 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2105 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2106 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2109 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2111 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2112 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2118 if (rs6000_recip_control)
2120 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2122 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2123 if (rs6000_recip_bits[m])
2126 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2128 (RS6000_RECIP_AUTO_RE_P (m)
2130 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2131 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2133 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2136 fputs ("\n", stderr);
2139 if (rs6000_cpu_index >= 0)
2140 fprintf (stderr, DEBUG_FMT_S, "cpu",
2141 processor_target_table[rs6000_cpu_index].name);
2143 if (rs6000_tune_index >= 0)
2144 fprintf (stderr, DEBUG_FMT_S, "tune",
2145 processor_target_table[rs6000_tune_index].name);
2147 switch (rs6000_sched_costly_dep)
2149 case max_dep_latency:
2150 costly_str = "max_dep_latency";
2154 costly_str = "no_dep_costly";
2157 case all_deps_costly:
2158 costly_str = "all_deps_costly";
2161 case true_store_to_load_dep_costly:
2162 costly_str = "true_store_to_load_dep_costly";
2165 case store_to_load_dep_costly:
2166 costly_str = "store_to_load_dep_costly";
2170 costly_str = costly_num;
2171 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2175 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2177 switch (rs6000_sched_insert_nops)
2179 case sched_finish_regroup_exact:
2180 nop_str = "sched_finish_regroup_exact";
2183 case sched_finish_pad_groups:
2184 nop_str = "sched_finish_pad_groups";
2187 case sched_finish_none:
2188 nop_str = "sched_finish_none";
2193 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2197 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2199 switch (rs6000_sdata)
2206 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2210 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2214 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2219 switch (rs6000_traceback)
2221 case traceback_default: trace_str = "default"; break;
2222 case traceback_none: trace_str = "none"; break;
2223 case traceback_part: trace_str = "part"; break;
2224 case traceback_full: trace_str = "full"; break;
2225 default: trace_str = "unknown"; break;
2228 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2230 switch (rs6000_current_cmodel)
2232 case CMODEL_SMALL: cmodel_str = "small"; break;
2233 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2234 case CMODEL_LARGE: cmodel_str = "large"; break;
2235 default: cmodel_str = "unknown"; break;
2238 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2240 switch (rs6000_current_abi)
2242 case ABI_NONE: abi_str = "none"; break;
2243 case ABI_AIX: abi_str = "aix"; break;
2244 case ABI_V4: abi_str = "V4"; break;
2245 case ABI_DARWIN: abi_str = "darwin"; break;
2246 default: abi_str = "unknown"; break;
2249 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2251 if (rs6000_altivec_abi)
2252 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2255 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2257 if (rs6000_darwin64_abi)
2258 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2260 if (rs6000_float_gprs)
2261 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2263 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2264 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2265 tf[!!rs6000_align_branch_targets]);
2266 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2267 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2268 rs6000_long_double_type_size);
2269 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2270 (int)rs6000_sched_restricted_insns_priority);
2273 /* Initialize the various global tables that are based on register size. */
2275 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2281 /* Precalculate REGNO_REG_CLASS. */
2282 rs6000_regno_regclass[0] = GENERAL_REGS;
2283 for (r = 1; r < 32; ++r)
2284 rs6000_regno_regclass[r] = BASE_REGS;
2286 for (r = 32; r < 64; ++r)
2287 rs6000_regno_regclass[r] = FLOAT_REGS;
2289 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2290 rs6000_regno_regclass[r] = NO_REGS;
2292 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2293 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2295 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2296 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2297 rs6000_regno_regclass[r] = CR_REGS;
2299 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2300 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2301 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2302 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2303 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2304 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2305 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2306 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2307 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2308 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2310 /* Precalculate vector information, this must be set up before the
2311 rs6000_hard_regno_nregs_internal below. */
2312 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2314 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2315 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2316 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2319 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2320 rs6000_constraints[c] = NO_REGS;
2322 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2323 believes it can use native alignment or still uses 128-bit alignment. */
2324 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2335 /* V2DF mode, VSX only. */
2338 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2339 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2340 rs6000_vector_align[V2DFmode] = align64;
2343 /* V4SF mode, either VSX or Altivec. */
2346 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2347 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2348 rs6000_vector_align[V4SFmode] = align32;
2350 else if (TARGET_ALTIVEC)
2352 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2353 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2354 rs6000_vector_align[V4SFmode] = align32;
2357 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2361 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2362 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2363 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2364 rs6000_vector_align[V4SImode] = align32;
2365 rs6000_vector_align[V8HImode] = align32;
2366 rs6000_vector_align[V16QImode] = align32;
2370 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2371 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2372 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2376 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2377 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2378 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2382 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2383 Altivec doesn't have 64-bit support. */
2386 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2387 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2388 rs6000_vector_align[V2DImode] = align64;
2391 /* DFmode, see if we want to use the VSX unit. */
2392 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2394 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2395 rs6000_vector_mem[DFmode]
2396 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2397 rs6000_vector_align[DFmode] = align64;
2400 /* TODO add SPE and paired floating point vector support. */
2402 /* Register class constaints for the constraints that depend on compile
2404 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2405 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2407 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2408 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2412 /* At present, we just use VSX_REGS, but we have different constraints
2413 based on the use, in case we want to fine tune the default register
2414 class used. wa = any VSX register, wf = register class to use for
2415 V4SF, wd = register class to use for V2DF, and ws = register classs to
2416 use for DF scalars. */
2417 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2418 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2419 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2420 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2426 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2428 /* Set up the reload helper functions. */
2429 if (TARGET_VSX || TARGET_ALTIVEC)
2433 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2434 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2435 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2436 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2437 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2438 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2439 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2440 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2441 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2442 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2443 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2444 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2448 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2449 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2450 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2451 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2452 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2453 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2454 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2455 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2456 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2457 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2458 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2459 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2463 /* Precalculate HARD_REGNO_NREGS. */
2464 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2465 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2466 rs6000_hard_regno_nregs[m][r]
2467 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2469 /* Precalculate HARD_REGNO_MODE_OK. */
2470 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2471 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2472 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2473 rs6000_hard_regno_mode_ok_p[m][r] = true;
2475 /* Precalculate CLASS_MAX_NREGS sizes. */
2476 for (c = 0; c < LIM_REG_CLASSES; ++c)
2480 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2481 reg_size = UNITS_PER_VSX_WORD;
2483 else if (c == ALTIVEC_REGS)
2484 reg_size = UNITS_PER_ALTIVEC_WORD;
2486 else if (c == FLOAT_REGS)
2487 reg_size = UNITS_PER_FP_WORD;
2490 reg_size = UNITS_PER_WORD;
2492 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2493 rs6000_class_max_nregs[m][c]
2494 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2497 if (TARGET_E500_DOUBLE)
2498 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2500 /* Calculate which modes to automatically generate code to use a the
2501 reciprocal divide and square root instructions. In the future, possibly
2502 automatically generate the instructions even if the user did not specify
2503 -mrecip. The older machines double precision reciprocal sqrt estimate is
2504 not accurate enough. */
2505 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2507 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2509 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2510 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2511 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2512 if (VECTOR_UNIT_VSX_P (V2DFmode))
2513 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2515 if (TARGET_FRSQRTES)
2516 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2518 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2519 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2520 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2521 if (VECTOR_UNIT_VSX_P (V2DFmode))
2522 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2524 if (rs6000_recip_control)
2526 if (!flag_finite_math_only)
2527 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2528 if (flag_trapping_math)
2529 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2530 if (!flag_reciprocal_math)
2531 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2532 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2534 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2535 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2536 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2538 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2539 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2540 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2542 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2543 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2544 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2546 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2547 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2548 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2550 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2551 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2552 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2554 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2555 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2556 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2558 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2559 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2560 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2562 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2563 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2564 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2568 if (global_init_p || TARGET_DEBUG_TARGET)
2570 if (TARGET_DEBUG_REG)
2571 rs6000_debug_reg_global ();
2573 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2575 "SImode variable mult cost = %d\n"
2576 "SImode constant mult cost = %d\n"
2577 "SImode short constant mult cost = %d\n"
2578 "DImode multipliciation cost = %d\n"
2579 "SImode division cost = %d\n"
2580 "DImode division cost = %d\n"
2581 "Simple fp operation cost = %d\n"
2582 "DFmode multiplication cost = %d\n"
2583 "SFmode division cost = %d\n"
2584 "DFmode division cost = %d\n"
2585 "cache line size = %d\n"
2586 "l1 cache size = %d\n"
2587 "l2 cache size = %d\n"
2588 "simultaneous prefetches = %d\n"
2591 rs6000_cost->mulsi_const,
2592 rs6000_cost->mulsi_const9,
2600 rs6000_cost->cache_line_size,
2601 rs6000_cost->l1_cache_size,
2602 rs6000_cost->l2_cache_size,
2603 rs6000_cost->simultaneous_prefetches);
2608 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2611 darwin_rs6000_override_options (void)
2613 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2615 rs6000_altivec_abi = 1;
2616 TARGET_ALTIVEC_VRSAVE = 1;
2618 if (DEFAULT_ABI == ABI_DARWIN
2620 darwin_one_byte_bool = 1;
2622 if (TARGET_64BIT && ! TARGET_POWERPC64)
2624 target_flags |= MASK_POWERPC64;
2625 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2629 rs6000_default_long_calls = 1;
2630 target_flags |= MASK_SOFT_FLOAT;
2633 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2635 if (!flag_mkernel && !flag_apple_kext
2637 && ! (target_flags_explicit & MASK_ALTIVEC))
2638 target_flags |= MASK_ALTIVEC;
2640 /* Unless the user (not the configurer) has explicitly overridden
2641 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2642 G4 unless targetting the kernel. */
2645 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2646 && ! (target_flags_explicit & MASK_ALTIVEC)
2647 && ! rs6000_select[1].string)
2649 target_flags |= MASK_ALTIVEC;
2654 /* If not otherwise specified by a target, make 'long double' equivalent to
2657 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2658 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2661 /* Override command line options. Mostly we process the processor type and
2662 sometimes adjust other TARGET_ options. */
2665 rs6000_option_override_internal (bool global_init_p)
2668 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2672 struct cl_target_option *main_target_opt
2673 = ((global_init_p || target_option_default_node == NULL)
2674 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2676 /* Numerous experiment shows that IRA based loop pressure
2677 calculation works better for RTL loop invariant motion on targets
2678 with enough (>= 32) registers. It is an expensive optimization.
2679 So it is on only for peak performance. */
2680 if (optimize >= 3 && global_init_p)
2681 flag_ira_loop_pressure = 1;
2683 /* Set the pointer size. */
2686 rs6000_pmode = (int)DImode;
2687 rs6000_pointer_size = 64;
2691 rs6000_pmode = (int)SImode;
2692 rs6000_pointer_size = 32;
2695 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2696 #ifdef OS_MISSING_POWERPC64
2697 if (OS_MISSING_POWERPC64)
2698 set_masks &= ~MASK_POWERPC64;
2700 #ifdef OS_MISSING_ALTIVEC
2701 if (OS_MISSING_ALTIVEC)
2702 set_masks &= ~MASK_ALTIVEC;
2705 /* Don't override by the processor default if given explicitly. */
2706 set_masks &= ~target_flags_explicit;
2708 /* Identify the processor type. */
2711 if (TARGET_POWERPC64)
2712 default_cpu = "powerpc64";
2713 else if (TARGET_POWERPC)
2714 default_cpu = "powerpc";
2717 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2718 the cpu in a target attribute or pragma, but did not specify a tuning
2719 option, use the cpu for the tuning option rather than the option specified
2720 with -mtune on the command line. */
2721 if (rs6000_cpu_index > 0)
2722 cpu_index = rs6000_cpu_index;
2723 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2724 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2726 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2728 if (rs6000_tune_index > 0)
2729 tune_index = rs6000_tune_index;
2731 rs6000_tune_index = tune_index = cpu_index;
2735 target_flags &= ~set_masks;
2736 target_flags |= (processor_target_table[cpu_index].target_enable
2740 rs6000_cpu = ((tune_index >= 0)
2741 ? processor_target_table[tune_index].processor
2743 ? PROCESSOR_DEFAULT64
2744 : PROCESSOR_DEFAULT));
2746 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2747 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2750 error ("AltiVec not supported in this target");
2752 error ("SPE not supported in this target");
2755 /* Disable Cell microcode if we are optimizing for the Cell
2756 and not optimizing for size. */
2757 if (rs6000_gen_cell_microcode == -1)
2758 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2761 /* If we are optimizing big endian systems for space and it's OK to
2762 use instructions that would be microcoded on the Cell, use the
2763 load/store multiple and string instructions. */
2764 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2765 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2767 /* Don't allow -mmultiple or -mstring on little endian systems
2768 unless the cpu is a 750, because the hardware doesn't support the
2769 instructions used in little endian mode, and causes an alignment
2770 trap. The 750 does not cause an alignment trap (except when the
2771 target is unaligned). */
2773 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2775 if (TARGET_MULTIPLE)
2777 target_flags &= ~MASK_MULTIPLE;
2778 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2779 warning (0, "-mmultiple is not supported on little endian systems");
2784 target_flags &= ~MASK_STRING;
2785 if ((target_flags_explicit & MASK_STRING) != 0)
2786 warning (0, "-mstring is not supported on little endian systems");
2790 /* Add some warnings for VSX. */
2793 const char *msg = NULL;
2794 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2795 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2797 if (target_flags_explicit & MASK_VSX)
2798 msg = N_("-mvsx requires hardware floating point");
2800 target_flags &= ~ MASK_VSX;
2802 else if (TARGET_PAIRED_FLOAT)
2803 msg = N_("-mvsx and -mpaired are incompatible");
2804 /* The hardware will allow VSX and little endian, but until we make sure
2805 things like vector select, etc. work don't allow VSX on little endian
2806 systems at this point. */
2807 else if (!BYTES_BIG_ENDIAN)
2808 msg = N_("-mvsx used with little endian code");
2809 else if (TARGET_AVOID_XFORM > 0)
2810 msg = N_("-mvsx needs indexed addressing");
2811 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2813 if (target_flags_explicit & MASK_VSX)
2814 msg = N_("-mvsx and -mno-altivec are incompatible");
2816 msg = N_("-mno-altivec disables vsx");
2822 target_flags &= ~ MASK_VSX;
2823 target_flags_explicit |= MASK_VSX;
2827 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2828 unless the user explicitly used the -mno-<option> to disable the code. */
2830 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2831 else if (TARGET_POPCNTD)
2832 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2833 else if (TARGET_DFP)
2834 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2835 else if (TARGET_CMPB)
2836 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2837 else if (TARGET_FPRND)
2838 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2839 else if (TARGET_POPCNTB)
2840 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2841 else if (TARGET_ALTIVEC)
2842 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2844 /* E500mc does "better" if we inline more aggressively. Respect the
2845 user's opinion, though. */
2846 if (rs6000_block_move_inline_limit == 0
2847 && (rs6000_cpu == PROCESSOR_PPCE500MC
2848 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2849 rs6000_block_move_inline_limit = 128;
2851 /* store_one_arg depends on expand_block_move to handle at least the
2852 size of reg_parm_stack_space. */
2853 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2854 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2858 /* If the appropriate debug option is enabled, replace the target hooks
2859 with debug versions that call the real version and then prints
2860 debugging information. */
2861 if (TARGET_DEBUG_COST)
2863 targetm.rtx_costs = rs6000_debug_rtx_costs;
2864 targetm.address_cost = rs6000_debug_address_cost;
2865 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2868 if (TARGET_DEBUG_ADDR)
2870 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2871 targetm.legitimize_address = rs6000_debug_legitimize_address;
2872 rs6000_secondary_reload_class_ptr
2873 = rs6000_debug_secondary_reload_class;
2874 rs6000_secondary_memory_needed_ptr
2875 = rs6000_debug_secondary_memory_needed;
2876 rs6000_cannot_change_mode_class_ptr
2877 = rs6000_debug_cannot_change_mode_class;
2878 rs6000_preferred_reload_class_ptr
2879 = rs6000_debug_preferred_reload_class;
2880 rs6000_legitimize_reload_address_ptr
2881 = rs6000_debug_legitimize_reload_address;
2882 rs6000_mode_dependent_address_ptr
2883 = rs6000_debug_mode_dependent_address;
2886 if (rs6000_veclibabi_name)
2888 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2889 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2892 error ("unknown vectorization library ABI type (%s) for "
2893 "-mveclibabi= switch", rs6000_veclibabi_name);
2899 if (!rs6000_explicit_options.long_double)
2901 if (main_target_opt != NULL
2902 && (main_target_opt->x_rs6000_long_double_type_size
2903 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2904 error ("target attribute or pragma changes long double size");
2906 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2909 #ifndef POWERPC_LINUX
2910 if (!rs6000_explicit_options.ieee)
2911 rs6000_ieeequad = 1;
2914 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2915 target attribute or pragma which automatically enables both options,
2916 unless the altivec ABI was set. This is set by default for 64-bit, but
2918 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2919 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2921 /* Enable Altivec ABI for AIX -maltivec. */
2922 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2924 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2925 error ("target attribute or pragma changes AltiVec ABI");
2927 rs6000_altivec_abi = 1;
2930 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2931 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2932 be explicitly overridden in either case. */
2935 if (!rs6000_explicit_options.altivec_abi
2936 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2938 if (main_target_opt != NULL &&
2939 !main_target_opt->x_rs6000_altivec_abi)
2940 error ("target attribute or pragma changes AltiVec ABI");
2942 rs6000_altivec_abi = 1;
2945 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2946 if (!rs6000_explicit_options.vrsave)
2947 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2950 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2951 So far, the only darwin64 targets are also MACH-O. */
2953 && DEFAULT_ABI == ABI_DARWIN
2956 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2957 error ("target attribute or pragma changes darwin64 ABI");
2960 rs6000_darwin64_abi = 1;
2961 /* Default to natural alignment, for better performance. */
2962 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2966 /* Place FP constants in the constant pool instead of TOC
2967 if section anchors enabled. */
2968 if (flag_section_anchors)
2969 TARGET_NO_FP_IN_TOC = 1;
2971 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2972 SUBTARGET_OVERRIDE_OPTIONS;
2974 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2975 SUBSUBTARGET_OVERRIDE_OPTIONS;
2977 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2978 SUB3TARGET_OVERRIDE_OPTIONS;
2981 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2982 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2984 /* The e500 and e500mc do not have string instructions, and we set
2985 MASK_STRING above when optimizing for size. */
2986 if ((target_flags & MASK_STRING) != 0)
2987 target_flags = target_flags & ~MASK_STRING;
2989 else if (rs6000_select[1].string != NULL)
2991 /* For the powerpc-eabispe configuration, we set all these by
2992 default, so let's unset them if we manually set another
2993 CPU that is not the E500. */
2994 if (main_target_opt != NULL
2995 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2996 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2997 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2998 error ("target attribute or pragma changes SPE ABI");
3001 if (!rs6000_explicit_options.spe_abi)
3003 if (!rs6000_explicit_options.spe)
3005 if (!rs6000_explicit_options.float_gprs)
3006 rs6000_float_gprs = 0;
3008 if (!(target_flags_explicit & MASK_ISEL))
3009 target_flags &= ~MASK_ISEL;
3012 /* Detect invalid option combinations with E500. */
3015 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3016 && rs6000_cpu != PROCESSOR_POWER5
3017 && rs6000_cpu != PROCESSOR_POWER6
3018 && rs6000_cpu != PROCESSOR_POWER7
3019 && rs6000_cpu != PROCESSOR_PPCA2
3020 && rs6000_cpu != PROCESSOR_CELL);
3021 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3022 || rs6000_cpu == PROCESSOR_POWER5
3023 || rs6000_cpu == PROCESSOR_POWER7);
3024 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3025 || rs6000_cpu == PROCESSOR_POWER5
3026 || rs6000_cpu == PROCESSOR_POWER6
3027 || rs6000_cpu == PROCESSOR_POWER7
3028 || rs6000_cpu == PROCESSOR_PPCE500MC
3029 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3031 /* Allow debug switches to override the above settings. These are set to -1
3032 in rs6000.opt to indicate the user hasn't directly set the switch. */
3033 if (TARGET_ALWAYS_HINT >= 0)
3034 rs6000_always_hint = TARGET_ALWAYS_HINT;
3036 if (TARGET_SCHED_GROUPS >= 0)
3037 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3039 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3040 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3042 rs6000_sched_restricted_insns_priority
3043 = (rs6000_sched_groups ? 1 : 0);
3045 /* Handle -msched-costly-dep option. */
3046 rs6000_sched_costly_dep
3047 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3049 if (rs6000_sched_costly_dep_str)
3051 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3052 rs6000_sched_costly_dep = no_dep_costly;
3053 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3054 rs6000_sched_costly_dep = all_deps_costly;
3055 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3056 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3057 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3058 rs6000_sched_costly_dep = store_to_load_dep_costly;
3060 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3061 atoi (rs6000_sched_costly_dep_str));
3064 /* Handle -minsert-sched-nops option. */
3065 rs6000_sched_insert_nops
3066 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3068 if (rs6000_sched_insert_nops_str)
3070 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3071 rs6000_sched_insert_nops = sched_finish_none;
3072 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3073 rs6000_sched_insert_nops = sched_finish_pad_groups;
3074 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3075 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3077 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3078 atoi (rs6000_sched_insert_nops_str));
3083 #ifdef TARGET_REGNAMES
3084 /* If the user desires alternate register names, copy in the
3085 alternate names now. */
3086 if (TARGET_REGNAMES)
3087 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3090 /* Set aix_struct_return last, after the ABI is determined.
3091 If -maix-struct-return or -msvr4-struct-return was explicitly
3092 used, don't override with the ABI default. */
3093 if (!rs6000_explicit_options.aix_struct_ret)
3094 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3097 /* IBM XL compiler defaults to unsigned bitfields. */
3098 if (TARGET_XL_COMPAT)
3099 flag_signed_bitfields = 0;
3102 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3103 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3106 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3108 /* We can only guarantee the availability of DI pseudo-ops when
3109 assembling for 64-bit targets. */
3112 targetm.asm_out.aligned_op.di = NULL;
3113 targetm.asm_out.unaligned_op.di = NULL;
3117 /* Set branch target alignment, if not optimizing for size. */
3120 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3121 aligned 8byte to avoid misprediction by the branch predictor. */
3122 if (rs6000_cpu == PROCESSOR_TITAN
3123 || rs6000_cpu == PROCESSOR_CELL)
3125 if (align_functions <= 0)
3126 align_functions = 8;
3127 if (align_jumps <= 0)
3129 if (align_loops <= 0)
3132 if (rs6000_align_branch_targets)
3134 if (align_functions <= 0)
3135 align_functions = 16;
3136 if (align_jumps <= 0)
3138 if (align_loops <= 0)
3140 can_override_loop_align = 1;
3144 if (align_jumps_max_skip <= 0)
3145 align_jumps_max_skip = 15;
3146 if (align_loops_max_skip <= 0)
3147 align_loops_max_skip = 15;
3150 /* Arrange to save and restore machine status around nested functions. */
3151 init_machine_status = rs6000_init_machine_status;
3153 /* We should always be splitting complex arguments, but we can't break
3154 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3155 if (DEFAULT_ABI != ABI_AIX)
3156 targetm.calls.split_complex_arg = NULL;
3159 /* Initialize rs6000_cost with the appropriate target costs. */
3161 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3165 case PROCESSOR_RIOS1:
3166 rs6000_cost = &rios1_cost;
3169 case PROCESSOR_RIOS2:
3170 rs6000_cost = &rios2_cost;
3173 case PROCESSOR_RS64A:
3174 rs6000_cost = &rs64a_cost;
3177 case PROCESSOR_MPCCORE:
3178 rs6000_cost = &mpccore_cost;
3181 case PROCESSOR_PPC403:
3182 rs6000_cost = &ppc403_cost;
3185 case PROCESSOR_PPC405:
3186 rs6000_cost = &ppc405_cost;
3189 case PROCESSOR_PPC440:
3190 rs6000_cost = &ppc440_cost;
3193 case PROCESSOR_PPC476:
3194 rs6000_cost = &ppc476_cost;
3197 case PROCESSOR_PPC601:
3198 rs6000_cost = &ppc601_cost;
3201 case PROCESSOR_PPC603:
3202 rs6000_cost = &ppc603_cost;
3205 case PROCESSOR_PPC604:
3206 rs6000_cost = &ppc604_cost;
3209 case PROCESSOR_PPC604e:
3210 rs6000_cost = &ppc604e_cost;
3213 case PROCESSOR_PPC620:
3214 rs6000_cost = &ppc620_cost;
3217 case PROCESSOR_PPC630:
3218 rs6000_cost = &ppc630_cost;
3221 case PROCESSOR_CELL:
3222 rs6000_cost = &ppccell_cost;
3225 case PROCESSOR_PPC750:
3226 case PROCESSOR_PPC7400:
3227 rs6000_cost = &ppc750_cost;
3230 case PROCESSOR_PPC7450:
3231 rs6000_cost = &ppc7450_cost;
3234 case PROCESSOR_PPC8540:
3235 rs6000_cost = &ppc8540_cost;
3238 case PROCESSOR_PPCE300C2:
3239 case PROCESSOR_PPCE300C3:
3240 rs6000_cost = &ppce300c2c3_cost;
3243 case PROCESSOR_PPCE500MC:
3244 rs6000_cost = &ppce500mc_cost;
3247 case PROCESSOR_PPCE500MC64:
3248 rs6000_cost = &ppce500mc64_cost;
3251 case PROCESSOR_TITAN:
3252 rs6000_cost = &titan_cost;
3255 case PROCESSOR_POWER4:
3256 case PROCESSOR_POWER5:
3257 rs6000_cost = &power4_cost;
3260 case PROCESSOR_POWER6:
3261 rs6000_cost = &power6_cost;
3264 case PROCESSOR_POWER7:
3265 rs6000_cost = &power7_cost;
3268 case PROCESSOR_PPCA2:
3269 rs6000_cost = &ppca2_cost;
3278 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3279 rs6000_cost->simultaneous_prefetches,
3280 global_options.x_param_values,
3281 global_options_set.x_param_values);
3282 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3283 global_options.x_param_values,
3284 global_options_set.x_param_values);
3285 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3286 rs6000_cost->cache_line_size,
3287 global_options.x_param_values,
3288 global_options_set.x_param_values);
3289 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3290 global_options.x_param_values,
3291 global_options_set.x_param_values);
3293 /* If using typedef char *va_list, signal that
3294 __builtin_va_start (&ap, 0) can be optimized to
3295 ap = __builtin_next_arg (0). */
3296 if (DEFAULT_ABI != ABI_V4)
3297 targetm.expand_builtin_va_start = NULL;
3300 /* Set up single/double float flags.
3301 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3302 then set both flags. */
3303 if (TARGET_HARD_FLOAT && TARGET_FPRS
3304 && rs6000_single_float == 0 && rs6000_double_float == 0)
3305 rs6000_single_float = rs6000_double_float = 1;
3307 /* Reset single and double FP flags if target is E500. */
3310 rs6000_single_float = rs6000_double_float = 0;
3311 if (TARGET_E500_SINGLE)
3312 rs6000_single_float = 1;
3313 if (TARGET_E500_DOUBLE)
3314 rs6000_single_float = rs6000_double_float = 1;
3317 if (main_target_opt)
3319 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3320 error ("target attribute or pragma changes single precision floating "
3322 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3323 error ("target attribute or pragma changes double precision floating "
3327 /* If not explicitly specified via option, decide whether to generate indexed
3328 load/store instructions. */
3329 if (TARGET_AVOID_XFORM == -1)
3330 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3331 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3332 need indexed accesses and the type used is the scalar type of the element
3333 being loaded or stored. */
3334 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3335 && !TARGET_ALTIVEC);
3337 /* Set the -mrecip options. */
3338 if (rs6000_recip_name)
3340 char *p = ASTRDUP (rs6000_recip_name);
3342 unsigned int mask, i;
3345 while ((q = strtok (p, ",")) != NULL)
3356 if (!strcmp (q, "default"))
3357 mask = ((TARGET_RECIP_PRECISION)
3358 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3361 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3362 if (!strcmp (q, recip_options[i].string))
3364 mask = recip_options[i].mask;
3368 if (i == ARRAY_SIZE (recip_options))
3370 error ("unknown option for -mrecip=%s", q);
3378 rs6000_recip_control &= ~mask;
3380 rs6000_recip_control |= mask;
3384 rs6000_init_hard_regno_mode_ok (global_init_p);
3386 /* Save the initial options in case the user does function specific options */
3388 target_option_default_node = target_option_current_node
3389 = build_target_option_node ();
3394 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3395 define the target cpu type. */
3398 rs6000_option_override (void)
3400 (void) rs6000_option_override_internal (true);
3404 /* Implement targetm.vectorize.builtin_mask_for_load. */
3406 rs6000_builtin_mask_for_load (void)
3408 if (TARGET_ALTIVEC || TARGET_VSX)
3409 return altivec_builtin_mask_for_load;
3414 /* Implement LOOP_ALIGN. */
3416 rs6000_loop_align (rtx label)
3421 /* Don't override loop alignment if -falign-loops was specified. */
3422 if (!can_override_loop_align)
3423 return align_loops_log;
3425 bb = BLOCK_FOR_INSN (label);
3426 ninsns = num_loop_insns(bb->loop_father);
3428 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3429 if (ninsns > 4 && ninsns <= 8
3430 && (rs6000_cpu == PROCESSOR_POWER4
3431 || rs6000_cpu == PROCESSOR_POWER5
3432 || rs6000_cpu == PROCESSOR_POWER6
3433 || rs6000_cpu == PROCESSOR_POWER7))
3436 return align_loops_log;
3439 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3441 rs6000_loop_align_max_skip (rtx label)
3443 return (1 << rs6000_loop_align (label)) - 1;
3446 /* Implement targetm.vectorize.builtin_conversion.
3447 Returns a decl of a function that implements conversion of an integer vector
3448 into a floating-point vector, or vice-versa. DEST_TYPE is the
3449 destination type and SRC_TYPE the source type of the conversion.
3450 Return NULL_TREE if it is not available. */
3452 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3454 enum tree_code code = (enum tree_code) tcode;
3458 case FIX_TRUNC_EXPR:
3459 switch (TYPE_MODE (dest_type))
3462 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3465 return TYPE_UNSIGNED (dest_type)
3466 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3467 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3470 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3473 return TYPE_UNSIGNED (dest_type)
3474 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3475 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3482 switch (TYPE_MODE (src_type))
3485 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3488 return TYPE_UNSIGNED (src_type)
3489 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3490 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3493 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3496 return TYPE_UNSIGNED (src_type)
3497 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3498 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3509 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3511 rs6000_builtin_mul_widen_even (tree type)
3513 if (!TARGET_ALTIVEC)
3516 switch (TYPE_MODE (type))
3519 return TYPE_UNSIGNED (type)
3520 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3521 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3524 return TYPE_UNSIGNED (type)
3525 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3526 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3532 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3534 rs6000_builtin_mul_widen_odd (tree type)
3536 if (!TARGET_ALTIVEC)
3539 switch (TYPE_MODE (type))
3542 return TYPE_UNSIGNED (type)
3543 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3544 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3547 return TYPE_UNSIGNED (type)
3548 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3549 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3556 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3557 after applying N number of iterations. This routine does not determine
3558 how may iterations are required to reach desired alignment. */
3561 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3568 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3571 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3581 /* Assuming that all other types are naturally aligned. CHECKME! */
3586 /* Return true if the vector misalignment factor is supported by the
3589 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3596 /* Return if movmisalign pattern is not supported for this mode. */
3597 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3600 if (misalignment == -1)
3602 /* Misalignment factor is unknown at compile time but we know
3603 it's word aligned. */
3604 if (rs6000_vector_alignment_reachable (type, is_packed))
3606 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3608 if (element_size == 64 || element_size == 32)
3615 /* VSX supports word-aligned vector. */
3616 if (misalignment % 4 == 0)
3622 /* Implement targetm.vectorize.builtin_vec_perm. */
3624 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3626 tree inner_type = TREE_TYPE (type);
3627 bool uns_p = TYPE_UNSIGNED (inner_type);
3630 *mask_element_type = unsigned_char_type_node;
3632 switch (TYPE_MODE (type))
3636 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3637 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3642 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3643 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3648 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3649 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3653 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3657 if (!TARGET_ALLOW_DF_PERMUTE)
3660 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3664 if (!TARGET_ALLOW_DF_PERMUTE)
3668 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3669 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3681 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3683 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3684 tree vectype, int misalign)
3688 switch (type_of_cost)
3698 case cond_branch_not_taken:
3702 case cond_branch_taken:
3705 case unaligned_load:
3706 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3708 elements = TYPE_VECTOR_SUBPARTS (vectype);
3710 /* Double word aligned. */
3718 /* Double word aligned. */
3722 /* Unknown misalignment. */
3735 /* Misaligned loads are not supported. */
3740 case unaligned_store:
3741 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3743 elements = TYPE_VECTOR_SUBPARTS (vectype);
3745 /* Double word aligned. */
3753 /* Double word aligned. */
3757 /* Unknown misalignment. */
3770 /* Misaligned stores are not supported. */
3780 /* Implement targetm.vectorize.preferred_simd_mode. */
3782 static enum machine_mode
3783 rs6000_preferred_simd_mode (enum machine_mode mode)
3792 if (TARGET_ALTIVEC || TARGET_VSX)
3816 if (TARGET_PAIRED_FLOAT
3822 /* Implement TARGET_OPTION_INIT_STRUCT. */
3825 rs6000_option_init_struct (struct gcc_options *opts)
3827 if (DEFAULT_ABI == ABI_DARWIN)
3828 /* The Darwin libraries never set errno, so we might as well
3829 avoid calling them when that's the only reason we would. */
3830 opts->x_flag_errno_math = 0;
3832 /* Enable section anchors by default. */
3834 opts->x_flag_section_anchors = 1;
3837 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3840 rs6000_option_default_params (void)
3842 /* Double growth factor to counter reduced min jump length. */
3843 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3846 static enum fpu_type_t
3847 rs6000_parse_fpu_option (const char *option)
3849 if (!strcmp("none", option)) return FPU_NONE;
3850 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3851 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3852 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3853 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3854 error("unknown value %s for -mfpu", option);
3859 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3860 library with vectorized intrinsics. */
3863 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3866 const char *suffix = NULL;
3867 tree fntype, new_fndecl, bdecl = NULL_TREE;
3870 enum machine_mode el_mode, in_mode;
3873 /* Libmass is suitable for unsafe math only as it does not correctly support
3874 parts of IEEE with the required precision such as denormals. Only support
3875 it if we have VSX to use the simd d2 or f4 functions.
3876 XXX: Add variable length support. */
3877 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3880 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3881 n = TYPE_VECTOR_SUBPARTS (type_out);
3882 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3883 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3884 if (el_mode != in_mode
3888 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3890 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3893 case BUILT_IN_ATAN2:
3894 case BUILT_IN_HYPOT:
3900 case BUILT_IN_ACOSH:
3902 case BUILT_IN_ASINH:
3904 case BUILT_IN_ATANH:
3912 case BUILT_IN_EXPM1:
3913 case BUILT_IN_LGAMMA:
3914 case BUILT_IN_LOG10:
3915 case BUILT_IN_LOG1P:
3923 bdecl = implicit_built_in_decls[fn];
3924 suffix = "d2"; /* pow -> powd2 */
3925 if (el_mode != DFmode
3930 case BUILT_IN_ATAN2F:
3931 case BUILT_IN_HYPOTF:
3936 case BUILT_IN_ACOSF:
3937 case BUILT_IN_ACOSHF:
3938 case BUILT_IN_ASINF:
3939 case BUILT_IN_ASINHF:
3940 case BUILT_IN_ATANF:
3941 case BUILT_IN_ATANHF:
3942 case BUILT_IN_CBRTF:
3944 case BUILT_IN_COSHF:
3946 case BUILT_IN_ERFCF:
3947 case BUILT_IN_EXP2F:
3949 case BUILT_IN_EXPM1F:
3950 case BUILT_IN_LGAMMAF:
3951 case BUILT_IN_LOG10F:
3952 case BUILT_IN_LOG1PF:
3953 case BUILT_IN_LOG2F:
3956 case BUILT_IN_SINHF:
3957 case BUILT_IN_SQRTF:
3959 case BUILT_IN_TANHF:
3960 bdecl = implicit_built_in_decls[fn];
3961 suffix = "4"; /* powf -> powf4 */
3962 if (el_mode != SFmode
3974 gcc_assert (suffix != NULL);
3975 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3976 strcpy (name, bname + sizeof ("__builtin_") - 1);
3977 strcat (name, suffix);
3980 fntype = build_function_type_list (type_out, type_in, NULL);
3981 else if (n_args == 2)
3982 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3986 /* Build a function declaration for the vectorized function. */
3987 new_fndecl = build_decl (BUILTINS_LOCATION,
3988 FUNCTION_DECL, get_identifier (name), fntype);
3989 TREE_PUBLIC (new_fndecl) = 1;
3990 DECL_EXTERNAL (new_fndecl) = 1;
3991 DECL_IS_NOVOPS (new_fndecl) = 1;
3992 TREE_READONLY (new_fndecl) = 1;
3997 /* Returns a function decl for a vectorized version of the builtin function
3998 with builtin function code FN and the result vector type TYPE, or NULL_TREE
3999 if it is not available. */
4002 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4005 enum machine_mode in_mode, out_mode;
4008 if (TREE_CODE (type_out) != VECTOR_TYPE
4009 || TREE_CODE (type_in) != VECTOR_TYPE
4010 || !TARGET_VECTORIZE_BUILTINS)
4013 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4014 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4015 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4016 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4018 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4020 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4023 case BUILT_IN_COPYSIGN:
4024 if (VECTOR_UNIT_VSX_P (V2DFmode)
4025 && out_mode == DFmode && out_n == 2
4026 && in_mode == DFmode && in_n == 2)
4027 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4029 case BUILT_IN_COPYSIGNF:
4030 if (out_mode != SFmode || out_n != 4
4031 || in_mode != SFmode || in_n != 4)
4033 if (VECTOR_UNIT_VSX_P (V4SFmode))
4034 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4035 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4036 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4039 if (VECTOR_UNIT_VSX_P (V2DFmode)
4040 && out_mode == DFmode && out_n == 2
4041 && in_mode == DFmode && in_n == 2)
4042 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4044 case BUILT_IN_SQRTF:
4045 if (VECTOR_UNIT_VSX_P (V4SFmode)
4046 && out_mode == SFmode && out_n == 4
4047 && in_mode == SFmode && in_n == 4)
4048 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4051 if (VECTOR_UNIT_VSX_P (V2DFmode)
4052 && out_mode == DFmode && out_n == 2
4053 && in_mode == DFmode && in_n == 2)
4054 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4056 case BUILT_IN_CEILF:
4057 if (out_mode != SFmode || out_n != 4
4058 || in_mode != SFmode || in_n != 4)
4060 if (VECTOR_UNIT_VSX_P (V4SFmode))
4061 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4062 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4063 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4065 case BUILT_IN_FLOOR:
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_XVRDPIM];
4071 case BUILT_IN_FLOORF:
4072 if (out_mode != SFmode || out_n != 4
4073 || in_mode != SFmode || in_n != 4)
4075 if (VECTOR_UNIT_VSX_P (V4SFmode))
4076 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4077 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4078 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4081 if (VECTOR_UNIT_VSX_P (V2DFmode)
4082 && out_mode == DFmode && out_n == 2
4083 && in_mode == DFmode && in_n == 2)
4084 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4087 if (VECTOR_UNIT_VSX_P (V4SFmode)
4088 && out_mode == SFmode && out_n == 4
4089 && in_mode == SFmode && in_n == 4)
4090 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4091 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4092 && out_mode == SFmode && out_n == 4
4093 && in_mode == SFmode && in_n == 4)
4094 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4096 case BUILT_IN_TRUNC:
4097 if (VECTOR_UNIT_VSX_P (V2DFmode)
4098 && out_mode == DFmode && out_n == 2
4099 && in_mode == DFmode && in_n == 2)
4100 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4102 case BUILT_IN_TRUNCF:
4103 if (out_mode != SFmode || out_n != 4
4104 || in_mode != SFmode || in_n != 4)
4106 if (VECTOR_UNIT_VSX_P (V4SFmode))
4107 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4108 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4109 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4111 case BUILT_IN_NEARBYINT:
4112 if (VECTOR_UNIT_VSX_P (V2DFmode)
4113 && flag_unsafe_math_optimizations
4114 && out_mode == DFmode && out_n == 2
4115 && in_mode == DFmode && in_n == 2)
4116 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4118 case BUILT_IN_NEARBYINTF:
4119 if (VECTOR_UNIT_VSX_P (V4SFmode)
4120 && flag_unsafe_math_optimizations
4121 && out_mode == SFmode && out_n == 4
4122 && in_mode == SFmode && in_n == 4)
4123 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4126 if (VECTOR_UNIT_VSX_P (V2DFmode)
4127 && !flag_trapping_math
4128 && out_mode == DFmode && out_n == 2
4129 && in_mode == DFmode && in_n == 2)
4130 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4132 case BUILT_IN_RINTF:
4133 if (VECTOR_UNIT_VSX_P (V4SFmode)
4134 && !flag_trapping_math
4135 && out_mode == SFmode && out_n == 4
4136 && in_mode == SFmode && in_n == 4)
4137 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4144 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4146 enum rs6000_builtins fn
4147 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4150 case RS6000_BUILTIN_RSQRTF:
4151 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4152 && out_mode == SFmode && out_n == 4
4153 && in_mode == SFmode && in_n == 4)
4154 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4156 case RS6000_BUILTIN_RSQRT:
4157 if (VECTOR_UNIT_VSX_P (V2DFmode)
4158 && out_mode == DFmode && out_n == 2
4159 && in_mode == DFmode && in_n == 2)
4160 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4162 case RS6000_BUILTIN_RECIPF:
4163 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4164 && out_mode == SFmode && out_n == 4
4165 && in_mode == SFmode && in_n == 4)
4166 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4168 case RS6000_BUILTIN_RECIP:
4169 if (VECTOR_UNIT_VSX_P (V2DFmode)
4170 && out_mode == DFmode && out_n == 2
4171 && in_mode == DFmode && in_n == 2)
4172 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4179 /* Generate calls to libmass if appropriate. */
4180 if (rs6000_veclib_handler)
4181 return rs6000_veclib_handler (fndecl, type_out, type_in);
4187 /* Implement TARGET_HANDLE_OPTION. */
4190 rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
4191 const struct cl_decoded_option *decoded,
4192 location_t loc ATTRIBUTE_UNUSED)
4194 enum fpu_type_t fpu_type = FPU_NONE;
4196 size_t code = decoded->opt_index;
4197 const char *arg = decoded->arg;
4198 int value = decoded->value;
4200 gcc_assert (opts == &global_options);
4201 gcc_assert (opts_set == &global_options_set);
4206 target_flags &= ~(MASK_POWER | MASK_POWER2
4207 | MASK_MULTIPLE | MASK_STRING);
4208 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4209 | MASK_MULTIPLE | MASK_STRING);
4211 case OPT_mno_powerpc:
4212 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4213 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4214 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4215 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4218 target_flags &= ~MASK_MINIMAL_TOC;
4219 TARGET_NO_FP_IN_TOC = 0;
4220 TARGET_NO_SUM_IN_TOC = 0;
4221 target_flags_explicit |= MASK_MINIMAL_TOC;
4222 #ifdef TARGET_USES_SYSV4_OPT
4223 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4224 just the same as -mminimal-toc. */
4225 target_flags |= MASK_MINIMAL_TOC;
4226 target_flags_explicit |= MASK_MINIMAL_TOC;
4230 #ifdef TARGET_USES_SYSV4_OPT
4232 /* Make -mtoc behave like -mminimal-toc. */
4233 target_flags |= MASK_MINIMAL_TOC;
4234 target_flags_explicit |= MASK_MINIMAL_TOC;
4238 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4240 if (strcmp (arg, "small") == 0)
4241 rs6000_current_cmodel = CMODEL_SMALL;
4242 else if (strcmp (arg, "medium") == 0)
4243 rs6000_current_cmodel = CMODEL_MEDIUM;
4244 else if (strcmp (arg, "large") == 0)
4245 rs6000_current_cmodel = CMODEL_LARGE;
4248 error ("invalid option for -mcmodel: '%s'", arg);
4251 rs6000_explicit_options.cmodel = true;
4254 #ifdef TARGET_USES_AIX64_OPT
4259 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4260 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4261 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4264 #ifdef TARGET_USES_AIX64_OPT
4269 target_flags &= ~MASK_POWERPC64;
4270 target_flags_explicit |= MASK_POWERPC64;
4273 case OPT_minsert_sched_nops_:
4274 rs6000_sched_insert_nops_str = arg;
4277 case OPT_mminimal_toc:
4280 TARGET_NO_FP_IN_TOC = 0;
4281 TARGET_NO_SUM_IN_TOC = 0;
4288 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4289 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4296 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4297 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4301 case OPT_mpowerpc_gpopt:
4302 case OPT_mpowerpc_gfxopt:
4305 target_flags |= MASK_POWERPC;
4306 target_flags_explicit |= MASK_POWERPC;
4310 case OPT_maix_struct_return:
4311 case OPT_msvr4_struct_return:
4312 rs6000_explicit_options.aix_struct_ret = true;
4316 rs6000_explicit_options.vrsave = true;
4317 TARGET_ALTIVEC_VRSAVE = value;
4321 rs6000_explicit_options.spe = true;
4329 while ((q = strtok (p, ",")) != NULL)
4343 if (! strcmp (q, "all"))
4344 mask = MASK_DEBUG_ALL;
4345 else if (! strcmp (q, "stack"))
4346 mask = MASK_DEBUG_STACK;
4347 else if (! strcmp (q, "arg"))
4348 mask = MASK_DEBUG_ARG;
4349 else if (! strcmp (q, "reg"))
4350 mask = MASK_DEBUG_REG;
4351 else if (! strcmp (q, "addr"))
4352 mask = MASK_DEBUG_ADDR;
4353 else if (! strcmp (q, "cost"))
4354 mask = MASK_DEBUG_COST;
4355 else if (! strcmp (q, "target"))
4356 mask = MASK_DEBUG_TARGET;
4358 error ("unknown -mdebug-%s switch", q);
4361 rs6000_debug &= ~mask;
4363 rs6000_debug |= mask;
4367 #ifdef TARGET_USES_SYSV4_OPT
4369 rs6000_abi_name = arg;
4373 rs6000_sdata_name = arg;
4376 case OPT_mtls_size_:
4377 if (strcmp (arg, "16") == 0)
4378 rs6000_tls_size = 16;
4379 else if (strcmp (arg, "32") == 0)
4380 rs6000_tls_size = 32;
4381 else if (strcmp (arg, "64") == 0)
4382 rs6000_tls_size = 64;
4384 error ("bad value %qs for -mtls-size switch", arg);
4387 case OPT_mrelocatable:
4390 target_flags |= MASK_MINIMAL_TOC;
4391 target_flags_explicit |= MASK_MINIMAL_TOC;
4392 TARGET_NO_FP_IN_TOC = 1;
4396 case OPT_mrelocatable_lib:
4399 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4400 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4401 TARGET_NO_FP_IN_TOC = 1;
4405 target_flags &= ~MASK_RELOCATABLE;
4406 target_flags_explicit |= MASK_RELOCATABLE;
4412 if (!strcmp (arg, "altivec"))
4414 rs6000_explicit_options.altivec_abi = true;
4415 rs6000_altivec_abi = 1;
4417 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4420 else if (! strcmp (arg, "no-altivec"))
4422 rs6000_explicit_options.altivec_abi = true;
4423 rs6000_altivec_abi = 0;
4425 else if (! strcmp (arg, "spe"))
4427 rs6000_explicit_options.spe_abi = true;
4429 rs6000_altivec_abi = 0;
4430 if (!TARGET_SPE_ABI)
4431 error ("not configured for ABI: '%s'", arg);
4433 else if (! strcmp (arg, "no-spe"))
4435 rs6000_explicit_options.spe_abi = true;
4439 /* These are here for testing during development only, do not
4440 document in the manual please. */
4441 else if (! strcmp (arg, "d64"))
4443 rs6000_darwin64_abi = 1;
4444 warning (0, "using darwin64 ABI");
4446 else if (! strcmp (arg, "d32"))
4448 rs6000_darwin64_abi = 0;
4449 warning (0, "using old darwin ABI");
4452 else if (! strcmp (arg, "ibmlongdouble"))
4454 rs6000_explicit_options.ieee = true;
4455 rs6000_ieeequad = 0;
4456 warning (0, "using IBM extended precision long double");
4458 else if (! strcmp (arg, "ieeelongdouble"))
4460 rs6000_explicit_options.ieee = true;
4461 rs6000_ieeequad = 1;
4462 warning (0, "using IEEE extended precision long double");
4467 error ("unknown ABI specified: '%s'", arg);
4473 rs6000_select[1].string = arg;
4474 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4475 if (rs6000_cpu_index < 0)
4476 error ("bad value (%s) for -mcpu", arg);
4480 rs6000_select[2].string = arg;
4481 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4482 if (rs6000_tune_index < 0)
4483 error ("bad value (%s) for -mtune", arg);
4486 case OPT_mtraceback_:
4487 if (! strncmp (arg, "full", 4))
4488 rs6000_traceback = traceback_full;
4489 else if (! strncmp (arg, "part", 4))
4490 rs6000_traceback = traceback_part;
4491 else if (! strncmp (arg, "no", 2))
4492 rs6000_traceback = traceback_none;
4494 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4495 "%<partial%> or %<none%>", arg);
4498 case OPT_mfloat_gprs_:
4499 rs6000_explicit_options.float_gprs = true;
4500 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4501 rs6000_float_gprs = 1;
4502 else if (! strcmp (arg, "double"))
4503 rs6000_float_gprs = 2;
4504 else if (! strcmp (arg, "no"))
4505 rs6000_float_gprs = 0;
4508 error ("invalid option for -mfloat-gprs: '%s'", arg);
4513 case OPT_mlong_double_:
4514 rs6000_explicit_options.long_double = true;
4515 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4516 if (value != 64 && value != 128)
4518 error ("unknown switch -mlong-double-%s", arg);
4519 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4523 rs6000_long_double_type_size = value;
4526 case OPT_msched_costly_dep_:
4527 rs6000_sched_costly_dep_str = arg;
4531 rs6000_explicit_options.alignment = true;
4532 if (! strcmp (arg, "power"))
4534 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4535 some C library functions, so warn about it. The flag may be
4536 useful for performance studies from time to time though, so
4537 don't disable it entirely. */
4538 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4539 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4540 " it is incompatible with the installed C and C++ libraries");
4541 rs6000_alignment_flags = MASK_ALIGN_POWER;
4543 else if (! strcmp (arg, "natural"))
4544 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4547 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4552 case OPT_msingle_float:
4553 if (!TARGET_SINGLE_FPU)
4554 warning (0, "-msingle-float option equivalent to -mhard-float");
4555 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4556 rs6000_double_float = 0;
4557 target_flags &= ~MASK_SOFT_FLOAT;
4558 target_flags_explicit |= MASK_SOFT_FLOAT;
4561 case OPT_mdouble_float:
4562 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4563 rs6000_single_float = 1;
4564 target_flags &= ~MASK_SOFT_FLOAT;
4565 target_flags_explicit |= MASK_SOFT_FLOAT;
4568 case OPT_msimple_fpu:
4569 if (!TARGET_SINGLE_FPU)
4570 warning (0, "-msimple-fpu option ignored");
4573 case OPT_mhard_float:
4574 /* -mhard_float implies -msingle-float and -mdouble-float. */
4575 rs6000_single_float = rs6000_double_float = 1;
4578 case OPT_msoft_float:
4579 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4580 rs6000_single_float = rs6000_double_float = 0;
4584 fpu_type = rs6000_parse_fpu_option(arg);
4585 if (fpu_type != FPU_NONE)
4586 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4588 target_flags &= ~MASK_SOFT_FLOAT;
4589 target_flags_explicit |= MASK_SOFT_FLOAT;
4590 rs6000_xilinx_fpu = 1;
4591 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4592 rs6000_single_float = 1;
4593 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4594 rs6000_single_float = rs6000_double_float = 1;
4595 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4596 rs6000_simple_fpu = 1;
4600 /* -mfpu=none is equivalent to -msoft-float */
4601 target_flags |= MASK_SOFT_FLOAT;
4602 target_flags_explicit |= MASK_SOFT_FLOAT;
4603 rs6000_single_float = rs6000_double_float = 0;
4607 rs6000_recip_name = (value) ? "default" : "none";
4611 rs6000_recip_name = arg;
4617 /* Do anything needed at the start of the asm file. */
4620 rs6000_file_start (void)
4624 const char *start = buffer;
4625 struct rs6000_cpu_select *ptr;
4626 const char *default_cpu = TARGET_CPU_DEFAULT;
4627 FILE *file = asm_out_file;
4629 default_file_start ();
4631 #ifdef TARGET_BI_ARCH
4632 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4636 if (flag_verbose_asm)
4638 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4639 rs6000_select[0].string = default_cpu;
4641 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4643 ptr = &rs6000_select[i];
4644 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4646 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4651 if (PPC405_ERRATUM77)
4653 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4657 #ifdef USING_ELFOS_H
4658 switch (rs6000_sdata)
4660 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4661 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4662 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4663 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4666 if (rs6000_sdata && g_switch_value)
4668 fprintf (file, "%s -G %d", start,
4678 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4680 switch_to_section (toc_section);
4681 switch_to_section (text_section);
4686 /* Return nonzero if this function is known to have a null epilogue. */
4689 direct_return (void)
4691 if (reload_completed)
4693 rs6000_stack_t *info = rs6000_stack_info ();
4695 if (info->first_gp_reg_save == 32
4696 && info->first_fp_reg_save == 64
4697 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4698 && ! info->lr_save_p
4699 && ! info->cr_save_p
4700 && info->vrsave_mask == 0
4708 /* Return the number of instructions it takes to form a constant in an
4709 integer register. */
4712 num_insns_constant_wide (HOST_WIDE_INT value)
4714 /* signed constant loadable with {cal|addi} */
4715 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4718 /* constant loadable with {cau|addis} */
4719 else if ((value & 0xffff) == 0
4720 && (value >> 31 == -1 || value >> 31 == 0))
4723 #if HOST_BITS_PER_WIDE_INT == 64
4724 else if (TARGET_POWERPC64)
4726 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4727 HOST_WIDE_INT high = value >> 31;
4729 if (high == 0 || high == -1)
4735 return num_insns_constant_wide (high) + 1;
4737 return num_insns_constant_wide (low) + 1;
4739 return (num_insns_constant_wide (high)
4740 + num_insns_constant_wide (low) + 1);
4749 num_insns_constant (rtx op, enum machine_mode mode)
4751 HOST_WIDE_INT low, high;
4753 switch (GET_CODE (op))
4756 #if HOST_BITS_PER_WIDE_INT == 64
4757 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4758 && mask64_operand (op, mode))
4762 return num_insns_constant_wide (INTVAL (op));
4765 if (mode == SFmode || mode == SDmode)
4770 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4771 if (DECIMAL_FLOAT_MODE_P (mode))
4772 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4774 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4775 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4778 if (mode == VOIDmode || mode == DImode)
4780 high = CONST_DOUBLE_HIGH (op);
4781 low = CONST_DOUBLE_LOW (op);
4788 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4789 if (DECIMAL_FLOAT_MODE_P (mode))
4790 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4792 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4793 high = l[WORDS_BIG_ENDIAN == 0];
4794 low = l[WORDS_BIG_ENDIAN != 0];
4798 return (num_insns_constant_wide (low)
4799 + num_insns_constant_wide (high));
4802 if ((high == 0 && low >= 0)
4803 || (high == -1 && low < 0))
4804 return num_insns_constant_wide (low);
4806 else if (mask64_operand (op, mode))
4810 return num_insns_constant_wide (high) + 1;
4813 return (num_insns_constant_wide (high)
4814 + num_insns_constant_wide (low) + 1);
4822 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4823 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4824 corresponding element of the vector, but for V4SFmode and V2SFmode,
4825 the corresponding "float" is interpreted as an SImode integer. */
4828 const_vector_elt_as_int (rtx op, unsigned int elt)
4832 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4833 gcc_assert (GET_MODE (op) != V2DImode
4834 && GET_MODE (op) != V2DFmode);
4836 tmp = CONST_VECTOR_ELT (op, elt);
4837 if (GET_MODE (op) == V4SFmode
4838 || GET_MODE (op) == V2SFmode)
4839 tmp = gen_lowpart (SImode, tmp);
4840 return INTVAL (tmp);
4843 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4844 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4845 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4846 all items are set to the same value and contain COPIES replicas of the
4847 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4848 operand and the others are set to the value of the operand's msb. */
4851 vspltis_constant (rtx op, unsigned step, unsigned copies)
4853 enum machine_mode mode = GET_MODE (op);
4854 enum machine_mode inner = GET_MODE_INNER (mode);
4862 HOST_WIDE_INT splat_val;
4863 HOST_WIDE_INT msb_val;
4865 if (mode == V2DImode || mode == V2DFmode)
4868 nunits = GET_MODE_NUNITS (mode);
4869 bitsize = GET_MODE_BITSIZE (inner);
4870 mask = GET_MODE_MASK (inner);
4872 val = const_vector_elt_as_int (op, nunits - 1);
4874 msb_val = val > 0 ? 0 : -1;
4876 /* Construct the value to be splatted, if possible. If not, return 0. */
4877 for (i = 2; i <= copies; i *= 2)
4879 HOST_WIDE_INT small_val;
4881 small_val = splat_val >> bitsize;
4883 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4885 splat_val = small_val;
4888 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4889 if (EASY_VECTOR_15 (splat_val))
4892 /* Also check if we can splat, and then add the result to itself. Do so if
4893 the value is positive, of if the splat instruction is using OP's mode;
4894 for splat_val < 0, the splat and the add should use the same mode. */
4895 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4896 && (splat_val >= 0 || (step == 1 && copies == 1)))
4899 /* Also check if are loading up the most significant bit which can be done by
4900 loading up -1 and shifting the value left by -1. */
4901 else if (EASY_VECTOR_MSB (splat_val, inner))
4907 /* Check if VAL is present in every STEP-th element, and the
4908 other elements are filled with its most significant bit. */
4909 for (i = 0; i < nunits - 1; ++i)
4911 HOST_WIDE_INT desired_val;
4912 if (((i + 1) & (step - 1)) == 0)
4915 desired_val = msb_val;
4917 if (desired_val != const_vector_elt_as_int (op, i))
4925 /* Return true if OP is of the given MODE and can be synthesized
4926 with a vspltisb, vspltish or vspltisw. */
4929 easy_altivec_constant (rtx op, enum machine_mode mode)
4931 unsigned step, copies;
4933 if (mode == VOIDmode)
4934 mode = GET_MODE (op);
4935 else if (mode != GET_MODE (op))
4938 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4940 if (mode == V2DFmode)
4941 return zero_constant (op, mode);
4943 if (mode == V2DImode)
4945 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4947 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4948 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4951 if (zero_constant (op, mode))
4954 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4955 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4961 /* Start with a vspltisw. */
4962 step = GET_MODE_NUNITS (mode) / 4;
4965 if (vspltis_constant (op, step, copies))
4968 /* Then try with a vspltish. */
4974 if (vspltis_constant (op, step, copies))
4977 /* And finally a vspltisb. */
4983 if (vspltis_constant (op, step, copies))
4989 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4990 result is OP. Abort if it is not possible. */
4993 gen_easy_altivec_constant (rtx op)
4995 enum machine_mode mode = GET_MODE (op);
4996 int nunits = GET_MODE_NUNITS (mode);
4997 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4998 unsigned step = nunits / 4;
4999 unsigned copies = 1;
5001 /* Start with a vspltisw. */
5002 if (vspltis_constant (op, step, copies))
5003 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5005 /* Then try with a vspltish. */
5011 if (vspltis_constant (op, step, copies))
5012 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5014 /* And finally a vspltisb. */
5020 if (vspltis_constant (op, step, copies))
5021 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5027 output_vec_const_move (rtx *operands)
5030 enum machine_mode mode;
5035 mode = GET_MODE (dest);
5039 if (zero_constant (vec, mode))
5040 return "xxlxor %x0,%x0,%x0";
5042 if (mode == V2DImode
5043 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5044 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5045 return "vspltisw %0,-1";
5051 if (zero_constant (vec, mode))
5052 return "vxor %0,%0,%0";
5054 splat_vec = gen_easy_altivec_constant (vec);
5055 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5056 operands[1] = XEXP (splat_vec, 0);
5057 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5060 switch (GET_MODE (splat_vec))
5063 return "vspltisw %0,%1";
5066 return "vspltish %0,%1";
5069 return "vspltisb %0,%1";
5076 gcc_assert (TARGET_SPE);
5078 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5079 pattern of V1DI, V4HI, and V2SF.
5081 FIXME: We should probably return # and add post reload
5082 splitters for these, but this way is so easy ;-). */
5083 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5084 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5085 operands[1] = CONST_VECTOR_ELT (vec, 0);
5086 operands[2] = CONST_VECTOR_ELT (vec, 1);
5088 return "li %0,%1\n\tevmergelo %0,%0,%0";
5090 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5093 /* Initialize TARGET of vector PAIRED to VALS. */
5096 paired_expand_vector_init (rtx target, rtx vals)
5098 enum machine_mode mode = GET_MODE (target);
5099 int n_elts = GET_MODE_NUNITS (mode);
5101 rtx x, new_rtx, tmp, constant_op, op1, op2;
5104 for (i = 0; i < n_elts; ++i)
5106 x = XVECEXP (vals, 0, i);
5107 if (!CONSTANT_P (x))
5112 /* Load from constant pool. */
5113 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5119 /* The vector is initialized only with non-constants. */
5120 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5121 XVECEXP (vals, 0, 1));
5123 emit_move_insn (target, new_rtx);
5127 /* One field is non-constant and the other one is a constant. Load the
5128 constant from the constant pool and use ps_merge instruction to
5129 construct the whole vector. */
5130 op1 = XVECEXP (vals, 0, 0);
5131 op2 = XVECEXP (vals, 0, 1);
5133 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5135 tmp = gen_reg_rtx (GET_MODE (constant_op));
5136 emit_move_insn (tmp, constant_op);
5138 if (CONSTANT_P (op1))
5139 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5141 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5143 emit_move_insn (target, new_rtx);
5147 paired_expand_vector_move (rtx operands[])
5149 rtx op0 = operands[0], op1 = operands[1];
5151 emit_move_insn (op0, op1);
5154 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5155 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5156 operands for the relation operation COND. This is a recursive
5160 paired_emit_vector_compare (enum rtx_code rcode,
5161 rtx dest, rtx op0, rtx op1,
5162 rtx cc_op0, rtx cc_op1)
5164 rtx tmp = gen_reg_rtx (V2SFmode);
5167 gcc_assert (TARGET_PAIRED_FLOAT);
5168 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5174 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5178 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5179 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5183 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5186 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5189 tmp1 = gen_reg_rtx (V2SFmode);
5190 max = gen_reg_rtx (V2SFmode);
5191 min = gen_reg_rtx (V2SFmode);
5192 gen_reg_rtx (V2SFmode);
5194 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5195 emit_insn (gen_selv2sf4
5196 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5197 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5198 emit_insn (gen_selv2sf4
5199 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5200 emit_insn (gen_subv2sf3 (tmp1, min, max));
5201 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5204 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5207 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5210 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5213 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5216 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5225 /* Emit vector conditional expression.
5226 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5227 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5230 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5231 rtx cond, rtx cc_op0, rtx cc_op1)
5233 enum rtx_code rcode = GET_CODE (cond);
5235 if (!TARGET_PAIRED_FLOAT)
5238 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5243 /* Initialize vector TARGET to VALS. */
5246 rs6000_expand_vector_init (rtx target, rtx vals)
5248 enum machine_mode mode = GET_MODE (target);
5249 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5250 int n_elts = GET_MODE_NUNITS (mode);
5251 int n_var = 0, one_var = -1;
5252 bool all_same = true, all_const_zero = true;
5256 for (i = 0; i < n_elts; ++i)
5258 x = XVECEXP (vals, 0, i);
5259 if (!CONSTANT_P (x))
5260 ++n_var, one_var = i;
5261 else if (x != CONST0_RTX (inner_mode))
5262 all_const_zero = false;
5264 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5270 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5271 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5272 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5274 /* Zero register. */
5275 emit_insn (gen_rtx_SET (VOIDmode, target,
5276 gen_rtx_XOR (mode, target, target)));
5279 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5281 /* Splat immediate. */
5282 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5287 /* Load from constant pool. */
5288 emit_move_insn (target, const_vec);
5293 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5294 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5298 rtx element = XVECEXP (vals, 0, 0);
5299 if (mode == V2DFmode)
5300 emit_insn (gen_vsx_splat_v2df (target, element));
5302 emit_insn (gen_vsx_splat_v2di (target, element));
5306 if (mode == V2DFmode)
5308 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5309 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5310 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5314 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5315 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5316 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5322 /* With single precision floating point on VSX, know that internally single
5323 precision is actually represented as a double, and either make 2 V2DF
5324 vectors, and convert these vectors to single precision, or do one
5325 conversion, and splat the result to the other elements. */
5326 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5330 rtx freg = gen_reg_rtx (V4SFmode);
5331 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5333 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5334 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5338 rtx dbl_even = gen_reg_rtx (V2DFmode);
5339 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5340 rtx flt_even = gen_reg_rtx (V4SFmode);
5341 rtx flt_odd = gen_reg_rtx (V4SFmode);
5343 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5344 copy_to_reg (XVECEXP (vals, 0, 0)),
5345 copy_to_reg (XVECEXP (vals, 0, 1))));
5346 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5347 copy_to_reg (XVECEXP (vals, 0, 2)),
5348 copy_to_reg (XVECEXP (vals, 0, 3))));
5349 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5350 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5351 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5356 /* Store value to stack temp. Load vector element. Splat. However, splat
5357 of 64-bit items is not supported on Altivec. */
5358 if (all_same && GET_MODE_SIZE (mode) <= 4)
5360 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5361 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5362 XVECEXP (vals, 0, 0));
5363 x = gen_rtx_UNSPEC (VOIDmode,
5364 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5365 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5367 gen_rtx_SET (VOIDmode,
5370 x = gen_rtx_VEC_SELECT (inner_mode, target,
5371 gen_rtx_PARALLEL (VOIDmode,
5372 gen_rtvec (1, const0_rtx)));
5373 emit_insn (gen_rtx_SET (VOIDmode, target,
5374 gen_rtx_VEC_DUPLICATE (mode, x)));
5378 /* One field is non-constant. Load constant then overwrite
5382 rtx copy = copy_rtx (vals);
5384 /* Load constant part of vector, substitute neighboring value for
5386 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5387 rs6000_expand_vector_init (target, copy);
5389 /* Insert variable. */
5390 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5394 /* Construct the vector in memory one field at a time
5395 and load the whole vector. */
5396 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5397 for (i = 0; i < n_elts; i++)
5398 emit_move_insn (adjust_address_nv (mem, inner_mode,
5399 i * GET_MODE_SIZE (inner_mode)),
5400 XVECEXP (vals, 0, i));
5401 emit_move_insn (target, mem);
5404 /* Set field ELT of TARGET to VAL. */
5407 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5409 enum machine_mode mode = GET_MODE (target);
5410 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5411 rtx reg = gen_reg_rtx (mode);
5413 int width = GET_MODE_SIZE (inner_mode);
5416 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5418 rtx (*set_func) (rtx, rtx, rtx, rtx)
5419 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5420 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5424 /* Load single variable value. */
5425 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5426 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5427 x = gen_rtx_UNSPEC (VOIDmode,
5428 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5429 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5431 gen_rtx_SET (VOIDmode,
5435 /* Linear sequence. */
5436 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5437 for (i = 0; i < 16; ++i)
5438 XVECEXP (mask, 0, i) = GEN_INT (i);
5440 /* Set permute mask to insert element into target. */
5441 for (i = 0; i < width; ++i)
5442 XVECEXP (mask, 0, elt*width + i)
5443 = GEN_INT (i + 0x10);
5444 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5445 x = gen_rtx_UNSPEC (mode,
5446 gen_rtvec (3, target, reg,
5447 force_reg (V16QImode, x)),
5449 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5452 /* Extract field ELT from VEC into TARGET. */
5455 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5457 enum machine_mode mode = GET_MODE (vec);
5458 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5461 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5463 rtx (*extract_func) (rtx, rtx, rtx)
5464 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5465 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5469 /* Allocate mode-sized buffer. */
5470 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5472 emit_move_insn (mem, vec);
5474 /* Add offset to field within buffer matching vector element. */
5475 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5477 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5480 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5481 implement ANDing by the mask IN. */
5483 build_mask64_2_operands (rtx in, rtx *out)
5485 #if HOST_BITS_PER_WIDE_INT >= 64
5486 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5489 gcc_assert (GET_CODE (in) == CONST_INT);
5494 /* Assume c initially something like 0x00fff000000fffff. The idea
5495 is to rotate the word so that the middle ^^^^^^ group of zeros
5496 is at the MS end and can be cleared with an rldicl mask. We then
5497 rotate back and clear off the MS ^^ group of zeros with a
5499 c = ~c; /* c == 0xff000ffffff00000 */
5500 lsb = c & -c; /* lsb == 0x0000000000100000 */
5501 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5502 c = ~c; /* c == 0x00fff000000fffff */
5503 c &= -lsb; /* c == 0x00fff00000000000 */
5504 lsb = c & -c; /* lsb == 0x0000100000000000 */
5505 c = ~c; /* c == 0xff000fffffffffff */
5506 c &= -lsb; /* c == 0xff00000000000000 */
5508 while ((lsb >>= 1) != 0)
5509 shift++; /* shift == 44 on exit from loop */
5510 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5511 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5512 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5516 /* Assume c initially something like 0xff000f0000000000. The idea
5517 is to rotate the word so that the ^^^ middle group of zeros
5518 is at the LS end and can be cleared with an rldicr mask. We then
5519 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5521 lsb = c & -c; /* lsb == 0x0000010000000000 */
5522 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5523 c = ~c; /* c == 0x00fff0ffffffffff */
5524 c &= -lsb; /* c == 0x00fff00000000000 */
5525 lsb = c & -c; /* lsb == 0x0000100000000000 */
5526 c = ~c; /* c == 0xff000fffffffffff */
5527 c &= -lsb; /* c == 0xff00000000000000 */
5529 while ((lsb >>= 1) != 0)
5530 shift++; /* shift == 44 on exit from loop */
5531 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5532 m1 >>= shift; /* m1 == 0x0000000000000fff */
5533 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5536 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5537 masks will be all 1's. We are guaranteed more than one transition. */
5538 out[0] = GEN_INT (64 - shift);
5539 out[1] = GEN_INT (m1);
5540 out[2] = GEN_INT (shift);
5541 out[3] = GEN_INT (m2);
5549 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5552 invalid_e500_subreg (rtx op, enum machine_mode mode)
5554 if (TARGET_E500_DOUBLE)
5556 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5557 subreg:TI and reg:TF. Decimal float modes are like integer
5558 modes (only low part of each register used) for this
5560 if (GET_CODE (op) == SUBREG
5561 && (mode == SImode || mode == DImode || mode == TImode
5562 || mode == DDmode || mode == TDmode)
5563 && REG_P (SUBREG_REG (op))
5564 && (GET_MODE (SUBREG_REG (op)) == DFmode
5565 || GET_MODE (SUBREG_REG (op)) == TFmode))
5568 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5570 if (GET_CODE (op) == SUBREG
5571 && (mode == DFmode || mode == TFmode)
5572 && REG_P (SUBREG_REG (op))
5573 && (GET_MODE (SUBREG_REG (op)) == DImode
5574 || GET_MODE (SUBREG_REG (op)) == TImode
5575 || GET_MODE (SUBREG_REG (op)) == DDmode
5576 || GET_MODE (SUBREG_REG (op)) == TDmode))
5581 && GET_CODE (op) == SUBREG
5583 && REG_P (SUBREG_REG (op))
5584 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5590 /* AIX increases natural record alignment to doubleword if the first
5591 field is an FP double while the FP fields remain word aligned. */
5594 rs6000_special_round_type_align (tree type, unsigned int computed,
5595 unsigned int specified)
5597 unsigned int align = MAX (computed, specified);
5598 tree field = TYPE_FIELDS (type);
5600 /* Skip all non field decls */
5601 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5602 field = DECL_CHAIN (field);
5604 if (field != NULL && field != type)
5606 type = TREE_TYPE (field);
5607 while (TREE_CODE (type) == ARRAY_TYPE)
5608 type = TREE_TYPE (type);
5610 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5611 align = MAX (align, 64);
5617 /* Darwin increases record alignment to the natural alignment of
5621 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5622 unsigned int specified)
5624 unsigned int align = MAX (computed, specified);
5626 if (TYPE_PACKED (type))
5629 /* Find the first field, looking down into aggregates. */
5631 tree field = TYPE_FIELDS (type);
5632 /* Skip all non field decls */
5633 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5634 field = DECL_CHAIN (field);
5637 /* A packed field does not contribute any extra alignment. */
5638 if (DECL_PACKED (field))
5640 type = TREE_TYPE (field);
5641 while (TREE_CODE (type) == ARRAY_TYPE)
5642 type = TREE_TYPE (type);
5643 } while (AGGREGATE_TYPE_P (type));
5645 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5646 align = MAX (align, TYPE_ALIGN (type));
5651 /* Return 1 for an operand in small memory on V.4/eabi. */
5654 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5655 enum machine_mode mode ATTRIBUTE_UNUSED)
5660 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5663 if (DEFAULT_ABI != ABI_V4)
5666 /* Vector and float memory instructions have a limited offset on the
5667 SPE, so using a vector or float variable directly as an operand is
5670 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5673 if (GET_CODE (op) == SYMBOL_REF)
5676 else if (GET_CODE (op) != CONST
5677 || GET_CODE (XEXP (op, 0)) != PLUS
5678 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5679 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5684 rtx sum = XEXP (op, 0);
5685 HOST_WIDE_INT summand;
5687 /* We have to be careful here, because it is the referenced address
5688 that must be 32k from _SDA_BASE_, not just the symbol. */
5689 summand = INTVAL (XEXP (sum, 1));
5690 if (summand < 0 || summand > g_switch_value)
5693 sym_ref = XEXP (sum, 0);
5696 return SYMBOL_REF_SMALL_P (sym_ref);
5702 /* Return true if either operand is a general purpose register. */
5705 gpr_or_gpr_p (rtx op0, rtx op1)
5707 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5708 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5712 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5715 reg_offset_addressing_ok_p (enum machine_mode mode)
5725 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5726 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5734 /* Paired vector modes. Only reg+reg addressing is valid. */
5735 if (TARGET_PAIRED_FLOAT)
5747 virtual_stack_registers_memory_p (rtx op)
5751 if (GET_CODE (op) == REG)
5752 regnum = REGNO (op);
5754 else if (GET_CODE (op) == PLUS
5755 && GET_CODE (XEXP (op, 0)) == REG
5756 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5757 regnum = REGNO (XEXP (op, 0));
5762 return (regnum >= FIRST_VIRTUAL_REGISTER
5763 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5766 /* Return true if memory accesses to OP are known to never straddle
5770 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5771 enum machine_mode mode)
5774 unsigned HOST_WIDE_INT dsize, dalign;
5776 if (GET_CODE (op) != SYMBOL_REF)
5779 decl = SYMBOL_REF_DECL (op);
5782 if (GET_MODE_SIZE (mode) == 0)
5785 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5786 replacing memory addresses with an anchor plus offset. We
5787 could find the decl by rummaging around in the block->objects
5788 VEC for the given offset but that seems like too much work. */
5790 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5791 && SYMBOL_REF_ANCHOR_P (op)
5792 && SYMBOL_REF_BLOCK (op) != NULL)
5794 struct object_block *block = SYMBOL_REF_BLOCK (op);
5795 HOST_WIDE_INT lsb, mask;
5797 /* Given the alignment of the block.. */
5798 dalign = block->alignment;
5799 mask = dalign / BITS_PER_UNIT - 1;
5801 /* ..and the combined offset of the anchor and any offset
5802 to this block object.. */
5803 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5804 lsb = offset & -offset;
5806 /* ..find how many bits of the alignment we know for the
5811 return dalign >= GET_MODE_SIZE (mode);
5816 if (TREE_CODE (decl) == FUNCTION_DECL)
5819 if (!DECL_SIZE_UNIT (decl))
5822 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5825 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5829 dalign = DECL_ALIGN_UNIT (decl);
5830 return dalign >= dsize;
5833 type = TREE_TYPE (decl);
5835 if (TREE_CODE (decl) == STRING_CST)
5836 dsize = TREE_STRING_LENGTH (decl);
5837 else if (TYPE_SIZE_UNIT (type)
5838 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5839 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5845 dalign = TYPE_ALIGN (type);
5846 if (CONSTANT_CLASS_P (decl))
5847 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5849 dalign = DATA_ALIGNMENT (decl, dalign);
5850 dalign /= BITS_PER_UNIT;
5851 return dalign >= dsize;
5855 constant_pool_expr_p (rtx op)
5859 split_const (op, &base, &offset);
5860 return (GET_CODE (base) == SYMBOL_REF
5861 && CONSTANT_POOL_ADDRESS_P (base)
5862 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5865 static rtx tocrel_base, tocrel_offset;
5868 toc_relative_expr_p (rtx op)
5870 if (GET_CODE (op) != CONST)
5873 split_const (op, &tocrel_base, &tocrel_offset);
5874 return (GET_CODE (tocrel_base) == UNSPEC
5875 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5878 /* Return true if X is a constant pool address, and also for cmodel=medium
5879 if X is a toc-relative address known to be offsettable within MODE. */
5882 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5886 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5887 && GET_CODE (XEXP (x, 0)) == REG
5888 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5889 || ((TARGET_MINIMAL_TOC
5890 || TARGET_CMODEL != CMODEL_SMALL)
5891 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5892 && toc_relative_expr_p (XEXP (x, 1))
5893 && (TARGET_CMODEL != CMODEL_MEDIUM
5894 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5896 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5897 INTVAL (tocrel_offset), mode)));
5901 legitimate_small_data_p (enum machine_mode mode, rtx x)
5903 return (DEFAULT_ABI == ABI_V4
5904 && !flag_pic && !TARGET_TOC
5905 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5906 && small_data_operand (x, mode));
5909 /* SPE offset addressing is limited to 5-bits worth of double words. */
5910 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5913 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5915 unsigned HOST_WIDE_INT offset, extra;
5917 if (GET_CODE (x) != PLUS)
5919 if (GET_CODE (XEXP (x, 0)) != REG)
5921 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5923 if (!reg_offset_addressing_ok_p (mode))
5924 return virtual_stack_registers_memory_p (x);
5925 if (legitimate_constant_pool_address_p (x, mode, strict))
5927 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5930 offset = INTVAL (XEXP (x, 1));
5938 /* SPE vector modes. */
5939 return SPE_CONST_OFFSET_OK (offset);
5942 if (TARGET_E500_DOUBLE)
5943 return SPE_CONST_OFFSET_OK (offset);
5945 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5947 if (VECTOR_MEM_VSX_P (DFmode))
5952 /* On e500v2, we may have:
5954 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5956 Which gets addressed with evldd instructions. */
5957 if (TARGET_E500_DOUBLE)
5958 return SPE_CONST_OFFSET_OK (offset);
5960 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5962 else if (offset & 3)
5967 if (TARGET_E500_DOUBLE)
5968 return (SPE_CONST_OFFSET_OK (offset)
5969 && SPE_CONST_OFFSET_OK (offset + 8));
5973 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5975 else if (offset & 3)
5986 return (offset < 0x10000) && (offset + extra < 0x10000);
5990 legitimate_indexed_address_p (rtx x, int strict)
5994 if (GET_CODE (x) != PLUS)
6000 /* Recognize the rtl generated by reload which we know will later be
6001 replaced with proper base and index regs. */
6003 && reload_in_progress
6004 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6008 return (REG_P (op0) && REG_P (op1)
6009 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6010 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6011 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6012 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6016 avoiding_indexed_address_p (enum machine_mode mode)
6018 /* Avoid indexed addressing for modes that have non-indexed
6019 load/store instruction forms. */
6020 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6024 legitimate_indirect_address_p (rtx x, int strict)
6026 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6030 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6032 if (!TARGET_MACHO || !flag_pic
6033 || mode != SImode || GET_CODE (x) != MEM)
6037 if (GET_CODE (x) != LO_SUM)
6039 if (GET_CODE (XEXP (x, 0)) != REG)
6041 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6045 return CONSTANT_P (x);
6049 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6051 if (GET_CODE (x) != LO_SUM)
6053 if (GET_CODE (XEXP (x, 0)) != REG)
6055 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6057 /* Restrict addressing for DI because of our SUBREG hackery. */
6058 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6059 || mode == DDmode || mode == TDmode
6064 if (TARGET_ELF || TARGET_MACHO)
6066 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6070 if (GET_MODE_NUNITS (mode) != 1)
6072 if (GET_MODE_BITSIZE (mode) > 64
6073 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6074 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6075 && (mode == DFmode || mode == DDmode))))
6078 return CONSTANT_P (x);
6085 /* Try machine-dependent ways of modifying an illegitimate address
6086 to be legitimate. If we find one, return the new, valid address.
6087 This is used from only one place: `memory_address' in explow.c.
6089 OLDX is the address as it was before break_out_memory_refs was
6090 called. In some cases it is useful to look at this to decide what
6093 It is always safe for this function to do nothing. It exists to
6094 recognize opportunities to optimize the output.
6096 On RS/6000, first check for the sum of a register with a constant
6097 integer that is out of range. If so, generate code to add the
6098 constant with the low-order 16 bits masked to the register and force
6099 this result into another register (this can be done with `cau').
6100 Then generate an address of REG+(CONST&0xffff), allowing for the
6101 possibility of bit 16 being a one.
6103 Then check for the sum of a register and something not constant, try to
6104 load the other things into a register and return the sum. */
6107 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6108 enum machine_mode mode)
6110 unsigned int extra = 0;
6112 if (!reg_offset_addressing_ok_p (mode))
6114 if (virtual_stack_registers_memory_p (x))
6117 /* In theory we should not be seeing addresses of the form reg+0,
6118 but just in case it is generated, optimize it away. */
6119 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6120 return force_reg (Pmode, XEXP (x, 0));
6122 /* Make sure both operands are registers. */
6123 else if (GET_CODE (x) == PLUS)
6124 return gen_rtx_PLUS (Pmode,
6125 force_reg (Pmode, XEXP (x, 0)),
6126 force_reg (Pmode, XEXP (x, 1)));
6128 return force_reg (Pmode, x);
6130 if (GET_CODE (x) == SYMBOL_REF)
6132 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6134 return rs6000_legitimize_tls_address (x, model);
6144 if (!TARGET_POWERPC64)
6152 extra = TARGET_POWERPC64 ? 8 : 12;
6158 if (GET_CODE (x) == PLUS
6159 && GET_CODE (XEXP (x, 0)) == REG
6160 && GET_CODE (XEXP (x, 1)) == CONST_INT
6161 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6163 && !((TARGET_POWERPC64
6164 && (mode == DImode || mode == TImode)
6165 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6166 || SPE_VECTOR_MODE (mode)
6167 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6168 || mode == DImode || mode == DDmode
6169 || mode == TDmode))))
6171 HOST_WIDE_INT high_int, low_int;
6173 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6174 if (low_int >= 0x8000 - extra)
6176 high_int = INTVAL (XEXP (x, 1)) - low_int;
6177 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6178 GEN_INT (high_int)), 0);
6179 return plus_constant (sum, low_int);
6181 else if (GET_CODE (x) == PLUS
6182 && GET_CODE (XEXP (x, 0)) == REG
6183 && GET_CODE (XEXP (x, 1)) != CONST_INT
6184 && GET_MODE_NUNITS (mode) == 1
6185 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6187 || ((mode != DImode && mode != DFmode && mode != DDmode)
6188 || (TARGET_E500_DOUBLE && mode != DDmode)))
6189 && (TARGET_POWERPC64 || mode != DImode)
6190 && !avoiding_indexed_address_p (mode)
6195 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6196 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6198 else if (SPE_VECTOR_MODE (mode)
6199 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6200 || mode == DDmode || mode == TDmode
6201 || mode == DImode)))
6205 /* We accept [reg + reg] and [reg + OFFSET]. */
6207 if (GET_CODE (x) == PLUS)
6209 rtx op1 = XEXP (x, 0);
6210 rtx op2 = XEXP (x, 1);
6213 op1 = force_reg (Pmode, op1);
6215 if (GET_CODE (op2) != REG
6216 && (GET_CODE (op2) != CONST_INT
6217 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6218 || (GET_MODE_SIZE (mode) > 8
6219 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6220 op2 = force_reg (Pmode, op2);
6222 /* We can't always do [reg + reg] for these, because [reg +
6223 reg + offset] is not a legitimate addressing mode. */
6224 y = gen_rtx_PLUS (Pmode, op1, op2);
6226 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6227 return force_reg (Pmode, y);
6232 return force_reg (Pmode, x);
6238 && GET_CODE (x) != CONST_INT
6239 && GET_CODE (x) != CONST_DOUBLE
6241 && GET_MODE_NUNITS (mode) == 1
6242 && (GET_MODE_BITSIZE (mode) <= 32
6243 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6244 && (mode == DFmode || mode == DDmode))))
6246 rtx reg = gen_reg_rtx (Pmode);
6247 emit_insn (gen_elf_high (reg, x));
6248 return gen_rtx_LO_SUM (Pmode, reg, x);
6250 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6253 && ! MACHO_DYNAMIC_NO_PIC_P
6255 && GET_CODE (x) != CONST_INT
6256 && GET_CODE (x) != CONST_DOUBLE
6258 && GET_MODE_NUNITS (mode) == 1
6259 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6260 || (mode != DFmode && mode != DDmode))
6264 rtx reg = gen_reg_rtx (Pmode);
6265 emit_insn (gen_macho_high (reg, x));
6266 return gen_rtx_LO_SUM (Pmode, reg, x);
6269 && GET_CODE (x) == SYMBOL_REF
6270 && constant_pool_expr_p (x)
6271 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6273 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6274 return create_TOC_reference (x, reg);
6280 /* Debug version of rs6000_legitimize_address. */
6282 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6288 ret = rs6000_legitimize_address (x, oldx, mode);
6289 insns = get_insns ();
6295 "\nrs6000_legitimize_address: mode %s, old code %s, "
6296 "new code %s, modified\n",
6297 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6298 GET_RTX_NAME (GET_CODE (ret)));
6300 fprintf (stderr, "Original address:\n");
6303 fprintf (stderr, "oldx:\n");
6306 fprintf (stderr, "New address:\n");
6311 fprintf (stderr, "Insns added:\n");
6312 debug_rtx_list (insns, 20);
6318 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6319 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6330 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6331 We need to emit DTP-relative relocations. */
6334 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6339 fputs ("\t.long\t", file);
6342 fputs (DOUBLE_INT_ASM_OP, file);
6347 output_addr_const (file, x);
6348 fputs ("@dtprel+0x8000", file);
6351 /* In the name of slightly smaller debug output, and to cater to
6352 general assembler lossage, recognize various UNSPEC sequences
6353 and turn them back into a direct symbol reference. */
6356 rs6000_delegitimize_address (rtx orig_x)
6360 orig_x = delegitimize_mem_from_attrs (orig_x);
6365 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6366 && GET_CODE (XEXP (x, 1)) == CONST)
6368 y = XEXP (XEXP (x, 1), 0);
6369 if (GET_CODE (y) == UNSPEC
6370 && XINT (y, 1) == UNSPEC_TOCREL
6371 && ((GET_CODE (XEXP (x, 0)) == REG
6372 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6373 || TARGET_MINIMAL_TOC
6374 || TARGET_CMODEL != CMODEL_SMALL))
6375 || (TARGET_CMODEL != CMODEL_SMALL
6376 && GET_CODE (XEXP (x, 0)) == PLUS
6377 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6378 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6379 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6380 && rtx_equal_p (XEXP (x, 1),
6381 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6383 y = XVECEXP (y, 0, 0);
6384 if (!MEM_P (orig_x))
6387 return replace_equiv_address_nv (orig_x, y);
6392 && GET_CODE (orig_x) == LO_SUM
6393 && GET_CODE (XEXP (x, 1)) == CONST)
6395 y = XEXP (XEXP (x, 1), 0);
6396 if (GET_CODE (y) == UNSPEC
6397 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6398 return XVECEXP (y, 0, 0);
6404 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6406 static GTY(()) rtx rs6000_tls_symbol;
6408 rs6000_tls_get_addr (void)
6410 if (!rs6000_tls_symbol)
6411 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6413 return rs6000_tls_symbol;
6416 /* Construct the SYMBOL_REF for TLS GOT references. */
6418 static GTY(()) rtx rs6000_got_symbol;
6420 rs6000_got_sym (void)
6422 if (!rs6000_got_symbol)
6424 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6425 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6426 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6429 return rs6000_got_symbol;
6432 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6433 this (thread-local) address. */
6436 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6440 dest = gen_reg_rtx (Pmode);
6441 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6447 tlsreg = gen_rtx_REG (Pmode, 13);
6448 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6452 tlsreg = gen_rtx_REG (Pmode, 2);
6453 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6457 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6461 tmp = gen_reg_rtx (Pmode);
6464 tlsreg = gen_rtx_REG (Pmode, 13);
6465 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6469 tlsreg = gen_rtx_REG (Pmode, 2);
6470 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6474 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6476 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6481 rtx r3, got, tga, tmp1, tmp2, call_insn;
6483 /* We currently use relocations like @got@tlsgd for tls, which
6484 means the linker will handle allocation of tls entries, placing
6485 them in the .got section. So use a pointer to the .got section,
6486 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6487 or to secondary GOT sections used by 32-bit -fPIC. */
6489 got = gen_rtx_REG (Pmode, 2);
6493 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6496 rtx gsym = rs6000_got_sym ();
6497 got = gen_reg_rtx (Pmode);
6499 rs6000_emit_move (got, gsym, Pmode);
6504 tmp1 = gen_reg_rtx (Pmode);
6505 tmp2 = gen_reg_rtx (Pmode);
6506 mem = gen_const_mem (Pmode, tmp1);
6507 lab = gen_label_rtx ();
6508 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6509 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6510 emit_move_insn (tmp2, mem);
6511 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6512 set_unique_reg_note (last, REG_EQUAL, gsym);
6517 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6519 r3 = gen_rtx_REG (Pmode, 3);
6520 tga = rs6000_tls_get_addr ();
6521 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6523 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6524 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6525 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6526 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6527 else if (DEFAULT_ABI == ABI_V4)
6528 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6531 call_insn = last_call_insn ();
6532 PATTERN (call_insn) = insn;
6533 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6534 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6535 pic_offset_table_rtx);
6537 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6539 r3 = gen_rtx_REG (Pmode, 3);
6540 tga = rs6000_tls_get_addr ();
6541 tmp1 = gen_reg_rtx (Pmode);
6542 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6544 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6545 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6546 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6547 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6548 else if (DEFAULT_ABI == ABI_V4)
6549 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6552 call_insn = last_call_insn ();
6553 PATTERN (call_insn) = insn;
6554 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6555 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6556 pic_offset_table_rtx);
6558 if (rs6000_tls_size == 16)
6561 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6563 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6565 else if (rs6000_tls_size == 32)
6567 tmp2 = gen_reg_rtx (Pmode);
6569 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6571 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6574 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6576 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6580 tmp2 = gen_reg_rtx (Pmode);
6582 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6584 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6586 insn = gen_rtx_SET (Pmode, dest,
6587 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6593 /* IE, or 64-bit offset LE. */
6594 tmp2 = gen_reg_rtx (Pmode);
6596 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6598 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6601 insn = gen_tls_tls_64 (dest, tmp2, addr);
6603 insn = gen_tls_tls_32 (dest, tmp2, addr);
6611 /* Return 1 if X contains a thread-local symbol. */
6614 rs6000_tls_referenced_p (rtx x)
6616 if (! TARGET_HAVE_TLS)
6619 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6622 /* Return 1 if *X is a thread-local symbol. This is the same as
6623 rs6000_tls_symbol_ref except for the type of the unused argument. */
6626 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6628 return RS6000_SYMBOL_REF_TLS_P (*x);
6631 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6632 replace the input X, or the original X if no replacement is called for.
6633 The output parameter *WIN is 1 if the calling macro should goto WIN,
6636 For RS/6000, we wish to handle large displacements off a base
6637 register by splitting the addend across an addiu/addis and the mem insn.
6638 This cuts number of extra insns needed from 3 to 1.
6640 On Darwin, we use this to generate code for floating point constants.
6641 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6642 The Darwin code is inside #if TARGET_MACHO because only then are the
6643 machopic_* functions defined. */
6645 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6646 int opnum, int type,
6647 int ind_levels ATTRIBUTE_UNUSED, int *win)
6649 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6651 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6652 DFmode/DImode MEM. */
6655 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6656 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6657 reg_offset_p = false;
6659 /* We must recognize output that we have already generated ourselves. */
6660 if (GET_CODE (x) == PLUS
6661 && GET_CODE (XEXP (x, 0)) == PLUS
6662 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6663 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6664 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6666 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6667 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6668 opnum, (enum reload_type)type);
6673 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6674 if (GET_CODE (x) == LO_SUM
6675 && GET_CODE (XEXP (x, 0)) == HIGH)
6677 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6678 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6679 opnum, (enum reload_type)type);
6685 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6686 && GET_CODE (x) == LO_SUM
6687 && GET_CODE (XEXP (x, 0)) == PLUS
6688 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6689 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6690 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6691 && machopic_operand_p (XEXP (x, 1)))
6693 /* Result of previous invocation of this function on Darwin
6694 floating point constant. */
6695 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6696 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6697 opnum, (enum reload_type)type);
6703 if (TARGET_CMODEL != CMODEL_SMALL
6704 && GET_CODE (x) == LO_SUM
6705 && GET_CODE (XEXP (x, 0)) == PLUS
6706 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6707 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6708 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6709 && GET_CODE (XEXP (x, 1)) == CONST
6710 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6711 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6712 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6714 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6715 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6716 opnum, (enum reload_type) type);
6721 /* Force ld/std non-word aligned offset into base register by wrapping
6723 if (GET_CODE (x) == PLUS
6724 && GET_CODE (XEXP (x, 0)) == REG
6725 && REGNO (XEXP (x, 0)) < 32
6726 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6727 && GET_CODE (XEXP (x, 1)) == CONST_INT
6729 && (INTVAL (XEXP (x, 1)) & 3) != 0
6730 && VECTOR_MEM_NONE_P (mode)
6731 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6732 && TARGET_POWERPC64)
6734 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6735 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6736 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6737 opnum, (enum reload_type) type);
6742 if (GET_CODE (x) == PLUS
6743 && GET_CODE (XEXP (x, 0)) == REG
6744 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6745 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6746 && GET_CODE (XEXP (x, 1)) == CONST_INT
6748 && !SPE_VECTOR_MODE (mode)
6749 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6750 || mode == DDmode || mode == TDmode
6752 && VECTOR_MEM_NONE_P (mode))
6754 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6755 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6757 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6759 /* Check for 32-bit overflow. */
6760 if (high + low != val)
6766 /* Reload the high part into a base reg; leave the low part
6767 in the mem directly. */
6769 x = gen_rtx_PLUS (GET_MODE (x),
6770 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6774 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6775 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6776 opnum, (enum reload_type)type);
6781 if (GET_CODE (x) == SYMBOL_REF
6783 && VECTOR_MEM_NONE_P (mode)
6784 && !SPE_VECTOR_MODE (mode)
6786 && DEFAULT_ABI == ABI_DARWIN
6787 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6789 && DEFAULT_ABI == ABI_V4
6792 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6793 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6797 && (mode != DImode || TARGET_POWERPC64)
6798 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6799 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6804 rtx offset = machopic_gen_offset (x);
6805 x = gen_rtx_LO_SUM (GET_MODE (x),
6806 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6807 gen_rtx_HIGH (Pmode, offset)), offset);
6811 x = gen_rtx_LO_SUM (GET_MODE (x),
6812 gen_rtx_HIGH (Pmode, x), x);
6814 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6815 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6816 opnum, (enum reload_type)type);
6821 /* Reload an offset address wrapped by an AND that represents the
6822 masking of the lower bits. Strip the outer AND and let reload
6823 convert the offset address into an indirect address. For VSX,
6824 force reload to create the address with an AND in a separate
6825 register, because we can't guarantee an altivec register will
6827 if (VECTOR_MEM_ALTIVEC_P (mode)
6828 && GET_CODE (x) == AND
6829 && GET_CODE (XEXP (x, 0)) == PLUS
6830 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6831 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6832 && GET_CODE (XEXP (x, 1)) == CONST_INT
6833 && INTVAL (XEXP (x, 1)) == -16)
6842 && GET_CODE (x) == SYMBOL_REF
6843 && constant_pool_expr_p (x)
6844 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6846 x = create_TOC_reference (x, NULL_RTX);
6847 if (TARGET_CMODEL != CMODEL_SMALL)
6848 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6849 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6850 opnum, (enum reload_type) type);
6858 /* Debug version of rs6000_legitimize_reload_address. */
6860 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6861 int opnum, int type,
6862 int ind_levels, int *win)
6864 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6867 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6868 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6869 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6873 fprintf (stderr, "Same address returned\n");
6875 fprintf (stderr, "NULL returned\n");
6878 fprintf (stderr, "New address:\n");
6885 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6886 that is a valid memory address for an instruction.
6887 The MODE argument is the machine mode for the MEM expression
6888 that wants to use this address.
6890 On the RS/6000, there are four valid address: a SYMBOL_REF that
6891 refers to a constant pool entry of an address (or the sum of it
6892 plus a constant), a short (16-bit signed) constant plus a register,
6893 the sum of two registers, or a register indirect, possibly with an
6894 auto-increment. For DFmode, DDmode and DImode with a constant plus
6895 register, we must ensure that both words are addressable or PowerPC64
6896 with offset word aligned.
6898 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6899 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6900 because adjacent memory cells are accessed by adding word-sized offsets
6901 during assembly output. */
6903 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6905 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6907 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6908 if (VECTOR_MEM_ALTIVEC_P (mode)
6909 && GET_CODE (x) == AND
6910 && GET_CODE (XEXP (x, 1)) == CONST_INT
6911 && INTVAL (XEXP (x, 1)) == -16)
6914 if (RS6000_SYMBOL_REF_TLS_P (x))
6916 if (legitimate_indirect_address_p (x, reg_ok_strict))
6918 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6919 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6920 && !SPE_VECTOR_MODE (mode)
6923 /* Restrict addressing for DI because of our SUBREG hackery. */
6924 && !(TARGET_E500_DOUBLE
6925 && (mode == DFmode || mode == DDmode || mode == DImode))
6927 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6929 if (virtual_stack_registers_memory_p (x))
6931 if (reg_offset_p && legitimate_small_data_p (mode, x))
6934 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6936 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6939 && GET_CODE (x) == PLUS
6940 && GET_CODE (XEXP (x, 0)) == REG
6941 && (XEXP (x, 0) == virtual_stack_vars_rtx
6942 || XEXP (x, 0) == arg_pointer_rtx)
6943 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6945 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6950 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6952 || (mode != DFmode && mode != DDmode)
6953 || (TARGET_E500_DOUBLE && mode != DDmode))
6954 && (TARGET_POWERPC64 || mode != DImode)
6955 && !avoiding_indexed_address_p (mode)
6956 && legitimate_indexed_address_p (x, reg_ok_strict))
6958 if (GET_CODE (x) == PRE_MODIFY
6962 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6964 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6965 && (TARGET_POWERPC64 || mode != DImode)
6966 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6967 && !SPE_VECTOR_MODE (mode)
6968 /* Restrict addressing for DI because of our SUBREG hackery. */
6969 && !(TARGET_E500_DOUBLE
6970 && (mode == DFmode || mode == DDmode || mode == DImode))
6972 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6973 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6974 || (!avoiding_indexed_address_p (mode)
6975 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6976 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6978 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6983 /* Debug version of rs6000_legitimate_address_p. */
6985 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6988 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6990 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
6991 "strict = %d, code = %s\n",
6992 ret ? "true" : "false",
6993 GET_MODE_NAME (mode),
6995 GET_RTX_NAME (GET_CODE (x)));
7001 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7004 rs6000_mode_dependent_address_p (const_rtx addr)
7006 return rs6000_mode_dependent_address_ptr (addr);
7009 /* Go to LABEL if ADDR (a legitimate address expression)
7010 has an effect that depends on the machine mode it is used for.
7012 On the RS/6000 this is true of all integral offsets (since AltiVec
7013 and VSX modes don't allow them) or is a pre-increment or decrement.
7015 ??? Except that due to conceptual problems in offsettable_address_p
7016 we can't really report the problems of integral offsets. So leave
7017 this assuming that the adjustable offset must be valid for the
7018 sub-words of a TFmode operand, which is what we had before. */
7021 rs6000_mode_dependent_address (const_rtx addr)
7023 switch (GET_CODE (addr))
7026 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7027 is considered a legitimate address before reload, so there
7028 are no offset restrictions in that case. Note that this
7029 condition is safe in strict mode because any address involving
7030 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7031 been rejected as illegitimate. */
7032 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7033 && XEXP (addr, 0) != arg_pointer_rtx
7034 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7036 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7037 return val + 12 + 0x8000 >= 0x10000;
7042 /* Anything in the constant pool is sufficiently aligned that
7043 all bytes have the same high part address. */
7044 return !legitimate_constant_pool_address_p (addr, QImode, false);
7046 /* Auto-increment cases are now treated generically in recog.c. */
7048 return TARGET_UPDATE;
7050 /* AND is only allowed in Altivec loads. */
7061 /* Debug version of rs6000_mode_dependent_address. */
7063 rs6000_debug_mode_dependent_address (const_rtx addr)
7065 bool ret = rs6000_mode_dependent_address (addr);
7067 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7068 ret ? "true" : "false");
7074 /* Implement FIND_BASE_TERM. */
7077 rs6000_find_base_term (rtx op)
7081 split_const (op, &base, &offset);
7082 if (GET_CODE (base) == UNSPEC)
7083 switch (XINT (base, 1))
7086 case UNSPEC_MACHOPIC_OFFSET:
7087 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7088 for aliasing purposes. */
7089 return XVECEXP (base, 0, 0);
7095 /* More elaborate version of recog's offsettable_memref_p predicate
7096 that works around the ??? note of rs6000_mode_dependent_address.
7097 In particular it accepts
7099 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7101 in 32-bit mode, that the recog predicate rejects. */
7104 rs6000_offsettable_memref_p (rtx op)
7109 /* First mimic offsettable_memref_p. */
7110 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7113 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7114 the latter predicate knows nothing about the mode of the memory
7115 reference and, therefore, assumes that it is the largest supported
7116 mode (TFmode). As a consequence, legitimate offsettable memory
7117 references are rejected. rs6000_legitimate_offset_address_p contains
7118 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7119 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7122 /* Change register usage conditional on target flags. */
7124 rs6000_conditional_register_usage (void)
7128 if (TARGET_DEBUG_TARGET)
7129 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7131 /* Set MQ register fixed (already call_used) if not POWER
7132 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7137 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7139 fixed_regs[13] = call_used_regs[13]
7140 = call_really_used_regs[13] = 1;
7142 /* Conditionally disable FPRs. */
7143 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7144 for (i = 32; i < 64; i++)
7145 fixed_regs[i] = call_used_regs[i]
7146 = call_really_used_regs[i] = 1;
7148 /* The TOC register is not killed across calls in a way that is
7149 visible to the compiler. */
7150 if (DEFAULT_ABI == ABI_AIX)
7151 call_really_used_regs[2] = 0;
7153 if (DEFAULT_ABI == ABI_V4
7154 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7156 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7158 if (DEFAULT_ABI == ABI_V4
7159 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7161 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7162 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7163 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7165 if (DEFAULT_ABI == ABI_DARWIN
7166 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7167 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7168 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7169 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7171 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7172 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7173 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7177 global_regs[SPEFSCR_REGNO] = 1;
7178 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7179 registers in prologues and epilogues. We no longer use r14
7180 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7181 pool for link-compatibility with older versions of GCC. Once
7182 "old" code has died out, we can return r14 to the allocation
7185 = call_used_regs[14]
7186 = call_really_used_regs[14] = 1;
7189 if (!TARGET_ALTIVEC && !TARGET_VSX)
7191 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7192 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7193 call_really_used_regs[VRSAVE_REGNO] = 1;
7196 if (TARGET_ALTIVEC || TARGET_VSX)
7197 global_regs[VSCR_REGNO] = 1;
7199 if (TARGET_ALTIVEC_ABI)
7201 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7202 call_used_regs[i] = call_really_used_regs[i] = 1;
7204 /* AIX reserves VR20:31 in non-extended ABI mode. */
7206 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7207 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7211 /* Try to output insns to set TARGET equal to the constant C if it can
7212 be done in less than N insns. Do all computations in MODE.
7213 Returns the place where the output has been placed if it can be
7214 done and the insns have been emitted. If it would take more than N
7215 insns, zero is returned and no insns and emitted. */
7218 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7219 rtx source, int n ATTRIBUTE_UNUSED)
7221 rtx result, insn, set;
7222 HOST_WIDE_INT c0, c1;
7229 dest = gen_reg_rtx (mode);
7230 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7234 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7236 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7237 GEN_INT (INTVAL (source)
7238 & (~ (HOST_WIDE_INT) 0xffff))));
7239 emit_insn (gen_rtx_SET (VOIDmode, dest,
7240 gen_rtx_IOR (SImode, copy_rtx (result),
7241 GEN_INT (INTVAL (source) & 0xffff))));
7246 switch (GET_CODE (source))
7249 c0 = INTVAL (source);
7254 #if HOST_BITS_PER_WIDE_INT >= 64
7255 c0 = CONST_DOUBLE_LOW (source);
7258 c0 = CONST_DOUBLE_LOW (source);
7259 c1 = CONST_DOUBLE_HIGH (source);
7267 result = rs6000_emit_set_long_const (dest, c0, c1);
7274 insn = get_last_insn ();
7275 set = single_set (insn);
7276 if (! CONSTANT_P (SET_SRC (set)))
7277 set_unique_reg_note (insn, REG_EQUAL, source);
7282 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7283 fall back to a straight forward decomposition. We do this to avoid
7284 exponential run times encountered when looking for longer sequences
7285 with rs6000_emit_set_const. */
7287 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7289 if (!TARGET_POWERPC64)
7291 rtx operand1, operand2;
7293 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7295 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7297 emit_move_insn (operand1, GEN_INT (c1));
7298 emit_move_insn (operand2, GEN_INT (c2));
7302 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7305 ud2 = (c1 & 0xffff0000) >> 16;
7306 #if HOST_BITS_PER_WIDE_INT >= 64
7310 ud4 = (c2 & 0xffff0000) >> 16;
7312 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7313 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7316 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7318 emit_move_insn (dest, GEN_INT (ud1));
7321 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7322 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7325 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7328 emit_move_insn (dest, GEN_INT (ud2 << 16));
7330 emit_move_insn (copy_rtx (dest),
7331 gen_rtx_IOR (DImode, copy_rtx (dest),
7334 else if (ud3 == 0 && ud4 == 0)
7336 gcc_assert (ud2 & 0x8000);
7337 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7340 emit_move_insn (copy_rtx (dest),
7341 gen_rtx_IOR (DImode, copy_rtx (dest),
7343 emit_move_insn (copy_rtx (dest),
7344 gen_rtx_ZERO_EXTEND (DImode,
7345 gen_lowpart (SImode,
7348 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7349 || (ud4 == 0 && ! (ud3 & 0x8000)))
7352 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7355 emit_move_insn (dest, GEN_INT (ud3 << 16));
7358 emit_move_insn (copy_rtx (dest),
7359 gen_rtx_IOR (DImode, copy_rtx (dest),
7361 emit_move_insn (copy_rtx (dest),
7362 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7365 emit_move_insn (copy_rtx (dest),
7366 gen_rtx_IOR (DImode, copy_rtx (dest),
7372 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7375 emit_move_insn (dest, GEN_INT (ud4 << 16));
7378 emit_move_insn (copy_rtx (dest),
7379 gen_rtx_IOR (DImode, copy_rtx (dest),
7382 emit_move_insn (copy_rtx (dest),
7383 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7386 emit_move_insn (copy_rtx (dest),
7387 gen_rtx_IOR (DImode, copy_rtx (dest),
7388 GEN_INT (ud2 << 16)));
7390 emit_move_insn (copy_rtx (dest),
7391 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7397 /* Helper for the following. Get rid of [r+r] memory refs
7398 in cases where it won't work (TImode, TFmode, TDmode). */
7401 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7403 if (reload_in_progress)
7406 if (GET_CODE (operands[0]) == MEM
7407 && GET_CODE (XEXP (operands[0], 0)) != REG
7408 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7409 GET_MODE (operands[0]), false))
7411 = replace_equiv_address (operands[0],
7412 copy_addr_to_reg (XEXP (operands[0], 0)));
7414 if (GET_CODE (operands[1]) == MEM
7415 && GET_CODE (XEXP (operands[1], 0)) != REG
7416 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7417 GET_MODE (operands[1]), false))
7419 = replace_equiv_address (operands[1],
7420 copy_addr_to_reg (XEXP (operands[1], 0)));
7423 /* Emit a move from SOURCE to DEST in mode MODE. */
7425 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7429 operands[1] = source;
7431 if (TARGET_DEBUG_ADDR)
7434 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7435 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7436 GET_MODE_NAME (mode),
7439 can_create_pseudo_p ());
7441 fprintf (stderr, "source:\n");
7445 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7446 if (GET_CODE (operands[1]) == CONST_DOUBLE
7447 && ! FLOAT_MODE_P (mode)
7448 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7450 /* FIXME. This should never happen. */
7451 /* Since it seems that it does, do the safe thing and convert
7453 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7455 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7456 || FLOAT_MODE_P (mode)
7457 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7458 || CONST_DOUBLE_LOW (operands[1]) < 0)
7459 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7460 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7462 /* Check if GCC is setting up a block move that will end up using FP
7463 registers as temporaries. We must make sure this is acceptable. */
7464 if (GET_CODE (operands[0]) == MEM
7465 && GET_CODE (operands[1]) == MEM
7467 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7468 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7469 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7470 ? 32 : MEM_ALIGN (operands[0])))
7471 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7473 : MEM_ALIGN (operands[1]))))
7474 && ! MEM_VOLATILE_P (operands [0])
7475 && ! MEM_VOLATILE_P (operands [1]))
7477 emit_move_insn (adjust_address (operands[0], SImode, 0),
7478 adjust_address (operands[1], SImode, 0));
7479 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7480 adjust_address (copy_rtx (operands[1]), SImode, 4));
7484 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7485 && !gpc_reg_operand (operands[1], mode))
7486 operands[1] = force_reg (mode, operands[1]);
7488 if (mode == SFmode && ! TARGET_POWERPC
7489 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7490 && GET_CODE (operands[0]) == MEM)
7494 if (reload_in_progress || reload_completed)
7495 regnum = true_regnum (operands[1]);
7496 else if (GET_CODE (operands[1]) == REG)
7497 regnum = REGNO (operands[1]);
7501 /* If operands[1] is a register, on POWER it may have
7502 double-precision data in it, so truncate it to single
7504 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7507 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7508 : gen_reg_rtx (mode));
7509 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7510 operands[1] = newreg;
7514 /* Recognize the case where operand[1] is a reference to thread-local
7515 data and load its address to a register. */
7516 if (rs6000_tls_referenced_p (operands[1]))
7518 enum tls_model model;
7519 rtx tmp = operands[1];
7522 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7524 addend = XEXP (XEXP (tmp, 0), 1);
7525 tmp = XEXP (XEXP (tmp, 0), 0);
7528 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7529 model = SYMBOL_REF_TLS_MODEL (tmp);
7530 gcc_assert (model != 0);
7532 tmp = rs6000_legitimize_tls_address (tmp, model);
7535 tmp = gen_rtx_PLUS (mode, tmp, addend);
7536 tmp = force_operand (tmp, operands[0]);
7541 /* Handle the case where reload calls us with an invalid address. */
7542 if (reload_in_progress && mode == Pmode
7543 && (! general_operand (operands[1], mode)
7544 || ! nonimmediate_operand (operands[0], mode)))
7547 /* 128-bit constant floating-point values on Darwin should really be
7548 loaded as two parts. */
7549 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7550 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7552 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7553 know how to get a DFmode SUBREG of a TFmode. */
7554 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7555 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7556 simplify_gen_subreg (imode, operands[1], mode, 0),
7558 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7559 GET_MODE_SIZE (imode)),
7560 simplify_gen_subreg (imode, operands[1], mode,
7561 GET_MODE_SIZE (imode)),
7566 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7567 cfun->machine->sdmode_stack_slot =
7568 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7570 if (reload_in_progress
7572 && MEM_P (operands[0])
7573 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7574 && REG_P (operands[1]))
7576 if (FP_REGNO_P (REGNO (operands[1])))
7578 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7579 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7580 emit_insn (gen_movsd_store (mem, operands[1]));
7582 else if (INT_REGNO_P (REGNO (operands[1])))
7584 rtx mem = adjust_address_nv (operands[0], mode, 4);
7585 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7586 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7592 if (reload_in_progress
7594 && REG_P (operands[0])
7595 && MEM_P (operands[1])
7596 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7598 if (FP_REGNO_P (REGNO (operands[0])))
7600 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7601 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7602 emit_insn (gen_movsd_load (operands[0], mem));
7604 else if (INT_REGNO_P (REGNO (operands[0])))
7606 rtx mem = adjust_address_nv (operands[1], mode, 4);
7607 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7608 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7615 /* FIXME: In the long term, this switch statement should go away
7616 and be replaced by a sequence of tests based on things like
7622 if (CONSTANT_P (operands[1])
7623 && GET_CODE (operands[1]) != CONST_INT)
7624 operands[1] = force_const_mem (mode, operands[1]);
7629 rs6000_eliminate_indexed_memrefs (operands);
7636 if (CONSTANT_P (operands[1])
7637 && ! easy_fp_constant (operands[1], mode))
7638 operands[1] = force_const_mem (mode, operands[1]);
7651 if (CONSTANT_P (operands[1])
7652 && !easy_vector_constant (operands[1], mode))
7653 operands[1] = force_const_mem (mode, operands[1]);
7658 /* Use default pattern for address of ELF small data */
7661 && DEFAULT_ABI == ABI_V4
7662 && (GET_CODE (operands[1]) == SYMBOL_REF
7663 || GET_CODE (operands[1]) == CONST)
7664 && small_data_operand (operands[1], mode))
7666 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7670 if (DEFAULT_ABI == ABI_V4
7671 && mode == Pmode && mode == SImode
7672 && flag_pic == 1 && got_operand (operands[1], mode))
7674 emit_insn (gen_movsi_got (operands[0], operands[1]));
7678 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7682 && CONSTANT_P (operands[1])
7683 && GET_CODE (operands[1]) != HIGH
7684 && GET_CODE (operands[1]) != CONST_INT)
7686 rtx target = (!can_create_pseudo_p ()
7688 : gen_reg_rtx (mode));
7690 /* If this is a function address on -mcall-aixdesc,
7691 convert it to the address of the descriptor. */
7692 if (DEFAULT_ABI == ABI_AIX
7693 && GET_CODE (operands[1]) == SYMBOL_REF
7694 && XSTR (operands[1], 0)[0] == '.')
7696 const char *name = XSTR (operands[1], 0);
7698 while (*name == '.')
7700 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7701 CONSTANT_POOL_ADDRESS_P (new_ref)
7702 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7703 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7704 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7705 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7706 operands[1] = new_ref;
7709 if (DEFAULT_ABI == ABI_DARWIN)
7712 if (MACHO_DYNAMIC_NO_PIC_P)
7714 /* Take care of any required data indirection. */
7715 operands[1] = rs6000_machopic_legitimize_pic_address (
7716 operands[1], mode, operands[0]);
7717 if (operands[0] != operands[1])
7718 emit_insn (gen_rtx_SET (VOIDmode,
7719 operands[0], operands[1]));
7723 emit_insn (gen_macho_high (target, operands[1]));
7724 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7728 emit_insn (gen_elf_high (target, operands[1]));
7729 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7733 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7734 and we have put it in the TOC, we just need to make a TOC-relative
7737 && GET_CODE (operands[1]) == SYMBOL_REF
7738 && constant_pool_expr_p (operands[1])
7739 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7740 get_pool_mode (operands[1])))
7741 || (TARGET_CMODEL == CMODEL_MEDIUM
7742 && GET_CODE (operands[1]) == SYMBOL_REF
7743 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7744 && SYMBOL_REF_LOCAL_P (operands[1])))
7747 if (TARGET_CMODEL != CMODEL_SMALL)
7749 if (can_create_pseudo_p ())
7750 reg = gen_reg_rtx (Pmode);
7754 operands[1] = create_TOC_reference (operands[1], reg);
7756 else if (mode == Pmode
7757 && CONSTANT_P (operands[1])
7758 && ((GET_CODE (operands[1]) != CONST_INT
7759 && ! easy_fp_constant (operands[1], mode))
7760 || (GET_CODE (operands[1]) == CONST_INT
7761 && (num_insns_constant (operands[1], mode)
7762 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7763 || (GET_CODE (operands[0]) == REG
7764 && FP_REGNO_P (REGNO (operands[0]))))
7765 && GET_CODE (operands[1]) != HIGH
7766 && ! legitimate_constant_pool_address_p (operands[1], mode,
7768 && ! toc_relative_expr_p (operands[1])
7769 && (TARGET_CMODEL == CMODEL_SMALL
7770 || can_create_pseudo_p ()
7771 || (REG_P (operands[0])
7772 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7776 /* Darwin uses a special PIC legitimizer. */
7777 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7780 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7782 if (operands[0] != operands[1])
7783 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7788 /* If we are to limit the number of things we put in the TOC and
7789 this is a symbol plus a constant we can add in one insn,
7790 just put the symbol in the TOC and add the constant. Don't do
7791 this if reload is in progress. */
7792 if (GET_CODE (operands[1]) == CONST
7793 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7794 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7795 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7796 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7797 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7798 && ! side_effects_p (operands[0]))
7801 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7802 rtx other = XEXP (XEXP (operands[1], 0), 1);
7804 sym = force_reg (mode, sym);
7805 emit_insn (gen_add3_insn (operands[0], sym, other));
7809 operands[1] = force_const_mem (mode, operands[1]);
7812 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7813 && constant_pool_expr_p (XEXP (operands[1], 0))
7814 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7815 get_pool_constant (XEXP (operands[1], 0)),
7816 get_pool_mode (XEXP (operands[1], 0))))
7820 if (TARGET_CMODEL != CMODEL_SMALL)
7822 if (can_create_pseudo_p ())
7823 reg = gen_reg_rtx (Pmode);
7827 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7828 operands[1] = gen_const_mem (mode, tocref);
7829 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7835 rs6000_eliminate_indexed_memrefs (operands);
7839 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7841 gen_rtx_SET (VOIDmode,
7842 operands[0], operands[1]),
7843 gen_rtx_CLOBBER (VOIDmode,
7844 gen_rtx_SCRATCH (SImode)))));
7850 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7853 /* Above, we may have called force_const_mem which may have returned
7854 an invalid address. If we can, fix this up; otherwise, reload will
7855 have to deal with it. */
7856 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7857 operands[1] = validize_mem (operands[1]);
7860 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7863 /* Nonzero if we can use a floating-point register to pass this arg. */
7864 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7865 (SCALAR_FLOAT_MODE_P (MODE) \
7866 && (CUM)->fregno <= FP_ARG_MAX_REG \
7867 && TARGET_HARD_FLOAT && TARGET_FPRS)
7869 /* Nonzero if we can use an AltiVec register to pass this arg. */
7870 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7871 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7872 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7873 && TARGET_ALTIVEC_ABI \
7876 /* Return a nonzero value to say to return the function value in
7877 memory, just as large structures are always returned. TYPE will be
7878 the data type of the value, and FNTYPE will be the type of the
7879 function doing the returning, or @code{NULL} for libcalls.
7881 The AIX ABI for the RS/6000 specifies that all structures are
7882 returned in memory. The Darwin ABI does the same.
7884 For the Darwin 64 Bit ABI, a function result can be returned in
7885 registers or in memory, depending on the size of the return data
7886 type. If it is returned in registers, the value occupies the same
7887 registers as it would if it were the first and only function
7888 argument. Otherwise, the function places its result in memory at
7889 the location pointed to by GPR3.
7891 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7892 but a draft put them in memory, and GCC used to implement the draft
7893 instead of the final standard. Therefore, aix_struct_return
7894 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7895 compatibility can change DRAFT_V4_STRUCT_RET to override the
7896 default, and -m switches get the final word. See
7897 rs6000_option_override_internal for more details.
7899 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7900 long double support is enabled. These values are returned in memory.
7902 int_size_in_bytes returns -1 for variable size objects, which go in
7903 memory always. The cast to unsigned makes -1 > 8. */
7906 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7908 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7910 && rs6000_darwin64_abi
7911 && TREE_CODE (type) == RECORD_TYPE
7912 && int_size_in_bytes (type) > 0)
7914 CUMULATIVE_ARGS valcum;
7918 valcum.fregno = FP_ARG_MIN_REG;
7919 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7920 /* Do a trial code generation as if this were going to be passed
7921 as an argument; if any part goes in memory, we return NULL. */
7922 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7925 /* Otherwise fall through to more conventional ABI rules. */
7928 if (AGGREGATE_TYPE_P (type)
7929 && (aix_struct_return
7930 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7933 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7934 modes only exist for GCC vector types if -maltivec. */
7935 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7936 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7939 /* Return synthetic vectors in memory. */
7940 if (TREE_CODE (type) == VECTOR_TYPE
7941 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7943 static bool warned_for_return_big_vectors = false;
7944 if (!warned_for_return_big_vectors)
7946 warning (0, "GCC vector returned by reference: "
7947 "non-standard ABI extension with no compatibility guarantee");
7948 warned_for_return_big_vectors = true;
7953 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7959 #ifdef HAVE_AS_GNU_ATTRIBUTE
7960 /* Return TRUE if a call to function FNDECL may be one that
7961 potentially affects the function calling ABI of the object file. */
7964 call_ABI_of_interest (tree fndecl)
7966 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7968 struct cgraph_node *c_node;
7970 /* Libcalls are always interesting. */
7971 if (fndecl == NULL_TREE)
7974 /* Any call to an external function is interesting. */
7975 if (DECL_EXTERNAL (fndecl))
7978 /* Interesting functions that we are emitting in this object file. */
7979 c_node = cgraph_node (fndecl);
7980 return !cgraph_only_called_directly_p (c_node);
7986 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7987 for a call to a function whose data type is FNTYPE.
7988 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7990 For incoming args we set the number of arguments in the prototype large
7991 so we never return a PARALLEL. */
7994 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
7995 rtx libname ATTRIBUTE_UNUSED, int incoming,
7996 int libcall, int n_named_args,
7997 tree fndecl ATTRIBUTE_UNUSED,
7998 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8000 static CUMULATIVE_ARGS zero_cumulative;
8002 *cum = zero_cumulative;
8004 cum->fregno = FP_ARG_MIN_REG;
8005 cum->vregno = ALTIVEC_ARG_MIN_REG;
8006 cum->prototype = (fntype && prototype_p (fntype));
8007 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8008 ? CALL_LIBCALL : CALL_NORMAL);
8009 cum->sysv_gregno = GP_ARG_MIN_REG;
8010 cum->stdarg = stdarg_p (fntype);
8012 cum->nargs_prototype = 0;
8013 if (incoming || cum->prototype)
8014 cum->nargs_prototype = n_named_args;
8016 /* Check for a longcall attribute. */
8017 if ((!fntype && rs6000_default_long_calls)
8019 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8020 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8021 cum->call_cookie |= CALL_LONG;
8023 if (TARGET_DEBUG_ARG)
8025 fprintf (stderr, "\ninit_cumulative_args:");
8028 tree ret_type = TREE_TYPE (fntype);
8029 fprintf (stderr, " ret code = %s,",
8030 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8033 if (cum->call_cookie & CALL_LONG)
8034 fprintf (stderr, " longcall,");
8036 fprintf (stderr, " proto = %d, nargs = %d\n",
8037 cum->prototype, cum->nargs_prototype);
8040 #ifdef HAVE_AS_GNU_ATTRIBUTE
8041 if (DEFAULT_ABI == ABI_V4)
8043 cum->escapes = call_ABI_of_interest (fndecl);
8050 return_type = TREE_TYPE (fntype);
8051 return_mode = TYPE_MODE (return_type);
8054 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8056 if (return_type != NULL)
8058 if (TREE_CODE (return_type) == RECORD_TYPE
8059 && TYPE_TRANSPARENT_AGGR (return_type))
8061 return_type = TREE_TYPE (first_field (return_type));
8062 return_mode = TYPE_MODE (return_type);
8064 if (AGGREGATE_TYPE_P (return_type)
8065 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8067 rs6000_returns_struct = true;
8069 if (SCALAR_FLOAT_MODE_P (return_mode))
8070 rs6000_passes_float = true;
8071 else if (ALTIVEC_VECTOR_MODE (return_mode)
8072 || VSX_VECTOR_MODE (return_mode)
8073 || SPE_VECTOR_MODE (return_mode))
8074 rs6000_passes_vector = true;
8081 && TARGET_ALTIVEC_ABI
8082 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8084 error ("cannot return value in vector register because"
8085 " altivec instructions are disabled, use -maltivec"
8090 /* Return true if TYPE must be passed on the stack and not in registers. */
8093 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8095 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8096 return must_pass_in_stack_var_size (mode, type);
8098 return must_pass_in_stack_var_size_or_pad (mode, type);
8101 /* If defined, a C expression which determines whether, and in which
8102 direction, to pad out an argument with extra space. The value
8103 should be of type `enum direction': either `upward' to pad above
8104 the argument, `downward' to pad below, or `none' to inhibit
8107 For the AIX ABI structs are always stored left shifted in their
8111 function_arg_padding (enum machine_mode mode, const_tree type)
8113 #ifndef AGGREGATE_PADDING_FIXED
8114 #define AGGREGATE_PADDING_FIXED 0
8116 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8117 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8120 if (!AGGREGATE_PADDING_FIXED)
8122 /* GCC used to pass structures of the same size as integer types as
8123 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8124 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8125 passed padded downward, except that -mstrict-align further
8126 muddied the water in that multi-component structures of 2 and 4
8127 bytes in size were passed padded upward.
8129 The following arranges for best compatibility with previous
8130 versions of gcc, but removes the -mstrict-align dependency. */
8131 if (BYTES_BIG_ENDIAN)
8133 HOST_WIDE_INT size = 0;
8135 if (mode == BLKmode)
8137 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8138 size = int_size_in_bytes (type);
8141 size = GET_MODE_SIZE (mode);
8143 if (size == 1 || size == 2 || size == 4)
8149 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8151 if (type != 0 && AGGREGATE_TYPE_P (type))
8155 /* Fall back to the default. */
8156 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8159 /* If defined, a C expression that gives the alignment boundary, in bits,
8160 of an argument with the specified mode and type. If it is not defined,
8161 PARM_BOUNDARY is used for all arguments.
8163 V.4 wants long longs and doubles to be double word aligned. Just
8164 testing the mode size is a boneheaded way to do this as it means
8165 that other types such as complex int are also double word aligned.
8166 However, we're stuck with this because changing the ABI might break
8167 existing library interfaces.
8169 Doubleword align SPE vectors.
8170 Quadword align Altivec vectors.
8171 Quadword align large synthetic vector types. */
8174 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8176 if (DEFAULT_ABI == ABI_V4
8177 && (GET_MODE_SIZE (mode) == 8
8178 || (TARGET_HARD_FLOAT
8180 && (mode == TFmode || mode == TDmode))))
8182 else if (SPE_VECTOR_MODE (mode)
8183 || (type && TREE_CODE (type) == VECTOR_TYPE
8184 && int_size_in_bytes (type) >= 8
8185 && int_size_in_bytes (type) < 16))
8187 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8188 || (type && TREE_CODE (type) == VECTOR_TYPE
8189 && int_size_in_bytes (type) >= 16))
8191 else if (TARGET_MACHO
8192 && rs6000_darwin64_abi
8194 && type && TYPE_ALIGN (type) > 64)
8197 return PARM_BOUNDARY;
8200 /* For a function parm of MODE and TYPE, return the starting word in
8201 the parameter area. NWORDS of the parameter area are already used. */
8204 rs6000_parm_start (enum machine_mode mode, const_tree type,
8205 unsigned int nwords)
8208 unsigned int parm_offset;
8210 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8211 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8212 return nwords + (-(parm_offset + nwords) & align);
8215 /* Compute the size (in words) of a function argument. */
8217 static unsigned long
8218 rs6000_arg_size (enum machine_mode mode, const_tree type)
8222 if (mode != BLKmode)
8223 size = GET_MODE_SIZE (mode);
8225 size = int_size_in_bytes (type);
8228 return (size + 3) >> 2;
8230 return (size + 7) >> 3;
8233 /* Use this to flush pending int fields. */
8236 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8237 HOST_WIDE_INT bitpos, int final)
8239 unsigned int startbit, endbit;
8240 int intregs, intoffset;
8241 enum machine_mode mode;
8243 /* Handle the situations where a float is taking up the first half
8244 of the GPR, and the other half is empty (typically due to
8245 alignment restrictions). We can detect this by a 8-byte-aligned
8246 int field, or by seeing that this is the final flush for this
8247 argument. Count the word and continue on. */
8248 if (cum->floats_in_gpr == 1
8249 && (cum->intoffset % 64 == 0
8250 || (cum->intoffset == -1 && final)))
8253 cum->floats_in_gpr = 0;
8256 if (cum->intoffset == -1)
8259 intoffset = cum->intoffset;
8260 cum->intoffset = -1;
8261 cum->floats_in_gpr = 0;
8263 if (intoffset % BITS_PER_WORD != 0)
8265 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8267 if (mode == BLKmode)
8269 /* We couldn't find an appropriate mode, which happens,
8270 e.g., in packed structs when there are 3 bytes to load.
8271 Back intoffset back to the beginning of the word in this
8273 intoffset = intoffset & -BITS_PER_WORD;
8277 startbit = intoffset & -BITS_PER_WORD;
8278 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8279 intregs = (endbit - startbit) / BITS_PER_WORD;
8280 cum->words += intregs;
8281 /* words should be unsigned. */
8282 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8284 int pad = (endbit/BITS_PER_WORD) - cum->words;
8289 /* The darwin64 ABI calls for us to recurse down through structs,
8290 looking for elements passed in registers. Unfortunately, we have
8291 to track int register count here also because of misalignments
8292 in powerpc alignment mode. */
8295 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8297 HOST_WIDE_INT startbitpos)
8301 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8302 if (TREE_CODE (f) == FIELD_DECL)
8304 HOST_WIDE_INT bitpos = startbitpos;
8305 tree ftype = TREE_TYPE (f);
8306 enum machine_mode mode;
8307 if (ftype == error_mark_node)
8309 mode = TYPE_MODE (ftype);
8311 if (DECL_SIZE (f) != 0
8312 && host_integerp (bit_position (f), 1))
8313 bitpos += int_bit_position (f);
8315 /* ??? FIXME: else assume zero offset. */
8317 if (TREE_CODE (ftype) == RECORD_TYPE)
8318 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8319 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8321 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8322 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8323 cum->fregno += n_fpregs;
8324 /* Single-precision floats present a special problem for
8325 us, because they are smaller than an 8-byte GPR, and so
8326 the structure-packing rules combined with the standard
8327 varargs behavior mean that we want to pack float/float
8328 and float/int combinations into a single register's
8329 space. This is complicated by the arg advance flushing,
8330 which works on arbitrarily large groups of int-type
8334 if (cum->floats_in_gpr == 1)
8336 /* Two floats in a word; count the word and reset
8339 cum->floats_in_gpr = 0;
8341 else if (bitpos % 64 == 0)
8343 /* A float at the beginning of an 8-byte word;
8344 count it and put off adjusting cum->words until
8345 we see if a arg advance flush is going to do it
8347 cum->floats_in_gpr++;
8351 /* The float is at the end of a word, preceded
8352 by integer fields, so the arg advance flush
8353 just above has already set cum->words and
8354 everything is taken care of. */
8358 cum->words += n_fpregs;
8360 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8362 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8366 else if (cum->intoffset == -1)
8367 cum->intoffset = bitpos;
8371 /* Check for an item that needs to be considered specially under the darwin 64
8372 bit ABI. These are record types where the mode is BLK or the structure is
8375 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8377 return rs6000_darwin64_abi
8378 && ((mode == BLKmode
8379 && TREE_CODE (type) == RECORD_TYPE
8380 && int_size_in_bytes (type) > 0)
8381 || (type && TREE_CODE (type) == RECORD_TYPE
8382 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8385 /* Update the data in CUM to advance over an argument
8386 of mode MODE and data type TYPE.
8387 (TYPE is null for libcalls where that information may not be available.)
8389 Note that for args passed by reference, function_arg will be called
8390 with MODE and TYPE set to that of the pointer to the arg, not the arg
8394 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8395 const_tree type, bool named, int depth)
8397 /* Only tick off an argument if we're not recursing. */
8399 cum->nargs_prototype--;
8401 #ifdef HAVE_AS_GNU_ATTRIBUTE
8402 if (DEFAULT_ABI == ABI_V4
8405 if (SCALAR_FLOAT_MODE_P (mode))
8406 rs6000_passes_float = true;
8407 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8408 rs6000_passes_vector = true;
8409 else if (SPE_VECTOR_MODE (mode)
8411 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8412 rs6000_passes_vector = true;
8416 if (TARGET_ALTIVEC_ABI
8417 && (ALTIVEC_VECTOR_MODE (mode)
8418 || VSX_VECTOR_MODE (mode)
8419 || (type && TREE_CODE (type) == VECTOR_TYPE
8420 && int_size_in_bytes (type) == 16)))
8424 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8427 if (!TARGET_ALTIVEC)
8428 error ("cannot pass argument in vector register because"
8429 " altivec instructions are disabled, use -maltivec"
8432 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8433 even if it is going to be passed in a vector register.
8434 Darwin does the same for variable-argument functions. */
8435 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8436 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8446 /* Vector parameters must be 16-byte aligned. This places
8447 them at 2 mod 4 in terms of words in 32-bit mode, since
8448 the parameter save area starts at offset 24 from the
8449 stack. In 64-bit mode, they just have to start on an
8450 even word, since the parameter save area is 16-byte
8451 aligned. Space for GPRs is reserved even if the argument
8452 will be passed in memory. */
8454 align = (2 - cum->words) & 3;
8456 align = cum->words & 1;
8457 cum->words += align + rs6000_arg_size (mode, type);
8459 if (TARGET_DEBUG_ARG)
8461 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8463 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8464 cum->nargs_prototype, cum->prototype,
8465 GET_MODE_NAME (mode));
8469 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8471 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8474 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8476 int size = int_size_in_bytes (type);
8477 /* Variable sized types have size == -1 and are
8478 treated as if consisting entirely of ints.
8479 Pad to 16 byte boundary if needed. */
8480 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8481 && (cum->words % 2) != 0)
8483 /* For varargs, we can just go up by the size of the struct. */
8485 cum->words += (size + 7) / 8;
8488 /* It is tempting to say int register count just goes up by
8489 sizeof(type)/8, but this is wrong in a case such as
8490 { int; double; int; } [powerpc alignment]. We have to
8491 grovel through the fields for these too. */
8493 cum->floats_in_gpr = 0;
8494 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8495 rs6000_darwin64_record_arg_advance_flush (cum,
8496 size * BITS_PER_UNIT, 1);
8498 if (TARGET_DEBUG_ARG)
8500 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8501 cum->words, TYPE_ALIGN (type), size);
8503 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8504 cum->nargs_prototype, cum->prototype,
8505 GET_MODE_NAME (mode));
8508 else if (DEFAULT_ABI == ABI_V4)
8510 if (TARGET_HARD_FLOAT && TARGET_FPRS
8511 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8512 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8513 || (mode == TFmode && !TARGET_IEEEQUAD)
8514 || mode == SDmode || mode == DDmode || mode == TDmode))
8516 /* _Decimal128 must use an even/odd register pair. This assumes
8517 that the register number is odd when fregno is odd. */
8518 if (mode == TDmode && (cum->fregno % 2) == 1)
8521 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8522 <= FP_ARG_V4_MAX_REG)
8523 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8526 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8527 if (mode == DFmode || mode == TFmode
8528 || mode == DDmode || mode == TDmode)
8529 cum->words += cum->words & 1;
8530 cum->words += rs6000_arg_size (mode, type);
8535 int n_words = rs6000_arg_size (mode, type);
8536 int gregno = cum->sysv_gregno;
8538 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8539 (r7,r8) or (r9,r10). As does any other 2 word item such
8540 as complex int due to a historical mistake. */
8542 gregno += (1 - gregno) & 1;
8544 /* Multi-reg args are not split between registers and stack. */
8545 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8547 /* Long long and SPE vectors are aligned on the stack.
8548 So are other 2 word items such as complex int due to
8549 a historical mistake. */
8551 cum->words += cum->words & 1;
8552 cum->words += n_words;
8555 /* Note: continuing to accumulate gregno past when we've started
8556 spilling to the stack indicates the fact that we've started
8557 spilling to the stack to expand_builtin_saveregs. */
8558 cum->sysv_gregno = gregno + n_words;
8561 if (TARGET_DEBUG_ARG)
8563 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8564 cum->words, cum->fregno);
8565 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8566 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8567 fprintf (stderr, "mode = %4s, named = %d\n",
8568 GET_MODE_NAME (mode), named);
8573 int n_words = rs6000_arg_size (mode, type);
8574 int start_words = cum->words;
8575 int align_words = rs6000_parm_start (mode, type, start_words);
8577 cum->words = align_words + n_words;
8579 if (SCALAR_FLOAT_MODE_P (mode)
8580 && TARGET_HARD_FLOAT && TARGET_FPRS)
8582 /* _Decimal128 must be passed in an even/odd float register pair.
8583 This assumes that the register number is odd when fregno is
8585 if (mode == TDmode && (cum->fregno % 2) == 1)
8587 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8590 if (TARGET_DEBUG_ARG)
8592 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8593 cum->words, cum->fregno);
8594 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8595 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8596 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8597 named, align_words - start_words, depth);
8603 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8604 const_tree type, bool named)
8606 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8610 spe_build_register_parallel (enum machine_mode mode, int gregno)
8617 r1 = gen_rtx_REG (DImode, gregno);
8618 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8619 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8623 r1 = gen_rtx_REG (DImode, gregno);
8624 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8625 r3 = gen_rtx_REG (DImode, gregno + 2);
8626 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8627 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8630 r1 = gen_rtx_REG (DImode, gregno);
8631 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8632 r3 = gen_rtx_REG (DImode, gregno + 2);
8633 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8634 r5 = gen_rtx_REG (DImode, gregno + 4);
8635 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8636 r7 = gen_rtx_REG (DImode, gregno + 6);
8637 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8638 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8645 /* Determine where to put a SIMD argument on the SPE. */
8647 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8650 int gregno = cum->sysv_gregno;
8652 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8653 are passed and returned in a pair of GPRs for ABI compatibility. */
8654 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8655 || mode == DCmode || mode == TCmode))
8657 int n_words = rs6000_arg_size (mode, type);
8659 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8661 gregno += (1 - gregno) & 1;
8663 /* Multi-reg args are not split between registers and stack. */
8664 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8667 return spe_build_register_parallel (mode, gregno);
8671 int n_words = rs6000_arg_size (mode, type);
8673 /* SPE vectors are put in odd registers. */
8674 if (n_words == 2 && (gregno & 1) == 0)
8677 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8680 enum machine_mode m = SImode;
8682 r1 = gen_rtx_REG (m, gregno);
8683 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8684 r2 = gen_rtx_REG (m, gregno + 1);
8685 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8686 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8693 if (gregno <= GP_ARG_MAX_REG)
8694 return gen_rtx_REG (mode, gregno);
8700 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8701 structure between cum->intoffset and bitpos to integer registers. */
8704 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8705 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8707 enum machine_mode mode;
8709 unsigned int startbit, endbit;
8710 int this_regno, intregs, intoffset;
8713 if (cum->intoffset == -1)
8716 intoffset = cum->intoffset;
8717 cum->intoffset = -1;
8719 /* If this is the trailing part of a word, try to only load that
8720 much into the register. Otherwise load the whole register. Note
8721 that in the latter case we may pick up unwanted bits. It's not a
8722 problem at the moment but may wish to revisit. */
8724 if (intoffset % BITS_PER_WORD != 0)
8726 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8728 if (mode == BLKmode)
8730 /* We couldn't find an appropriate mode, which happens,
8731 e.g., in packed structs when there are 3 bytes to load.
8732 Back intoffset back to the beginning of the word in this
8734 intoffset = intoffset & -BITS_PER_WORD;
8741 startbit = intoffset & -BITS_PER_WORD;
8742 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8743 intregs = (endbit - startbit) / BITS_PER_WORD;
8744 this_regno = cum->words + intoffset / BITS_PER_WORD;
8746 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8749 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8753 intoffset /= BITS_PER_UNIT;
8756 regno = GP_ARG_MIN_REG + this_regno;
8757 reg = gen_rtx_REG (mode, regno);
8759 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8762 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8766 while (intregs > 0);
8769 /* Recursive workhorse for the following. */
8772 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8773 HOST_WIDE_INT startbitpos, rtx rvec[],
8778 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8779 if (TREE_CODE (f) == FIELD_DECL)
8781 HOST_WIDE_INT bitpos = startbitpos;
8782 tree ftype = TREE_TYPE (f);
8783 enum machine_mode mode;
8784 if (ftype == error_mark_node)
8786 mode = TYPE_MODE (ftype);
8788 if (DECL_SIZE (f) != 0
8789 && host_integerp (bit_position (f), 1))
8790 bitpos += int_bit_position (f);
8792 /* ??? FIXME: else assume zero offset. */
8794 if (TREE_CODE (ftype) == RECORD_TYPE)
8795 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8796 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8798 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8802 case SCmode: mode = SFmode; break;
8803 case DCmode: mode = DFmode; break;
8804 case TCmode: mode = TFmode; break;
8808 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8809 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8811 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8812 && (mode == TFmode || mode == TDmode));
8813 /* Long double or _Decimal128 split over regs and memory. */
8814 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8818 = gen_rtx_EXPR_LIST (VOIDmode,
8819 gen_rtx_REG (mode, cum->fregno++),
8820 GEN_INT (bitpos / BITS_PER_UNIT));
8821 if (mode == TFmode || mode == TDmode)
8824 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8826 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8828 = gen_rtx_EXPR_LIST (VOIDmode,
8829 gen_rtx_REG (mode, cum->vregno++),
8830 GEN_INT (bitpos / BITS_PER_UNIT));
8832 else if (cum->intoffset == -1)
8833 cum->intoffset = bitpos;
8837 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8838 the register(s) to be used for each field and subfield of a struct
8839 being passed by value, along with the offset of where the
8840 register's value may be found in the block. FP fields go in FP
8841 register, vector fields go in vector registers, and everything
8842 else goes in int registers, packed as in memory.
8844 This code is also used for function return values. RETVAL indicates
8845 whether this is the case.
8847 Much of this is taken from the SPARC V9 port, which has a similar
8848 calling convention. */
8851 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8852 bool named, bool retval)
8854 rtx rvec[FIRST_PSEUDO_REGISTER];
8855 int k = 1, kbase = 1;
8856 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8857 /* This is a copy; modifications are not visible to our caller. */
8858 CUMULATIVE_ARGS copy_cum = *orig_cum;
8859 CUMULATIVE_ARGS *cum = ©_cum;
8861 /* Pad to 16 byte boundary if needed. */
8862 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8863 && (cum->words % 2) != 0)
8870 /* Put entries into rvec[] for individual FP and vector fields, and
8871 for the chunks of memory that go in int regs. Note we start at
8872 element 1; 0 is reserved for an indication of using memory, and
8873 may or may not be filled in below. */
8874 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8875 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8877 /* If any part of the struct went on the stack put all of it there.
8878 This hack is because the generic code for
8879 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8880 parts of the struct are not at the beginning. */
8884 return NULL_RTX; /* doesn't go in registers at all */
8886 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8888 if (k > 1 || cum->use_stack)
8889 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8894 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8897 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8902 rtx rvec[GP_ARG_NUM_REG + 1];
8904 if (align_words >= GP_ARG_NUM_REG)
8907 n_units = rs6000_arg_size (mode, type);
8909 /* Optimize the simple case where the arg fits in one gpr, except in
8910 the case of BLKmode due to assign_parms assuming that registers are
8911 BITS_PER_WORD wide. */
8913 || (n_units == 1 && mode != BLKmode))
8914 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8917 if (align_words + n_units > GP_ARG_NUM_REG)
8918 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8919 using a magic NULL_RTX component.
8920 This is not strictly correct. Only some of the arg belongs in
8921 memory, not all of it. However, the normal scheme using
8922 function_arg_partial_nregs can result in unusual subregs, eg.
8923 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8924 store the whole arg to memory is often more efficient than code
8925 to store pieces, and we know that space is available in the right
8926 place for the whole arg. */
8927 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8932 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8933 rtx off = GEN_INT (i++ * 4);
8934 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8936 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8938 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8941 /* Determine where to put an argument to a function.
8942 Value is zero to push the argument on the stack,
8943 or a hard register in which to store the argument.
8945 MODE is the argument's machine mode.
8946 TYPE is the data type of the argument (as a tree).
8947 This is null for libcalls where that information may
8949 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8950 the preceding args and about the function being called. It is
8951 not modified in this routine.
8952 NAMED is nonzero if this argument is a named parameter
8953 (otherwise it is an extra parameter matching an ellipsis).
8955 On RS/6000 the first eight words of non-FP are normally in registers
8956 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8957 Under V.4, the first 8 FP args are in registers.
8959 If this is floating-point and no prototype is specified, we use
8960 both an FP and integer register (or possibly FP reg and stack). Library
8961 functions (when CALL_LIBCALL is set) always have the proper types for args,
8962 so we can pass the FP value just in one register. emit_library_function
8963 doesn't support PARALLEL anyway.
8965 Note that for args passed by reference, function_arg will be called
8966 with MODE and TYPE set to that of the pointer to the arg, not the arg
8970 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8971 const_tree type, bool named)
8973 enum rs6000_abi abi = DEFAULT_ABI;
8975 /* Return a marker to indicate whether CR1 needs to set or clear the
8976 bit that V.4 uses to say fp args were passed in registers.
8977 Assume that we don't need the marker for software floating point,
8978 or compiler generated library calls. */
8979 if (mode == VOIDmode)
8982 && (cum->call_cookie & CALL_LIBCALL) == 0
8984 || (cum->nargs_prototype < 0
8985 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8987 /* For the SPE, we need to crxor CR6 always. */
8989 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8990 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
8991 return GEN_INT (cum->call_cookie
8992 | ((cum->fregno == FP_ARG_MIN_REG)
8993 ? CALL_V4_SET_FP_ARGS
8994 : CALL_V4_CLEAR_FP_ARGS));
8997 return GEN_INT (cum->call_cookie);
9000 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9002 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9003 if (rslt != NULL_RTX)
9005 /* Else fall through to usual handling. */
9008 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9009 if (TARGET_64BIT && ! cum->prototype)
9011 /* Vector parameters get passed in vector register
9012 and also in GPRs or memory, in absence of prototype. */
9015 align_words = (cum->words + 1) & ~1;
9017 if (align_words >= GP_ARG_NUM_REG)
9023 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9025 return gen_rtx_PARALLEL (mode,
9027 gen_rtx_EXPR_LIST (VOIDmode,
9029 gen_rtx_EXPR_LIST (VOIDmode,
9030 gen_rtx_REG (mode, cum->vregno),
9034 return gen_rtx_REG (mode, cum->vregno);
9035 else if (TARGET_ALTIVEC_ABI
9036 && (ALTIVEC_VECTOR_MODE (mode)
9037 || VSX_VECTOR_MODE (mode)
9038 || (type && TREE_CODE (type) == VECTOR_TYPE
9039 && int_size_in_bytes (type) == 16)))
9041 if (named || abi == ABI_V4)
9045 /* Vector parameters to varargs functions under AIX or Darwin
9046 get passed in memory and possibly also in GPRs. */
9047 int align, align_words, n_words;
9048 enum machine_mode part_mode;
9050 /* Vector parameters must be 16-byte aligned. This places them at
9051 2 mod 4 in terms of words in 32-bit mode, since the parameter
9052 save area starts at offset 24 from the stack. In 64-bit mode,
9053 they just have to start on an even word, since the parameter
9054 save area is 16-byte aligned. */
9056 align = (2 - cum->words) & 3;
9058 align = cum->words & 1;
9059 align_words = cum->words + align;
9061 /* Out of registers? Memory, then. */
9062 if (align_words >= GP_ARG_NUM_REG)
9065 if (TARGET_32BIT && TARGET_POWERPC64)
9066 return rs6000_mixed_function_arg (mode, type, align_words);
9068 /* The vector value goes in GPRs. Only the part of the
9069 value in GPRs is reported here. */
9071 n_words = rs6000_arg_size (mode, type);
9072 if (align_words + n_words > GP_ARG_NUM_REG)
9073 /* Fortunately, there are only two possibilities, the value
9074 is either wholly in GPRs or half in GPRs and half not. */
9077 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9080 else if (TARGET_SPE_ABI && TARGET_SPE
9081 && (SPE_VECTOR_MODE (mode)
9082 || (TARGET_E500_DOUBLE && (mode == DFmode
9085 || mode == TCmode))))
9086 return rs6000_spe_function_arg (cum, mode, type);
9088 else if (abi == ABI_V4)
9090 if (TARGET_HARD_FLOAT && TARGET_FPRS
9091 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9092 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9093 || (mode == TFmode && !TARGET_IEEEQUAD)
9094 || mode == SDmode || mode == DDmode || mode == TDmode))
9096 /* _Decimal128 must use an even/odd register pair. This assumes
9097 that the register number is odd when fregno is odd. */
9098 if (mode == TDmode && (cum->fregno % 2) == 1)
9101 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9102 <= FP_ARG_V4_MAX_REG)
9103 return gen_rtx_REG (mode, cum->fregno);
9109 int n_words = rs6000_arg_size (mode, type);
9110 int gregno = cum->sysv_gregno;
9112 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9113 (r7,r8) or (r9,r10). As does any other 2 word item such
9114 as complex int due to a historical mistake. */
9116 gregno += (1 - gregno) & 1;
9118 /* Multi-reg args are not split between registers and stack. */
9119 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9122 if (TARGET_32BIT && TARGET_POWERPC64)
9123 return rs6000_mixed_function_arg (mode, type,
9124 gregno - GP_ARG_MIN_REG);
9125 return gen_rtx_REG (mode, gregno);
9130 int align_words = rs6000_parm_start (mode, type, cum->words);
9132 /* _Decimal128 must be passed in an even/odd float register pair.
9133 This assumes that the register number is odd when fregno is odd. */
9134 if (mode == TDmode && (cum->fregno % 2) == 1)
9137 if (USE_FP_FOR_ARG_P (cum, mode, type))
9139 rtx rvec[GP_ARG_NUM_REG + 1];
9143 enum machine_mode fmode = mode;
9144 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9146 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9148 /* Currently, we only ever need one reg here because complex
9149 doubles are split. */
9150 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9151 && (fmode == TFmode || fmode == TDmode));
9153 /* Long double or _Decimal128 split over regs and memory. */
9154 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9157 /* Do we also need to pass this arg in the parameter save
9160 && (cum->nargs_prototype <= 0
9161 || (DEFAULT_ABI == ABI_AIX
9163 && align_words >= GP_ARG_NUM_REG)));
9165 if (!needs_psave && mode == fmode)
9166 return gen_rtx_REG (fmode, cum->fregno);
9171 /* Describe the part that goes in gprs or the stack.
9172 This piece must come first, before the fprs. */
9173 if (align_words < GP_ARG_NUM_REG)
9175 unsigned long n_words = rs6000_arg_size (mode, type);
9177 if (align_words + n_words > GP_ARG_NUM_REG
9178 || (TARGET_32BIT && TARGET_POWERPC64))
9180 /* If this is partially on the stack, then we only
9181 include the portion actually in registers here. */
9182 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9185 if (align_words + n_words > GP_ARG_NUM_REG)
9186 /* Not all of the arg fits in gprs. Say that it
9187 goes in memory too, using a magic NULL_RTX
9188 component. Also see comment in
9189 rs6000_mixed_function_arg for why the normal
9190 function_arg_partial_nregs scheme doesn't work
9192 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9196 r = gen_rtx_REG (rmode,
9197 GP_ARG_MIN_REG + align_words);
9198 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9199 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9201 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9205 /* The whole arg fits in gprs. */
9206 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9207 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9211 /* It's entirely in memory. */
9212 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9215 /* Describe where this piece goes in the fprs. */
9216 r = gen_rtx_REG (fmode, cum->fregno);
9217 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9219 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9221 else if (align_words < GP_ARG_NUM_REG)
9223 if (TARGET_32BIT && TARGET_POWERPC64)
9224 return rs6000_mixed_function_arg (mode, type, align_words);
9226 if (mode == BLKmode)
9229 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9236 /* For an arg passed partly in registers and partly in memory, this is
9237 the number of bytes passed in registers. For args passed entirely in
9238 registers or entirely in memory, zero. When an arg is described by a
9239 PARALLEL, perhaps using more than one register type, this function
9240 returns the number of bytes used by the first element of the PARALLEL. */
9243 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9244 tree type, bool named)
9249 if (DEFAULT_ABI == ABI_V4)
9252 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9253 && cum->nargs_prototype >= 0)
9256 /* In this complicated case we just disable the partial_nregs code. */
9257 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9260 align_words = rs6000_parm_start (mode, type, cum->words);
9262 if (USE_FP_FOR_ARG_P (cum, mode, type))
9264 /* If we are passing this arg in the fixed parameter save area
9265 (gprs or memory) as well as fprs, then this function should
9266 return the number of partial bytes passed in the parameter
9267 save area rather than partial bytes passed in fprs. */
9269 && (cum->nargs_prototype <= 0
9270 || (DEFAULT_ABI == ABI_AIX
9272 && align_words >= GP_ARG_NUM_REG)))
9274 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9275 > FP_ARG_MAX_REG + 1)
9276 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9277 else if (cum->nargs_prototype >= 0)
9281 if (align_words < GP_ARG_NUM_REG
9282 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9283 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9285 if (ret != 0 && TARGET_DEBUG_ARG)
9286 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9291 /* A C expression that indicates when an argument must be passed by
9292 reference. If nonzero for an argument, a copy of that argument is
9293 made in memory and a pointer to the argument is passed instead of
9294 the argument itself. The pointer is passed in whatever way is
9295 appropriate for passing a pointer to that type.
9297 Under V.4, aggregates and long double are passed by reference.
9299 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9300 reference unless the AltiVec vector extension ABI is in force.
9302 As an extension to all ABIs, variable sized types are passed by
9306 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9307 enum machine_mode mode, const_tree type,
9308 bool named ATTRIBUTE_UNUSED)
9310 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9312 if (TARGET_DEBUG_ARG)
9313 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9320 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9322 if (TARGET_DEBUG_ARG)
9323 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9327 if (int_size_in_bytes (type) < 0)
9329 if (TARGET_DEBUG_ARG)
9330 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9334 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9335 modes only exist for GCC vector types if -maltivec. */
9336 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9338 if (TARGET_DEBUG_ARG)
9339 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9343 /* Pass synthetic vectors in memory. */
9344 if (TREE_CODE (type) == VECTOR_TYPE
9345 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9347 static bool warned_for_pass_big_vectors = false;
9348 if (TARGET_DEBUG_ARG)
9349 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9350 if (!warned_for_pass_big_vectors)
9352 warning (0, "GCC vector passed by reference: "
9353 "non-standard ABI extension with no compatibility guarantee");
9354 warned_for_pass_big_vectors = true;
9363 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9366 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9371 for (i = 0; i < nregs; i++)
9373 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9374 if (reload_completed)
9376 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9379 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9380 i * GET_MODE_SIZE (reg_mode));
9383 tem = replace_equiv_address (tem, XEXP (tem, 0));
9387 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9391 /* Perform any needed actions needed for a function that is receiving a
9392 variable number of arguments.
9396 MODE and TYPE are the mode and type of the current parameter.
9398 PRETEND_SIZE is a variable that should be set to the amount of stack
9399 that must be pushed by the prolog to pretend that our caller pushed
9402 Normally, this macro will push all remaining incoming registers on the
9403 stack and set PRETEND_SIZE to the length of the registers pushed. */
9406 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9407 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9410 CUMULATIVE_ARGS next_cum;
9411 int reg_size = TARGET_32BIT ? 4 : 8;
9412 rtx save_area = NULL_RTX, mem;
9413 int first_reg_offset;
9416 /* Skip the last named argument. */
9418 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9420 if (DEFAULT_ABI == ABI_V4)
9422 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9426 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9427 HOST_WIDE_INT offset = 0;
9429 /* Try to optimize the size of the varargs save area.
9430 The ABI requires that ap.reg_save_area is doubleword
9431 aligned, but we don't need to allocate space for all
9432 the bytes, only those to which we actually will save
9434 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9435 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9436 if (TARGET_HARD_FLOAT && TARGET_FPRS
9437 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9438 && cfun->va_list_fpr_size)
9441 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9442 * UNITS_PER_FP_WORD;
9443 if (cfun->va_list_fpr_size
9444 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9445 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9447 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9448 * UNITS_PER_FP_WORD;
9452 offset = -((first_reg_offset * reg_size) & ~7);
9453 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9455 gpr_reg_num = cfun->va_list_gpr_size;
9456 if (reg_size == 4 && (first_reg_offset & 1))
9459 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9462 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9464 - (int) (GP_ARG_NUM_REG * reg_size);
9466 if (gpr_size + fpr_size)
9469 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9470 gcc_assert (GET_CODE (reg_save_area) == MEM);
9471 reg_save_area = XEXP (reg_save_area, 0);
9472 if (GET_CODE (reg_save_area) == PLUS)
9474 gcc_assert (XEXP (reg_save_area, 0)
9475 == virtual_stack_vars_rtx);
9476 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9477 offset += INTVAL (XEXP (reg_save_area, 1));
9480 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9483 cfun->machine->varargs_save_offset = offset;
9484 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9489 first_reg_offset = next_cum.words;
9490 save_area = virtual_incoming_args_rtx;
9492 if (targetm.calls.must_pass_in_stack (mode, type))
9493 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9496 set = get_varargs_alias_set ();
9497 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9498 && cfun->va_list_gpr_size)
9500 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9502 if (va_list_gpr_counter_field)
9504 /* V4 va_list_gpr_size counts number of registers needed. */
9505 if (nregs > cfun->va_list_gpr_size)
9506 nregs = cfun->va_list_gpr_size;
9510 /* char * va_list instead counts number of bytes needed. */
9511 if (nregs > cfun->va_list_gpr_size / reg_size)
9512 nregs = cfun->va_list_gpr_size / reg_size;
9515 mem = gen_rtx_MEM (BLKmode,
9516 plus_constant (save_area,
9517 first_reg_offset * reg_size));
9518 MEM_NOTRAP_P (mem) = 1;
9519 set_mem_alias_set (mem, set);
9520 set_mem_align (mem, BITS_PER_WORD);
9522 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9526 /* Save FP registers if needed. */
9527 if (DEFAULT_ABI == ABI_V4
9528 && TARGET_HARD_FLOAT && TARGET_FPRS
9530 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9531 && cfun->va_list_fpr_size)
9533 int fregno = next_cum.fregno, nregs;
9534 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9535 rtx lab = gen_label_rtx ();
9536 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9537 * UNITS_PER_FP_WORD);
9540 (gen_rtx_SET (VOIDmode,
9542 gen_rtx_IF_THEN_ELSE (VOIDmode,
9543 gen_rtx_NE (VOIDmode, cr1,
9545 gen_rtx_LABEL_REF (VOIDmode, lab),
9549 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9550 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9552 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9554 plus_constant (save_area, off));
9555 MEM_NOTRAP_P (mem) = 1;
9556 set_mem_alias_set (mem, set);
9557 set_mem_align (mem, GET_MODE_ALIGNMENT (
9558 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9559 ? DFmode : SFmode));
9560 emit_move_insn (mem, gen_rtx_REG (
9561 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9562 ? DFmode : SFmode, fregno));
9569 /* Create the va_list data type. */
9572 rs6000_build_builtin_va_list (void)
9574 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9576 /* For AIX, prefer 'char *' because that's what the system
9577 header files like. */
9578 if (DEFAULT_ABI != ABI_V4)
9579 return build_pointer_type (char_type_node);
9581 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9582 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9583 get_identifier ("__va_list_tag"), record);
9585 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9586 unsigned_char_type_node);
9587 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9588 unsigned_char_type_node);
9589 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9591 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9592 get_identifier ("reserved"), short_unsigned_type_node);
9593 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9594 get_identifier ("overflow_arg_area"),
9596 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9597 get_identifier ("reg_save_area"),
9600 va_list_gpr_counter_field = f_gpr;
9601 va_list_fpr_counter_field = f_fpr;
9603 DECL_FIELD_CONTEXT (f_gpr) = record;
9604 DECL_FIELD_CONTEXT (f_fpr) = record;
9605 DECL_FIELD_CONTEXT (f_res) = record;
9606 DECL_FIELD_CONTEXT (f_ovf) = record;
9607 DECL_FIELD_CONTEXT (f_sav) = record;
9609 TYPE_STUB_DECL (record) = type_decl;
9610 TYPE_NAME (record) = type_decl;
9611 TYPE_FIELDS (record) = f_gpr;
9612 DECL_CHAIN (f_gpr) = f_fpr;
9613 DECL_CHAIN (f_fpr) = f_res;
9614 DECL_CHAIN (f_res) = f_ovf;
9615 DECL_CHAIN (f_ovf) = f_sav;
9617 layout_type (record);
9619 /* The correct type is an array type of one element. */
9620 return build_array_type (record, build_index_type (size_zero_node));
9623 /* Implement va_start. */
9626 rs6000_va_start (tree valist, rtx nextarg)
9628 HOST_WIDE_INT words, n_gpr, n_fpr;
9629 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9630 tree gpr, fpr, ovf, sav, t;
9632 /* Only SVR4 needs something special. */
9633 if (DEFAULT_ABI != ABI_V4)
9635 std_expand_builtin_va_start (valist, nextarg);
9639 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9640 f_fpr = DECL_CHAIN (f_gpr);
9641 f_res = DECL_CHAIN (f_fpr);
9642 f_ovf = DECL_CHAIN (f_res);
9643 f_sav = DECL_CHAIN (f_ovf);
9645 valist = build_simple_mem_ref (valist);
9646 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9647 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9649 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9651 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9654 /* Count number of gp and fp argument registers used. */
9655 words = crtl->args.info.words;
9656 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9658 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9661 if (TARGET_DEBUG_ARG)
9662 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9663 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9664 words, n_gpr, n_fpr);
9666 if (cfun->va_list_gpr_size)
9668 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9669 build_int_cst (NULL_TREE, n_gpr));
9670 TREE_SIDE_EFFECTS (t) = 1;
9671 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9674 if (cfun->va_list_fpr_size)
9676 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9677 build_int_cst (NULL_TREE, n_fpr));
9678 TREE_SIDE_EFFECTS (t) = 1;
9679 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9681 #ifdef HAVE_AS_GNU_ATTRIBUTE
9682 if (call_ABI_of_interest (cfun->decl))
9683 rs6000_passes_float = true;
9687 /* Find the overflow area. */
9688 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9690 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9691 size_int (words * UNITS_PER_WORD));
9692 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9693 TREE_SIDE_EFFECTS (t) = 1;
9694 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9696 /* If there were no va_arg invocations, don't set up the register
9698 if (!cfun->va_list_gpr_size
9699 && !cfun->va_list_fpr_size
9700 && n_gpr < GP_ARG_NUM_REG
9701 && n_fpr < FP_ARG_V4_MAX_REG)
9704 /* Find the register save area. */
9705 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9706 if (cfun->machine->varargs_save_offset)
9707 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9708 size_int (cfun->machine->varargs_save_offset));
9709 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9710 TREE_SIDE_EFFECTS (t) = 1;
9711 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9714 /* Implement va_arg. */
9717 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9720 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9721 tree gpr, fpr, ovf, sav, reg, t, u;
9722 int size, rsize, n_reg, sav_ofs, sav_scale;
9723 tree lab_false, lab_over, addr;
9725 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9729 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9731 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9732 return build_va_arg_indirect_ref (t);
9735 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9736 earlier version of gcc, with the property that it always applied alignment
9737 adjustments to the va-args (even for zero-sized types). The cheapest way
9738 to deal with this is to replicate the effect of the part of
9739 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9741 We don't need to check for pass-by-reference because of the test above.
9742 We can return a simplifed answer, since we know there's no offset to add. */
9745 && rs6000_darwin64_abi
9746 && integer_zerop (TYPE_SIZE (type)))
9748 unsigned HOST_WIDE_INT align, boundary;
9749 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9750 align = PARM_BOUNDARY / BITS_PER_UNIT;
9751 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9752 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9753 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9754 boundary /= BITS_PER_UNIT;
9755 if (boundary > align)
9758 /* This updates arg ptr by the amount that would be necessary
9759 to align the zero-sized (but not zero-alignment) item. */
9760 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9761 fold_build2 (POINTER_PLUS_EXPR,
9763 valist_tmp, size_int (boundary - 1)));
9764 gimplify_and_add (t, pre_p);
9766 t = fold_convert (sizetype, valist_tmp);
9767 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9768 fold_convert (TREE_TYPE (valist),
9769 fold_build2 (BIT_AND_EXPR, sizetype, t,
9770 size_int (-boundary))));
9771 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9772 gimplify_and_add (t, pre_p);
9774 /* Since it is zero-sized there's no increment for the item itself. */
9775 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9776 return build_va_arg_indirect_ref (valist_tmp);
9779 if (DEFAULT_ABI != ABI_V4)
9781 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9783 tree elem_type = TREE_TYPE (type);
9784 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9785 int elem_size = GET_MODE_SIZE (elem_mode);
9787 if (elem_size < UNITS_PER_WORD)
9789 tree real_part, imag_part;
9790 gimple_seq post = NULL;
9792 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9794 /* Copy the value into a temporary, lest the formal temporary
9795 be reused out from under us. */
9796 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9797 gimple_seq_add_seq (pre_p, post);
9799 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9802 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9806 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9809 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9810 f_fpr = DECL_CHAIN (f_gpr);
9811 f_res = DECL_CHAIN (f_fpr);
9812 f_ovf = DECL_CHAIN (f_res);
9813 f_sav = DECL_CHAIN (f_ovf);
9815 valist = build_va_arg_indirect_ref (valist);
9816 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9817 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9819 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9821 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9824 size = int_size_in_bytes (type);
9825 rsize = (size + 3) / 4;
9828 if (TARGET_HARD_FLOAT && TARGET_FPRS
9829 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9830 || (TARGET_DOUBLE_FLOAT
9831 && (TYPE_MODE (type) == DFmode
9832 || TYPE_MODE (type) == TFmode
9833 || TYPE_MODE (type) == SDmode
9834 || TYPE_MODE (type) == DDmode
9835 || TYPE_MODE (type) == TDmode))))
9837 /* FP args go in FP registers, if present. */
9839 n_reg = (size + 7) / 8;
9840 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9841 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9842 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9847 /* Otherwise into GP registers. */
9856 /* Pull the value out of the saved registers.... */
9859 addr = create_tmp_var (ptr_type_node, "addr");
9861 /* AltiVec vectors never go in registers when -mabi=altivec. */
9862 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9866 lab_false = create_artificial_label (input_location);
9867 lab_over = create_artificial_label (input_location);
9869 /* Long long and SPE vectors are aligned in the registers.
9870 As are any other 2 gpr item such as complex int due to a
9871 historical mistake. */
9873 if (n_reg == 2 && reg == gpr)
9876 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9877 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9878 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9879 unshare_expr (reg), u);
9881 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9882 reg number is 0 for f1, so we want to make it odd. */
9883 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9885 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9886 build_int_cst (TREE_TYPE (reg), 1));
9887 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9890 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9891 t = build2 (GE_EXPR, boolean_type_node, u, t);
9892 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9893 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9894 gimplify_and_add (t, pre_p);
9898 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9900 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9901 build_int_cst (TREE_TYPE (reg), n_reg));
9902 u = fold_convert (sizetype, u);
9903 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9904 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9906 /* _Decimal32 varargs are located in the second word of the 64-bit
9907 FP register for 32-bit binaries. */
9908 if (!TARGET_POWERPC64
9909 && TARGET_HARD_FLOAT && TARGET_FPRS
9910 && TYPE_MODE (type) == SDmode)
9911 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9913 gimplify_assign (addr, t, pre_p);
9915 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9917 stmt = gimple_build_label (lab_false);
9918 gimple_seq_add_stmt (pre_p, stmt);
9920 if ((n_reg == 2 && !regalign) || n_reg > 2)
9922 /* Ensure that we don't find any more args in regs.
9923 Alignment has taken care of for special cases. */
9924 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9928 /* ... otherwise out of the overflow area. */
9930 /* Care for on-stack alignment if needed. */
9934 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9935 t = fold_convert (sizetype, t);
9936 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9938 t = fold_convert (TREE_TYPE (ovf), t);
9940 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9942 gimplify_assign (unshare_expr (addr), t, pre_p);
9944 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9945 gimplify_assign (unshare_expr (ovf), t, pre_p);
9949 stmt = gimple_build_label (lab_over);
9950 gimple_seq_add_stmt (pre_p, stmt);
9953 if (STRICT_ALIGNMENT
9954 && (TYPE_ALIGN (type)
9955 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9957 /* The value (of type complex double, for example) may not be
9958 aligned in memory in the saved registers, so copy via a
9959 temporary. (This is the same code as used for SPARC.) */
9960 tree tmp = create_tmp_var (type, "va_arg_tmp");
9961 tree dest_addr = build_fold_addr_expr (tmp);
9963 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9964 3, dest_addr, addr, size_int (rsize * 4));
9966 gimplify_and_add (copy, pre_p);
9970 addr = fold_convert (ptrtype, addr);
9971 return build_va_arg_indirect_ref (addr);
9977 def_builtin (int mask, const char *name, tree type, int code)
9979 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9982 if (rs6000_builtin_decls[code])
9983 fatal_error ("internal error: builtin function to %s already processed",
9986 rs6000_builtin_decls[code] = t =
9987 add_builtin_function (name, type, code, BUILT_IN_MD,
9990 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
9991 switch (builtin_classify[code])
9996 /* assume builtin can do anything. */
9997 case RS6000_BTC_MISC:
10000 /* const function, function only depends on the inputs. */
10001 case RS6000_BTC_CONST:
10002 TREE_READONLY (t) = 1;
10003 TREE_NOTHROW (t) = 1;
10006 /* pure function, function can read global memory. */
10007 case RS6000_BTC_PURE:
10008 DECL_PURE_P (t) = 1;
10009 TREE_NOTHROW (t) = 1;
10012 /* Function is a math function. If rounding mode is on, then treat
10013 the function as not reading global memory, but it can have
10014 arbitrary side effects. If it is off, then assume the function is
10015 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10016 attribute in builtin-attribute.def that is used for the math
10018 case RS6000_BTC_FP_PURE:
10019 TREE_NOTHROW (t) = 1;
10020 if (flag_rounding_math)
10022 DECL_PURE_P (t) = 1;
10023 DECL_IS_NOVOPS (t) = 1;
10026 TREE_READONLY (t) = 1;
10032 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10034 static const struct builtin_description bdesc_3arg[] =
10036 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10037 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10038 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10039 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10040 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10041 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10042 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10043 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10044 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10045 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10046 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10047 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10048 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10049 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10050 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10051 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10052 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10053 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10054 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10055 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10056 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10057 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10058 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10059 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10060 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10061 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10062 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10063 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10064 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10065 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10066 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10067 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10068 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10069 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10070 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10072 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10073 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10074 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10075 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10076 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10077 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10078 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10079 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10080 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10088 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10089 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10090 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10091 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10093 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10094 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10095 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10096 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10101 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10102 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10103 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10104 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10105 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10106 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10107 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10108 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10109 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10110 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10112 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10113 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10114 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10115 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10116 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10117 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10118 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10119 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10120 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10121 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10123 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10124 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10125 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10126 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10127 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10128 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10129 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10130 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10131 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10133 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10134 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10135 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10136 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10137 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10138 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10139 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10141 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10142 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10143 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10144 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10145 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10146 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10147 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10148 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10149 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10152 /* DST operations: void foo (void *, const int, const char). */
10154 static const struct builtin_description bdesc_dst[] =
10156 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10157 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10158 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10159 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10161 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10162 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10167 /* Simple binary operations: VECc = foo (VECa, VECb). */
10169 static struct builtin_description bdesc_2arg[] =
10171 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10172 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10173 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10174 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10175 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10176 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10177 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10178 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10179 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10180 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10181 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10182 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10183 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10184 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10185 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10186 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10187 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10188 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10189 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10190 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10191 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10192 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10193 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10194 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10195 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10196 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10197 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10198 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10199 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10200 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10201 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10202 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10203 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10204 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10205 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10206 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10207 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10208 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10209 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10210 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10211 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10212 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10213 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10214 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10216 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10217 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10218 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10219 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10220 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10221 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10222 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10223 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10224 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10225 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10226 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10227 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10228 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10229 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10230 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10231 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10232 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10233 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10234 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10235 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10236 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10237 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10238 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10239 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10240 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10241 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10242 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10243 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10244 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10245 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10246 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10247 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10248 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10249 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10250 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10251 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10252 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10253 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10254 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10255 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10256 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10257 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10258 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10259 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10260 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10261 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10262 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10263 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10264 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10265 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10266 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10267 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10268 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10269 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10270 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10271 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10272 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10273 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10274 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10275 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10276 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10277 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10278 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10279 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10280 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10281 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10282 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10283 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10284 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10285 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10286 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10287 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10289 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10290 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10291 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10292 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10293 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10294 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10295 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10296 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10297 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10298 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10299 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10300 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10302 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10303 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10304 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10305 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10306 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10307 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10308 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10309 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10310 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10311 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10312 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10313 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10315 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10316 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10317 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10318 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10319 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10320 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10322 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10323 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10324 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10325 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10326 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10327 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10328 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10329 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10330 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10331 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10332 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10333 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10335 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10336 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10337 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10338 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10339 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10340 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10341 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10342 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10343 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10344 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10345 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10346 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10347 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10348 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10349 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10375 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10376 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10391 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10392 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10409 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10410 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10444 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10445 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10463 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10465 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10466 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10468 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10469 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10470 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10471 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10472 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10473 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10474 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10475 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10476 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10477 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10479 /* Place holder, leave as first spe builtin. */
10480 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10481 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10482 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10483 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10484 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10485 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10486 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10487 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10488 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10489 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10490 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10491 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10492 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10493 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10494 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10495 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10496 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10497 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10498 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10499 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10500 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10501 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10502 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10503 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10504 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10505 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10506 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10507 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10508 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10509 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10510 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10511 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10512 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10513 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10514 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10515 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10516 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10517 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10518 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10519 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10520 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10521 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10522 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10523 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10524 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10525 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10526 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10527 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10528 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10529 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10530 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10531 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10532 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10533 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10534 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10535 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10536 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10537 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10538 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10539 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10540 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10541 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10542 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10543 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10544 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10545 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10546 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10547 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10548 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10549 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10550 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10551 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10552 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10553 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10554 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10555 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10556 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10557 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10558 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10559 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10560 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10561 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10562 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10563 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10564 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10565 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10566 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10567 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10568 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10569 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10570 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10571 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10572 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10573 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10574 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10575 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10576 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10577 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10578 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10579 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10580 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10581 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10582 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10583 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10584 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10585 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10586 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10587 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10588 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10590 /* SPE binary operations expecting a 5-bit unsigned literal. */
10591 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10593 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10594 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10595 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10596 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10597 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10598 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10599 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10600 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10601 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10602 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10603 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10604 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10605 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10606 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10607 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10608 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10609 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10610 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10611 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10612 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10613 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10614 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10615 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10616 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10617 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10618 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10620 /* Place-holder. Leave as last binary SPE builtin. */
10621 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10624 /* AltiVec predicates. */
10626 struct builtin_description_predicates
10628 const unsigned int mask;
10629 const enum insn_code icode;
10630 const char *const name;
10631 const enum rs6000_builtins code;
10634 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10636 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10637 ALTIVEC_BUILTIN_VCMPBFP_P },
10638 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10639 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10640 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10641 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10642 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10643 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10644 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10645 ALTIVEC_BUILTIN_VCMPEQUW_P },
10646 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10647 ALTIVEC_BUILTIN_VCMPGTSW_P },
10648 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10649 ALTIVEC_BUILTIN_VCMPGTUW_P },
10650 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10651 ALTIVEC_BUILTIN_VCMPEQUH_P },
10652 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10653 ALTIVEC_BUILTIN_VCMPGTSH_P },
10654 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10655 ALTIVEC_BUILTIN_VCMPGTUH_P },
10656 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10657 ALTIVEC_BUILTIN_VCMPEQUB_P },
10658 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10659 ALTIVEC_BUILTIN_VCMPGTSB_P },
10660 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10661 ALTIVEC_BUILTIN_VCMPGTUB_P },
10663 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10664 VSX_BUILTIN_XVCMPEQSP_P },
10665 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10666 VSX_BUILTIN_XVCMPGESP_P },
10667 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10668 VSX_BUILTIN_XVCMPGTSP_P },
10669 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10670 VSX_BUILTIN_XVCMPEQDP_P },
10671 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10672 VSX_BUILTIN_XVCMPGEDP_P },
10673 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10674 VSX_BUILTIN_XVCMPGTDP_P },
10676 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10677 ALTIVEC_BUILTIN_VCMPEQ_P },
10678 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10679 ALTIVEC_BUILTIN_VCMPGT_P },
10680 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10681 ALTIVEC_BUILTIN_VCMPGE_P }
10684 /* SPE predicates. */
10685 static struct builtin_description bdesc_spe_predicates[] =
10687 /* Place-holder. Leave as first. */
10688 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10689 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10690 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10691 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10692 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10693 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10694 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10695 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10696 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10697 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10698 /* Place-holder. Leave as last. */
10699 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10702 /* SPE evsel predicates. */
10703 static struct builtin_description bdesc_spe_evsel[] =
10705 /* Place-holder. Leave as first. */
10706 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10707 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10708 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10709 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10710 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10711 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10712 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10713 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10714 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10715 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10716 /* Place-holder. Leave as last. */
10717 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10720 /* PAIRED predicates. */
10721 static const struct builtin_description bdesc_paired_preds[] =
10723 /* Place-holder. Leave as first. */
10724 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10725 /* Place-holder. Leave as last. */
10726 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10729 /* ABS* operations. */
10731 static const struct builtin_description bdesc_abs[] =
10733 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10734 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10735 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10736 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10737 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10738 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10739 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10740 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10741 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10742 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10743 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10746 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10749 static struct builtin_description bdesc_1arg[] =
10751 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10752 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10753 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10754 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10755 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10756 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10757 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10758 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10759 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10760 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10761 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10762 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10763 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10764 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10765 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10766 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10767 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10768 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10770 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10771 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10772 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10773 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10774 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10775 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10776 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10778 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10779 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10780 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10781 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10782 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10783 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10784 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10786 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10787 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10788 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10789 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10790 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10791 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10793 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10794 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10795 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10796 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10797 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10798 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10800 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10801 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10802 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10803 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10805 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10806 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10807 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10808 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10809 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10810 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10811 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10812 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10813 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10815 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10816 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10817 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10818 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10819 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10820 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10821 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10822 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10823 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10825 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10826 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10827 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10828 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10829 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10852 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10853 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10854 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10856 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10857 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10858 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10859 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10861 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10862 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10863 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10864 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10865 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10866 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10867 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10868 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10869 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10870 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10871 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10872 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10873 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10874 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10875 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10876 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10877 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10878 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10879 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10880 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10881 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10882 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10883 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10884 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10885 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10886 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10887 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10888 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10889 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10890 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10892 /* Place-holder. Leave as last unary SPE builtin. */
10893 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10895 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10896 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10897 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10898 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10899 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10903 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10906 tree arg0 = CALL_EXPR_ARG (exp, 0);
10907 rtx op0 = expand_normal (arg0);
10908 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10909 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10911 if (icode == CODE_FOR_nothing)
10912 /* Builtin not supported on this processor. */
10915 /* If we got invalid arguments bail out before generating bad rtl. */
10916 if (arg0 == error_mark_node)
10919 if (icode == CODE_FOR_altivec_vspltisb
10920 || icode == CODE_FOR_altivec_vspltish
10921 || icode == CODE_FOR_altivec_vspltisw
10922 || icode == CODE_FOR_spe_evsplatfi
10923 || icode == CODE_FOR_spe_evsplati)
10925 /* Only allow 5-bit *signed* literals. */
10926 if (GET_CODE (op0) != CONST_INT
10927 || INTVAL (op0) > 15
10928 || INTVAL (op0) < -16)
10930 error ("argument 1 must be a 5-bit signed literal");
10936 || GET_MODE (target) != tmode
10937 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10938 target = gen_reg_rtx (tmode);
10940 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10941 op0 = copy_to_mode_reg (mode0, op0);
10943 pat = GEN_FCN (icode) (target, op0);
10952 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10954 rtx pat, scratch1, scratch2;
10955 tree arg0 = CALL_EXPR_ARG (exp, 0);
10956 rtx op0 = expand_normal (arg0);
10957 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10958 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10960 /* If we have invalid arguments, bail out before generating bad rtl. */
10961 if (arg0 == error_mark_node)
10965 || GET_MODE (target) != tmode
10966 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10967 target = gen_reg_rtx (tmode);
10969 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10970 op0 = copy_to_mode_reg (mode0, op0);
10972 scratch1 = gen_reg_rtx (mode0);
10973 scratch2 = gen_reg_rtx (mode0);
10975 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10984 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10987 tree arg0 = CALL_EXPR_ARG (exp, 0);
10988 tree arg1 = CALL_EXPR_ARG (exp, 1);
10989 rtx op0 = expand_normal (arg0);
10990 rtx op1 = expand_normal (arg1);
10991 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10992 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10993 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
10995 if (icode == CODE_FOR_nothing)
10996 /* Builtin not supported on this processor. */
10999 /* If we got invalid arguments bail out before generating bad rtl. */
11000 if (arg0 == error_mark_node || arg1 == error_mark_node)
11003 if (icode == CODE_FOR_altivec_vcfux
11004 || icode == CODE_FOR_altivec_vcfsx
11005 || icode == CODE_FOR_altivec_vctsxs
11006 || icode == CODE_FOR_altivec_vctuxs
11007 || icode == CODE_FOR_altivec_vspltb
11008 || icode == CODE_FOR_altivec_vsplth
11009 || icode == CODE_FOR_altivec_vspltw
11010 || icode == CODE_FOR_spe_evaddiw
11011 || icode == CODE_FOR_spe_evldd
11012 || icode == CODE_FOR_spe_evldh
11013 || icode == CODE_FOR_spe_evldw
11014 || icode == CODE_FOR_spe_evlhhesplat
11015 || icode == CODE_FOR_spe_evlhhossplat
11016 || icode == CODE_FOR_spe_evlhhousplat
11017 || icode == CODE_FOR_spe_evlwhe
11018 || icode == CODE_FOR_spe_evlwhos
11019 || icode == CODE_FOR_spe_evlwhou
11020 || icode == CODE_FOR_spe_evlwhsplat
11021 || icode == CODE_FOR_spe_evlwwsplat
11022 || icode == CODE_FOR_spe_evrlwi
11023 || icode == CODE_FOR_spe_evslwi
11024 || icode == CODE_FOR_spe_evsrwis
11025 || icode == CODE_FOR_spe_evsubifw
11026 || icode == CODE_FOR_spe_evsrwiu)
11028 /* Only allow 5-bit unsigned literals. */
11030 if (TREE_CODE (arg1) != INTEGER_CST
11031 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11033 error ("argument 2 must be a 5-bit unsigned literal");
11039 || GET_MODE (target) != tmode
11040 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11041 target = gen_reg_rtx (tmode);
11043 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11044 op0 = copy_to_mode_reg (mode0, op0);
11045 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11046 op1 = copy_to_mode_reg (mode1, op1);
11048 pat = GEN_FCN (icode) (target, op0, op1);
11057 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11060 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11061 tree arg0 = CALL_EXPR_ARG (exp, 1);
11062 tree arg1 = CALL_EXPR_ARG (exp, 2);
11063 rtx op0 = expand_normal (arg0);
11064 rtx op1 = expand_normal (arg1);
11065 enum machine_mode tmode = SImode;
11066 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11067 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11070 if (TREE_CODE (cr6_form) != INTEGER_CST)
11072 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11076 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11078 gcc_assert (mode0 == mode1);
11080 /* If we have invalid arguments, bail out before generating bad rtl. */
11081 if (arg0 == error_mark_node || arg1 == error_mark_node)
11085 || GET_MODE (target) != tmode
11086 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11087 target = gen_reg_rtx (tmode);
11089 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11090 op0 = copy_to_mode_reg (mode0, op0);
11091 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11092 op1 = copy_to_mode_reg (mode1, op1);
11094 scratch = gen_reg_rtx (mode0);
11096 pat = GEN_FCN (icode) (scratch, op0, op1);
11101 /* The vec_any* and vec_all* predicates use the same opcodes for two
11102 different operations, but the bits in CR6 will be different
11103 depending on what information we want. So we have to play tricks
11104 with CR6 to get the right bits out.
11106 If you think this is disgusting, look at the specs for the
11107 AltiVec predicates. */
11109 switch (cr6_form_int)
11112 emit_insn (gen_cr6_test_for_zero (target));
11115 emit_insn (gen_cr6_test_for_zero_reverse (target));
11118 emit_insn (gen_cr6_test_for_lt (target));
11121 emit_insn (gen_cr6_test_for_lt_reverse (target));
11124 error ("argument 1 of __builtin_altivec_predicate is out of range");
11132 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11135 tree arg0 = CALL_EXPR_ARG (exp, 0);
11136 tree arg1 = CALL_EXPR_ARG (exp, 1);
11137 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11138 enum machine_mode mode0 = Pmode;
11139 enum machine_mode mode1 = Pmode;
11140 rtx op0 = expand_normal (arg0);
11141 rtx op1 = expand_normal (arg1);
11143 if (icode == CODE_FOR_nothing)
11144 /* Builtin not supported on this processor. */
11147 /* If we got invalid arguments bail out before generating bad rtl. */
11148 if (arg0 == error_mark_node || arg1 == error_mark_node)
11152 || GET_MODE (target) != tmode
11153 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11154 target = gen_reg_rtx (tmode);
11156 op1 = copy_to_mode_reg (mode1, op1);
11158 if (op0 == const0_rtx)
11160 addr = gen_rtx_MEM (tmode, op1);
11164 op0 = copy_to_mode_reg (mode0, op0);
11165 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11168 pat = GEN_FCN (icode) (target, addr);
11178 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11181 tree arg0 = CALL_EXPR_ARG (exp, 0);
11182 tree arg1 = CALL_EXPR_ARG (exp, 1);
11183 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11184 enum machine_mode mode0 = Pmode;
11185 enum machine_mode mode1 = Pmode;
11186 rtx op0 = expand_normal (arg0);
11187 rtx op1 = expand_normal (arg1);
11189 if (icode == CODE_FOR_nothing)
11190 /* Builtin not supported on this processor. */
11193 /* If we got invalid arguments bail out before generating bad rtl. */
11194 if (arg0 == error_mark_node || arg1 == error_mark_node)
11198 || GET_MODE (target) != tmode
11199 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11200 target = gen_reg_rtx (tmode);
11202 op1 = copy_to_mode_reg (mode1, op1);
11204 if (op0 == const0_rtx)
11206 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11210 op0 = copy_to_mode_reg (mode0, op0);
11211 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11214 pat = GEN_FCN (icode) (target, addr);
11224 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11226 tree arg0 = CALL_EXPR_ARG (exp, 0);
11227 tree arg1 = CALL_EXPR_ARG (exp, 1);
11228 tree arg2 = CALL_EXPR_ARG (exp, 2);
11229 rtx op0 = expand_normal (arg0);
11230 rtx op1 = expand_normal (arg1);
11231 rtx op2 = expand_normal (arg2);
11233 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11234 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11235 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11237 /* Invalid arguments. Bail before doing anything stoopid! */
11238 if (arg0 == error_mark_node
11239 || arg1 == error_mark_node
11240 || arg2 == error_mark_node)
11243 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11244 op0 = copy_to_mode_reg (mode2, op0);
11245 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11246 op1 = copy_to_mode_reg (mode0, op1);
11247 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11248 op2 = copy_to_mode_reg (mode1, op2);
11250 pat = GEN_FCN (icode) (op1, op2, op0);
11257 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11259 tree arg0 = CALL_EXPR_ARG (exp, 0);
11260 tree arg1 = CALL_EXPR_ARG (exp, 1);
11261 tree arg2 = CALL_EXPR_ARG (exp, 2);
11262 rtx op0 = expand_normal (arg0);
11263 rtx op1 = expand_normal (arg1);
11264 rtx op2 = expand_normal (arg2);
11266 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11267 enum machine_mode mode1 = Pmode;
11268 enum machine_mode mode2 = Pmode;
11270 /* Invalid arguments. Bail before doing anything stoopid! */
11271 if (arg0 == error_mark_node
11272 || arg1 == error_mark_node
11273 || arg2 == error_mark_node)
11276 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11277 op0 = copy_to_mode_reg (tmode, op0);
11279 op2 = copy_to_mode_reg (mode2, op2);
11281 if (op1 == const0_rtx)
11283 addr = gen_rtx_MEM (tmode, op2);
11287 op1 = copy_to_mode_reg (mode1, op1);
11288 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11291 pat = GEN_FCN (icode) (addr, op0);
11298 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11300 tree arg0 = CALL_EXPR_ARG (exp, 0);
11301 tree arg1 = CALL_EXPR_ARG (exp, 1);
11302 tree arg2 = CALL_EXPR_ARG (exp, 2);
11303 rtx op0 = expand_normal (arg0);
11304 rtx op1 = expand_normal (arg1);
11305 rtx op2 = expand_normal (arg2);
11307 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11308 enum machine_mode smode = insn_data[icode].operand[1].mode;
11309 enum machine_mode mode1 = Pmode;
11310 enum machine_mode mode2 = Pmode;
11312 /* Invalid arguments. Bail before doing anything stoopid! */
11313 if (arg0 == error_mark_node
11314 || arg1 == error_mark_node
11315 || arg2 == error_mark_node)
11318 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11319 op0 = copy_to_mode_reg (smode, op0);
11321 op2 = copy_to_mode_reg (mode2, op2);
11323 if (op1 == const0_rtx)
11325 addr = gen_rtx_MEM (tmode, op2);
11329 op1 = copy_to_mode_reg (mode1, op1);
11330 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11333 pat = GEN_FCN (icode) (addr, op0);
11340 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11343 tree arg0 = CALL_EXPR_ARG (exp, 0);
11344 tree arg1 = CALL_EXPR_ARG (exp, 1);
11345 tree arg2 = CALL_EXPR_ARG (exp, 2);
11346 rtx op0 = expand_normal (arg0);
11347 rtx op1 = expand_normal (arg1);
11348 rtx op2 = expand_normal (arg2);
11349 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11350 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11351 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11352 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11354 if (icode == CODE_FOR_nothing)
11355 /* Builtin not supported on this processor. */
11358 /* If we got invalid arguments bail out before generating bad rtl. */
11359 if (arg0 == error_mark_node
11360 || arg1 == error_mark_node
11361 || arg2 == error_mark_node)
11364 /* Check and prepare argument depending on the instruction code.
11366 Note that a switch statement instead of the sequence of tests
11367 would be incorrect as many of the CODE_FOR values could be
11368 CODE_FOR_nothing and that would yield multiple alternatives
11369 with identical values. We'd never reach here at runtime in
11371 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11372 || icode == CODE_FOR_altivec_vsldoi_v4si
11373 || icode == CODE_FOR_altivec_vsldoi_v8hi
11374 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11376 /* Only allow 4-bit unsigned literals. */
11378 if (TREE_CODE (arg2) != INTEGER_CST
11379 || TREE_INT_CST_LOW (arg2) & ~0xf)
11381 error ("argument 3 must be a 4-bit unsigned literal");
11385 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11386 || icode == CODE_FOR_vsx_xxpermdi_v2di
11387 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11388 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11389 || icode == CODE_FOR_vsx_xxsldwi_v4si
11390 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11391 || icode == CODE_FOR_vsx_xxsldwi_v2di
11392 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11394 /* Only allow 2-bit unsigned literals. */
11396 if (TREE_CODE (arg2) != INTEGER_CST
11397 || TREE_INT_CST_LOW (arg2) & ~0x3)
11399 error ("argument 3 must be a 2-bit unsigned literal");
11403 else if (icode == CODE_FOR_vsx_set_v2df
11404 || icode == CODE_FOR_vsx_set_v2di)
11406 /* Only allow 1-bit unsigned literals. */
11408 if (TREE_CODE (arg2) != INTEGER_CST
11409 || TREE_INT_CST_LOW (arg2) & ~0x1)
11411 error ("argument 3 must be a 1-bit unsigned literal");
11417 || GET_MODE (target) != tmode
11418 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11419 target = gen_reg_rtx (tmode);
11421 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11422 op0 = copy_to_mode_reg (mode0, op0);
11423 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11424 op1 = copy_to_mode_reg (mode1, op1);
11425 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11426 op2 = copy_to_mode_reg (mode2, op2);
11428 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11429 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11431 pat = GEN_FCN (icode) (target, op0, op1, op2);
11439 /* Expand the lvx builtins. */
11441 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11443 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11444 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11446 enum machine_mode tmode, mode0;
11448 enum insn_code icode;
11452 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11453 icode = CODE_FOR_vector_altivec_load_v16qi;
11455 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11456 icode = CODE_FOR_vector_altivec_load_v8hi;
11458 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11459 icode = CODE_FOR_vector_altivec_load_v4si;
11461 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11462 icode = CODE_FOR_vector_altivec_load_v4sf;
11464 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11465 icode = CODE_FOR_vector_altivec_load_v2df;
11467 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11468 icode = CODE_FOR_vector_altivec_load_v2di;
11471 *expandedp = false;
11477 arg0 = CALL_EXPR_ARG (exp, 0);
11478 op0 = expand_normal (arg0);
11479 tmode = insn_data[icode].operand[0].mode;
11480 mode0 = insn_data[icode].operand[1].mode;
11483 || GET_MODE (target) != tmode
11484 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11485 target = gen_reg_rtx (tmode);
11487 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11488 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11490 pat = GEN_FCN (icode) (target, op0);
11497 /* Expand the stvx builtins. */
11499 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11502 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11503 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11505 enum machine_mode mode0, mode1;
11507 enum insn_code icode;
11511 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11512 icode = CODE_FOR_vector_altivec_store_v16qi;
11514 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11515 icode = CODE_FOR_vector_altivec_store_v8hi;
11517 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11518 icode = CODE_FOR_vector_altivec_store_v4si;
11520 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11521 icode = CODE_FOR_vector_altivec_store_v4sf;
11523 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11524 icode = CODE_FOR_vector_altivec_store_v2df;
11526 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11527 icode = CODE_FOR_vector_altivec_store_v2di;
11530 *expandedp = false;
11534 arg0 = CALL_EXPR_ARG (exp, 0);
11535 arg1 = CALL_EXPR_ARG (exp, 1);
11536 op0 = expand_normal (arg0);
11537 op1 = expand_normal (arg1);
11538 mode0 = insn_data[icode].operand[0].mode;
11539 mode1 = insn_data[icode].operand[1].mode;
11541 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11542 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11543 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11544 op1 = copy_to_mode_reg (mode1, op1);
11546 pat = GEN_FCN (icode) (op0, op1);
11554 /* Expand the dst builtins. */
11556 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11559 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11560 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11561 tree arg0, arg1, arg2;
11562 enum machine_mode mode0, mode1;
11563 rtx pat, op0, op1, op2;
11564 const struct builtin_description *d;
11567 *expandedp = false;
11569 /* Handle DST variants. */
11571 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11572 if (d->code == fcode)
11574 arg0 = CALL_EXPR_ARG (exp, 0);
11575 arg1 = CALL_EXPR_ARG (exp, 1);
11576 arg2 = CALL_EXPR_ARG (exp, 2);
11577 op0 = expand_normal (arg0);
11578 op1 = expand_normal (arg1);
11579 op2 = expand_normal (arg2);
11580 mode0 = insn_data[d->icode].operand[0].mode;
11581 mode1 = insn_data[d->icode].operand[1].mode;
11583 /* Invalid arguments, bail out before generating bad rtl. */
11584 if (arg0 == error_mark_node
11585 || arg1 == error_mark_node
11586 || arg2 == error_mark_node)
11591 if (TREE_CODE (arg2) != INTEGER_CST
11592 || TREE_INT_CST_LOW (arg2) & ~0x3)
11594 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11598 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11599 op0 = copy_to_mode_reg (Pmode, op0);
11600 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11601 op1 = copy_to_mode_reg (mode1, op1);
11603 pat = GEN_FCN (d->icode) (op0, op1, op2);
11613 /* Expand vec_init builtin. */
11615 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11617 enum machine_mode tmode = TYPE_MODE (type);
11618 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11619 int i, n_elt = GET_MODE_NUNITS (tmode);
11620 rtvec v = rtvec_alloc (n_elt);
11622 gcc_assert (VECTOR_MODE_P (tmode));
11623 gcc_assert (n_elt == call_expr_nargs (exp));
11625 for (i = 0; i < n_elt; ++i)
11627 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11628 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11631 if (!target || !register_operand (target, tmode))
11632 target = gen_reg_rtx (tmode);
11634 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11638 /* Return the integer constant in ARG. Constrain it to be in the range
11639 of the subparts of VEC_TYPE; issue an error if not. */
11642 get_element_number (tree vec_type, tree arg)
11644 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11646 if (!host_integerp (arg, 1)
11647 || (elt = tree_low_cst (arg, 1), elt > max))
11649 error ("selector must be an integer constant in the range 0..%wi", max);
11656 /* Expand vec_set builtin. */
11658 altivec_expand_vec_set_builtin (tree exp)
11660 enum machine_mode tmode, mode1;
11661 tree arg0, arg1, arg2;
11665 arg0 = CALL_EXPR_ARG (exp, 0);
11666 arg1 = CALL_EXPR_ARG (exp, 1);
11667 arg2 = CALL_EXPR_ARG (exp, 2);
11669 tmode = TYPE_MODE (TREE_TYPE (arg0));
11670 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11671 gcc_assert (VECTOR_MODE_P (tmode));
11673 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11674 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11675 elt = get_element_number (TREE_TYPE (arg0), arg2);
11677 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11678 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11680 op0 = force_reg (tmode, op0);
11681 op1 = force_reg (mode1, op1);
11683 rs6000_expand_vector_set (op0, op1, elt);
11688 /* Expand vec_ext builtin. */
11690 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11692 enum machine_mode tmode, mode0;
11697 arg0 = CALL_EXPR_ARG (exp, 0);
11698 arg1 = CALL_EXPR_ARG (exp, 1);
11700 op0 = expand_normal (arg0);
11701 elt = get_element_number (TREE_TYPE (arg0), arg1);
11703 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11704 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11705 gcc_assert (VECTOR_MODE_P (mode0));
11707 op0 = force_reg (mode0, op0);
11709 if (optimize || !target || !register_operand (target, tmode))
11710 target = gen_reg_rtx (tmode);
11712 rs6000_expand_vector_extract (target, op0, elt);
11717 /* Expand the builtin in EXP and store the result in TARGET. Store
11718 true in *EXPANDEDP if we found a builtin to expand. */
11720 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11722 const struct builtin_description *d;
11723 const struct builtin_description_predicates *dp;
11725 enum insn_code icode;
11726 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11729 enum machine_mode tmode, mode0;
11730 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11732 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11733 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11734 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11735 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11738 error ("unresolved overload for Altivec builtin %qF", fndecl);
11742 target = altivec_expand_ld_builtin (exp, target, expandedp);
11746 target = altivec_expand_st_builtin (exp, target, expandedp);
11750 target = altivec_expand_dst_builtin (exp, target, expandedp);
11758 case ALTIVEC_BUILTIN_STVX:
11759 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11760 case ALTIVEC_BUILTIN_STVEBX:
11761 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11762 case ALTIVEC_BUILTIN_STVEHX:
11763 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11764 case ALTIVEC_BUILTIN_STVEWX:
11765 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11766 case ALTIVEC_BUILTIN_STVXL:
11767 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11769 case ALTIVEC_BUILTIN_STVLX:
11770 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11771 case ALTIVEC_BUILTIN_STVLXL:
11772 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11773 case ALTIVEC_BUILTIN_STVRX:
11774 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11775 case ALTIVEC_BUILTIN_STVRXL:
11776 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11778 case VSX_BUILTIN_STXVD2X_V2DF:
11779 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11780 case VSX_BUILTIN_STXVD2X_V2DI:
11781 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11782 case VSX_BUILTIN_STXVW4X_V4SF:
11783 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11784 case VSX_BUILTIN_STXVW4X_V4SI:
11785 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11786 case VSX_BUILTIN_STXVW4X_V8HI:
11787 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11788 case VSX_BUILTIN_STXVW4X_V16QI:
11789 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11791 case ALTIVEC_BUILTIN_MFVSCR:
11792 icode = CODE_FOR_altivec_mfvscr;
11793 tmode = insn_data[icode].operand[0].mode;
11796 || GET_MODE (target) != tmode
11797 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11798 target = gen_reg_rtx (tmode);
11800 pat = GEN_FCN (icode) (target);
11806 case ALTIVEC_BUILTIN_MTVSCR:
11807 icode = CODE_FOR_altivec_mtvscr;
11808 arg0 = CALL_EXPR_ARG (exp, 0);
11809 op0 = expand_normal (arg0);
11810 mode0 = insn_data[icode].operand[0].mode;
11812 /* If we got invalid arguments bail out before generating bad rtl. */
11813 if (arg0 == error_mark_node)
11816 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11817 op0 = copy_to_mode_reg (mode0, op0);
11819 pat = GEN_FCN (icode) (op0);
11824 case ALTIVEC_BUILTIN_DSSALL:
11825 emit_insn (gen_altivec_dssall ());
11828 case ALTIVEC_BUILTIN_DSS:
11829 icode = CODE_FOR_altivec_dss;
11830 arg0 = CALL_EXPR_ARG (exp, 0);
11832 op0 = expand_normal (arg0);
11833 mode0 = insn_data[icode].operand[0].mode;
11835 /* If we got invalid arguments bail out before generating bad rtl. */
11836 if (arg0 == error_mark_node)
11839 if (TREE_CODE (arg0) != INTEGER_CST
11840 || TREE_INT_CST_LOW (arg0) & ~0x3)
11842 error ("argument to dss must be a 2-bit unsigned literal");
11846 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11847 op0 = copy_to_mode_reg (mode0, op0);
11849 emit_insn (gen_altivec_dss (op0));
11852 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11853 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11854 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11855 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11856 case VSX_BUILTIN_VEC_INIT_V2DF:
11857 case VSX_BUILTIN_VEC_INIT_V2DI:
11858 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11860 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11861 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11862 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11863 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11864 case VSX_BUILTIN_VEC_SET_V2DF:
11865 case VSX_BUILTIN_VEC_SET_V2DI:
11866 return altivec_expand_vec_set_builtin (exp);
11868 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11869 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11870 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11871 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11872 case VSX_BUILTIN_VEC_EXT_V2DF:
11873 case VSX_BUILTIN_VEC_EXT_V2DI:
11874 return altivec_expand_vec_ext_builtin (exp, target);
11878 /* Fall through. */
11881 /* Expand abs* operations. */
11883 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11884 if (d->code == fcode)
11885 return altivec_expand_abs_builtin (d->icode, exp, target);
11887 /* Expand the AltiVec predicates. */
11888 dp = bdesc_altivec_preds;
11889 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11890 if (dp->code == fcode)
11891 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11893 /* LV* are funky. We initialized them differently. */
11896 case ALTIVEC_BUILTIN_LVSL:
11897 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11898 exp, target, false);
11899 case ALTIVEC_BUILTIN_LVSR:
11900 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11901 exp, target, false);
11902 case ALTIVEC_BUILTIN_LVEBX:
11903 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11904 exp, target, false);
11905 case ALTIVEC_BUILTIN_LVEHX:
11906 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11907 exp, target, false);
11908 case ALTIVEC_BUILTIN_LVEWX:
11909 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11910 exp, target, false);
11911 case ALTIVEC_BUILTIN_LVXL:
11912 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11913 exp, target, false);
11914 case ALTIVEC_BUILTIN_LVX:
11915 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11916 exp, target, false);
11917 case ALTIVEC_BUILTIN_LVLX:
11918 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11919 exp, target, true);
11920 case ALTIVEC_BUILTIN_LVLXL:
11921 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11922 exp, target, true);
11923 case ALTIVEC_BUILTIN_LVRX:
11924 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11925 exp, target, true);
11926 case ALTIVEC_BUILTIN_LVRXL:
11927 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11928 exp, target, true);
11929 case VSX_BUILTIN_LXVD2X_V2DF:
11930 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11931 exp, target, false);
11932 case VSX_BUILTIN_LXVD2X_V2DI:
11933 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11934 exp, target, false);
11935 case VSX_BUILTIN_LXVW4X_V4SF:
11936 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11937 exp, target, false);
11938 case VSX_BUILTIN_LXVW4X_V4SI:
11939 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11940 exp, target, false);
11941 case VSX_BUILTIN_LXVW4X_V8HI:
11942 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11943 exp, target, false);
11944 case VSX_BUILTIN_LXVW4X_V16QI:
11945 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11946 exp, target, false);
11950 /* Fall through. */
11953 *expandedp = false;
11957 /* Expand the builtin in EXP and store the result in TARGET. Store
11958 true in *EXPANDEDP if we found a builtin to expand. */
11960 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11962 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11963 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11964 const struct builtin_description *d;
11971 case PAIRED_BUILTIN_STX:
11972 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11973 case PAIRED_BUILTIN_LX:
11974 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11977 /* Fall through. */
11980 /* Expand the paired predicates. */
11981 d = bdesc_paired_preds;
11982 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11983 if (d->code == fcode)
11984 return paired_expand_predicate_builtin (d->icode, exp, target);
11986 *expandedp = false;
11990 /* Binops that need to be initialized manually, but can be expanded
11991 automagically by rs6000_expand_binop_builtin. */
11992 static struct builtin_description bdesc_2arg_spe[] =
11994 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
11995 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
11996 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
11997 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
11998 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
11999 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12000 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12001 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12002 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12003 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12004 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12005 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12006 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12007 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12008 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12009 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12010 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12011 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12012 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12013 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12014 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12015 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12018 /* Expand the builtin in EXP and store the result in TARGET. Store
12019 true in *EXPANDEDP if we found a builtin to expand.
12021 This expands the SPE builtins that are not simple unary and binary
12024 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12026 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12028 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12029 enum insn_code icode;
12030 enum machine_mode tmode, mode0;
12032 struct builtin_description *d;
12037 /* Syntax check for a 5-bit unsigned immediate. */
12040 case SPE_BUILTIN_EVSTDD:
12041 case SPE_BUILTIN_EVSTDH:
12042 case SPE_BUILTIN_EVSTDW:
12043 case SPE_BUILTIN_EVSTWHE:
12044 case SPE_BUILTIN_EVSTWHO:
12045 case SPE_BUILTIN_EVSTWWE:
12046 case SPE_BUILTIN_EVSTWWO:
12047 arg1 = CALL_EXPR_ARG (exp, 2);
12048 if (TREE_CODE (arg1) != INTEGER_CST
12049 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12051 error ("argument 2 must be a 5-bit unsigned literal");
12059 /* The evsplat*i instructions are not quite generic. */
12062 case SPE_BUILTIN_EVSPLATFI:
12063 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12065 case SPE_BUILTIN_EVSPLATI:
12066 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12072 d = (struct builtin_description *) bdesc_2arg_spe;
12073 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12074 if (d->code == fcode)
12075 return rs6000_expand_binop_builtin (d->icode, exp, target);
12077 d = (struct builtin_description *) bdesc_spe_predicates;
12078 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12079 if (d->code == fcode)
12080 return spe_expand_predicate_builtin (d->icode, exp, target);
12082 d = (struct builtin_description *) bdesc_spe_evsel;
12083 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12084 if (d->code == fcode)
12085 return spe_expand_evsel_builtin (d->icode, exp, target);
12089 case SPE_BUILTIN_EVSTDDX:
12090 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12091 case SPE_BUILTIN_EVSTDHX:
12092 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12093 case SPE_BUILTIN_EVSTDWX:
12094 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12095 case SPE_BUILTIN_EVSTWHEX:
12096 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12097 case SPE_BUILTIN_EVSTWHOX:
12098 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12099 case SPE_BUILTIN_EVSTWWEX:
12100 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12101 case SPE_BUILTIN_EVSTWWOX:
12102 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12103 case SPE_BUILTIN_EVSTDD:
12104 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12105 case SPE_BUILTIN_EVSTDH:
12106 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12107 case SPE_BUILTIN_EVSTDW:
12108 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12109 case SPE_BUILTIN_EVSTWHE:
12110 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12111 case SPE_BUILTIN_EVSTWHO:
12112 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12113 case SPE_BUILTIN_EVSTWWE:
12114 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12115 case SPE_BUILTIN_EVSTWWO:
12116 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12117 case SPE_BUILTIN_MFSPEFSCR:
12118 icode = CODE_FOR_spe_mfspefscr;
12119 tmode = insn_data[icode].operand[0].mode;
12122 || GET_MODE (target) != tmode
12123 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12124 target = gen_reg_rtx (tmode);
12126 pat = GEN_FCN (icode) (target);
12131 case SPE_BUILTIN_MTSPEFSCR:
12132 icode = CODE_FOR_spe_mtspefscr;
12133 arg0 = CALL_EXPR_ARG (exp, 0);
12134 op0 = expand_normal (arg0);
12135 mode0 = insn_data[icode].operand[0].mode;
12137 if (arg0 == error_mark_node)
12140 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12141 op0 = copy_to_mode_reg (mode0, op0);
12143 pat = GEN_FCN (icode) (op0);
12151 *expandedp = false;
12156 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12158 rtx pat, scratch, tmp;
12159 tree form = CALL_EXPR_ARG (exp, 0);
12160 tree arg0 = CALL_EXPR_ARG (exp, 1);
12161 tree arg1 = CALL_EXPR_ARG (exp, 2);
12162 rtx op0 = expand_normal (arg0);
12163 rtx op1 = expand_normal (arg1);
12164 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12165 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12167 enum rtx_code code;
12169 if (TREE_CODE (form) != INTEGER_CST)
12171 error ("argument 1 of __builtin_paired_predicate must be a constant");
12175 form_int = TREE_INT_CST_LOW (form);
12177 gcc_assert (mode0 == mode1);
12179 if (arg0 == error_mark_node || arg1 == error_mark_node)
12183 || GET_MODE (target) != SImode
12184 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12185 target = gen_reg_rtx (SImode);
12186 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12187 op0 = copy_to_mode_reg (mode0, op0);
12188 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12189 op1 = copy_to_mode_reg (mode1, op1);
12191 scratch = gen_reg_rtx (CCFPmode);
12193 pat = GEN_FCN (icode) (scratch, op0, op1);
12215 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12218 error ("argument 1 of __builtin_paired_predicate is out of range");
12222 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12223 emit_move_insn (target, tmp);
12228 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12230 rtx pat, scratch, tmp;
12231 tree form = CALL_EXPR_ARG (exp, 0);
12232 tree arg0 = CALL_EXPR_ARG (exp, 1);
12233 tree arg1 = CALL_EXPR_ARG (exp, 2);
12234 rtx op0 = expand_normal (arg0);
12235 rtx op1 = expand_normal (arg1);
12236 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12237 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12239 enum rtx_code code;
12241 if (TREE_CODE (form) != INTEGER_CST)
12243 error ("argument 1 of __builtin_spe_predicate must be a constant");
12247 form_int = TREE_INT_CST_LOW (form);
12249 gcc_assert (mode0 == mode1);
12251 if (arg0 == error_mark_node || arg1 == error_mark_node)
12255 || GET_MODE (target) != SImode
12256 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12257 target = gen_reg_rtx (SImode);
12259 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12260 op0 = copy_to_mode_reg (mode0, op0);
12261 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12262 op1 = copy_to_mode_reg (mode1, op1);
12264 scratch = gen_reg_rtx (CCmode);
12266 pat = GEN_FCN (icode) (scratch, op0, op1);
12271 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12272 _lower_. We use one compare, but look in different bits of the
12273 CR for each variant.
12275 There are 2 elements in each SPE simd type (upper/lower). The CR
12276 bits are set as follows:
12278 BIT0 | BIT 1 | BIT 2 | BIT 3
12279 U | L | (U | L) | (U & L)
12281 So, for an "all" relationship, BIT 3 would be set.
12282 For an "any" relationship, BIT 2 would be set. Etc.
12284 Following traditional nomenclature, these bits map to:
12286 BIT0 | BIT 1 | BIT 2 | BIT 3
12289 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12294 /* All variant. OV bit. */
12296 /* We need to get to the OV bit, which is the ORDERED bit. We
12297 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12298 that's ugly and will make validate_condition_mode die.
12299 So let's just use another pattern. */
12300 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12302 /* Any variant. EQ bit. */
12306 /* Upper variant. LT bit. */
12310 /* Lower variant. GT bit. */
12315 error ("argument 1 of __builtin_spe_predicate is out of range");
12319 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12320 emit_move_insn (target, tmp);
12325 /* The evsel builtins look like this:
12327 e = __builtin_spe_evsel_OP (a, b, c, d);
12329 and work like this:
12331 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12332 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12336 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12339 tree arg0 = CALL_EXPR_ARG (exp, 0);
12340 tree arg1 = CALL_EXPR_ARG (exp, 1);
12341 tree arg2 = CALL_EXPR_ARG (exp, 2);
12342 tree arg3 = CALL_EXPR_ARG (exp, 3);
12343 rtx op0 = expand_normal (arg0);
12344 rtx op1 = expand_normal (arg1);
12345 rtx op2 = expand_normal (arg2);
12346 rtx op3 = expand_normal (arg3);
12347 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12348 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12350 gcc_assert (mode0 == mode1);
12352 if (arg0 == error_mark_node || arg1 == error_mark_node
12353 || arg2 == error_mark_node || arg3 == error_mark_node)
12357 || GET_MODE (target) != mode0
12358 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12359 target = gen_reg_rtx (mode0);
12361 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12362 op0 = copy_to_mode_reg (mode0, op0);
12363 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12364 op1 = copy_to_mode_reg (mode0, op1);
12365 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12366 op2 = copy_to_mode_reg (mode0, op2);
12367 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12368 op3 = copy_to_mode_reg (mode0, op3);
12370 /* Generate the compare. */
12371 scratch = gen_reg_rtx (CCmode);
12372 pat = GEN_FCN (icode) (scratch, op0, op1);
12377 if (mode0 == V2SImode)
12378 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12380 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12385 /* Expand an expression EXP that calls a built-in function,
12386 with result going to TARGET if that's convenient
12387 (and in mode MODE if that's convenient).
12388 SUBTARGET may be used as the target for computing one of EXP's operands.
12389 IGNORE is nonzero if the value is to be ignored. */
12392 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12393 enum machine_mode mode ATTRIBUTE_UNUSED,
12394 int ignore ATTRIBUTE_UNUSED)
12396 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12397 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12398 const struct builtin_description *d;
12405 case RS6000_BUILTIN_RECIP:
12406 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12408 case RS6000_BUILTIN_RECIPF:
12409 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12411 case RS6000_BUILTIN_RSQRTF:
12412 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12414 case RS6000_BUILTIN_RSQRT:
12415 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12417 case RS6000_BUILTIN_BSWAP_HI:
12418 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12420 case POWER7_BUILTIN_BPERMD:
12421 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12422 ? CODE_FOR_bpermd_di
12423 : CODE_FOR_bpermd_si), exp, target);
12425 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12426 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12428 int icode = (int) CODE_FOR_altivec_lvsr;
12429 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12430 enum machine_mode mode = insn_data[icode].operand[1].mode;
12434 gcc_assert (TARGET_ALTIVEC);
12436 arg = CALL_EXPR_ARG (exp, 0);
12437 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12438 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12439 addr = memory_address (mode, op);
12440 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12444 /* For the load case need to negate the address. */
12445 op = gen_reg_rtx (GET_MODE (addr));
12446 emit_insn (gen_rtx_SET (VOIDmode, op,
12447 gen_rtx_NEG (GET_MODE (addr), addr)));
12449 op = gen_rtx_MEM (mode, op);
12452 || GET_MODE (target) != tmode
12453 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12454 target = gen_reg_rtx (tmode);
12456 /*pat = gen_altivec_lvsr (target, op);*/
12457 pat = GEN_FCN (icode) (target, op);
12465 case ALTIVEC_BUILTIN_VCFUX:
12466 case ALTIVEC_BUILTIN_VCFSX:
12467 case ALTIVEC_BUILTIN_VCTUXS:
12468 case ALTIVEC_BUILTIN_VCTSXS:
12469 /* FIXME: There's got to be a nicer way to handle this case than
12470 constructing a new CALL_EXPR. */
12471 if (call_expr_nargs (exp) == 1)
12473 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12474 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12482 if (TARGET_ALTIVEC)
12484 ret = altivec_expand_builtin (exp, target, &success);
12491 ret = spe_expand_builtin (exp, target, &success);
12496 if (TARGET_PAIRED_FLOAT)
12498 ret = paired_expand_builtin (exp, target, &success);
12504 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12506 /* Handle simple unary operations. */
12507 d = (struct builtin_description *) bdesc_1arg;
12508 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12509 if (d->code == fcode)
12510 return rs6000_expand_unop_builtin (d->icode, exp, target);
12512 /* Handle simple binary operations. */
12513 d = (struct builtin_description *) bdesc_2arg;
12514 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12515 if (d->code == fcode)
12516 return rs6000_expand_binop_builtin (d->icode, exp, target);
12518 /* Handle simple ternary operations. */
12520 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12521 if (d->code == fcode)
12522 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12524 gcc_unreachable ();
12528 rs6000_init_builtins (void)
12533 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12534 V2SF_type_node = build_vector_type (float_type_node, 2);
12535 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12536 V2DF_type_node = build_vector_type (double_type_node, 2);
12537 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12538 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12539 V4SF_type_node = build_vector_type (float_type_node, 4);
12540 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12541 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12543 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12544 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12545 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12546 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12548 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12549 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12550 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12551 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12553 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12554 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12555 'vector unsigned short'. */
12557 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12558 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12559 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12560 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12561 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12563 long_integer_type_internal_node = long_integer_type_node;
12564 long_unsigned_type_internal_node = long_unsigned_type_node;
12565 long_long_integer_type_internal_node = long_long_integer_type_node;
12566 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12567 intQI_type_internal_node = intQI_type_node;
12568 uintQI_type_internal_node = unsigned_intQI_type_node;
12569 intHI_type_internal_node = intHI_type_node;
12570 uintHI_type_internal_node = unsigned_intHI_type_node;
12571 intSI_type_internal_node = intSI_type_node;
12572 uintSI_type_internal_node = unsigned_intSI_type_node;
12573 intDI_type_internal_node = intDI_type_node;
12574 uintDI_type_internal_node = unsigned_intDI_type_node;
12575 float_type_internal_node = float_type_node;
12576 double_type_internal_node = double_type_node;
12577 void_type_internal_node = void_type_node;
12579 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12581 builtin_mode_to_type[QImode][0] = integer_type_node;
12582 builtin_mode_to_type[HImode][0] = integer_type_node;
12583 builtin_mode_to_type[SImode][0] = intSI_type_node;
12584 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12585 builtin_mode_to_type[DImode][0] = intDI_type_node;
12586 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12587 builtin_mode_to_type[SFmode][0] = float_type_node;
12588 builtin_mode_to_type[DFmode][0] = double_type_node;
12589 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12590 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12591 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12592 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12593 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12594 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12595 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12596 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12597 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12598 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12599 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12600 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12601 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12603 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12604 get_identifier ("__bool char"),
12605 bool_char_type_node);
12606 TYPE_NAME (bool_char_type_node) = tdecl;
12607 (*lang_hooks.decls.pushdecl) (tdecl);
12608 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12609 get_identifier ("__bool short"),
12610 bool_short_type_node);
12611 TYPE_NAME (bool_short_type_node) = tdecl;
12612 (*lang_hooks.decls.pushdecl) (tdecl);
12613 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12614 get_identifier ("__bool int"),
12615 bool_int_type_node);
12616 TYPE_NAME (bool_int_type_node) = tdecl;
12617 (*lang_hooks.decls.pushdecl) (tdecl);
12618 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12620 TYPE_NAME (pixel_type_node) = tdecl;
12621 (*lang_hooks.decls.pushdecl) (tdecl);
12623 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12624 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12625 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12626 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12627 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12629 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12630 get_identifier ("__vector unsigned char"),
12631 unsigned_V16QI_type_node);
12632 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12633 (*lang_hooks.decls.pushdecl) (tdecl);
12634 tdecl = build_decl (BUILTINS_LOCATION,
12635 TYPE_DECL, get_identifier ("__vector signed char"),
12637 TYPE_NAME (V16QI_type_node) = tdecl;
12638 (*lang_hooks.decls.pushdecl) (tdecl);
12639 tdecl = build_decl (BUILTINS_LOCATION,
12640 TYPE_DECL, get_identifier ("__vector __bool char"),
12641 bool_V16QI_type_node);
12642 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12643 (*lang_hooks.decls.pushdecl) (tdecl);
12645 tdecl = build_decl (BUILTINS_LOCATION,
12646 TYPE_DECL, get_identifier ("__vector unsigned short"),
12647 unsigned_V8HI_type_node);
12648 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12649 (*lang_hooks.decls.pushdecl) (tdecl);
12650 tdecl = build_decl (BUILTINS_LOCATION,
12651 TYPE_DECL, get_identifier ("__vector signed short"),
12653 TYPE_NAME (V8HI_type_node) = tdecl;
12654 (*lang_hooks.decls.pushdecl) (tdecl);
12655 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12656 get_identifier ("__vector __bool short"),
12657 bool_V8HI_type_node);
12658 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12659 (*lang_hooks.decls.pushdecl) (tdecl);
12661 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12662 get_identifier ("__vector unsigned int"),
12663 unsigned_V4SI_type_node);
12664 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12665 (*lang_hooks.decls.pushdecl) (tdecl);
12666 tdecl = build_decl (BUILTINS_LOCATION,
12667 TYPE_DECL, get_identifier ("__vector signed int"),
12669 TYPE_NAME (V4SI_type_node) = tdecl;
12670 (*lang_hooks.decls.pushdecl) (tdecl);
12671 tdecl = build_decl (BUILTINS_LOCATION,
12672 TYPE_DECL, get_identifier ("__vector __bool int"),
12673 bool_V4SI_type_node);
12674 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12675 (*lang_hooks.decls.pushdecl) (tdecl);
12677 tdecl = build_decl (BUILTINS_LOCATION,
12678 TYPE_DECL, get_identifier ("__vector float"),
12680 TYPE_NAME (V4SF_type_node) = tdecl;
12681 (*lang_hooks.decls.pushdecl) (tdecl);
12682 tdecl = build_decl (BUILTINS_LOCATION,
12683 TYPE_DECL, get_identifier ("__vector __pixel"),
12684 pixel_V8HI_type_node);
12685 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12686 (*lang_hooks.decls.pushdecl) (tdecl);
12690 tdecl = build_decl (BUILTINS_LOCATION,
12691 TYPE_DECL, get_identifier ("__vector double"),
12693 TYPE_NAME (V2DF_type_node) = tdecl;
12694 (*lang_hooks.decls.pushdecl) (tdecl);
12696 tdecl = build_decl (BUILTINS_LOCATION,
12697 TYPE_DECL, get_identifier ("__vector long"),
12699 TYPE_NAME (V2DI_type_node) = tdecl;
12700 (*lang_hooks.decls.pushdecl) (tdecl);
12702 tdecl = build_decl (BUILTINS_LOCATION,
12703 TYPE_DECL, get_identifier ("__vector unsigned long"),
12704 unsigned_V2DI_type_node);
12705 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12706 (*lang_hooks.decls.pushdecl) (tdecl);
12708 tdecl = build_decl (BUILTINS_LOCATION,
12709 TYPE_DECL, get_identifier ("__vector __bool long"),
12710 bool_V2DI_type_node);
12711 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12712 (*lang_hooks.decls.pushdecl) (tdecl);
12715 if (TARGET_PAIRED_FLOAT)
12716 paired_init_builtins ();
12718 spe_init_builtins ();
12719 if (TARGET_ALTIVEC)
12720 altivec_init_builtins ();
12721 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12722 rs6000_common_init_builtins ();
12725 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12726 RS6000_BUILTIN_RECIP,
12727 "__builtin_recipdiv");
12728 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12729 RS6000_BUILTIN_RECIP);
12733 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12734 RS6000_BUILTIN_RECIPF,
12735 "__builtin_recipdivf");
12736 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12737 RS6000_BUILTIN_RECIPF);
12739 if (TARGET_FRSQRTE)
12741 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12742 RS6000_BUILTIN_RSQRT,
12743 "__builtin_rsqrt");
12744 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12745 RS6000_BUILTIN_RSQRT);
12747 if (TARGET_FRSQRTES)
12749 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12750 RS6000_BUILTIN_RSQRTF,
12751 "__builtin_rsqrtf");
12752 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12753 RS6000_BUILTIN_RSQRTF);
12755 if (TARGET_POPCNTD)
12757 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12758 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12759 POWER7_BUILTIN_BPERMD,
12760 "__builtin_bpermd");
12761 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12762 POWER7_BUILTIN_BPERMD);
12764 if (TARGET_POWERPC)
12766 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12767 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12768 unsigned_intHI_type_node,
12770 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12771 RS6000_BUILTIN_BSWAP_HI);
12775 /* AIX libm provides clog as __clog. */
12776 if (built_in_decls [BUILT_IN_CLOG])
12777 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12780 #ifdef SUBTARGET_INIT_BUILTINS
12781 SUBTARGET_INIT_BUILTINS;
12785 /* Returns the rs6000 builtin decl for CODE. */
12788 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12790 if (code >= RS6000_BUILTIN_COUNT)
12791 return error_mark_node;
12793 return rs6000_builtin_decls[code];
12796 /* Search through a set of builtins and enable the mask bits.
12797 DESC is an array of builtins.
12798 SIZE is the total number of builtins.
12799 START is the builtin enum at which to start.
12800 END is the builtin enum at which to end. */
12802 enable_mask_for_builtins (struct builtin_description *desc, int size,
12803 enum rs6000_builtins start,
12804 enum rs6000_builtins end)
12808 for (i = 0; i < size; ++i)
12809 if (desc[i].code == start)
12815 for (; i < size; ++i)
12817 /* Flip all the bits on. */
12818 desc[i].mask = target_flags;
12819 if (desc[i].code == end)
12825 spe_init_builtins (void)
12827 tree endlink = void_list_node;
12828 tree puint_type_node = build_pointer_type (unsigned_type_node);
12829 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12830 struct builtin_description *d;
12833 tree v2si_ftype_4_v2si
12834 = build_function_type
12835 (opaque_V2SI_type_node,
12836 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12837 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12838 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12839 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12842 tree v2sf_ftype_4_v2sf
12843 = build_function_type
12844 (opaque_V2SF_type_node,
12845 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12846 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12847 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12848 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12851 tree int_ftype_int_v2si_v2si
12852 = build_function_type
12853 (integer_type_node,
12854 tree_cons (NULL_TREE, integer_type_node,
12855 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12856 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12859 tree int_ftype_int_v2sf_v2sf
12860 = build_function_type
12861 (integer_type_node,
12862 tree_cons (NULL_TREE, integer_type_node,
12863 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12864 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12867 tree void_ftype_v2si_puint_int
12868 = build_function_type (void_type_node,
12869 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12870 tree_cons (NULL_TREE, puint_type_node,
12871 tree_cons (NULL_TREE,
12875 tree void_ftype_v2si_puint_char
12876 = build_function_type (void_type_node,
12877 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12878 tree_cons (NULL_TREE, puint_type_node,
12879 tree_cons (NULL_TREE,
12883 tree void_ftype_v2si_pv2si_int
12884 = build_function_type (void_type_node,
12885 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12886 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12887 tree_cons (NULL_TREE,
12891 tree void_ftype_v2si_pv2si_char
12892 = build_function_type (void_type_node,
12893 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12894 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12895 tree_cons (NULL_TREE,
12899 tree void_ftype_int
12900 = build_function_type (void_type_node,
12901 tree_cons (NULL_TREE, integer_type_node, endlink));
12903 tree int_ftype_void
12904 = build_function_type (integer_type_node, endlink);
12906 tree v2si_ftype_pv2si_int
12907 = build_function_type (opaque_V2SI_type_node,
12908 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12909 tree_cons (NULL_TREE, integer_type_node,
12912 tree v2si_ftype_puint_int
12913 = build_function_type (opaque_V2SI_type_node,
12914 tree_cons (NULL_TREE, puint_type_node,
12915 tree_cons (NULL_TREE, integer_type_node,
12918 tree v2si_ftype_pushort_int
12919 = build_function_type (opaque_V2SI_type_node,
12920 tree_cons (NULL_TREE, pushort_type_node,
12921 tree_cons (NULL_TREE, integer_type_node,
12924 tree v2si_ftype_signed_char
12925 = build_function_type (opaque_V2SI_type_node,
12926 tree_cons (NULL_TREE, signed_char_type_node,
12929 /* The initialization of the simple binary and unary builtins is
12930 done in rs6000_common_init_builtins, but we have to enable the
12931 mask bits here manually because we have run out of `target_flags'
12932 bits. We really need to redesign this mask business. */
12934 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12935 ARRAY_SIZE (bdesc_2arg),
12936 SPE_BUILTIN_EVADDW,
12937 SPE_BUILTIN_EVXOR);
12938 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12939 ARRAY_SIZE (bdesc_1arg),
12941 SPE_BUILTIN_EVSUBFUSIAAW);
12942 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12943 ARRAY_SIZE (bdesc_spe_predicates),
12944 SPE_BUILTIN_EVCMPEQ,
12945 SPE_BUILTIN_EVFSTSTLT);
12946 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12947 ARRAY_SIZE (bdesc_spe_evsel),
12948 SPE_BUILTIN_EVSEL_CMPGTS,
12949 SPE_BUILTIN_EVSEL_FSTSTEQ);
12951 (*lang_hooks.decls.pushdecl)
12952 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12953 get_identifier ("__ev64_opaque__"),
12954 opaque_V2SI_type_node));
12956 /* Initialize irregular SPE builtins. */
12958 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12959 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12960 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12961 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12962 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12963 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12964 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12965 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12966 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12967 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12968 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12969 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12970 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12971 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12972 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12973 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12974 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12975 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12978 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12979 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12980 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12981 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12982 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12983 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12984 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12985 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12986 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12987 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12988 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12989 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12990 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
12991 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
12992 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
12993 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
12994 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
12995 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
12996 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
12997 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
12998 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
12999 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13002 d = (struct builtin_description *) bdesc_spe_predicates;
13003 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13007 switch (insn_data[d->icode].operand[1].mode)
13010 type = int_ftype_int_v2si_v2si;
13013 type = int_ftype_int_v2sf_v2sf;
13016 gcc_unreachable ();
13019 def_builtin (d->mask, d->name, type, d->code);
13022 /* Evsel predicates. */
13023 d = (struct builtin_description *) bdesc_spe_evsel;
13024 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13028 switch (insn_data[d->icode].operand[1].mode)
13031 type = v2si_ftype_4_v2si;
13034 type = v2sf_ftype_4_v2sf;
13037 gcc_unreachable ();
13040 def_builtin (d->mask, d->name, type, d->code);
13045 paired_init_builtins (void)
13047 const struct builtin_description *d;
13049 tree endlink = void_list_node;
13051 tree int_ftype_int_v2sf_v2sf
13052 = build_function_type
13053 (integer_type_node,
13054 tree_cons (NULL_TREE, integer_type_node,
13055 tree_cons (NULL_TREE, V2SF_type_node,
13056 tree_cons (NULL_TREE, V2SF_type_node,
13058 tree pcfloat_type_node =
13059 build_pointer_type (build_qualified_type
13060 (float_type_node, TYPE_QUAL_CONST));
13062 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13063 long_integer_type_node,
13066 tree void_ftype_v2sf_long_pcfloat =
13067 build_function_type_list (void_type_node,
13069 long_integer_type_node,
13074 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13075 PAIRED_BUILTIN_LX);
13078 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13079 PAIRED_BUILTIN_STX);
13082 d = bdesc_paired_preds;
13083 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13087 switch (insn_data[d->icode].operand[1].mode)
13090 type = int_ftype_int_v2sf_v2sf;
13093 gcc_unreachable ();
13096 def_builtin (d->mask, d->name, type, d->code);
13101 altivec_init_builtins (void)
13103 const struct builtin_description *d;
13104 const struct builtin_description_predicates *dp;
13108 tree pvoid_type_node = build_pointer_type (void_type_node);
13110 tree pcvoid_type_node
13111 = build_pointer_type (build_qualified_type (void_type_node,
13114 tree int_ftype_opaque
13115 = build_function_type_list (integer_type_node,
13116 opaque_V4SI_type_node, NULL_TREE);
13117 tree opaque_ftype_opaque
13118 = build_function_type (integer_type_node,
13120 tree opaque_ftype_opaque_int
13121 = build_function_type_list (opaque_V4SI_type_node,
13122 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13123 tree opaque_ftype_opaque_opaque_int
13124 = build_function_type_list (opaque_V4SI_type_node,
13125 opaque_V4SI_type_node, opaque_V4SI_type_node,
13126 integer_type_node, NULL_TREE);
13127 tree int_ftype_int_opaque_opaque
13128 = build_function_type_list (integer_type_node,
13129 integer_type_node, opaque_V4SI_type_node,
13130 opaque_V4SI_type_node, NULL_TREE);
13131 tree int_ftype_int_v4si_v4si
13132 = build_function_type_list (integer_type_node,
13133 integer_type_node, V4SI_type_node,
13134 V4SI_type_node, NULL_TREE);
13135 tree void_ftype_v4si
13136 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13137 tree v8hi_ftype_void
13138 = build_function_type (V8HI_type_node, void_list_node);
13139 tree void_ftype_void
13140 = build_function_type (void_type_node, void_list_node);
13141 tree void_ftype_int
13142 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13144 tree opaque_ftype_long_pcvoid
13145 = build_function_type_list (opaque_V4SI_type_node,
13146 long_integer_type_node, pcvoid_type_node,
13148 tree v16qi_ftype_long_pcvoid
13149 = build_function_type_list (V16QI_type_node,
13150 long_integer_type_node, pcvoid_type_node,
13152 tree v8hi_ftype_long_pcvoid
13153 = build_function_type_list (V8HI_type_node,
13154 long_integer_type_node, pcvoid_type_node,
13156 tree v4si_ftype_long_pcvoid
13157 = build_function_type_list (V4SI_type_node,
13158 long_integer_type_node, pcvoid_type_node,
13160 tree v4sf_ftype_long_pcvoid
13161 = build_function_type_list (V4SF_type_node,
13162 long_integer_type_node, pcvoid_type_node,
13164 tree v2df_ftype_long_pcvoid
13165 = build_function_type_list (V2DF_type_node,
13166 long_integer_type_node, pcvoid_type_node,
13168 tree v2di_ftype_long_pcvoid
13169 = build_function_type_list (V2DI_type_node,
13170 long_integer_type_node, pcvoid_type_node,
13173 tree void_ftype_opaque_long_pvoid
13174 = build_function_type_list (void_type_node,
13175 opaque_V4SI_type_node, long_integer_type_node,
13176 pvoid_type_node, NULL_TREE);
13177 tree void_ftype_v4si_long_pvoid
13178 = build_function_type_list (void_type_node,
13179 V4SI_type_node, long_integer_type_node,
13180 pvoid_type_node, NULL_TREE);
13181 tree void_ftype_v16qi_long_pvoid
13182 = build_function_type_list (void_type_node,
13183 V16QI_type_node, long_integer_type_node,
13184 pvoid_type_node, NULL_TREE);
13185 tree void_ftype_v8hi_long_pvoid
13186 = build_function_type_list (void_type_node,
13187 V8HI_type_node, long_integer_type_node,
13188 pvoid_type_node, NULL_TREE);
13189 tree void_ftype_v4sf_long_pvoid
13190 = build_function_type_list (void_type_node,
13191 V4SF_type_node, long_integer_type_node,
13192 pvoid_type_node, NULL_TREE);
13193 tree void_ftype_v2df_long_pvoid
13194 = build_function_type_list (void_type_node,
13195 V2DF_type_node, long_integer_type_node,
13196 pvoid_type_node, NULL_TREE);
13197 tree void_ftype_v2di_long_pvoid
13198 = build_function_type_list (void_type_node,
13199 V2DI_type_node, long_integer_type_node,
13200 pvoid_type_node, NULL_TREE);
13201 tree int_ftype_int_v8hi_v8hi
13202 = build_function_type_list (integer_type_node,
13203 integer_type_node, V8HI_type_node,
13204 V8HI_type_node, NULL_TREE);
13205 tree int_ftype_int_v16qi_v16qi
13206 = build_function_type_list (integer_type_node,
13207 integer_type_node, V16QI_type_node,
13208 V16QI_type_node, NULL_TREE);
13209 tree int_ftype_int_v4sf_v4sf
13210 = build_function_type_list (integer_type_node,
13211 integer_type_node, V4SF_type_node,
13212 V4SF_type_node, NULL_TREE);
13213 tree int_ftype_int_v2df_v2df
13214 = build_function_type_list (integer_type_node,
13215 integer_type_node, V2DF_type_node,
13216 V2DF_type_node, NULL_TREE);
13217 tree v4si_ftype_v4si
13218 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13219 tree v8hi_ftype_v8hi
13220 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13221 tree v16qi_ftype_v16qi
13222 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13223 tree v4sf_ftype_v4sf
13224 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13225 tree v2df_ftype_v2df
13226 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13227 tree void_ftype_pcvoid_int_int
13228 = build_function_type_list (void_type_node,
13229 pcvoid_type_node, integer_type_node,
13230 integer_type_node, NULL_TREE);
13232 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13233 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13234 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13235 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13236 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13237 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13238 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13239 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13240 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13241 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13242 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13243 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13244 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13245 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13246 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13247 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13248 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13249 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13250 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13251 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13252 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13253 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13254 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13255 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13256 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13257 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13258 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13259 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13260 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13261 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13263 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13264 VSX_BUILTIN_LXVD2X_V2DF);
13265 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13266 VSX_BUILTIN_LXVD2X_V2DI);
13267 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13268 VSX_BUILTIN_LXVW4X_V4SF);
13269 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13270 VSX_BUILTIN_LXVW4X_V4SI);
13271 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13272 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13273 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13274 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13275 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13276 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13277 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13278 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13279 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13280 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13281 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13282 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13283 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13284 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13285 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13286 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13287 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13288 VSX_BUILTIN_VEC_LD);
13289 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13290 VSX_BUILTIN_VEC_ST);
13292 if (rs6000_cpu == PROCESSOR_CELL)
13294 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13295 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13296 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13297 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13299 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13300 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13301 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13302 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13304 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13305 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13306 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13307 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13309 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13310 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13311 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13312 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13314 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13315 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13316 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13318 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13319 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13320 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13321 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13322 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13323 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13324 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13325 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13326 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13327 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13328 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13329 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13331 /* Add the DST variants. */
13333 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13334 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13336 /* Initialize the predicates. */
13337 dp = bdesc_altivec_preds;
13338 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13340 enum machine_mode mode1;
13342 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13343 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13344 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13345 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13350 mode1 = insn_data[dp->icode].operand[1].mode;
13355 type = int_ftype_int_opaque_opaque;
13358 type = int_ftype_int_v4si_v4si;
13361 type = int_ftype_int_v8hi_v8hi;
13364 type = int_ftype_int_v16qi_v16qi;
13367 type = int_ftype_int_v4sf_v4sf;
13370 type = int_ftype_int_v2df_v2df;
13373 gcc_unreachable ();
13376 def_builtin (dp->mask, dp->name, type, dp->code);
13379 /* Initialize the abs* operators. */
13381 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13383 enum machine_mode mode0;
13386 mode0 = insn_data[d->icode].operand[0].mode;
13391 type = v4si_ftype_v4si;
13394 type = v8hi_ftype_v8hi;
13397 type = v16qi_ftype_v16qi;
13400 type = v4sf_ftype_v4sf;
13403 type = v2df_ftype_v2df;
13406 gcc_unreachable ();
13409 def_builtin (d->mask, d->name, type, d->code);
13412 if (TARGET_ALTIVEC)
13416 /* Initialize target builtin that implements
13417 targetm.vectorize.builtin_mask_for_load. */
13419 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13420 v16qi_ftype_long_pcvoid,
13421 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13422 BUILT_IN_MD, NULL, NULL_TREE);
13423 TREE_READONLY (decl) = 1;
13424 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13425 altivec_builtin_mask_for_load = decl;
13428 /* Access to the vec_init patterns. */
13429 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13430 integer_type_node, integer_type_node,
13431 integer_type_node, NULL_TREE);
13432 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13433 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13435 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13436 short_integer_type_node,
13437 short_integer_type_node,
13438 short_integer_type_node,
13439 short_integer_type_node,
13440 short_integer_type_node,
13441 short_integer_type_node,
13442 short_integer_type_node, NULL_TREE);
13443 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13444 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13446 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13447 char_type_node, char_type_node,
13448 char_type_node, char_type_node,
13449 char_type_node, char_type_node,
13450 char_type_node, char_type_node,
13451 char_type_node, char_type_node,
13452 char_type_node, char_type_node,
13453 char_type_node, char_type_node,
13454 char_type_node, NULL_TREE);
13455 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13456 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13458 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13459 float_type_node, float_type_node,
13460 float_type_node, NULL_TREE);
13461 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13462 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13466 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13467 double_type_node, NULL_TREE);
13468 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13469 VSX_BUILTIN_VEC_INIT_V2DF);
13471 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13472 intDI_type_node, NULL_TREE);
13473 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13474 VSX_BUILTIN_VEC_INIT_V2DI);
13477 /* Access to the vec_set patterns. */
13478 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13480 integer_type_node, NULL_TREE);
13481 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13482 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13484 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13486 integer_type_node, NULL_TREE);
13487 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13488 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13490 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13492 integer_type_node, NULL_TREE);
13493 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13494 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13496 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13498 integer_type_node, NULL_TREE);
13499 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13500 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13504 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13506 integer_type_node, NULL_TREE);
13507 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13508 VSX_BUILTIN_VEC_SET_V2DF);
13510 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13512 integer_type_node, NULL_TREE);
13513 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13514 VSX_BUILTIN_VEC_SET_V2DI);
13517 /* Access to the vec_extract patterns. */
13518 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13519 integer_type_node, NULL_TREE);
13520 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13521 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13523 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13524 integer_type_node, NULL_TREE);
13525 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13526 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13528 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13529 integer_type_node, NULL_TREE);
13530 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13531 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13533 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13534 integer_type_node, NULL_TREE);
13535 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13536 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13540 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13541 integer_type_node, NULL_TREE);
13542 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13543 VSX_BUILTIN_VEC_EXT_V2DF);
13545 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13546 integer_type_node, NULL_TREE);
13547 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13548 VSX_BUILTIN_VEC_EXT_V2DI);
13552 /* Hash function for builtin functions with up to 3 arguments and a return
13555 builtin_hash_function (const void *hash_entry)
13559 const struct builtin_hash_struct *bh =
13560 (const struct builtin_hash_struct *) hash_entry;
13562 for (i = 0; i < 4; i++)
13564 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13565 ret = (ret * 2) + bh->uns_p[i];
13571 /* Compare builtin hash entries H1 and H2 for equivalence. */
13573 builtin_hash_eq (const void *h1, const void *h2)
13575 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13576 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13578 return ((p1->mode[0] == p2->mode[0])
13579 && (p1->mode[1] == p2->mode[1])
13580 && (p1->mode[2] == p2->mode[2])
13581 && (p1->mode[3] == p2->mode[3])
13582 && (p1->uns_p[0] == p2->uns_p[0])
13583 && (p1->uns_p[1] == p2->uns_p[1])
13584 && (p1->uns_p[2] == p2->uns_p[2])
13585 && (p1->uns_p[3] == p2->uns_p[3]));
13588 /* Map types for builtin functions with an explicit return type and up to 3
13589 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13590 of the argument. */
13592 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13593 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13594 enum rs6000_builtins builtin, const char *name)
13596 struct builtin_hash_struct h;
13597 struct builtin_hash_struct *h2;
13601 tree ret_type = NULL_TREE;
13602 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13605 /* Create builtin_hash_table. */
13606 if (builtin_hash_table == NULL)
13607 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13608 builtin_hash_eq, NULL);
13610 h.type = NULL_TREE;
13611 h.mode[0] = mode_ret;
13612 h.mode[1] = mode_arg0;
13613 h.mode[2] = mode_arg1;
13614 h.mode[3] = mode_arg2;
13620 /* If the builtin is a type that produces unsigned results or takes unsigned
13621 arguments, and it is returned as a decl for the vectorizer (such as
13622 widening multiplies, permute), make sure the arguments and return value
13623 are type correct. */
13626 /* unsigned 2 argument functions. */
13627 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13628 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13629 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13630 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13636 /* unsigned 3 argument functions. */
13637 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13638 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13639 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13640 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13641 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13642 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13643 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13644 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13645 case VSX_BUILTIN_VPERM_16QI_UNS:
13646 case VSX_BUILTIN_VPERM_8HI_UNS:
13647 case VSX_BUILTIN_VPERM_4SI_UNS:
13648 case VSX_BUILTIN_VPERM_2DI_UNS:
13649 case VSX_BUILTIN_XXSEL_16QI_UNS:
13650 case VSX_BUILTIN_XXSEL_8HI_UNS:
13651 case VSX_BUILTIN_XXSEL_4SI_UNS:
13652 case VSX_BUILTIN_XXSEL_2DI_UNS:
13659 /* signed permute functions with unsigned char mask. */
13660 case ALTIVEC_BUILTIN_VPERM_16QI:
13661 case ALTIVEC_BUILTIN_VPERM_8HI:
13662 case ALTIVEC_BUILTIN_VPERM_4SI:
13663 case ALTIVEC_BUILTIN_VPERM_4SF:
13664 case ALTIVEC_BUILTIN_VPERM_2DI:
13665 case ALTIVEC_BUILTIN_VPERM_2DF:
13666 case VSX_BUILTIN_VPERM_16QI:
13667 case VSX_BUILTIN_VPERM_8HI:
13668 case VSX_BUILTIN_VPERM_4SI:
13669 case VSX_BUILTIN_VPERM_4SF:
13670 case VSX_BUILTIN_VPERM_2DI:
13671 case VSX_BUILTIN_VPERM_2DF:
13675 /* unsigned args, signed return. */
13676 case VSX_BUILTIN_XVCVUXDDP_UNS:
13677 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13681 /* signed args, unsigned return. */
13682 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13683 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13691 /* Figure out how many args are present. */
13692 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13696 fatal_error ("internal error: builtin function %s had no type", name);
13698 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13699 if (!ret_type && h.uns_p[0])
13700 ret_type = builtin_mode_to_type[h.mode[0]][0];
13703 fatal_error ("internal error: builtin function %s had an unexpected "
13704 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13706 for (i = 0; i < num_args; i++)
13708 int m = (int) h.mode[i+1];
13709 int uns_p = h.uns_p[i+1];
13711 arg_type[i] = builtin_mode_to_type[m][uns_p];
13712 if (!arg_type[i] && uns_p)
13713 arg_type[i] = builtin_mode_to_type[m][0];
13716 fatal_error ("internal error: builtin function %s, argument %d "
13717 "had unexpected argument type %s", name, i,
13718 GET_MODE_NAME (m));
13721 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13722 if (*found == NULL)
13724 h2 = ggc_alloc_builtin_hash_struct ();
13726 *found = (void *)h2;
13727 args = void_list_node;
13729 for (i = num_args - 1; i >= 0; i--)
13730 args = tree_cons (NULL_TREE, arg_type[i], args);
13732 h2->type = build_function_type (ret_type, args);
13735 return ((struct builtin_hash_struct *)(*found))->type;
13739 rs6000_common_init_builtins (void)
13741 const struct builtin_description *d;
13744 tree opaque_ftype_opaque = NULL_TREE;
13745 tree opaque_ftype_opaque_opaque = NULL_TREE;
13746 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13747 tree v2si_ftype_qi = NULL_TREE;
13748 tree v2si_ftype_v2si_qi = NULL_TREE;
13749 tree v2si_ftype_int_qi = NULL_TREE;
13751 if (!TARGET_PAIRED_FLOAT)
13753 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13754 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13757 /* Add the ternary operators. */
13759 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13762 int mask = d->mask;
13764 if ((mask != 0 && (mask & target_flags) == 0)
13765 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13768 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13769 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13770 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13771 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13773 if (! (type = opaque_ftype_opaque_opaque_opaque))
13774 type = opaque_ftype_opaque_opaque_opaque
13775 = build_function_type_list (opaque_V4SI_type_node,
13776 opaque_V4SI_type_node,
13777 opaque_V4SI_type_node,
13778 opaque_V4SI_type_node,
13783 enum insn_code icode = d->icode;
13784 if (d->name == 0 || icode == CODE_FOR_nothing)
13787 type = builtin_function_type (insn_data[icode].operand[0].mode,
13788 insn_data[icode].operand[1].mode,
13789 insn_data[icode].operand[2].mode,
13790 insn_data[icode].operand[3].mode,
13794 def_builtin (d->mask, d->name, type, d->code);
13797 /* Add the binary operators. */
13799 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13801 enum machine_mode mode0, mode1, mode2;
13803 int mask = d->mask;
13805 if ((mask != 0 && (mask & target_flags) == 0)
13806 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13809 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13810 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13811 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13812 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13814 if (! (type = opaque_ftype_opaque_opaque))
13815 type = opaque_ftype_opaque_opaque
13816 = build_function_type_list (opaque_V4SI_type_node,
13817 opaque_V4SI_type_node,
13818 opaque_V4SI_type_node,
13823 enum insn_code icode = d->icode;
13824 if (d->name == 0 || icode == CODE_FOR_nothing)
13827 mode0 = insn_data[icode].operand[0].mode;
13828 mode1 = insn_data[icode].operand[1].mode;
13829 mode2 = insn_data[icode].operand[2].mode;
13831 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13833 if (! (type = v2si_ftype_v2si_qi))
13834 type = v2si_ftype_v2si_qi
13835 = build_function_type_list (opaque_V2SI_type_node,
13836 opaque_V2SI_type_node,
13841 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13842 && mode2 == QImode)
13844 if (! (type = v2si_ftype_int_qi))
13845 type = v2si_ftype_int_qi
13846 = build_function_type_list (opaque_V2SI_type_node,
13853 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13857 def_builtin (d->mask, d->name, type, d->code);
13860 /* Add the simple unary operators. */
13861 d = (struct builtin_description *) bdesc_1arg;
13862 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13864 enum machine_mode mode0, mode1;
13866 int mask = d->mask;
13868 if ((mask != 0 && (mask & target_flags) == 0)
13869 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13872 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13873 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13874 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13875 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13877 if (! (type = opaque_ftype_opaque))
13878 type = opaque_ftype_opaque
13879 = build_function_type_list (opaque_V4SI_type_node,
13880 opaque_V4SI_type_node,
13885 enum insn_code icode = d->icode;
13886 if (d->name == 0 || icode == CODE_FOR_nothing)
13889 mode0 = insn_data[icode].operand[0].mode;
13890 mode1 = insn_data[icode].operand[1].mode;
13892 if (mode0 == V2SImode && mode1 == QImode)
13894 if (! (type = v2si_ftype_qi))
13895 type = v2si_ftype_qi
13896 = build_function_type_list (opaque_V2SI_type_node,
13902 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13906 def_builtin (d->mask, d->name, type, d->code);
13911 rs6000_init_libfuncs (void)
13913 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13914 && !TARGET_POWER2 && !TARGET_POWERPC)
13916 /* AIX library routines for float->int conversion. */
13917 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13918 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13919 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13920 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13923 if (!TARGET_IEEEQUAD)
13924 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13925 if (!TARGET_XL_COMPAT)
13927 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13928 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13929 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13930 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13932 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13934 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13935 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13936 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13937 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13938 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13939 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13940 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13942 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13943 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13944 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13945 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13946 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13947 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13948 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13949 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13952 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13953 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13957 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13958 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13959 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13960 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13964 /* 32-bit SVR4 quad floating point routines. */
13966 set_optab_libfunc (add_optab, TFmode, "_q_add");
13967 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13968 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13969 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13970 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13971 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13972 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13974 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13975 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13976 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13977 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13978 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13979 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13981 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13982 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13983 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13984 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13985 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13986 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13987 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13988 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
13993 /* Expand a block clear operation, and return 1 if successful. Return 0
13994 if we should let the compiler generate normal code.
13996 operands[0] is the destination
13997 operands[1] is the length
13998 operands[3] is the alignment */
14001 expand_block_clear (rtx operands[])
14003 rtx orig_dest = operands[0];
14004 rtx bytes_rtx = operands[1];
14005 rtx align_rtx = operands[3];
14006 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14007 HOST_WIDE_INT align;
14008 HOST_WIDE_INT bytes;
14013 /* If this is not a fixed size move, just call memcpy */
14017 /* This must be a fixed size alignment */
14018 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14019 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14021 /* Anything to clear? */
14022 bytes = INTVAL (bytes_rtx);
14026 /* Use the builtin memset after a point, to avoid huge code bloat.
14027 When optimize_size, avoid any significant code bloat; calling
14028 memset is about 4 instructions, so allow for one instruction to
14029 load zero and three to do clearing. */
14030 if (TARGET_ALTIVEC && align >= 128)
14032 else if (TARGET_POWERPC64 && align >= 32)
14034 else if (TARGET_SPE && align >= 64)
14039 if (optimize_size && bytes > 3 * clear_step)
14041 if (! optimize_size && bytes > 8 * clear_step)
14044 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14046 enum machine_mode mode = BLKmode;
14049 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14054 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14059 else if (bytes >= 8 && TARGET_POWERPC64
14060 /* 64-bit loads and stores require word-aligned
14062 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14067 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14068 { /* move 4 bytes */
14072 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14073 { /* move 2 bytes */
14077 else /* move 1 byte at a time */
14083 dest = adjust_address (orig_dest, mode, offset);
14085 emit_move_insn (dest, CONST0_RTX (mode));
14092 /* Expand a block move operation, and return 1 if successful. Return 0
14093 if we should let the compiler generate normal code.
14095 operands[0] is the destination
14096 operands[1] is the source
14097 operands[2] is the length
14098 operands[3] is the alignment */
14100 #define MAX_MOVE_REG 4
14103 expand_block_move (rtx operands[])
14105 rtx orig_dest = operands[0];
14106 rtx orig_src = operands[1];
14107 rtx bytes_rtx = operands[2];
14108 rtx align_rtx = operands[3];
14109 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14114 rtx stores[MAX_MOVE_REG];
14117 /* If this is not a fixed size move, just call memcpy */
14121 /* This must be a fixed size alignment */
14122 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14123 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14125 /* Anything to move? */
14126 bytes = INTVAL (bytes_rtx);
14130 if (bytes > rs6000_block_move_inline_limit)
14133 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14136 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14137 rtx (*mov) (rtx, rtx);
14139 enum machine_mode mode = BLKmode;
14142 /* Altivec first, since it will be faster than a string move
14143 when it applies, and usually not significantly larger. */
14144 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14148 gen_func.mov = gen_movv4si;
14150 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14154 gen_func.mov = gen_movv2si;
14156 else if (TARGET_STRING
14157 && bytes > 24 /* move up to 32 bytes at a time */
14163 && ! fixed_regs[10]
14164 && ! fixed_regs[11]
14165 && ! fixed_regs[12])
14167 move_bytes = (bytes > 32) ? 32 : bytes;
14168 gen_func.movmemsi = gen_movmemsi_8reg;
14170 else if (TARGET_STRING
14171 && bytes > 16 /* move up to 24 bytes at a time */
14177 && ! fixed_regs[10])
14179 move_bytes = (bytes > 24) ? 24 : bytes;
14180 gen_func.movmemsi = gen_movmemsi_6reg;
14182 else if (TARGET_STRING
14183 && bytes > 8 /* move up to 16 bytes at a time */
14187 && ! fixed_regs[8])
14189 move_bytes = (bytes > 16) ? 16 : bytes;
14190 gen_func.movmemsi = gen_movmemsi_4reg;
14192 else if (bytes >= 8 && TARGET_POWERPC64
14193 /* 64-bit loads and stores require word-aligned
14195 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14199 gen_func.mov = gen_movdi;
14201 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14202 { /* move up to 8 bytes at a time */
14203 move_bytes = (bytes > 8) ? 8 : bytes;
14204 gen_func.movmemsi = gen_movmemsi_2reg;
14206 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14207 { /* move 4 bytes */
14210 gen_func.mov = gen_movsi;
14212 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14213 { /* move 2 bytes */
14216 gen_func.mov = gen_movhi;
14218 else if (TARGET_STRING && bytes > 1)
14219 { /* move up to 4 bytes at a time */
14220 move_bytes = (bytes > 4) ? 4 : bytes;
14221 gen_func.movmemsi = gen_movmemsi_1reg;
14223 else /* move 1 byte at a time */
14227 gen_func.mov = gen_movqi;
14230 src = adjust_address (orig_src, mode, offset);
14231 dest = adjust_address (orig_dest, mode, offset);
14233 if (mode != BLKmode)
14235 rtx tmp_reg = gen_reg_rtx (mode);
14237 emit_insn ((*gen_func.mov) (tmp_reg, src));
14238 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14241 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14244 for (i = 0; i < num_reg; i++)
14245 emit_insn (stores[i]);
14249 if (mode == BLKmode)
14251 /* Move the address into scratch registers. The movmemsi
14252 patterns require zero offset. */
14253 if (!REG_P (XEXP (src, 0)))
14255 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14256 src = replace_equiv_address (src, src_reg);
14258 set_mem_size (src, GEN_INT (move_bytes));
14260 if (!REG_P (XEXP (dest, 0)))
14262 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14263 dest = replace_equiv_address (dest, dest_reg);
14265 set_mem_size (dest, GEN_INT (move_bytes));
14267 emit_insn ((*gen_func.movmemsi) (dest, src,
14268 GEN_INT (move_bytes & 31),
14277 /* Return a string to perform a load_multiple operation.
14278 operands[0] is the vector.
14279 operands[1] is the source address.
14280 operands[2] is the first destination register. */
14283 rs6000_output_load_multiple (rtx operands[3])
14285 /* We have to handle the case where the pseudo used to contain the address
14286 is assigned to one of the output registers. */
14288 int words = XVECLEN (operands[0], 0);
14291 if (XVECLEN (operands[0], 0) == 1)
14292 return "{l|lwz} %2,0(%1)";
14294 for (i = 0; i < words; i++)
14295 if (refers_to_regno_p (REGNO (operands[2]) + i,
14296 REGNO (operands[2]) + i + 1, operands[1], 0))
14300 xop[0] = GEN_INT (4 * (words-1));
14301 xop[1] = operands[1];
14302 xop[2] = operands[2];
14303 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14308 xop[0] = GEN_INT (4 * (words-1));
14309 xop[1] = operands[1];
14310 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14311 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);
14316 for (j = 0; j < words; j++)
14319 xop[0] = GEN_INT (j * 4);
14320 xop[1] = operands[1];
14321 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14322 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14324 xop[0] = GEN_INT (i * 4);
14325 xop[1] = operands[1];
14326 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14331 return "{lsi|lswi} %2,%1,%N0";
14335 /* A validation routine: say whether CODE, a condition code, and MODE
14336 match. The other alternatives either don't make sense or should
14337 never be generated. */
14340 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14342 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14343 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14344 && GET_MODE_CLASS (mode) == MODE_CC);
14346 /* These don't make sense. */
14347 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14348 || mode != CCUNSmode);
14350 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14351 || mode == CCUNSmode);
14353 gcc_assert (mode == CCFPmode
14354 || (code != ORDERED && code != UNORDERED
14355 && code != UNEQ && code != LTGT
14356 && code != UNGT && code != UNLT
14357 && code != UNGE && code != UNLE));
14359 /* These should never be generated except for
14360 flag_finite_math_only. */
14361 gcc_assert (mode != CCFPmode
14362 || flag_finite_math_only
14363 || (code != LE && code != GE
14364 && code != UNEQ && code != LTGT
14365 && code != UNGT && code != UNLT));
14367 /* These are invalid; the information is not there. */
14368 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14372 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14373 mask required to convert the result of a rotate insn into a shift
14374 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14377 includes_lshift_p (rtx shiftop, rtx andop)
14379 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14381 shift_mask <<= INTVAL (shiftop);
14383 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14386 /* Similar, but for right shift. */
14389 includes_rshift_p (rtx shiftop, rtx andop)
14391 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14393 shift_mask >>= INTVAL (shiftop);
14395 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14398 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14399 to perform a left shift. It must have exactly SHIFTOP least
14400 significant 0's, then one or more 1's, then zero or more 0's. */
14403 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14405 if (GET_CODE (andop) == CONST_INT)
14407 HOST_WIDE_INT c, lsb, shift_mask;
14409 c = INTVAL (andop);
14410 if (c == 0 || c == ~0)
14414 shift_mask <<= INTVAL (shiftop);
14416 /* Find the least significant one bit. */
14419 /* It must coincide with the LSB of the shift mask. */
14420 if (-lsb != shift_mask)
14423 /* Invert to look for the next transition (if any). */
14426 /* Remove the low group of ones (originally low group of zeros). */
14429 /* Again find the lsb, and check we have all 1's above. */
14433 else if (GET_CODE (andop) == CONST_DOUBLE
14434 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14436 HOST_WIDE_INT low, high, lsb;
14437 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14439 low = CONST_DOUBLE_LOW (andop);
14440 if (HOST_BITS_PER_WIDE_INT < 64)
14441 high = CONST_DOUBLE_HIGH (andop);
14443 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14444 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14447 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14449 shift_mask_high = ~0;
14450 if (INTVAL (shiftop) > 32)
14451 shift_mask_high <<= INTVAL (shiftop) - 32;
14453 lsb = high & -high;
14455 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14461 lsb = high & -high;
14462 return high == -lsb;
14465 shift_mask_low = ~0;
14466 shift_mask_low <<= INTVAL (shiftop);
14470 if (-lsb != shift_mask_low)
14473 if (HOST_BITS_PER_WIDE_INT < 64)
14478 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14480 lsb = high & -high;
14481 return high == -lsb;
14485 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14491 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14492 to perform a left shift. It must have SHIFTOP or more least
14493 significant 0's, with the remainder of the word 1's. */
14496 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14498 if (GET_CODE (andop) == CONST_INT)
14500 HOST_WIDE_INT c, lsb, shift_mask;
14503 shift_mask <<= INTVAL (shiftop);
14504 c = INTVAL (andop);
14506 /* Find the least significant one bit. */
14509 /* It must be covered by the shift mask.
14510 This test also rejects c == 0. */
14511 if ((lsb & shift_mask) == 0)
14514 /* Check we have all 1's above the transition, and reject all 1's. */
14515 return c == -lsb && lsb != 1;
14517 else if (GET_CODE (andop) == CONST_DOUBLE
14518 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14520 HOST_WIDE_INT low, lsb, shift_mask_low;
14522 low = CONST_DOUBLE_LOW (andop);
14524 if (HOST_BITS_PER_WIDE_INT < 64)
14526 HOST_WIDE_INT high, shift_mask_high;
14528 high = CONST_DOUBLE_HIGH (andop);
14532 shift_mask_high = ~0;
14533 if (INTVAL (shiftop) > 32)
14534 shift_mask_high <<= INTVAL (shiftop) - 32;
14536 lsb = high & -high;
14538 if ((lsb & shift_mask_high) == 0)
14541 return high == -lsb;
14547 shift_mask_low = ~0;
14548 shift_mask_low <<= INTVAL (shiftop);
14552 if ((lsb & shift_mask_low) == 0)
14555 return low == -lsb && lsb != 1;
14561 /* Return 1 if operands will generate a valid arguments to rlwimi
14562 instruction for insert with right shift in 64-bit mode. The mask may
14563 not start on the first bit or stop on the last bit because wrap-around
14564 effects of instruction do not correspond to semantics of RTL insn. */
14567 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14569 if (INTVAL (startop) > 32
14570 && INTVAL (startop) < 64
14571 && INTVAL (sizeop) > 1
14572 && INTVAL (sizeop) + INTVAL (startop) < 64
14573 && INTVAL (shiftop) > 0
14574 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14575 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14581 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14582 for lfq and stfq insns iff the registers are hard registers. */
14585 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14587 /* We might have been passed a SUBREG. */
14588 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14591 /* We might have been passed non floating point registers. */
14592 if (!FP_REGNO_P (REGNO (reg1))
14593 || !FP_REGNO_P (REGNO (reg2)))
14596 return (REGNO (reg1) == REGNO (reg2) - 1);
14599 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14600 addr1 and addr2 must be in consecutive memory locations
14601 (addr2 == addr1 + 8). */
14604 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14607 unsigned int reg1, reg2;
14608 int offset1, offset2;
14610 /* The mems cannot be volatile. */
14611 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14614 addr1 = XEXP (mem1, 0);
14615 addr2 = XEXP (mem2, 0);
14617 /* Extract an offset (if used) from the first addr. */
14618 if (GET_CODE (addr1) == PLUS)
14620 /* If not a REG, return zero. */
14621 if (GET_CODE (XEXP (addr1, 0)) != REG)
14625 reg1 = REGNO (XEXP (addr1, 0));
14626 /* The offset must be constant! */
14627 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14629 offset1 = INTVAL (XEXP (addr1, 1));
14632 else if (GET_CODE (addr1) != REG)
14636 reg1 = REGNO (addr1);
14637 /* This was a simple (mem (reg)) expression. Offset is 0. */
14641 /* And now for the second addr. */
14642 if (GET_CODE (addr2) == PLUS)
14644 /* If not a REG, return zero. */
14645 if (GET_CODE (XEXP (addr2, 0)) != REG)
14649 reg2 = REGNO (XEXP (addr2, 0));
14650 /* The offset must be constant. */
14651 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14653 offset2 = INTVAL (XEXP (addr2, 1));
14656 else if (GET_CODE (addr2) != REG)
14660 reg2 = REGNO (addr2);
14661 /* This was a simple (mem (reg)) expression. Offset is 0. */
14665 /* Both of these must have the same base register. */
14669 /* The offset for the second addr must be 8 more than the first addr. */
14670 if (offset2 != offset1 + 8)
14673 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14680 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14682 static bool eliminated = false;
14685 if (mode != SDmode)
14686 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14689 rtx mem = cfun->machine->sdmode_stack_slot;
14690 gcc_assert (mem != NULL_RTX);
14694 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14695 cfun->machine->sdmode_stack_slot = mem;
14701 if (TARGET_DEBUG_ADDR)
14703 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14704 GET_MODE_NAME (mode));
14706 fprintf (stderr, "\tNULL_RTX\n");
14715 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14717 /* Don't walk into types. */
14718 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14720 *walk_subtrees = 0;
14724 switch (TREE_CODE (*tp))
14733 case VIEW_CONVERT_EXPR:
14734 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14744 enum reload_reg_type {
14746 VECTOR_REGISTER_TYPE,
14747 OTHER_REGISTER_TYPE
14750 static enum reload_reg_type
14751 rs6000_reload_register_type (enum reg_class rclass)
14757 return GPR_REGISTER_TYPE;
14762 return VECTOR_REGISTER_TYPE;
14765 return OTHER_REGISTER_TYPE;
14769 /* Inform reload about cases where moving X with a mode MODE to a register in
14770 RCLASS requires an extra scratch or immediate register. Return the class
14771 needed for the immediate register.
14773 For VSX and Altivec, we may need a register to convert sp+offset into
14776 For misaligned 64-bit gpr loads and stores we need a register to
14777 convert an offset address to indirect. */
14780 rs6000_secondary_reload (bool in_p,
14782 reg_class_t rclass_i,
14783 enum machine_mode mode,
14784 secondary_reload_info *sri)
14786 enum reg_class rclass = (enum reg_class) rclass_i;
14787 reg_class_t ret = ALL_REGS;
14788 enum insn_code icode;
14789 bool default_p = false;
14791 sri->icode = CODE_FOR_nothing;
14793 /* Convert vector loads and stores into gprs to use an additional base
14795 icode = rs6000_vector_reload[mode][in_p != false];
14796 if (icode != CODE_FOR_nothing)
14799 sri->icode = CODE_FOR_nothing;
14800 sri->extra_cost = 0;
14802 if (GET_CODE (x) == MEM)
14804 rtx addr = XEXP (x, 0);
14806 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14807 an extra register in that case, but it would need an extra
14808 register if the addressing is reg+reg or (reg+reg)&(-16). */
14809 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14811 if (!legitimate_indirect_address_p (addr, false)
14812 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14814 sri->icode = icode;
14815 /* account for splitting the loads, and converting the
14816 address from reg+reg to reg. */
14817 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14818 + ((GET_CODE (addr) == AND) ? 1 : 0));
14821 /* Loads to and stores from vector registers can only do reg+reg
14822 addressing. Altivec registers can also do (reg+reg)&(-16). */
14823 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14824 || rclass == FLOAT_REGS || rclass == NO_REGS)
14826 if (!VECTOR_MEM_ALTIVEC_P (mode)
14827 && GET_CODE (addr) == AND
14828 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14829 && INTVAL (XEXP (addr, 1)) == -16
14830 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14831 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14833 sri->icode = icode;
14834 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14837 else if (!legitimate_indirect_address_p (addr, false)
14838 && (rclass == NO_REGS
14839 || !legitimate_indexed_address_p (addr, false)))
14841 sri->icode = icode;
14842 sri->extra_cost = 1;
14845 icode = CODE_FOR_nothing;
14847 /* Any other loads, including to pseudo registers which haven't been
14848 assigned to a register yet, default to require a scratch
14852 sri->icode = icode;
14853 sri->extra_cost = 2;
14856 else if (REG_P (x))
14858 int regno = true_regnum (x);
14860 icode = CODE_FOR_nothing;
14861 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14865 enum reg_class xclass = REGNO_REG_CLASS (regno);
14866 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14867 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14869 /* If memory is needed, use default_secondary_reload to create the
14871 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14880 else if (TARGET_POWERPC64
14881 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14883 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14885 rtx addr = XEXP (x, 0);
14887 if (GET_CODE (addr) == PRE_MODIFY)
14888 addr = XEXP (addr, 1);
14889 else if (GET_CODE (addr) == LO_SUM
14890 && GET_CODE (XEXP (addr, 0)) == REG
14891 && GET_CODE (XEXP (addr, 1)) == CONST)
14892 addr = XEXP (XEXP (addr, 1), 0);
14894 if (GET_CODE (addr) == PLUS
14895 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14896 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14899 sri->icode = CODE_FOR_reload_di_load;
14901 sri->icode = CODE_FOR_reload_di_store;
14902 sri->extra_cost = 2;
14912 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14914 gcc_assert (ret != ALL_REGS);
14916 if (TARGET_DEBUG_ADDR)
14919 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14921 reg_class_names[ret],
14922 in_p ? "true" : "false",
14923 reg_class_names[rclass],
14924 GET_MODE_NAME (mode));
14927 fprintf (stderr, ", default secondary reload");
14929 if (sri->icode != CODE_FOR_nothing)
14930 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14931 insn_data[sri->icode].name, sri->extra_cost);
14933 fprintf (stderr, "\n");
14941 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14942 to SP+reg addressing. */
14945 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14947 int regno = true_regnum (reg);
14948 enum machine_mode mode = GET_MODE (reg);
14949 enum reg_class rclass;
14951 rtx and_op2 = NULL_RTX;
14954 rtx scratch_or_premodify = scratch;
14958 if (TARGET_DEBUG_ADDR)
14960 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14961 store_p ? "store" : "load");
14962 fprintf (stderr, "reg:\n");
14964 fprintf (stderr, "mem:\n");
14966 fprintf (stderr, "scratch:\n");
14967 debug_rtx (scratch);
14970 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14971 gcc_assert (GET_CODE (mem) == MEM);
14972 rclass = REGNO_REG_CLASS (regno);
14973 addr = XEXP (mem, 0);
14977 /* GPRs can handle reg + small constant, all other addresses need to use
14978 the scratch register. */
14981 if (GET_CODE (addr) == AND)
14983 and_op2 = XEXP (addr, 1);
14984 addr = XEXP (addr, 0);
14987 if (GET_CODE (addr) == PRE_MODIFY)
14989 scratch_or_premodify = XEXP (addr, 0);
14990 gcc_assert (REG_P (scratch_or_premodify));
14991 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
14992 addr = XEXP (addr, 1);
14995 if (GET_CODE (addr) == PLUS
14996 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
14997 || and_op2 != NULL_RTX))
14999 addr_op1 = XEXP (addr, 0);
15000 addr_op2 = XEXP (addr, 1);
15001 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15003 if (!REG_P (addr_op2)
15004 && (GET_CODE (addr_op2) != CONST_INT
15005 || !satisfies_constraint_I (addr_op2)))
15007 if (TARGET_DEBUG_ADDR)
15010 "\nMove plus addr to register %s, mode = %s: ",
15011 rs6000_reg_names[REGNO (scratch)],
15012 GET_MODE_NAME (mode));
15013 debug_rtx (addr_op2);
15015 rs6000_emit_move (scratch, addr_op2, Pmode);
15016 addr_op2 = scratch;
15019 emit_insn (gen_rtx_SET (VOIDmode,
15020 scratch_or_premodify,
15021 gen_rtx_PLUS (Pmode,
15025 addr = scratch_or_premodify;
15026 scratch_or_premodify = scratch;
15028 else if (!legitimate_indirect_address_p (addr, false)
15029 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15031 if (TARGET_DEBUG_ADDR)
15033 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15034 rs6000_reg_names[REGNO (scratch_or_premodify)],
15035 GET_MODE_NAME (mode));
15038 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15039 addr = scratch_or_premodify;
15040 scratch_or_premodify = scratch;
15044 /* Float/Altivec registers can only handle reg+reg addressing. Move
15045 other addresses into a scratch register. */
15050 /* With float regs, we need to handle the AND ourselves, since we can't
15051 use the Altivec instruction with an implicit AND -16. Allow scalar
15052 loads to float registers to use reg+offset even if VSX. */
15053 if (GET_CODE (addr) == AND
15054 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15055 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15056 || INTVAL (XEXP (addr, 1)) != -16
15057 || !VECTOR_MEM_ALTIVEC_P (mode)))
15059 and_op2 = XEXP (addr, 1);
15060 addr = XEXP (addr, 0);
15063 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15064 as the address later. */
15065 if (GET_CODE (addr) == PRE_MODIFY
15066 && (!VECTOR_MEM_VSX_P (mode)
15067 || and_op2 != NULL_RTX
15068 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15070 scratch_or_premodify = XEXP (addr, 0);
15071 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15073 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15074 addr = XEXP (addr, 1);
15077 if (legitimate_indirect_address_p (addr, false) /* reg */
15078 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15079 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15080 || (GET_CODE (addr) == AND /* Altivec memory */
15081 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15082 && INTVAL (XEXP (addr, 1)) == -16
15083 && VECTOR_MEM_ALTIVEC_P (mode))
15084 || (rclass == FLOAT_REGS /* legacy float mem */
15085 && GET_MODE_SIZE (mode) == 8
15086 && and_op2 == NULL_RTX
15087 && scratch_or_premodify == scratch
15088 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15091 else if (GET_CODE (addr) == PLUS)
15093 addr_op1 = XEXP (addr, 0);
15094 addr_op2 = XEXP (addr, 1);
15095 gcc_assert (REG_P (addr_op1));
15097 if (TARGET_DEBUG_ADDR)
15099 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15100 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15101 debug_rtx (addr_op2);
15103 rs6000_emit_move (scratch, addr_op2, Pmode);
15104 emit_insn (gen_rtx_SET (VOIDmode,
15105 scratch_or_premodify,
15106 gen_rtx_PLUS (Pmode,
15109 addr = scratch_or_premodify;
15110 scratch_or_premodify = scratch;
15113 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15114 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15116 if (TARGET_DEBUG_ADDR)
15118 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15119 rs6000_reg_names[REGNO (scratch_or_premodify)],
15120 GET_MODE_NAME (mode));
15124 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15125 addr = scratch_or_premodify;
15126 scratch_or_premodify = scratch;
15130 gcc_unreachable ();
15135 gcc_unreachable ();
15138 /* If the original address involved a pre-modify that we couldn't use the VSX
15139 memory instruction with update, and we haven't taken care of already,
15140 store the address in the pre-modify register and use that as the
15142 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15144 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15145 addr = scratch_or_premodify;
15148 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15149 memory instruction, recreate the AND now, including the clobber which is
15150 generated by the general ANDSI3/ANDDI3 patterns for the
15151 andi. instruction. */
15152 if (and_op2 != NULL_RTX)
15154 if (! legitimate_indirect_address_p (addr, false))
15156 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15160 if (TARGET_DEBUG_ADDR)
15162 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15163 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15164 debug_rtx (and_op2);
15167 and_rtx = gen_rtx_SET (VOIDmode,
15169 gen_rtx_AND (Pmode,
15173 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15174 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15175 gen_rtvec (2, and_rtx, cc_clobber)));
15179 /* Adjust the address if it changed. */
15180 if (addr != XEXP (mem, 0))
15182 mem = change_address (mem, mode, addr);
15183 if (TARGET_DEBUG_ADDR)
15184 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15187 /* Now create the move. */
15189 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15191 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15196 /* Convert reloads involving 64-bit gprs and misaligned offset
15197 addressing to use indirect addressing. */
15200 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
15202 int regno = true_regnum (reg);
15203 enum reg_class rclass;
15205 rtx scratch_or_premodify = scratch;
15207 if (TARGET_DEBUG_ADDR)
15209 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
15210 store_p ? "store" : "load");
15211 fprintf (stderr, "reg:\n");
15213 fprintf (stderr, "mem:\n");
15215 fprintf (stderr, "scratch:\n");
15216 debug_rtx (scratch);
15219 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
15220 gcc_assert (GET_CODE (mem) == MEM);
15221 rclass = REGNO_REG_CLASS (regno);
15222 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
15223 addr = XEXP (mem, 0);
15225 if (GET_CODE (addr) == PRE_MODIFY)
15227 scratch_or_premodify = XEXP (addr, 0);
15228 gcc_assert (REG_P (scratch_or_premodify));
15229 addr = XEXP (addr, 1);
15231 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
15233 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15235 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
15237 /* Now create the move. */
15239 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15241 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15246 /* Allocate a 64-bit stack slot to be used for copying SDmode
15247 values through if this function has any SDmode references. */
15250 rs6000_alloc_sdmode_stack_slot (void)
15254 gimple_stmt_iterator gsi;
15256 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15259 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15261 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15264 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15265 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15271 /* Check for any SDmode parameters of the function. */
15272 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15274 if (TREE_TYPE (t) == error_mark_node)
15277 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15278 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15280 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15281 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15289 rs6000_instantiate_decls (void)
15291 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15292 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15295 /* Given an rtx X being reloaded into a reg required to be
15296 in class CLASS, return the class of reg to actually use.
15297 In general this is just CLASS; but on some machines
15298 in some cases it is preferable to use a more restrictive class.
15300 On the RS/6000, we have to return NO_REGS when we want to reload a
15301 floating-point CONST_DOUBLE to force it to be copied to memory.
15303 We also don't want to reload integer values into floating-point
15304 registers if we can at all help it. In fact, this can
15305 cause reload to die, if it tries to generate a reload of CTR
15306 into a FP register and discovers it doesn't have the memory location
15309 ??? Would it be a good idea to have reload do the converse, that is
15310 try to reload floating modes into FP registers if possible?
15313 static enum reg_class
15314 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15316 enum machine_mode mode = GET_MODE (x);
15318 if (VECTOR_UNIT_VSX_P (mode)
15319 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15322 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15323 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15324 && easy_vector_constant (x, mode))
15325 return ALTIVEC_REGS;
15327 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15330 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15331 return GENERAL_REGS;
15333 /* For VSX, prefer the traditional registers for 64-bit values because we can
15334 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15335 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15336 prefer Altivec loads.. */
15337 if (rclass == VSX_REGS)
15339 if (GET_MODE_SIZE (mode) <= 8)
15342 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15343 return ALTIVEC_REGS;
15351 /* Debug version of rs6000_preferred_reload_class. */
15352 static enum reg_class
15353 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15355 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15358 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15360 reg_class_names[ret], reg_class_names[rclass],
15361 GET_MODE_NAME (GET_MODE (x)));
15367 /* If we are copying between FP or AltiVec registers and anything else, we need
15368 a memory location. The exception is when we are targeting ppc64 and the
15369 move to/from fpr to gpr instructions are available. Also, under VSX, you
15370 can copy vector registers from the FP register set to the Altivec register
15371 set and vice versa. */
15374 rs6000_secondary_memory_needed (enum reg_class class1,
15375 enum reg_class class2,
15376 enum machine_mode mode)
15378 if (class1 == class2)
15381 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15382 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15383 between these classes. But we need memory for other things that can go in
15384 FLOAT_REGS like SFmode. */
15386 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15387 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15388 || class1 == FLOAT_REGS))
15389 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15390 && class2 != FLOAT_REGS);
15392 if (class1 == VSX_REGS || class2 == VSX_REGS)
15395 if (class1 == FLOAT_REGS
15396 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15397 || ((mode != DFmode)
15398 && (mode != DDmode)
15399 && (mode != DImode))))
15402 if (class2 == FLOAT_REGS
15403 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15404 || ((mode != DFmode)
15405 && (mode != DDmode)
15406 && (mode != DImode))))
15409 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15415 /* Debug version of rs6000_secondary_memory_needed. */
15417 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15418 enum reg_class class2,
15419 enum machine_mode mode)
15421 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15424 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15425 "class2 = %s, mode = %s\n",
15426 ret ? "true" : "false", reg_class_names[class1],
15427 reg_class_names[class2], GET_MODE_NAME (mode));
15432 /* Return the register class of a scratch register needed to copy IN into
15433 or out of a register in RCLASS in MODE. If it can be done directly,
15434 NO_REGS is returned. */
15436 static enum reg_class
15437 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15442 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15444 && MACHOPIC_INDIRECT
15448 /* We cannot copy a symbolic operand directly into anything
15449 other than BASE_REGS for TARGET_ELF. So indicate that a
15450 register from BASE_REGS is needed as an intermediate
15453 On Darwin, pic addresses require a load from memory, which
15454 needs a base register. */
15455 if (rclass != BASE_REGS
15456 && (GET_CODE (in) == SYMBOL_REF
15457 || GET_CODE (in) == HIGH
15458 || GET_CODE (in) == LABEL_REF
15459 || GET_CODE (in) == CONST))
15463 if (GET_CODE (in) == REG)
15465 regno = REGNO (in);
15466 if (regno >= FIRST_PSEUDO_REGISTER)
15468 regno = true_regnum (in);
15469 if (regno >= FIRST_PSEUDO_REGISTER)
15473 else if (GET_CODE (in) == SUBREG)
15475 regno = true_regnum (in);
15476 if (regno >= FIRST_PSEUDO_REGISTER)
15482 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15484 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15485 || (regno >= 0 && INT_REGNO_P (regno)))
15488 /* Constants, memory, and FP registers can go into FP registers. */
15489 if ((regno == -1 || FP_REGNO_P (regno))
15490 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15491 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15493 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15496 && (regno == -1 || VSX_REGNO_P (regno))
15497 && VSX_REG_CLASS_P (rclass))
15500 /* Memory, and AltiVec registers can go into AltiVec registers. */
15501 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15502 && rclass == ALTIVEC_REGS)
15505 /* We can copy among the CR registers. */
15506 if ((rclass == CR_REGS || rclass == CR0_REGS)
15507 && regno >= 0 && CR_REGNO_P (regno))
15510 /* Otherwise, we need GENERAL_REGS. */
15511 return GENERAL_REGS;
15514 /* Debug version of rs6000_secondary_reload_class. */
15515 static enum reg_class
15516 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15517 enum machine_mode mode, rtx in)
15519 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15521 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15522 "mode = %s, input rtx:\n",
15523 reg_class_names[ret], reg_class_names[rclass],
15524 GET_MODE_NAME (mode));
15530 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15533 rs6000_cannot_change_mode_class (enum machine_mode from,
15534 enum machine_mode to,
15535 enum reg_class rclass)
15537 unsigned from_size = GET_MODE_SIZE (from);
15538 unsigned to_size = GET_MODE_SIZE (to);
15540 if (from_size != to_size)
15542 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15543 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15544 && reg_classes_intersect_p (xclass, rclass));
15547 if (TARGET_E500_DOUBLE
15548 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15549 || (((to) == TFmode) + ((from) == TFmode)) == 1
15550 || (((to) == DDmode) + ((from) == DDmode)) == 1
15551 || (((to) == TDmode) + ((from) == TDmode)) == 1
15552 || (((to) == DImode) + ((from) == DImode)) == 1))
15555 /* Since the VSX register set includes traditional floating point registers
15556 and altivec registers, just check for the size being different instead of
15557 trying to check whether the modes are vector modes. Otherwise it won't
15558 allow say DF and DI to change classes. */
15559 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15560 return (from_size != 8 && from_size != 16);
15562 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15563 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15566 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15567 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15573 /* Debug version of rs6000_cannot_change_mode_class. */
15575 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15576 enum machine_mode to,
15577 enum reg_class rclass)
15579 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15582 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15583 "to = %s, rclass = %s\n",
15584 ret ? "true" : "false",
15585 GET_MODE_NAME (from), GET_MODE_NAME (to),
15586 reg_class_names[rclass]);
15591 /* Given a comparison operation, return the bit number in CCR to test. We
15592 know this is a valid comparison.
15594 SCC_P is 1 if this is for an scc. That means that %D will have been
15595 used instead of %C, so the bits will be in different places.
15597 Return -1 if OP isn't a valid comparison for some reason. */
15600 ccr_bit (rtx op, int scc_p)
15602 enum rtx_code code = GET_CODE (op);
15603 enum machine_mode cc_mode;
15608 if (!COMPARISON_P (op))
15611 reg = XEXP (op, 0);
15613 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15615 cc_mode = GET_MODE (reg);
15616 cc_regnum = REGNO (reg);
15617 base_bit = 4 * (cc_regnum - CR0_REGNO);
15619 validate_condition_mode (code, cc_mode);
15621 /* When generating a sCOND operation, only positive conditions are
15624 || code == EQ || code == GT || code == LT || code == UNORDERED
15625 || code == GTU || code == LTU);
15630 return scc_p ? base_bit + 3 : base_bit + 2;
15632 return base_bit + 2;
15633 case GT: case GTU: case UNLE:
15634 return base_bit + 1;
15635 case LT: case LTU: case UNGE:
15637 case ORDERED: case UNORDERED:
15638 return base_bit + 3;
15641 /* If scc, we will have done a cror to put the bit in the
15642 unordered position. So test that bit. For integer, this is ! LT
15643 unless this is an scc insn. */
15644 return scc_p ? base_bit + 3 : base_bit;
15647 return scc_p ? base_bit + 3 : base_bit + 1;
15650 gcc_unreachable ();
15654 /* Return the GOT register. */
15657 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15659 /* The second flow pass currently (June 1999) can't update
15660 regs_ever_live without disturbing other parts of the compiler, so
15661 update it here to make the prolog/epilogue code happy. */
15662 if (!can_create_pseudo_p ()
15663 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15664 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15666 crtl->uses_pic_offset_table = 1;
15668 return pic_offset_table_rtx;
15671 static rs6000_stack_t stack_info;
15673 /* Function to init struct machine_function.
15674 This will be called, via a pointer variable,
15675 from push_function_context. */
15677 static struct machine_function *
15678 rs6000_init_machine_status (void)
15680 stack_info.reload_completed = 0;
15681 return ggc_alloc_cleared_machine_function ();
15684 /* These macros test for integers and extract the low-order bits. */
15686 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15687 && GET_MODE (X) == VOIDmode)
15689 #define INT_LOWPART(X) \
15690 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15693 extract_MB (rtx op)
15696 unsigned long val = INT_LOWPART (op);
15698 /* If the high bit is zero, the value is the first 1 bit we find
15700 if ((val & 0x80000000) == 0)
15702 gcc_assert (val & 0xffffffff);
15705 while (((val <<= 1) & 0x80000000) == 0)
15710 /* If the high bit is set and the low bit is not, or the mask is all
15711 1's, the value is zero. */
15712 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15715 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15718 while (((val >>= 1) & 1) != 0)
15725 extract_ME (rtx op)
15728 unsigned long val = INT_LOWPART (op);
15730 /* If the low bit is zero, the value is the first 1 bit we find from
15732 if ((val & 1) == 0)
15734 gcc_assert (val & 0xffffffff);
15737 while (((val >>= 1) & 1) == 0)
15743 /* If the low bit is set and the high bit is not, or the mask is all
15744 1's, the value is 31. */
15745 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15748 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15751 while (((val <<= 1) & 0x80000000) != 0)
15757 /* Locate some local-dynamic symbol still in use by this function
15758 so that we can print its name in some tls_ld pattern. */
15760 static const char *
15761 rs6000_get_some_local_dynamic_name (void)
15765 if (cfun->machine->some_ld_name)
15766 return cfun->machine->some_ld_name;
15768 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15770 && for_each_rtx (&PATTERN (insn),
15771 rs6000_get_some_local_dynamic_name_1, 0))
15772 return cfun->machine->some_ld_name;
15774 gcc_unreachable ();
15777 /* Helper function for rs6000_get_some_local_dynamic_name. */
15780 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15784 if (GET_CODE (x) == SYMBOL_REF)
15786 const char *str = XSTR (x, 0);
15787 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15789 cfun->machine->some_ld_name = str;
15797 /* Write out a function code label. */
15800 rs6000_output_function_entry (FILE *file, const char *fname)
15802 if (fname[0] != '.')
15804 switch (DEFAULT_ABI)
15807 gcc_unreachable ();
15813 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15822 RS6000_OUTPUT_BASENAME (file, fname);
15825 /* Print an operand. Recognize special options, documented below. */
15828 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15829 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15831 #define SMALL_DATA_RELOC "sda21"
15832 #define SMALL_DATA_REG 0
15836 print_operand (FILE *file, rtx x, int code)
15840 unsigned HOST_WIDE_INT uval;
15845 /* Write out an instruction after the call which may be replaced
15846 with glue code by the loader. This depends on the AIX version. */
15847 asm_fprintf (file, RS6000_CALL_GLUE);
15850 /* %a is output_address. */
15853 /* If X is a constant integer whose low-order 5 bits are zero,
15854 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15855 in the AIX assembler where "sri" with a zero shift count
15856 writes a trash instruction. */
15857 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15864 /* If constant, low-order 16 bits of constant, unsigned.
15865 Otherwise, write normally. */
15867 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15869 print_operand (file, x, 0);
15873 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15874 for 64-bit mask direction. */
15875 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15878 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15882 /* X is a CR register. Print the number of the GT bit of the CR. */
15883 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15884 output_operand_lossage ("invalid %%c value");
15886 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15890 /* Like 'J' but get to the GT bit only. */
15891 gcc_assert (GET_CODE (x) == REG);
15893 /* Bit 1 is GT bit. */
15894 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15896 /* Add one for shift count in rlinm for scc. */
15897 fprintf (file, "%d", i + 1);
15901 /* X is a CR register. Print the number of the EQ bit of the CR */
15902 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15903 output_operand_lossage ("invalid %%E value");
15905 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15909 /* X is a CR register. Print the shift count needed to move it
15910 to the high-order four bits. */
15911 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15912 output_operand_lossage ("invalid %%f value");
15914 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15918 /* Similar, but print the count for the rotate in the opposite
15920 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15921 output_operand_lossage ("invalid %%F value");
15923 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15927 /* X is a constant integer. If it is negative, print "m",
15928 otherwise print "z". This is to make an aze or ame insn. */
15929 if (GET_CODE (x) != CONST_INT)
15930 output_operand_lossage ("invalid %%G value");
15931 else if (INTVAL (x) >= 0)
15938 /* If constant, output low-order five bits. Otherwise, write
15941 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15943 print_operand (file, x, 0);
15947 /* If constant, output low-order six bits. Otherwise, write
15950 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15952 print_operand (file, x, 0);
15956 /* Print `i' if this is a constant, else nothing. */
15962 /* Write the bit number in CCR for jump. */
15963 i = ccr_bit (x, 0);
15965 output_operand_lossage ("invalid %%j code");
15967 fprintf (file, "%d", i);
15971 /* Similar, but add one for shift count in rlinm for scc and pass
15972 scc flag to `ccr_bit'. */
15973 i = ccr_bit (x, 1);
15975 output_operand_lossage ("invalid %%J code");
15977 /* If we want bit 31, write a shift count of zero, not 32. */
15978 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15982 /* X must be a constant. Write the 1's complement of the
15985 output_operand_lossage ("invalid %%k value");
15987 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
15991 /* X must be a symbolic constant on ELF. Write an
15992 expression suitable for an 'addi' that adds in the low 16
15993 bits of the MEM. */
15994 if (GET_CODE (x) == CONST)
15996 if (GET_CODE (XEXP (x, 0)) != PLUS
15997 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
15998 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
15999 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
16000 output_operand_lossage ("invalid %%K value");
16002 print_operand_address (file, x);
16003 fputs ("@l", file);
16006 /* %l is output_asm_label. */
16009 /* Write second word of DImode or DFmode reference. Works on register
16010 or non-indexed memory only. */
16011 if (GET_CODE (x) == REG)
16012 fputs (reg_names[REGNO (x) + 1], file);
16013 else if (GET_CODE (x) == MEM)
16015 /* Handle possible auto-increment. Since it is pre-increment and
16016 we have already done it, we can just use an offset of word. */
16017 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16018 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16019 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16021 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16022 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16025 output_address (XEXP (adjust_address_nv (x, SImode,
16029 if (small_data_operand (x, GET_MODE (x)))
16030 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16031 reg_names[SMALL_DATA_REG]);
16036 /* MB value for a mask operand. */
16037 if (! mask_operand (x, SImode))
16038 output_operand_lossage ("invalid %%m value");
16040 fprintf (file, "%d", extract_MB (x));
16044 /* ME value for a mask operand. */
16045 if (! mask_operand (x, SImode))
16046 output_operand_lossage ("invalid %%M value");
16048 fprintf (file, "%d", extract_ME (x));
16051 /* %n outputs the negative of its operand. */
16054 /* Write the number of elements in the vector times 4. */
16055 if (GET_CODE (x) != PARALLEL)
16056 output_operand_lossage ("invalid %%N value");
16058 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16062 /* Similar, but subtract 1 first. */
16063 if (GET_CODE (x) != PARALLEL)
16064 output_operand_lossage ("invalid %%O value");
16066 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16070 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16072 || INT_LOWPART (x) < 0
16073 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16074 output_operand_lossage ("invalid %%p value");
16076 fprintf (file, "%d", i);
16080 /* The operand must be an indirect memory reference. The result
16081 is the register name. */
16082 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16083 || REGNO (XEXP (x, 0)) >= 32)
16084 output_operand_lossage ("invalid %%P value");
16086 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16090 /* This outputs the logical code corresponding to a boolean
16091 expression. The expression may have one or both operands
16092 negated (if one, only the first one). For condition register
16093 logical operations, it will also treat the negated
16094 CR codes as NOTs, but not handle NOTs of them. */
16096 const char *const *t = 0;
16098 enum rtx_code code = GET_CODE (x);
16099 static const char * const tbl[3][3] = {
16100 { "and", "andc", "nor" },
16101 { "or", "orc", "nand" },
16102 { "xor", "eqv", "xor" } };
16106 else if (code == IOR)
16108 else if (code == XOR)
16111 output_operand_lossage ("invalid %%q value");
16113 if (GET_CODE (XEXP (x, 0)) != NOT)
16117 if (GET_CODE (XEXP (x, 1)) == NOT)
16135 /* X is a CR register. Print the mask for `mtcrf'. */
16136 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16137 output_operand_lossage ("invalid %%R value");
16139 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16143 /* Low 5 bits of 32 - value */
16145 output_operand_lossage ("invalid %%s value");
16147 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16151 /* PowerPC64 mask position. All 0's is excluded.
16152 CONST_INT 32-bit mask is considered sign-extended so any
16153 transition must occur within the CONST_INT, not on the boundary. */
16154 if (! mask64_operand (x, DImode))
16155 output_operand_lossage ("invalid %%S value");
16157 uval = INT_LOWPART (x);
16159 if (uval & 1) /* Clear Left */
16161 #if HOST_BITS_PER_WIDE_INT > 64
16162 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16166 else /* Clear Right */
16169 #if HOST_BITS_PER_WIDE_INT > 64
16170 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16176 gcc_assert (i >= 0);
16177 fprintf (file, "%d", i);
16181 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16182 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16184 /* Bit 3 is OV bit. */
16185 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16187 /* If we want bit 31, write a shift count of zero, not 32. */
16188 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16192 /* Print the symbolic name of a branch target register. */
16193 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16194 && REGNO (x) != CTR_REGNO))
16195 output_operand_lossage ("invalid %%T value");
16196 else if (REGNO (x) == LR_REGNO)
16197 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16199 fputs ("ctr", file);
16203 /* High-order 16 bits of constant for use in unsigned operand. */
16205 output_operand_lossage ("invalid %%u value");
16207 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16208 (INT_LOWPART (x) >> 16) & 0xffff);
16212 /* High-order 16 bits of constant for use in signed operand. */
16214 output_operand_lossage ("invalid %%v value");
16216 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16217 (INT_LOWPART (x) >> 16) & 0xffff);
16221 /* Print `u' if this has an auto-increment or auto-decrement. */
16222 if (GET_CODE (x) == MEM
16223 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16224 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16225 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16230 /* Print the trap code for this operand. */
16231 switch (GET_CODE (x))
16234 fputs ("eq", file); /* 4 */
16237 fputs ("ne", file); /* 24 */
16240 fputs ("lt", file); /* 16 */
16243 fputs ("le", file); /* 20 */
16246 fputs ("gt", file); /* 8 */
16249 fputs ("ge", file); /* 12 */
16252 fputs ("llt", file); /* 2 */
16255 fputs ("lle", file); /* 6 */
16258 fputs ("lgt", file); /* 1 */
16261 fputs ("lge", file); /* 5 */
16264 gcc_unreachable ();
16269 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16272 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16273 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16275 print_operand (file, x, 0);
16279 /* MB value for a PowerPC64 rldic operand. */
16280 val = (GET_CODE (x) == CONST_INT
16281 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16286 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16287 if ((val <<= 1) < 0)
16290 #if HOST_BITS_PER_WIDE_INT == 32
16291 if (GET_CODE (x) == CONST_INT && i >= 0)
16292 i += 32; /* zero-extend high-part was all 0's */
16293 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16295 val = CONST_DOUBLE_LOW (x);
16301 for ( ; i < 64; i++)
16302 if ((val <<= 1) < 0)
16307 fprintf (file, "%d", i + 1);
16311 /* X is a FPR or Altivec register used in a VSX context. */
16312 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16313 output_operand_lossage ("invalid %%x value");
16316 int reg = REGNO (x);
16317 int vsx_reg = (FP_REGNO_P (reg)
16319 : reg - FIRST_ALTIVEC_REGNO + 32);
16321 #ifdef TARGET_REGNAMES
16322 if (TARGET_REGNAMES)
16323 fprintf (file, "%%vs%d", vsx_reg);
16326 fprintf (file, "%d", vsx_reg);
16331 if (GET_CODE (x) == MEM
16332 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16333 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16334 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16339 /* Like 'L', for third word of TImode */
16340 if (GET_CODE (x) == REG)
16341 fputs (reg_names[REGNO (x) + 2], file);
16342 else if (GET_CODE (x) == MEM)
16344 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16345 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16346 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16347 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16348 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16350 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16351 if (small_data_operand (x, GET_MODE (x)))
16352 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16353 reg_names[SMALL_DATA_REG]);
16358 /* X is a SYMBOL_REF. Write out the name preceded by a
16359 period and without any trailing data in brackets. Used for function
16360 names. If we are configured for System V (or the embedded ABI) on
16361 the PowerPC, do not emit the period, since those systems do not use
16362 TOCs and the like. */
16363 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16365 /* Mark the decl as referenced so that cgraph will output the
16367 if (SYMBOL_REF_DECL (x))
16368 mark_decl_referenced (SYMBOL_REF_DECL (x));
16370 /* For macho, check to see if we need a stub. */
16373 const char *name = XSTR (x, 0);
16375 if (darwin_emit_branch_islands
16376 && MACHOPIC_INDIRECT
16377 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16378 name = machopic_indirection_name (x, /*stub_p=*/true);
16380 assemble_name (file, name);
16382 else if (!DOT_SYMBOLS)
16383 assemble_name (file, XSTR (x, 0));
16385 rs6000_output_function_entry (file, XSTR (x, 0));
16389 /* Like 'L', for last word of TImode. */
16390 if (GET_CODE (x) == REG)
16391 fputs (reg_names[REGNO (x) + 3], file);
16392 else if (GET_CODE (x) == MEM)
16394 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16395 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16396 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16397 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16398 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16400 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16401 if (small_data_operand (x, GET_MODE (x)))
16402 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16403 reg_names[SMALL_DATA_REG]);
16407 /* Print AltiVec or SPE memory operand. */
16412 gcc_assert (GET_CODE (x) == MEM);
16416 /* Ugly hack because %y is overloaded. */
16417 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16418 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16419 || GET_MODE (x) == TFmode
16420 || GET_MODE (x) == TImode))
16422 /* Handle [reg]. */
16423 if (GET_CODE (tmp) == REG)
16425 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16428 /* Handle [reg+UIMM]. */
16429 else if (GET_CODE (tmp) == PLUS &&
16430 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16434 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16436 x = INTVAL (XEXP (tmp, 1));
16437 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16441 /* Fall through. Must be [reg+reg]. */
16443 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16444 && GET_CODE (tmp) == AND
16445 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16446 && INTVAL (XEXP (tmp, 1)) == -16)
16447 tmp = XEXP (tmp, 0);
16448 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16449 && GET_CODE (tmp) == PRE_MODIFY)
16450 tmp = XEXP (tmp, 1);
16451 if (GET_CODE (tmp) == REG)
16452 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16455 if (!GET_CODE (tmp) == PLUS
16456 || !REG_P (XEXP (tmp, 0))
16457 || !REG_P (XEXP (tmp, 1)))
16459 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16463 if (REGNO (XEXP (tmp, 0)) == 0)
16464 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16465 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16467 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16468 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16474 if (GET_CODE (x) == REG)
16475 fprintf (file, "%s", reg_names[REGNO (x)]);
16476 else if (GET_CODE (x) == MEM)
16478 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16479 know the width from the mode. */
16480 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16481 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16482 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16483 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16484 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16485 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16486 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16487 output_address (XEXP (XEXP (x, 0), 1));
16489 output_address (XEXP (x, 0));
16493 if (toc_relative_expr_p (x))
16494 /* This hack along with a corresponding hack in
16495 rs6000_output_addr_const_extra arranges to output addends
16496 where the assembler expects to find them. eg.
16497 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16498 without this hack would be output as "x@toc+4". We
16500 output_addr_const (file, tocrel_base);
16502 output_addr_const (file, x);
16507 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16511 output_operand_lossage ("invalid %%xn code");
16515 /* Print the address of an operand. */
16518 print_operand_address (FILE *file, rtx x)
16520 if (GET_CODE (x) == REG)
16521 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16522 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16523 || GET_CODE (x) == LABEL_REF)
16525 output_addr_const (file, x);
16526 if (small_data_operand (x, GET_MODE (x)))
16527 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16528 reg_names[SMALL_DATA_REG]);
16530 gcc_assert (!TARGET_TOC);
16532 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16534 gcc_assert (REG_P (XEXP (x, 0)));
16535 if (REGNO (XEXP (x, 0)) == 0)
16536 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16537 reg_names[ REGNO (XEXP (x, 0)) ]);
16539 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16540 reg_names[ REGNO (XEXP (x, 1)) ]);
16542 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16543 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16544 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16546 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16547 && CONSTANT_P (XEXP (x, 1)))
16549 fprintf (file, "lo16(");
16550 output_addr_const (file, XEXP (x, 1));
16551 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16554 else if (legitimate_constant_pool_address_p (x, QImode, true))
16556 /* This hack along with a corresponding hack in
16557 rs6000_output_addr_const_extra arranges to output addends
16558 where the assembler expects to find them. eg.
16560 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16561 without this hack would be output as "x@toc+8@l(9)". We
16562 want "x+8@toc@l(9)". */
16563 output_addr_const (file, tocrel_base);
16564 if (GET_CODE (x) == LO_SUM)
16565 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16567 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16570 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16571 && CONSTANT_P (XEXP (x, 1)))
16573 output_addr_const (file, XEXP (x, 1));
16574 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16578 gcc_unreachable ();
16581 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16584 rs6000_output_addr_const_extra (FILE *file, rtx x)
16586 if (GET_CODE (x) == UNSPEC)
16587 switch (XINT (x, 1))
16589 case UNSPEC_TOCREL:
16590 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16591 output_addr_const (file, XVECEXP (x, 0, 0));
16592 if (x == tocrel_base && tocrel_offset != const0_rtx)
16594 if (INTVAL (tocrel_offset) >= 0)
16595 fprintf (file, "+");
16596 output_addr_const (file, tocrel_offset);
16598 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16601 assemble_name (file, toc_label_name);
16603 else if (TARGET_ELF)
16604 fputs ("@toc", file);
16608 case UNSPEC_MACHOPIC_OFFSET:
16609 output_addr_const (file, XVECEXP (x, 0, 0));
16611 machopic_output_function_base_name (file);
16618 /* Target hook for assembling integer objects. The PowerPC version has
16619 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16620 is defined. It also needs to handle DI-mode objects on 64-bit
16624 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16626 #ifdef RELOCATABLE_NEEDS_FIXUP
16627 /* Special handling for SI values. */
16628 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16630 static int recurse = 0;
16632 /* For -mrelocatable, we mark all addresses that need to be fixed up
16633 in the .fixup section. */
16634 if (TARGET_RELOCATABLE
16635 && in_section != toc_section
16636 && in_section != text_section
16637 && !unlikely_text_section_p (in_section)
16639 && GET_CODE (x) != CONST_INT
16640 && GET_CODE (x) != CONST_DOUBLE
16646 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16648 ASM_OUTPUT_LABEL (asm_out_file, buf);
16649 fprintf (asm_out_file, "\t.long\t(");
16650 output_addr_const (asm_out_file, x);
16651 fprintf (asm_out_file, ")@fixup\n");
16652 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16653 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16654 fprintf (asm_out_file, "\t.long\t");
16655 assemble_name (asm_out_file, buf);
16656 fprintf (asm_out_file, "\n\t.previous\n");
16660 /* Remove initial .'s to turn a -mcall-aixdesc function
16661 address into the address of the descriptor, not the function
16663 else if (GET_CODE (x) == SYMBOL_REF
16664 && XSTR (x, 0)[0] == '.'
16665 && DEFAULT_ABI == ABI_AIX)
16667 const char *name = XSTR (x, 0);
16668 while (*name == '.')
16671 fprintf (asm_out_file, "\t.long\t%s\n", name);
16675 #endif /* RELOCATABLE_NEEDS_FIXUP */
16676 return default_assemble_integer (x, size, aligned_p);
16679 #ifdef HAVE_GAS_HIDDEN
16680 /* Emit an assembler directive to set symbol visibility for DECL to
16681 VISIBILITY_TYPE. */
16684 rs6000_assemble_visibility (tree decl, int vis)
16686 /* Functions need to have their entry point symbol visibility set as
16687 well as their descriptor symbol visibility. */
16688 if (DEFAULT_ABI == ABI_AIX
16690 && TREE_CODE (decl) == FUNCTION_DECL)
16692 static const char * const visibility_types[] = {
16693 NULL, "internal", "hidden", "protected"
16696 const char *name, *type;
16698 name = ((* targetm.strip_name_encoding)
16699 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16700 type = visibility_types[vis];
16702 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16703 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16706 default_assemble_visibility (decl, vis);
16711 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16713 /* Reversal of FP compares takes care -- an ordered compare
16714 becomes an unordered compare and vice versa. */
16715 if (mode == CCFPmode
16716 && (!flag_finite_math_only
16717 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16718 || code == UNEQ || code == LTGT))
16719 return reverse_condition_maybe_unordered (code);
16721 return reverse_condition (code);
16724 /* Generate a compare for CODE. Return a brand-new rtx that
16725 represents the result of the compare. */
16728 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16730 enum machine_mode comp_mode;
16731 rtx compare_result;
16732 enum rtx_code code = GET_CODE (cmp);
16733 rtx op0 = XEXP (cmp, 0);
16734 rtx op1 = XEXP (cmp, 1);
16736 if (FLOAT_MODE_P (mode))
16737 comp_mode = CCFPmode;
16738 else if (code == GTU || code == LTU
16739 || code == GEU || code == LEU)
16740 comp_mode = CCUNSmode;
16741 else if ((code == EQ || code == NE)
16742 && GET_CODE (op0) == SUBREG
16743 && GET_CODE (op1) == SUBREG
16744 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16745 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16746 /* These are unsigned values, perhaps there will be a later
16747 ordering compare that can be shared with this one.
16748 Unfortunately we cannot detect the signedness of the operands
16749 for non-subregs. */
16750 comp_mode = CCUNSmode;
16752 comp_mode = CCmode;
16754 /* First, the compare. */
16755 compare_result = gen_reg_rtx (comp_mode);
16757 /* E500 FP compare instructions on the GPRs. Yuck! */
16758 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16759 && FLOAT_MODE_P (mode))
16761 rtx cmp, or_result, compare_result2;
16762 enum machine_mode op_mode = GET_MODE (op0);
16764 if (op_mode == VOIDmode)
16765 op_mode = GET_MODE (op1);
16767 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16768 This explains the following mess. */
16772 case EQ: case UNEQ: case NE: case LTGT:
16776 cmp = (flag_finite_math_only && !flag_trapping_math)
16777 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16778 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16782 cmp = (flag_finite_math_only && !flag_trapping_math)
16783 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16784 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16788 cmp = (flag_finite_math_only && !flag_trapping_math)
16789 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16790 : gen_cmptfeq_gpr (compare_result, op0, op1);
16794 gcc_unreachable ();
16798 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16802 cmp = (flag_finite_math_only && !flag_trapping_math)
16803 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16804 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16808 cmp = (flag_finite_math_only && !flag_trapping_math)
16809 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16810 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16814 cmp = (flag_finite_math_only && !flag_trapping_math)
16815 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16816 : gen_cmptfgt_gpr (compare_result, op0, op1);
16820 gcc_unreachable ();
16824 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16828 cmp = (flag_finite_math_only && !flag_trapping_math)
16829 ? gen_tstsflt_gpr (compare_result, op0, op1)
16830 : gen_cmpsflt_gpr (compare_result, op0, op1);
16834 cmp = (flag_finite_math_only && !flag_trapping_math)
16835 ? gen_tstdflt_gpr (compare_result, op0, op1)
16836 : gen_cmpdflt_gpr (compare_result, op0, op1);
16840 cmp = (flag_finite_math_only && !flag_trapping_math)
16841 ? gen_tsttflt_gpr (compare_result, op0, op1)
16842 : gen_cmptflt_gpr (compare_result, op0, op1);
16846 gcc_unreachable ();
16850 gcc_unreachable ();
16853 /* Synthesize LE and GE from LT/GT || EQ. */
16854 if (code == LE || code == GE || code == LEU || code == GEU)
16860 case LE: code = LT; break;
16861 case GE: code = GT; break;
16862 case LEU: code = LT; break;
16863 case GEU: code = GT; break;
16864 default: gcc_unreachable ();
16867 compare_result2 = gen_reg_rtx (CCFPmode);
16873 cmp = (flag_finite_math_only && !flag_trapping_math)
16874 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16875 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16879 cmp = (flag_finite_math_only && !flag_trapping_math)
16880 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16881 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16885 cmp = (flag_finite_math_only && !flag_trapping_math)
16886 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16887 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16891 gcc_unreachable ();
16895 /* OR them together. */
16896 or_result = gen_reg_rtx (CCFPmode);
16897 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16899 compare_result = or_result;
16904 if (code == NE || code == LTGT)
16914 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16915 CLOBBERs to match cmptf_internal2 pattern. */
16916 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16917 && GET_MODE (op0) == TFmode
16918 && !TARGET_IEEEQUAD
16919 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16920 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16922 gen_rtx_SET (VOIDmode,
16924 gen_rtx_COMPARE (comp_mode, op0, op1)),
16925 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16926 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16927 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16928 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16929 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16930 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16931 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16932 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16933 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16934 else if (GET_CODE (op1) == UNSPEC
16935 && XINT (op1, 1) == UNSPEC_SP_TEST)
16937 rtx op1b = XVECEXP (op1, 0, 0);
16938 comp_mode = CCEQmode;
16939 compare_result = gen_reg_rtx (CCEQmode);
16941 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16943 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16946 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16947 gen_rtx_COMPARE (comp_mode, op0, op1)));
16950 /* Some kinds of FP comparisons need an OR operation;
16951 under flag_finite_math_only we don't bother. */
16952 if (FLOAT_MODE_P (mode)
16953 && !flag_finite_math_only
16954 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16955 && (code == LE || code == GE
16956 || code == UNEQ || code == LTGT
16957 || code == UNGT || code == UNLT))
16959 enum rtx_code or1, or2;
16960 rtx or1_rtx, or2_rtx, compare2_rtx;
16961 rtx or_result = gen_reg_rtx (CCEQmode);
16965 case LE: or1 = LT; or2 = EQ; break;
16966 case GE: or1 = GT; or2 = EQ; break;
16967 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16968 case LTGT: or1 = LT; or2 = GT; break;
16969 case UNGT: or1 = UNORDERED; or2 = GT; break;
16970 case UNLT: or1 = UNORDERED; or2 = LT; break;
16971 default: gcc_unreachable ();
16973 validate_condition_mode (or1, comp_mode);
16974 validate_condition_mode (or2, comp_mode);
16975 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16976 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16977 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16978 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16980 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16982 compare_result = or_result;
16986 validate_condition_mode (code, GET_MODE (compare_result));
16988 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
16992 /* Emit the RTL for an sISEL pattern. */
16995 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
16997 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
17001 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
17004 enum machine_mode op_mode;
17005 enum rtx_code cond_code;
17006 rtx result = operands[0];
17008 if (TARGET_ISEL && (mode == SImode || mode == DImode))
17010 rs6000_emit_sISEL (mode, operands);
17014 condition_rtx = rs6000_generate_compare (operands[1], mode);
17015 cond_code = GET_CODE (condition_rtx);
17017 if (FLOAT_MODE_P (mode)
17018 && !TARGET_FPRS && TARGET_HARD_FLOAT)
17022 PUT_MODE (condition_rtx, SImode);
17023 t = XEXP (condition_rtx, 0);
17025 gcc_assert (cond_code == NE || cond_code == EQ);
17027 if (cond_code == NE)
17028 emit_insn (gen_e500_flip_gt_bit (t, t));
17030 emit_insn (gen_move_from_CR_gt_bit (result, t));
17034 if (cond_code == NE
17035 || cond_code == GE || cond_code == LE
17036 || cond_code == GEU || cond_code == LEU
17037 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17039 rtx not_result = gen_reg_rtx (CCEQmode);
17040 rtx not_op, rev_cond_rtx;
17041 enum machine_mode cc_mode;
17043 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17045 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17046 SImode, XEXP (condition_rtx, 0), const0_rtx);
17047 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17048 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17049 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17052 op_mode = GET_MODE (XEXP (operands[1], 0));
17053 if (op_mode == VOIDmode)
17054 op_mode = GET_MODE (XEXP (operands[1], 1));
17056 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17058 PUT_MODE (condition_rtx, DImode);
17059 convert_move (result, condition_rtx, 0);
17063 PUT_MODE (condition_rtx, SImode);
17064 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17068 /* Emit a branch of kind CODE to location LOC. */
17071 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17073 rtx condition_rtx, loc_ref;
17075 condition_rtx = rs6000_generate_compare (operands[0], mode);
17076 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17077 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17078 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17079 loc_ref, pc_rtx)));
17082 /* Return the string to output a conditional branch to LABEL, which is
17083 the operand number of the label, or -1 if the branch is really a
17084 conditional return.
17086 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17087 condition code register and its mode specifies what kind of
17088 comparison we made.
17090 REVERSED is nonzero if we should reverse the sense of the comparison.
17092 INSN is the insn. */
17095 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17097 static char string[64];
17098 enum rtx_code code = GET_CODE (op);
17099 rtx cc_reg = XEXP (op, 0);
17100 enum machine_mode mode = GET_MODE (cc_reg);
17101 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17102 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17103 int really_reversed = reversed ^ need_longbranch;
17109 validate_condition_mode (code, mode);
17111 /* Work out which way this really branches. We could use
17112 reverse_condition_maybe_unordered here always but this
17113 makes the resulting assembler clearer. */
17114 if (really_reversed)
17116 /* Reversal of FP compares takes care -- an ordered compare
17117 becomes an unordered compare and vice versa. */
17118 if (mode == CCFPmode)
17119 code = reverse_condition_maybe_unordered (code);
17121 code = reverse_condition (code);
17124 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17126 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17131 /* Opposite of GT. */
17140 gcc_unreachable ();
17146 /* Not all of these are actually distinct opcodes, but
17147 we distinguish them for clarity of the resulting assembler. */
17148 case NE: case LTGT:
17149 ccode = "ne"; break;
17150 case EQ: case UNEQ:
17151 ccode = "eq"; break;
17153 ccode = "ge"; break;
17154 case GT: case GTU: case UNGT:
17155 ccode = "gt"; break;
17157 ccode = "le"; break;
17158 case LT: case LTU: case UNLT:
17159 ccode = "lt"; break;
17160 case UNORDERED: ccode = "un"; break;
17161 case ORDERED: ccode = "nu"; break;
17162 case UNGE: ccode = "nl"; break;
17163 case UNLE: ccode = "ng"; break;
17165 gcc_unreachable ();
17168 /* Maybe we have a guess as to how likely the branch is.
17169 The old mnemonics don't have a way to specify this information. */
17171 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17172 if (note != NULL_RTX)
17174 /* PROB is the difference from 50%. */
17175 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17177 /* Only hint for highly probable/improbable branches on newer
17178 cpus as static prediction overrides processor dynamic
17179 prediction. For older cpus we may as well always hint, but
17180 assume not taken for branches that are very close to 50% as a
17181 mispredicted taken branch is more expensive than a
17182 mispredicted not-taken branch. */
17183 if (rs6000_always_hint
17184 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17185 && br_prob_note_reliable_p (note)))
17187 if (abs (prob) > REG_BR_PROB_BASE / 20
17188 && ((prob > 0) ^ need_longbranch))
17196 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17198 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17200 /* We need to escape any '%' characters in the reg_names string.
17201 Assume they'd only be the first character.... */
17202 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17204 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17208 /* If the branch distance was too far, we may have to use an
17209 unconditional branch to go the distance. */
17210 if (need_longbranch)
17211 s += sprintf (s, ",$+8\n\tb %s", label);
17213 s += sprintf (s, ",%s", label);
17219 /* Return the string to flip the GT bit on a CR. */
17221 output_e500_flip_gt_bit (rtx dst, rtx src)
17223 static char string[64];
17226 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17227 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17230 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17231 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17233 sprintf (string, "crnot %d,%d", a, b);
17237 /* Return insn for VSX or Altivec comparisons. */
17240 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17243 enum machine_mode mode = GET_MODE (op0);
17251 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17257 mask = gen_reg_rtx (mode);
17258 emit_insn (gen_rtx_SET (VOIDmode,
17260 gen_rtx_fmt_ee (code, mode, op0, op1)));
17267 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17268 DMODE is expected destination mode. This is a recursive function. */
17271 rs6000_emit_vector_compare (enum rtx_code rcode,
17273 enum machine_mode dmode)
17276 bool swap_operands = false;
17277 bool try_again = false;
17279 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17280 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17282 /* See if the comparison works as is. */
17283 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17291 swap_operands = true;
17296 swap_operands = true;
17304 /* Invert condition and try again.
17305 e.g., A != B becomes ~(A==B). */
17307 enum rtx_code rev_code;
17308 enum insn_code nor_code;
17311 rev_code = reverse_condition_maybe_unordered (rcode);
17312 if (rev_code == UNKNOWN)
17315 nor_code = optab_handler (one_cmpl_optab, dmode);
17316 if (nor_code == CODE_FOR_nothing)
17319 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17323 mask = gen_reg_rtx (dmode);
17324 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17332 /* Try GT/GTU/LT/LTU OR EQ */
17335 enum insn_code ior_code;
17336 enum rtx_code new_code;
17357 gcc_unreachable ();
17360 ior_code = optab_handler (ior_optab, dmode);
17361 if (ior_code == CODE_FOR_nothing)
17364 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17368 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17372 mask = gen_reg_rtx (dmode);
17373 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17391 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17396 /* You only get two chances. */
17400 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17401 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17402 operands for the relation operation COND. */
17405 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17406 rtx cond, rtx cc_op0, rtx cc_op1)
17408 enum machine_mode dest_mode = GET_MODE (dest);
17409 enum rtx_code rcode = GET_CODE (cond);
17410 enum machine_mode cc_mode = CCmode;
17414 bool invert_move = false;
17416 if (VECTOR_UNIT_NONE_P (dest_mode))
17421 /* Swap operands if we can, and fall back to doing the operation as
17422 specified, and doing a NOR to invert the test. */
17428 /* Invert condition and try again.
17429 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17430 invert_move = true;
17431 rcode = reverse_condition_maybe_unordered (rcode);
17432 if (rcode == UNKNOWN)
17436 /* Mark unsigned tests with CCUNSmode. */
17441 cc_mode = CCUNSmode;
17448 /* Get the vector mask for the given relational operations. */
17449 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17457 op_true = op_false;
17461 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17462 emit_insn (gen_rtx_SET (VOIDmode,
17464 gen_rtx_IF_THEN_ELSE (dest_mode,
17471 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17472 operands of the last comparison is nonzero/true, FALSE_COND if it
17473 is zero/false. Return 0 if the hardware has no such operation. */
17476 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17478 enum rtx_code code = GET_CODE (op);
17479 rtx op0 = XEXP (op, 0);
17480 rtx op1 = XEXP (op, 1);
17481 REAL_VALUE_TYPE c1;
17482 enum machine_mode compare_mode = GET_MODE (op0);
17483 enum machine_mode result_mode = GET_MODE (dest);
17485 bool is_against_zero;
17487 /* These modes should always match. */
17488 if (GET_MODE (op1) != compare_mode
17489 /* In the isel case however, we can use a compare immediate, so
17490 op1 may be a small constant. */
17491 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17493 if (GET_MODE (true_cond) != result_mode)
17495 if (GET_MODE (false_cond) != result_mode)
17498 /* First, work out if the hardware can do this at all, or
17499 if it's too slow.... */
17500 if (!FLOAT_MODE_P (compare_mode))
17503 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17506 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17507 && SCALAR_FLOAT_MODE_P (compare_mode))
17510 is_against_zero = op1 == CONST0_RTX (compare_mode);
17512 /* A floating-point subtract might overflow, underflow, or produce
17513 an inexact result, thus changing the floating-point flags, so it
17514 can't be generated if we care about that. It's safe if one side
17515 of the construct is zero, since then no subtract will be
17517 if (SCALAR_FLOAT_MODE_P (compare_mode)
17518 && flag_trapping_math && ! is_against_zero)
17521 /* Eliminate half of the comparisons by switching operands, this
17522 makes the remaining code simpler. */
17523 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17524 || code == LTGT || code == LT || code == UNLE)
17526 code = reverse_condition_maybe_unordered (code);
17528 true_cond = false_cond;
17532 /* UNEQ and LTGT take four instructions for a comparison with zero,
17533 it'll probably be faster to use a branch here too. */
17534 if (code == UNEQ && HONOR_NANS (compare_mode))
17537 if (GET_CODE (op1) == CONST_DOUBLE)
17538 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17540 /* We're going to try to implement comparisons by performing
17541 a subtract, then comparing against zero. Unfortunately,
17542 Inf - Inf is NaN which is not zero, and so if we don't
17543 know that the operand is finite and the comparison
17544 would treat EQ different to UNORDERED, we can't do it. */
17545 if (HONOR_INFINITIES (compare_mode)
17546 && code != GT && code != UNGE
17547 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17548 /* Constructs of the form (a OP b ? a : b) are safe. */
17549 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17550 || (! rtx_equal_p (op0, true_cond)
17551 && ! rtx_equal_p (op1, true_cond))))
17554 /* At this point we know we can use fsel. */
17556 /* Reduce the comparison to a comparison against zero. */
17557 if (! is_against_zero)
17559 temp = gen_reg_rtx (compare_mode);
17560 emit_insn (gen_rtx_SET (VOIDmode, temp,
17561 gen_rtx_MINUS (compare_mode, op0, op1)));
17563 op1 = CONST0_RTX (compare_mode);
17566 /* If we don't care about NaNs we can reduce some of the comparisons
17567 down to faster ones. */
17568 if (! HONOR_NANS (compare_mode))
17574 true_cond = false_cond;
17587 /* Now, reduce everything down to a GE. */
17594 temp = gen_reg_rtx (compare_mode);
17595 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17600 temp = gen_reg_rtx (compare_mode);
17601 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17606 temp = gen_reg_rtx (compare_mode);
17607 emit_insn (gen_rtx_SET (VOIDmode, temp,
17608 gen_rtx_NEG (compare_mode,
17609 gen_rtx_ABS (compare_mode, op0))));
17614 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17615 temp = gen_reg_rtx (result_mode);
17616 emit_insn (gen_rtx_SET (VOIDmode, temp,
17617 gen_rtx_IF_THEN_ELSE (result_mode,
17618 gen_rtx_GE (VOIDmode,
17620 true_cond, false_cond)));
17621 false_cond = true_cond;
17624 temp = gen_reg_rtx (compare_mode);
17625 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17630 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17631 temp = gen_reg_rtx (result_mode);
17632 emit_insn (gen_rtx_SET (VOIDmode, temp,
17633 gen_rtx_IF_THEN_ELSE (result_mode,
17634 gen_rtx_GE (VOIDmode,
17636 true_cond, false_cond)));
17637 true_cond = false_cond;
17640 temp = gen_reg_rtx (compare_mode);
17641 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17646 gcc_unreachable ();
17649 emit_insn (gen_rtx_SET (VOIDmode, dest,
17650 gen_rtx_IF_THEN_ELSE (result_mode,
17651 gen_rtx_GE (VOIDmode,
17653 true_cond, false_cond)));
17657 /* Same as above, but for ints (isel). */
17660 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17662 rtx condition_rtx, cr;
17663 enum machine_mode mode = GET_MODE (dest);
17664 enum rtx_code cond_code;
17665 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17668 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17671 /* We still have to do the compare, because isel doesn't do a
17672 compare, it just looks at the CRx bits set by a previous compare
17674 condition_rtx = rs6000_generate_compare (op, mode);
17675 cond_code = GET_CODE (condition_rtx);
17676 cr = XEXP (condition_rtx, 0);
17677 signedp = GET_MODE (cr) == CCmode;
17679 isel_func = (mode == SImode
17680 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17681 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17685 case LT: case GT: case LTU: case GTU: case EQ:
17686 /* isel handles these directly. */
17690 /* We need to swap the sense of the comparison. */
17693 true_cond = false_cond;
17695 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17700 false_cond = force_reg (mode, false_cond);
17701 if (true_cond != const0_rtx)
17702 true_cond = force_reg (mode, true_cond);
17704 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17710 output_isel (rtx *operands)
17712 enum rtx_code code;
17714 code = GET_CODE (operands[1]);
17716 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17718 gcc_assert (GET_CODE (operands[2]) == REG
17719 && GET_CODE (operands[3]) == REG);
17720 PUT_CODE (operands[1], reverse_condition (code));
17721 return "isel %0,%3,%2,%j1";
17724 return "isel %0,%2,%3,%j1";
17728 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17730 enum machine_mode mode = GET_MODE (op0);
17734 /* VSX/altivec have direct min/max insns. */
17735 if ((code == SMAX || code == SMIN)
17736 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17737 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17739 emit_insn (gen_rtx_SET (VOIDmode,
17741 gen_rtx_fmt_ee (code, mode, op0, op1)));
17745 if (code == SMAX || code == SMIN)
17750 if (code == SMAX || code == UMAX)
17751 target = emit_conditional_move (dest, c, op0, op1, mode,
17752 op0, op1, mode, 0);
17754 target = emit_conditional_move (dest, c, op0, op1, mode,
17755 op1, op0, mode, 0);
17756 gcc_assert (target);
17757 if (target != dest)
17758 emit_move_insn (dest, target);
17761 /* Emit instructions to perform a load-reserved/store-conditional operation.
17762 The operation performed is an atomic
17763 (set M (CODE:MODE M OP))
17764 If not NULL, BEFORE is atomically set to M before the operation, and
17765 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17766 If SYNC_P then a memory barrier is emitted before the operation.
17767 Either OP or M may be wrapped in a NOT operation. */
17770 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17771 rtx m, rtx op, rtx before_param, rtx after_param,
17774 enum machine_mode used_mode;
17775 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17778 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17779 rtx shift = NULL_RTX;
17782 emit_insn (gen_lwsync ());
17786 /* If this is smaller than SImode, we'll have to use SImode with
17788 if (mode == QImode || mode == HImode)
17792 if (MEM_ALIGN (used_m) >= 32)
17795 if (BYTES_BIG_ENDIAN)
17796 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17798 shift = GEN_INT (ishift);
17799 used_m = change_address (used_m, SImode, 0);
17803 rtx addrSI, aligned_addr;
17804 int shift_mask = mode == QImode ? 0x18 : 0x10;
17806 addrSI = gen_lowpart_common (SImode,
17807 force_reg (Pmode, XEXP (used_m, 0)));
17808 addrSI = force_reg (SImode, addrSI);
17809 shift = gen_reg_rtx (SImode);
17811 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17812 GEN_INT (shift_mask)));
17813 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17815 aligned_addr = expand_binop (Pmode, and_optab,
17817 GEN_INT (-4), NULL_RTX,
17818 1, OPTAB_LIB_WIDEN);
17819 used_m = change_address (used_m, SImode, aligned_addr);
17820 set_mem_align (used_m, 32);
17822 /* It's safe to keep the old alias set of USED_M, because
17823 the operation is atomic and only affects the original
17827 if (GET_CODE (op) == NOT)
17829 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17830 oldop = gen_rtx_NOT (SImode, oldop);
17833 oldop = lowpart_subreg (SImode, op, mode);
17839 newop = expand_binop (SImode, and_optab,
17840 oldop, GEN_INT (imask), NULL_RTX,
17841 1, OPTAB_LIB_WIDEN);
17842 emit_insn (gen_ashlsi3 (newop, newop, shift));
17845 case NOT: /* NAND */
17846 newop = expand_binop (SImode, ior_optab,
17847 oldop, GEN_INT (~imask), NULL_RTX,
17848 1, OPTAB_LIB_WIDEN);
17849 emit_insn (gen_rotlsi3 (newop, newop, shift));
17853 newop = expand_binop (SImode, ior_optab,
17854 oldop, GEN_INT (~imask), NULL_RTX,
17855 1, OPTAB_LIB_WIDEN);
17856 emit_insn (gen_rotlsi3 (newop, newop, shift));
17864 newop = expand_binop (SImode, and_optab,
17865 oldop, GEN_INT (imask), NULL_RTX,
17866 1, OPTAB_LIB_WIDEN);
17867 emit_insn (gen_ashlsi3 (newop, newop, shift));
17869 mask = gen_reg_rtx (SImode);
17870 emit_move_insn (mask, GEN_INT (imask));
17871 emit_insn (gen_ashlsi3 (mask, mask, shift));
17874 newop = gen_rtx_PLUS (SImode, m, newop);
17876 newop = gen_rtx_MINUS (SImode, m, newop);
17877 newop = gen_rtx_AND (SImode, newop, mask);
17878 newop = gen_rtx_IOR (SImode, newop,
17879 gen_rtx_AND (SImode,
17880 gen_rtx_NOT (SImode, mask),
17886 gcc_unreachable ();
17890 used_mode = SImode;
17891 before = gen_reg_rtx (used_mode);
17892 after = gen_reg_rtx (used_mode);
17897 before = before_param;
17898 after = after_param;
17900 if (before == NULL_RTX)
17901 before = gen_reg_rtx (used_mode);
17902 if (after == NULL_RTX)
17903 after = gen_reg_rtx (used_mode);
17906 if ((code == PLUS || code == MINUS)
17907 && used_mode != mode)
17908 the_op = op; /* Computed above. */
17909 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17910 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17911 else if (code == NOT)
17912 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17913 gen_rtx_NOT (used_mode, m),
17914 gen_rtx_NOT (used_mode, op));
17916 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17918 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17919 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17920 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17921 gen_rtx_UNSPEC (used_mode,
17922 gen_rtvec (1, the_op),
17924 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17926 if ((code == PLUS || code == MINUS) && used_mode != mode)
17927 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17928 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17930 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17931 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17933 /* Shift and mask the return values properly. */
17934 if (used_mode != mode && before_param)
17936 emit_insn (gen_lshrsi3 (before, before, shift));
17937 convert_move (before_param, before, 1);
17940 if (used_mode != mode && after_param)
17942 emit_insn (gen_lshrsi3 (after, after, shift));
17943 convert_move (after_param, after, 1);
17946 /* The previous sequence will end with a branch that's dependent on
17947 the conditional store, so placing an isync will ensure that no
17948 other instructions (especially, no load or store instructions)
17949 can start before the atomic operation completes. */
17951 emit_insn (gen_isync ());
17954 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17955 COND is true. Mark the jump as unlikely to be taken. */
17958 emit_unlikely_jump (rtx cond, rtx label)
17960 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17963 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17964 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17965 add_reg_note (x, REG_BR_PROB, very_unlikely);
17968 /* A subroutine of the atomic operation splitters. Emit a load-locked
17969 instruction in MODE. */
17972 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17974 rtx (*fn) (rtx, rtx) = NULL;
17975 if (mode == SImode)
17976 fn = gen_load_locked_si;
17977 else if (mode == DImode)
17978 fn = gen_load_locked_di;
17979 emit_insn (fn (reg, mem));
17982 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17983 instruction in MODE. */
17986 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17988 rtx (*fn) (rtx, rtx, rtx) = NULL;
17989 if (mode == SImode)
17990 fn = gen_store_conditional_si;
17991 else if (mode == DImode)
17992 fn = gen_store_conditional_di;
17994 /* Emit sync before stwcx. to address PPC405 Erratum. */
17995 if (PPC405_ERRATUM77)
17996 emit_insn (gen_memory_barrier ());
17998 emit_insn (fn (res, mem, val));
18001 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
18002 to perform. MEM is the memory on which to operate. VAL is the second
18003 operand of the binary operator. BEFORE and AFTER are optional locations to
18004 return the value of MEM either before of after the operation. SCRATCH is
18005 a scratch register. */
18008 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
18009 rtx before, rtx after, rtx scratch)
18011 enum machine_mode mode = GET_MODE (mem);
18012 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18014 emit_insn (gen_lwsync ());
18016 label = gen_label_rtx ();
18017 emit_label (label);
18018 label = gen_rtx_LABEL_REF (VOIDmode, label);
18020 if (before == NULL_RTX)
18022 emit_load_locked (mode, before, mem);
18025 x = gen_rtx_IOR (mode,
18026 gen_rtx_NOT (mode, before),
18027 gen_rtx_NOT (mode, val));
18028 else if (code == AND)
18029 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
18031 x = gen_rtx_fmt_ee (code, mode, before, val);
18033 if (after != NULL_RTX)
18034 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18035 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18037 emit_store_conditional (mode, cond, mem, scratch);
18039 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18040 emit_unlikely_jump (x, label);
18042 emit_insn (gen_isync ());
18045 /* Expand an atomic compare and swap operation. MEM is the memory on which
18046 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18047 value to be stored. SCRATCH is a scratch GPR. */
18050 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18053 enum machine_mode mode = GET_MODE (mem);
18054 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18056 emit_insn (gen_lwsync ());
18058 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18059 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18060 emit_label (XEXP (label1, 0));
18062 emit_load_locked (mode, retval, mem);
18064 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18065 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18067 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18068 emit_unlikely_jump (x, label2);
18070 emit_move_insn (scratch, newval);
18071 emit_store_conditional (mode, cond, mem, scratch);
18073 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18074 emit_unlikely_jump (x, label1);
18076 emit_insn (gen_isync ());
18077 emit_label (XEXP (label2, 0));
18080 /* Expand an atomic test and set operation. MEM is the memory on which
18081 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18084 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18086 enum machine_mode mode = GET_MODE (mem);
18087 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18089 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18090 emit_label (XEXP (label, 0));
18092 emit_load_locked (mode, retval, mem);
18093 emit_move_insn (scratch, val);
18094 emit_store_conditional (mode, cond, mem, scratch);
18096 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18097 emit_unlikely_jump (x, label);
18099 emit_insn (gen_isync ());
18103 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18105 enum machine_mode mode = GET_MODE (mem);
18106 rtx addrSI, align, wdst, shift, mask;
18107 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18108 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18110 /* Shift amount for subword relative to aligned word. */
18111 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18112 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18113 shift = gen_reg_rtx (SImode);
18114 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18115 GEN_INT (shift_mask)));
18116 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18118 /* Shift and mask old value into position within word. */
18119 oldval = convert_modes (SImode, mode, oldval, 1);
18120 oldval = expand_binop (SImode, and_optab,
18121 oldval, GEN_INT (imask), NULL_RTX,
18122 1, OPTAB_LIB_WIDEN);
18123 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18125 /* Shift and mask new value into position within word. */
18126 newval = convert_modes (SImode, mode, newval, 1);
18127 newval = expand_binop (SImode, and_optab,
18128 newval, GEN_INT (imask), NULL_RTX,
18129 1, OPTAB_LIB_WIDEN);
18130 emit_insn (gen_ashlsi3 (newval, newval, shift));
18132 /* Mask for insertion. */
18133 mask = gen_reg_rtx (SImode);
18134 emit_move_insn (mask, GEN_INT (imask));
18135 emit_insn (gen_ashlsi3 (mask, mask, shift));
18137 /* Address of aligned word containing subword. */
18138 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18139 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18140 mem = change_address (mem, SImode, align);
18141 set_mem_align (mem, 32);
18142 MEM_VOLATILE_P (mem) = 1;
18144 wdst = gen_reg_rtx (SImode);
18145 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18146 oldval, newval, mem));
18148 /* Shift the result back. */
18149 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18151 emit_move_insn (dst, gen_lowpart (mode, wdst));
18155 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18156 rtx oldval, rtx newval, rtx mem,
18159 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18161 emit_insn (gen_lwsync ());
18162 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18163 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18164 emit_label (XEXP (label1, 0));
18166 emit_load_locked (SImode, scratch, mem);
18168 /* Mask subword within loaded value for comparison with oldval.
18169 Use UNSPEC_AND to avoid clobber.*/
18170 emit_insn (gen_rtx_SET (SImode, dest,
18171 gen_rtx_UNSPEC (SImode,
18172 gen_rtvec (2, scratch, mask),
18175 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18176 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18178 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18179 emit_unlikely_jump (x, label2);
18181 /* Clear subword within loaded value for insertion of new value. */
18182 emit_insn (gen_rtx_SET (SImode, scratch,
18183 gen_rtx_AND (SImode,
18184 gen_rtx_NOT (SImode, mask), scratch)));
18185 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18186 emit_store_conditional (SImode, cond, mem, scratch);
18188 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18189 emit_unlikely_jump (x, label1);
18191 emit_insn (gen_isync ());
18192 emit_label (XEXP (label2, 0));
18196 /* Emit instructions to move SRC to DST. Called by splitters for
18197 multi-register moves. It will emit at most one instruction for
18198 each register that is accessed; that is, it won't emit li/lis pairs
18199 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18203 rs6000_split_multireg_move (rtx dst, rtx src)
18205 /* The register number of the first register being moved. */
18207 /* The mode that is to be moved. */
18208 enum machine_mode mode;
18209 /* The mode that the move is being done in, and its size. */
18210 enum machine_mode reg_mode;
18212 /* The number of registers that will be moved. */
18215 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18216 mode = GET_MODE (dst);
18217 nregs = hard_regno_nregs[reg][mode];
18218 if (FP_REGNO_P (reg))
18219 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18220 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18221 else if (ALTIVEC_REGNO_P (reg))
18222 reg_mode = V16QImode;
18223 else if (TARGET_E500_DOUBLE && mode == TFmode)
18226 reg_mode = word_mode;
18227 reg_mode_size = GET_MODE_SIZE (reg_mode);
18229 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18231 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18233 /* Move register range backwards, if we might have destructive
18236 for (i = nregs - 1; i >= 0; i--)
18237 emit_insn (gen_rtx_SET (VOIDmode,
18238 simplify_gen_subreg (reg_mode, dst, mode,
18239 i * reg_mode_size),
18240 simplify_gen_subreg (reg_mode, src, mode,
18241 i * reg_mode_size)));
18247 bool used_update = false;
18248 rtx restore_basereg = NULL_RTX;
18250 if (MEM_P (src) && INT_REGNO_P (reg))
18254 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18255 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18258 breg = XEXP (XEXP (src, 0), 0);
18259 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18260 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18261 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18262 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18263 src = replace_equiv_address (src, breg);
18265 else if (! rs6000_offsettable_memref_p (src))
18267 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18269 rtx basereg = XEXP (XEXP (src, 0), 0);
18272 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18273 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18274 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18275 used_update = true;
18278 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18279 XEXP (XEXP (src, 0), 1)));
18280 src = replace_equiv_address (src, basereg);
18284 rtx basereg = gen_rtx_REG (Pmode, reg);
18285 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18286 src = replace_equiv_address (src, basereg);
18290 breg = XEXP (src, 0);
18291 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18292 breg = XEXP (breg, 0);
18294 /* If the base register we are using to address memory is
18295 also a destination reg, then change that register last. */
18297 && REGNO (breg) >= REGNO (dst)
18298 && REGNO (breg) < REGNO (dst) + nregs)
18299 j = REGNO (breg) - REGNO (dst);
18301 else if (MEM_P (dst) && INT_REGNO_P (reg))
18305 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18306 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18309 breg = XEXP (XEXP (dst, 0), 0);
18310 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18311 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18312 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18314 /* We have to update the breg before doing the store.
18315 Use store with update, if available. */
18319 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18320 emit_insn (TARGET_32BIT
18321 ? (TARGET_POWERPC64
18322 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18323 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18324 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18325 used_update = true;
18328 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18329 dst = replace_equiv_address (dst, breg);
18331 else if (!rs6000_offsettable_memref_p (dst)
18332 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18334 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18336 rtx basereg = XEXP (XEXP (dst, 0), 0);
18339 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18340 emit_insn (gen_rtx_SET (VOIDmode,
18341 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18342 used_update = true;
18345 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18346 XEXP (XEXP (dst, 0), 1)));
18347 dst = replace_equiv_address (dst, basereg);
18351 rtx basereg = XEXP (XEXP (dst, 0), 0);
18352 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18353 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18355 && REG_P (offsetreg)
18356 && REGNO (basereg) != REGNO (offsetreg));
18357 if (REGNO (basereg) == 0)
18359 rtx tmp = offsetreg;
18360 offsetreg = basereg;
18363 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18364 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18365 dst = replace_equiv_address (dst, basereg);
18368 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18369 gcc_assert (rs6000_offsettable_memref_p (dst));
18372 for (i = 0; i < nregs; i++)
18374 /* Calculate index to next subword. */
18379 /* If compiler already emitted move of first word by
18380 store with update, no need to do anything. */
18381 if (j == 0 && used_update)
18384 emit_insn (gen_rtx_SET (VOIDmode,
18385 simplify_gen_subreg (reg_mode, dst, mode,
18386 j * reg_mode_size),
18387 simplify_gen_subreg (reg_mode, src, mode,
18388 j * reg_mode_size)));
18390 if (restore_basereg != NULL_RTX)
18391 emit_insn (restore_basereg);
18396 /* This page contains routines that are used to determine what the
18397 function prologue and epilogue code will do and write them out. */
18399 /* Return the first fixed-point register that is required to be
18400 saved. 32 if none. */
18403 first_reg_to_save (void)
18407 /* Find lowest numbered live register. */
18408 for (first_reg = 13; first_reg <= 31; first_reg++)
18409 if (df_regs_ever_live_p (first_reg)
18410 && (! call_used_regs[first_reg]
18411 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18412 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18413 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18414 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18419 && crtl->uses_pic_offset_table
18420 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18421 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18427 /* Similar, for FP regs. */
18430 first_fp_reg_to_save (void)
18434 /* Find lowest numbered live register. */
18435 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18436 if (df_regs_ever_live_p (first_reg))
18442 /* Similar, for AltiVec regs. */
18445 first_altivec_reg_to_save (void)
18449 /* Stack frame remains as is unless we are in AltiVec ABI. */
18450 if (! TARGET_ALTIVEC_ABI)
18451 return LAST_ALTIVEC_REGNO + 1;
18453 /* On Darwin, the unwind routines are compiled without
18454 TARGET_ALTIVEC, and use save_world to save/restore the
18455 altivec registers when necessary. */
18456 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18457 && ! TARGET_ALTIVEC)
18458 return FIRST_ALTIVEC_REGNO + 20;
18460 /* Find lowest numbered live register. */
18461 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18462 if (df_regs_ever_live_p (i))
18468 /* Return a 32-bit mask of the AltiVec registers we need to set in
18469 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18470 the 32-bit word is 0. */
18472 static unsigned int
18473 compute_vrsave_mask (void)
18475 unsigned int i, mask = 0;
18477 /* On Darwin, the unwind routines are compiled without
18478 TARGET_ALTIVEC, and use save_world to save/restore the
18479 call-saved altivec registers when necessary. */
18480 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18481 && ! TARGET_ALTIVEC)
18484 /* First, find out if we use _any_ altivec registers. */
18485 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18486 if (df_regs_ever_live_p (i))
18487 mask |= ALTIVEC_REG_BIT (i);
18492 /* Next, remove the argument registers from the set. These must
18493 be in the VRSAVE mask set by the caller, so we don't need to add
18494 them in again. More importantly, the mask we compute here is
18495 used to generate CLOBBERs in the set_vrsave insn, and we do not
18496 wish the argument registers to die. */
18497 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18498 mask &= ~ALTIVEC_REG_BIT (i);
18500 /* Similarly, remove the return value from the set. */
18503 diddle_return_value (is_altivec_return_reg, &yes);
18505 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18511 /* For a very restricted set of circumstances, we can cut down the
18512 size of prologues/epilogues by calling our own save/restore-the-world
18516 compute_save_world_info (rs6000_stack_t *info_ptr)
18518 info_ptr->world_save_p = 1;
18519 info_ptr->world_save_p
18520 = (WORLD_SAVE_P (info_ptr)
18521 && DEFAULT_ABI == ABI_DARWIN
18522 && ! (cfun->calls_setjmp && flag_exceptions)
18523 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18524 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18525 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18526 && info_ptr->cr_save_p);
18528 /* This will not work in conjunction with sibcalls. Make sure there
18529 are none. (This check is expensive, but seldom executed.) */
18530 if (WORLD_SAVE_P (info_ptr))
18533 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18534 if ( GET_CODE (insn) == CALL_INSN
18535 && SIBLING_CALL_P (insn))
18537 info_ptr->world_save_p = 0;
18542 if (WORLD_SAVE_P (info_ptr))
18544 /* Even if we're not touching VRsave, make sure there's room on the
18545 stack for it, if it looks like we're calling SAVE_WORLD, which
18546 will attempt to save it. */
18547 info_ptr->vrsave_size = 4;
18549 /* If we are going to save the world, we need to save the link register too. */
18550 info_ptr->lr_save_p = 1;
18552 /* "Save" the VRsave register too if we're saving the world. */
18553 if (info_ptr->vrsave_mask == 0)
18554 info_ptr->vrsave_mask = compute_vrsave_mask ();
18556 /* Because the Darwin register save/restore routines only handle
18557 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18559 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18560 && (info_ptr->first_altivec_reg_save
18561 >= FIRST_SAVED_ALTIVEC_REGNO));
18568 is_altivec_return_reg (rtx reg, void *xyes)
18570 bool *yes = (bool *) xyes;
18571 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18576 /* Determine the strategy for savings/restoring registers. */
18579 SAVRES_MULTIPLE = 0x1,
18580 SAVE_INLINE_FPRS = 0x2,
18581 SAVE_INLINE_GPRS = 0x4,
18582 REST_INLINE_FPRS = 0x8,
18583 REST_INLINE_GPRS = 0x10,
18584 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18585 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18586 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18590 rs6000_savres_strategy (rs6000_stack_t *info,
18591 bool using_static_chain_p)
18595 if (TARGET_MULTIPLE
18596 && !TARGET_POWERPC64
18597 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18598 && info->first_gp_reg_save < 31
18599 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18600 strategy |= SAVRES_MULTIPLE;
18602 if (crtl->calls_eh_return
18603 || cfun->machine->ra_need_lr
18604 || info->total_size > 32767)
18605 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18606 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18608 if (info->first_fp_reg_save == 64
18609 || FP_SAVE_INLINE (info->first_fp_reg_save)
18610 /* The out-of-line FP routines use double-precision stores;
18611 we can't use those routines if we don't have such stores. */
18612 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18613 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18614 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18616 if (info->first_gp_reg_save == 32
18617 || GP_SAVE_INLINE (info->first_gp_reg_save)
18618 || !((strategy & SAVRES_MULTIPLE)
18619 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18620 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18622 /* Don't bother to try to save things out-of-line if r11 is occupied
18623 by the static chain. It would require too much fiddling and the
18624 static chain is rarely used anyway. */
18625 if (using_static_chain_p)
18626 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18628 /* If we are going to use store multiple, then don't even bother
18629 with the out-of-line routines, since the store-multiple
18630 instruction will always be smaller. */
18631 if ((strategy & SAVRES_MULTIPLE))
18632 strategy |= SAVE_INLINE_GPRS;
18634 /* The situation is more complicated with load multiple. We'd
18635 prefer to use the out-of-line routines for restores, since the
18636 "exit" out-of-line routines can handle the restore of LR and the
18637 frame teardown. However if doesn't make sense to use the
18638 out-of-line routine if that is the only reason we'd need to save
18639 LR, and we can't use the "exit" out-of-line gpr restore if we
18640 have saved some fprs; In those cases it is advantageous to use
18641 load multiple when available. */
18642 if ((strategy & SAVRES_MULTIPLE)
18643 && (!info->lr_save_p
18644 || info->first_fp_reg_save != 64))
18645 strategy |= REST_INLINE_GPRS;
18647 /* We can only use load multiple or the out-of-line routines to
18648 restore if we've used store multiple or out-of-line routines
18649 in the prologue, i.e. if we've saved all the registers from
18650 first_gp_reg_save. Otherwise, we risk loading garbage. */
18651 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18652 strategy |= REST_INLINE_GPRS;
18654 /* Saving CR interferes with the exit routines used on the SPE, so
18657 && info->spe_64bit_regs_used
18658 && info->cr_save_p)
18659 strategy |= REST_INLINE_GPRS;
18661 #ifdef POWERPC_LINUX
18664 if (!(strategy & SAVE_INLINE_FPRS))
18665 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18666 else if (!(strategy & SAVE_INLINE_GPRS)
18667 && info->first_fp_reg_save == 64)
18668 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18671 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18672 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18677 /* Calculate the stack information for the current function. This is
18678 complicated by having two separate calling sequences, the AIX calling
18679 sequence and the V.4 calling sequence.
18681 AIX (and Darwin/Mac OS X) stack frames look like:
18683 SP----> +---------------------------------------+
18684 | back chain to caller | 0 0
18685 +---------------------------------------+
18686 | saved CR | 4 8 (8-11)
18687 +---------------------------------------+
18689 +---------------------------------------+
18690 | reserved for compilers | 12 24
18691 +---------------------------------------+
18692 | reserved for binders | 16 32
18693 +---------------------------------------+
18694 | saved TOC pointer | 20 40
18695 +---------------------------------------+
18696 | Parameter save area (P) | 24 48
18697 +---------------------------------------+
18698 | Alloca space (A) | 24+P etc.
18699 +---------------------------------------+
18700 | Local variable space (L) | 24+P+A
18701 +---------------------------------------+
18702 | Float/int conversion temporary (X) | 24+P+A+L
18703 +---------------------------------------+
18704 | Save area for AltiVec registers (W) | 24+P+A+L+X
18705 +---------------------------------------+
18706 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18707 +---------------------------------------+
18708 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18709 +---------------------------------------+
18710 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18711 +---------------------------------------+
18712 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18713 +---------------------------------------+
18714 old SP->| back chain to caller's caller |
18715 +---------------------------------------+
18717 The required alignment for AIX configurations is two words (i.e., 8
18721 V.4 stack frames look like:
18723 SP----> +---------------------------------------+
18724 | back chain to caller | 0
18725 +---------------------------------------+
18726 | caller's saved LR | 4
18727 +---------------------------------------+
18728 | Parameter save area (P) | 8
18729 +---------------------------------------+
18730 | Alloca space (A) | 8+P
18731 +---------------------------------------+
18732 | Varargs save area (V) | 8+P+A
18733 +---------------------------------------+
18734 | Local variable space (L) | 8+P+A+V
18735 +---------------------------------------+
18736 | Float/int conversion temporary (X) | 8+P+A+V+L
18737 +---------------------------------------+
18738 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18739 +---------------------------------------+
18740 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18741 +---------------------------------------+
18742 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18743 +---------------------------------------+
18744 | SPE: area for 64-bit GP registers |
18745 +---------------------------------------+
18746 | SPE alignment padding |
18747 +---------------------------------------+
18748 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18749 +---------------------------------------+
18750 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18751 +---------------------------------------+
18752 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18753 +---------------------------------------+
18754 old SP->| back chain to caller's caller |
18755 +---------------------------------------+
18757 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18758 given. (But note below and in sysv4.h that we require only 8 and
18759 may round up the size of our stack frame anyways. The historical
18760 reason is early versions of powerpc-linux which didn't properly
18761 align the stack at program startup. A happy side-effect is that
18762 -mno-eabi libraries can be used with -meabi programs.)
18764 The EABI configuration defaults to the V.4 layout. However,
18765 the stack alignment requirements may differ. If -mno-eabi is not
18766 given, the required stack alignment is 8 bytes; if -mno-eabi is
18767 given, the required alignment is 16 bytes. (But see V.4 comment
18770 #ifndef ABI_STACK_BOUNDARY
18771 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18774 static rs6000_stack_t *
18775 rs6000_stack_info (void)
18777 rs6000_stack_t *info_ptr = &stack_info;
18778 int reg_size = TARGET_32BIT ? 4 : 8;
18782 HOST_WIDE_INT non_fixed_size;
18783 bool using_static_chain_p;
18785 if (reload_completed && info_ptr->reload_completed)
18788 memset (info_ptr, 0, sizeof (*info_ptr));
18789 info_ptr->reload_completed = reload_completed;
18793 /* Cache value so we don't rescan instruction chain over and over. */
18794 if (cfun->machine->insn_chain_scanned_p == 0)
18795 cfun->machine->insn_chain_scanned_p
18796 = spe_func_has_64bit_regs_p () + 1;
18797 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18800 /* Select which calling sequence. */
18801 info_ptr->abi = DEFAULT_ABI;
18803 /* Calculate which registers need to be saved & save area size. */
18804 info_ptr->first_gp_reg_save = first_reg_to_save ();
18805 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18806 even if it currently looks like we won't. Reload may need it to
18807 get at a constant; if so, it will have already created a constant
18808 pool entry for it. */
18809 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18810 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18811 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18812 && crtl->uses_const_pool
18813 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18814 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18816 first_gp = info_ptr->first_gp_reg_save;
18818 info_ptr->gp_size = reg_size * (32 - first_gp);
18820 /* For the SPE, we have an additional upper 32-bits on each GPR.
18821 Ideally we should save the entire 64-bits only when the upper
18822 half is used in SIMD instructions. Since we only record
18823 registers live (not the size they are used in), this proves
18824 difficult because we'd have to traverse the instruction chain at
18825 the right time, taking reload into account. This is a real pain,
18826 so we opt to save the GPRs in 64-bits always if but one register
18827 gets used in 64-bits. Otherwise, all the registers in the frame
18828 get saved in 32-bits.
18830 So... since when we save all GPRs (except the SP) in 64-bits, the
18831 traditional GP save area will be empty. */
18832 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18833 info_ptr->gp_size = 0;
18835 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18836 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18838 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18839 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18840 - info_ptr->first_altivec_reg_save);
18842 /* Does this function call anything? */
18843 info_ptr->calls_p = (! current_function_is_leaf
18844 || cfun->machine->ra_needs_full_frame);
18846 /* Determine if we need to save the condition code registers. */
18847 if (df_regs_ever_live_p (CR2_REGNO)
18848 || df_regs_ever_live_p (CR3_REGNO)
18849 || df_regs_ever_live_p (CR4_REGNO))
18851 info_ptr->cr_save_p = 1;
18852 if (DEFAULT_ABI == ABI_V4)
18853 info_ptr->cr_size = reg_size;
18856 /* If the current function calls __builtin_eh_return, then we need
18857 to allocate stack space for registers that will hold data for
18858 the exception handler. */
18859 if (crtl->calls_eh_return)
18862 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18865 /* SPE saves EH registers in 64-bits. */
18866 ehrd_size = i * (TARGET_SPE_ABI
18867 && info_ptr->spe_64bit_regs_used != 0
18868 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18873 /* Determine various sizes. */
18874 info_ptr->reg_size = reg_size;
18875 info_ptr->fixed_size = RS6000_SAVE_AREA;
18876 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18877 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18878 TARGET_ALTIVEC ? 16 : 8);
18879 if (FRAME_GROWS_DOWNWARD)
18880 info_ptr->vars_size
18881 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18882 + info_ptr->parm_size,
18883 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18884 - (info_ptr->fixed_size + info_ptr->vars_size
18885 + info_ptr->parm_size);
18887 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18888 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18890 info_ptr->spe_gp_size = 0;
18892 if (TARGET_ALTIVEC_ABI)
18893 info_ptr->vrsave_mask = compute_vrsave_mask ();
18895 info_ptr->vrsave_mask = 0;
18897 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18898 info_ptr->vrsave_size = 4;
18900 info_ptr->vrsave_size = 0;
18902 compute_save_world_info (info_ptr);
18904 /* Calculate the offsets. */
18905 switch (DEFAULT_ABI)
18909 gcc_unreachable ();
18913 info_ptr->fp_save_offset = - info_ptr->fp_size;
18914 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18916 if (TARGET_ALTIVEC_ABI)
18918 info_ptr->vrsave_save_offset
18919 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18921 /* Align stack so vector save area is on a quadword boundary.
18922 The padding goes above the vectors. */
18923 if (info_ptr->altivec_size != 0)
18924 info_ptr->altivec_padding_size
18925 = info_ptr->vrsave_save_offset & 0xF;
18927 info_ptr->altivec_padding_size = 0;
18929 info_ptr->altivec_save_offset
18930 = info_ptr->vrsave_save_offset
18931 - info_ptr->altivec_padding_size
18932 - info_ptr->altivec_size;
18933 gcc_assert (info_ptr->altivec_size == 0
18934 || info_ptr->altivec_save_offset % 16 == 0);
18936 /* Adjust for AltiVec case. */
18937 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18940 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18941 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18942 info_ptr->lr_save_offset = 2*reg_size;
18946 info_ptr->fp_save_offset = - info_ptr->fp_size;
18947 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18948 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18950 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18952 /* Align stack so SPE GPR save area is aligned on a
18953 double-word boundary. */
18954 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18955 info_ptr->spe_padding_size
18956 = 8 - (-info_ptr->cr_save_offset % 8);
18958 info_ptr->spe_padding_size = 0;
18960 info_ptr->spe_gp_save_offset
18961 = info_ptr->cr_save_offset
18962 - info_ptr->spe_padding_size
18963 - info_ptr->spe_gp_size;
18965 /* Adjust for SPE case. */
18966 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18968 else if (TARGET_ALTIVEC_ABI)
18970 info_ptr->vrsave_save_offset
18971 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18973 /* Align stack so vector save area is on a quadword boundary. */
18974 if (info_ptr->altivec_size != 0)
18975 info_ptr->altivec_padding_size
18976 = 16 - (-info_ptr->vrsave_save_offset % 16);
18978 info_ptr->altivec_padding_size = 0;
18980 info_ptr->altivec_save_offset
18981 = info_ptr->vrsave_save_offset
18982 - info_ptr->altivec_padding_size
18983 - info_ptr->altivec_size;
18985 /* Adjust for AltiVec case. */
18986 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18989 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18990 info_ptr->ehrd_offset -= ehrd_size;
18991 info_ptr->lr_save_offset = reg_size;
18995 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
18996 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
18997 + info_ptr->gp_size
18998 + info_ptr->altivec_size
18999 + info_ptr->altivec_padding_size
19000 + info_ptr->spe_gp_size
19001 + info_ptr->spe_padding_size
19003 + info_ptr->cr_size
19004 + info_ptr->vrsave_size,
19007 non_fixed_size = (info_ptr->vars_size
19008 + info_ptr->parm_size
19009 + info_ptr->save_size);
19011 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
19012 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
19014 /* Determine if we need to save the link register. */
19015 if (info_ptr->calls_p
19016 || (DEFAULT_ABI == ABI_AIX
19018 && !TARGET_PROFILE_KERNEL)
19019 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
19020 #ifdef TARGET_RELOCATABLE
19021 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
19023 || rs6000_ra_ever_killed ())
19024 info_ptr->lr_save_p = 1;
19026 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19027 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19028 && call_used_regs[STATIC_CHAIN_REGNUM]);
19029 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19030 using_static_chain_p);
19032 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19033 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19034 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19035 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19036 info_ptr->lr_save_p = 1;
19038 if (info_ptr->lr_save_p)
19039 df_set_regs_ever_live (LR_REGNO, true);
19041 /* Determine if we need to allocate any stack frame:
19043 For AIX we need to push the stack if a frame pointer is needed
19044 (because the stack might be dynamically adjusted), if we are
19045 debugging, if we make calls, or if the sum of fp_save, gp_save,
19046 and local variables are more than the space needed to save all
19047 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19048 + 18*8 = 288 (GPR13 reserved).
19050 For V.4 we don't have the stack cushion that AIX uses, but assume
19051 that the debugger can handle stackless frames. */
19053 if (info_ptr->calls_p)
19054 info_ptr->push_p = 1;
19056 else if (DEFAULT_ABI == ABI_V4)
19057 info_ptr->push_p = non_fixed_size != 0;
19059 else if (frame_pointer_needed)
19060 info_ptr->push_p = 1;
19062 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19063 info_ptr->push_p = 1;
19066 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19068 /* Zero offsets if we're not saving those registers. */
19069 if (info_ptr->fp_size == 0)
19070 info_ptr->fp_save_offset = 0;
19072 if (info_ptr->gp_size == 0)
19073 info_ptr->gp_save_offset = 0;
19075 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19076 info_ptr->altivec_save_offset = 0;
19078 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19079 info_ptr->vrsave_save_offset = 0;
19081 if (! TARGET_SPE_ABI
19082 || info_ptr->spe_64bit_regs_used == 0
19083 || info_ptr->spe_gp_size == 0)
19084 info_ptr->spe_gp_save_offset = 0;
19086 if (! info_ptr->lr_save_p)
19087 info_ptr->lr_save_offset = 0;
19089 if (! info_ptr->cr_save_p)
19090 info_ptr->cr_save_offset = 0;
19095 /* Return true if the current function uses any GPRs in 64-bit SIMD
19099 spe_func_has_64bit_regs_p (void)
19103 /* Functions that save and restore all the call-saved registers will
19104 need to save/restore the registers in 64-bits. */
19105 if (crtl->calls_eh_return
19106 || cfun->calls_setjmp
19107 || crtl->has_nonlocal_goto)
19110 insns = get_insns ();
19112 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19118 /* FIXME: This should be implemented with attributes...
19120 (set_attr "spe64" "true")....then,
19121 if (get_spe64(insn)) return true;
19123 It's the only reliable way to do the stuff below. */
19125 i = PATTERN (insn);
19126 if (GET_CODE (i) == SET)
19128 enum machine_mode mode = GET_MODE (SET_SRC (i));
19130 if (SPE_VECTOR_MODE (mode))
19132 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19142 debug_stack_info (rs6000_stack_t *info)
19144 const char *abi_string;
19147 info = rs6000_stack_info ();
19149 fprintf (stderr, "\nStack information for function %s:\n",
19150 ((current_function_decl && DECL_NAME (current_function_decl))
19151 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19156 default: abi_string = "Unknown"; break;
19157 case ABI_NONE: abi_string = "NONE"; break;
19158 case ABI_AIX: abi_string = "AIX"; break;
19159 case ABI_DARWIN: abi_string = "Darwin"; break;
19160 case ABI_V4: abi_string = "V.4"; break;
19163 fprintf (stderr, "\tABI = %5s\n", abi_string);
19165 if (TARGET_ALTIVEC_ABI)
19166 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19168 if (TARGET_SPE_ABI)
19169 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19171 if (info->first_gp_reg_save != 32)
19172 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19174 if (info->first_fp_reg_save != 64)
19175 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19177 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19178 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19179 info->first_altivec_reg_save);
19181 if (info->lr_save_p)
19182 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19184 if (info->cr_save_p)
19185 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19187 if (info->vrsave_mask)
19188 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19191 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19194 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19196 if (info->gp_save_offset)
19197 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19199 if (info->fp_save_offset)
19200 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19202 if (info->altivec_save_offset)
19203 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19204 info->altivec_save_offset);
19206 if (info->spe_gp_save_offset)
19207 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19208 info->spe_gp_save_offset);
19210 if (info->vrsave_save_offset)
19211 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19212 info->vrsave_save_offset);
19214 if (info->lr_save_offset)
19215 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19217 if (info->cr_save_offset)
19218 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19220 if (info->varargs_save_offset)
19221 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19223 if (info->total_size)
19224 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19227 if (info->vars_size)
19228 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19231 if (info->parm_size)
19232 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19234 if (info->fixed_size)
19235 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19238 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19240 if (info->spe_gp_size)
19241 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19244 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19246 if (info->altivec_size)
19247 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19249 if (info->vrsave_size)
19250 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19252 if (info->altivec_padding_size)
19253 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19254 info->altivec_padding_size);
19256 if (info->spe_padding_size)
19257 fprintf (stderr, "\tspe_padding_size = %5d\n",
19258 info->spe_padding_size);
19261 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19263 if (info->save_size)
19264 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19266 if (info->reg_size != 4)
19267 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19269 fprintf (stderr, "\n");
19273 rs6000_return_addr (int count, rtx frame)
19275 /* Currently we don't optimize very well between prolog and body
19276 code and for PIC code the code can be actually quite bad, so
19277 don't try to be too clever here. */
19278 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19280 cfun->machine->ra_needs_full_frame = 1;
19287 plus_constant (copy_to_reg
19288 (gen_rtx_MEM (Pmode,
19289 memory_address (Pmode, frame))),
19290 RETURN_ADDRESS_OFFSET)));
19293 cfun->machine->ra_need_lr = 1;
19294 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19297 /* Say whether a function is a candidate for sibcall handling or not.
19298 We do not allow indirect calls to be optimized into sibling calls.
19299 Also, we can't do it if there are any vector parameters; there's
19300 nowhere to put the VRsave code so it works; note that functions with
19301 vector parameters are required to have a prototype, so the argument
19302 type info must be available here. (The tail recursion case can work
19303 with vector parameters, but there's no way to distinguish here.) */
19305 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19310 if (TARGET_ALTIVEC_VRSAVE)
19312 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19313 type; type = TREE_CHAIN (type))
19315 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19319 if (DEFAULT_ABI == ABI_DARWIN
19320 || ((*targetm.binds_local_p) (decl)
19321 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19323 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19325 if (!lookup_attribute ("longcall", attr_list)
19326 || lookup_attribute ("shortcall", attr_list))
19333 /* NULL if INSN insn is valid within a low-overhead loop.
19334 Otherwise return why doloop cannot be applied.
19335 PowerPC uses the COUNT register for branch on table instructions. */
19337 static const char *
19338 rs6000_invalid_within_doloop (const_rtx insn)
19341 return "Function call in the loop.";
19344 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19345 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19346 return "Computed branch in the loop.";
19352 rs6000_ra_ever_killed (void)
19358 if (cfun->is_thunk)
19361 if (cfun->machine->lr_save_state)
19362 return cfun->machine->lr_save_state - 1;
19364 /* regs_ever_live has LR marked as used if any sibcalls are present,
19365 but this should not force saving and restoring in the
19366 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19367 clobbers LR, so that is inappropriate. */
19369 /* Also, the prologue can generate a store into LR that
19370 doesn't really count, like this:
19373 bcl to set PIC register
19377 When we're called from the epilogue, we need to avoid counting
19378 this as a store. */
19380 push_topmost_sequence ();
19381 top = get_insns ();
19382 pop_topmost_sequence ();
19383 reg = gen_rtx_REG (Pmode, LR_REGNO);
19385 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19391 if (!SIBLING_CALL_P (insn))
19394 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19396 else if (set_of (reg, insn) != NULL_RTX
19397 && !prologue_epilogue_contains (insn))
19404 /* Emit instructions needed to load the TOC register.
19405 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19406 a constant pool; or for SVR4 -fpic. */
19409 rs6000_emit_load_toc_table (int fromprolog)
19412 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19414 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19417 rtx lab, tmp1, tmp2, got;
19419 lab = gen_label_rtx ();
19420 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19421 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19423 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19425 got = rs6000_got_sym ();
19426 tmp1 = tmp2 = dest;
19429 tmp1 = gen_reg_rtx (Pmode);
19430 tmp2 = gen_reg_rtx (Pmode);
19432 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19433 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19434 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19435 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19437 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19439 emit_insn (gen_load_toc_v4_pic_si ());
19440 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19442 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19445 rtx temp0 = (fromprolog
19446 ? gen_rtx_REG (Pmode, 0)
19447 : gen_reg_rtx (Pmode));
19453 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19454 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19456 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19457 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19459 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19460 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19461 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19467 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19468 lab = gen_label_rtx ();
19469 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19470 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19471 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19473 emit_insn (gen_addsi3 (dest, temp0, dest));
19475 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19477 /* This is for AIX code running in non-PIC ELF32. */
19480 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19481 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19483 emit_insn (gen_elf_high (dest, realsym));
19484 emit_insn (gen_elf_low (dest, dest, realsym));
19488 gcc_assert (DEFAULT_ABI == ABI_AIX);
19491 emit_insn (gen_load_toc_aix_si (dest));
19493 emit_insn (gen_load_toc_aix_di (dest));
19497 /* Emit instructions to restore the link register after determining where
19498 its value has been stored. */
19501 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19503 rs6000_stack_t *info = rs6000_stack_info ();
19506 operands[0] = source;
19507 operands[1] = scratch;
19509 if (info->lr_save_p)
19511 rtx frame_rtx = stack_pointer_rtx;
19512 HOST_WIDE_INT sp_offset = 0;
19515 if (frame_pointer_needed
19516 || cfun->calls_alloca
19517 || info->total_size > 32767)
19519 tmp = gen_frame_mem (Pmode, frame_rtx);
19520 emit_move_insn (operands[1], tmp);
19521 frame_rtx = operands[1];
19523 else if (info->push_p)
19524 sp_offset = info->total_size;
19526 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19527 tmp = gen_frame_mem (Pmode, tmp);
19528 emit_move_insn (tmp, operands[0]);
19531 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19533 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19534 state of lr_save_p so any change from here on would be a bug. In
19535 particular, stop rs6000_ra_ever_killed from considering the SET
19536 of lr we may have added just above. */
19537 cfun->machine->lr_save_state = info->lr_save_p + 1;
19540 static GTY(()) alias_set_type set = -1;
19543 get_TOC_alias_set (void)
19546 set = new_alias_set ();
19550 /* This returns nonzero if the current function uses the TOC. This is
19551 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19552 is generated by the ABI_V4 load_toc_* patterns. */
19559 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19562 rtx pat = PATTERN (insn);
19565 if (GET_CODE (pat) == PARALLEL)
19566 for (i = 0; i < XVECLEN (pat, 0); i++)
19568 rtx sub = XVECEXP (pat, 0, i);
19569 if (GET_CODE (sub) == USE)
19571 sub = XEXP (sub, 0);
19572 if (GET_CODE (sub) == UNSPEC
19573 && XINT (sub, 1) == UNSPEC_TOC)
19583 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19585 rtx tocrel, tocreg;
19587 if (TARGET_DEBUG_ADDR)
19589 if (GET_CODE (symbol) == SYMBOL_REF)
19590 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19594 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19595 GET_RTX_NAME (GET_CODE (symbol)));
19596 debug_rtx (symbol);
19600 if (!can_create_pseudo_p ())
19601 df_set_regs_ever_live (TOC_REGISTER, true);
19603 tocrel = gen_rtx_CONST (Pmode,
19604 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19606 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19607 if (TARGET_CMODEL != CMODEL_SMALL)
19609 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19610 if (largetoc_reg != NULL)
19612 emit_move_insn (largetoc_reg, hi);
19615 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19618 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19621 /* Issue assembly directives that create a reference to the given DWARF
19622 FRAME_TABLE_LABEL from the current function section. */
19624 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19626 fprintf (asm_out_file, "\t.ref %s\n",
19627 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19630 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19631 and the change to the stack pointer. */
19634 rs6000_emit_stack_tie (void)
19636 rtx mem = gen_frame_mem (BLKmode,
19637 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19639 emit_insn (gen_stack_tie (mem));
19642 /* Emit the correct code for allocating stack space, as insns.
19643 If COPY_REG, make sure a copy of the old frame is left there.
19644 The generated code may use hard register 0 as a temporary. */
19647 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19650 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19651 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19652 rtx todec = gen_int_mode (-size, Pmode);
19655 if (INTVAL (todec) != -size)
19657 warning (0, "stack frame too large");
19658 emit_insn (gen_trap ());
19662 if (crtl->limit_stack)
19664 if (REG_P (stack_limit_rtx)
19665 && REGNO (stack_limit_rtx) > 1
19666 && REGNO (stack_limit_rtx) <= 31)
19668 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19669 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19672 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19674 && DEFAULT_ABI == ABI_V4)
19676 rtx toload = gen_rtx_CONST (VOIDmode,
19677 gen_rtx_PLUS (Pmode,
19681 emit_insn (gen_elf_high (tmp_reg, toload));
19682 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19683 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19687 warning (0, "stack limit expression is not supported");
19691 emit_move_insn (copy_reg, stack_reg);
19695 /* Need a note here so that try_split doesn't get confused. */
19696 if (get_last_insn () == NULL_RTX)
19697 emit_note (NOTE_INSN_DELETED);
19698 insn = emit_move_insn (tmp_reg, todec);
19699 try_split (PATTERN (insn), insn, 0);
19703 insn = emit_insn (TARGET_32BIT
19704 ? gen_movsi_update_stack (stack_reg, stack_reg,
19706 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19707 todec, stack_reg));
19708 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19709 it now and set the alias set/attributes. The above gen_*_update
19710 calls will generate a PARALLEL with the MEM set being the first
19712 par = PATTERN (insn);
19713 gcc_assert (GET_CODE (par) == PARALLEL);
19714 set = XVECEXP (par, 0, 0);
19715 gcc_assert (GET_CODE (set) == SET);
19716 mem = SET_DEST (set);
19717 gcc_assert (MEM_P (mem));
19718 MEM_NOTRAP_P (mem) = 1;
19719 set_mem_alias_set (mem, get_frame_alias_set ());
19721 RTX_FRAME_RELATED_P (insn) = 1;
19722 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19723 gen_rtx_SET (VOIDmode, stack_reg,
19724 gen_rtx_PLUS (Pmode, stack_reg,
19725 GEN_INT (-size))));
19728 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19730 #if PROBE_INTERVAL > 32768
19731 #error Cannot use indexed addressing mode for stack probing
19734 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19735 inclusive. These are offsets from the current stack pointer. */
19738 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19740 /* See if we have a constant small number of probes to generate. If so,
19741 that's the easy case. */
19742 if (first + size <= 32768)
19746 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19747 it exceeds SIZE. If only one probe is needed, this will not
19748 generate any code. Then probe at FIRST + SIZE. */
19749 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19750 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19752 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19755 /* Otherwise, do the same as above, but in a loop. Note that we must be
19756 extra careful with variables wrapping around because we might be at
19757 the very top (or the very bottom) of the address space and we have
19758 to be able to handle this case properly; in particular, we use an
19759 equality test for the loop condition. */
19762 HOST_WIDE_INT rounded_size;
19763 rtx r12 = gen_rtx_REG (Pmode, 12);
19764 rtx r0 = gen_rtx_REG (Pmode, 0);
19766 /* Sanity check for the addressing mode we're going to use. */
19767 gcc_assert (first <= 32768);
19769 /* Step 1: round SIZE to the previous multiple of the interval. */
19771 rounded_size = size & -PROBE_INTERVAL;
19774 /* Step 2: compute initial and final value of the loop counter. */
19776 /* TEST_ADDR = SP + FIRST. */
19777 emit_insn (gen_rtx_SET (VOIDmode, r12,
19778 plus_constant (stack_pointer_rtx, -first)));
19780 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19781 if (rounded_size > 32768)
19783 emit_move_insn (r0, GEN_INT (-rounded_size));
19784 emit_insn (gen_rtx_SET (VOIDmode, r0,
19785 gen_rtx_PLUS (Pmode, r12, r0)));
19788 emit_insn (gen_rtx_SET (VOIDmode, r0,
19789 plus_constant (r12, -rounded_size)));
19792 /* Step 3: the loop
19794 while (TEST_ADDR != LAST_ADDR)
19796 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19800 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19801 until it is equal to ROUNDED_SIZE. */
19804 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19806 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19809 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19810 that SIZE is equal to ROUNDED_SIZE. */
19812 if (size != rounded_size)
19813 emit_stack_probe (plus_constant (r12, rounded_size - size));
19817 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19818 absolute addresses. */
19821 output_probe_stack_range (rtx reg1, rtx reg2)
19823 static int labelno = 0;
19824 char loop_lab[32], end_lab[32];
19827 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19828 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19830 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19832 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19836 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19838 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19840 fputs ("\tbeq 0,", asm_out_file);
19841 assemble_name_raw (asm_out_file, end_lab);
19842 fputc ('\n', asm_out_file);
19844 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19845 xops[1] = GEN_INT (-PROBE_INTERVAL);
19846 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19848 /* Probe at TEST_ADDR and branch. */
19849 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19850 fprintf (asm_out_file, "\tb ");
19851 assemble_name_raw (asm_out_file, loop_lab);
19852 fputc ('\n', asm_out_file);
19854 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19859 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19860 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19861 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19862 deduce these equivalences by itself so it wasn't necessary to hold
19863 its hand so much. */
19866 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19867 rtx reg2, rtx rreg)
19871 /* copy_rtx will not make unique copies of registers, so we need to
19872 ensure we don't have unwanted sharing here. */
19874 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19877 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19879 real = copy_rtx (PATTERN (insn));
19881 if (reg2 != NULL_RTX)
19882 real = replace_rtx (real, reg2, rreg);
19884 real = replace_rtx (real, reg,
19885 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19886 STACK_POINTER_REGNUM),
19889 /* We expect that 'real' is either a SET or a PARALLEL containing
19890 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19891 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19893 if (GET_CODE (real) == SET)
19897 temp = simplify_rtx (SET_SRC (set));
19899 SET_SRC (set) = temp;
19900 temp = simplify_rtx (SET_DEST (set));
19902 SET_DEST (set) = temp;
19903 if (GET_CODE (SET_DEST (set)) == MEM)
19905 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19907 XEXP (SET_DEST (set), 0) = temp;
19914 gcc_assert (GET_CODE (real) == PARALLEL);
19915 for (i = 0; i < XVECLEN (real, 0); i++)
19916 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19918 rtx set = XVECEXP (real, 0, i);
19920 temp = simplify_rtx (SET_SRC (set));
19922 SET_SRC (set) = temp;
19923 temp = simplify_rtx (SET_DEST (set));
19925 SET_DEST (set) = temp;
19926 if (GET_CODE (SET_DEST (set)) == MEM)
19928 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19930 XEXP (SET_DEST (set), 0) = temp;
19932 RTX_FRAME_RELATED_P (set) = 1;
19936 RTX_FRAME_RELATED_P (insn) = 1;
19937 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19940 /* Returns an insn that has a vrsave set operation with the
19941 appropriate CLOBBERs. */
19944 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19947 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19948 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19951 = gen_rtx_SET (VOIDmode,
19953 gen_rtx_UNSPEC_VOLATILE (SImode,
19954 gen_rtvec (2, reg, vrsave),
19955 UNSPECV_SET_VRSAVE));
19959 /* We need to clobber the registers in the mask so the scheduler
19960 does not move sets to VRSAVE before sets of AltiVec registers.
19962 However, if the function receives nonlocal gotos, reload will set
19963 all call saved registers live. We will end up with:
19965 (set (reg 999) (mem))
19966 (parallel [ (set (reg vrsave) (unspec blah))
19967 (clobber (reg 999))])
19969 The clobber will cause the store into reg 999 to be dead, and
19970 flow will attempt to delete an epilogue insn. In this case, we
19971 need an unspec use/set of the register. */
19973 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19974 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19976 if (!epiloguep || call_used_regs [i])
19977 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19978 gen_rtx_REG (V4SImode, i));
19981 rtx reg = gen_rtx_REG (V4SImode, i);
19984 = gen_rtx_SET (VOIDmode,
19986 gen_rtx_UNSPEC (V4SImode,
19987 gen_rtvec (1, reg), 27));
19991 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
19993 for (i = 0; i < nclobs; ++i)
19994 XVECEXP (insn, 0, i) = clobs[i];
19999 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
20000 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
20003 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
20004 unsigned int regno, int offset, HOST_WIDE_INT total_size)
20006 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
20007 rtx replacea, replaceb;
20009 int_rtx = GEN_INT (offset);
20011 /* Some cases that need register indexed addressing. */
20012 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
20013 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
20014 || (TARGET_E500_DOUBLE && mode == DFmode)
20016 && SPE_VECTOR_MODE (mode)
20017 && !SPE_CONST_OFFSET_OK (offset)))
20019 /* Whomever calls us must make sure r11 is available in the
20020 flow path of instructions in the prologue. */
20021 offset_rtx = gen_rtx_REG (Pmode, 11);
20022 emit_move_insn (offset_rtx, int_rtx);
20024 replacea = offset_rtx;
20025 replaceb = int_rtx;
20029 offset_rtx = int_rtx;
20030 replacea = NULL_RTX;
20031 replaceb = NULL_RTX;
20034 reg = gen_rtx_REG (mode, regno);
20035 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20036 mem = gen_frame_mem (mode, addr);
20038 insn = emit_move_insn (mem, reg);
20040 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20043 /* Emit an offset memory reference suitable for a frame store, while
20044 converting to a valid addressing mode. */
20047 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20049 rtx int_rtx, offset_rtx;
20051 int_rtx = GEN_INT (offset);
20053 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20054 || (TARGET_E500_DOUBLE && mode == DFmode))
20056 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20057 emit_move_insn (offset_rtx, int_rtx);
20060 offset_rtx = int_rtx;
20062 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20065 /* Look for user-defined global regs. We should not save and restore these,
20066 and cannot use stmw/lmw if there are any in its range. */
20069 no_global_regs_above (int first, bool gpr)
20072 int last = gpr ? 32 : 64;
20073 for (i = first; i < last; i++)
20074 if (global_regs[i])
20079 #ifndef TARGET_FIX_AND_CONTINUE
20080 #define TARGET_FIX_AND_CONTINUE 0
20083 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20084 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20085 #define LAST_SAVRES_REGISTER 31
20086 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20088 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20090 /* Temporary holding space for an out-of-line register save/restore
20092 static char savres_routine_name[30];
20094 /* Return the name for an out-of-line register save/restore routine.
20095 We are saving/restoring GPRs if GPR is true. */
20098 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20099 bool savep, bool gpr, bool lr)
20101 const char *prefix = "";
20102 const char *suffix = "";
20104 /* Different targets are supposed to define
20105 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20106 routine name could be defined with:
20108 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20110 This is a nice idea in practice, but in reality, things are
20111 complicated in several ways:
20113 - ELF targets have save/restore routines for GPRs.
20115 - SPE targets use different prefixes for 32/64-bit registers, and
20116 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20118 - PPC64 ELF targets have routines for save/restore of GPRs that
20119 differ in what they do with the link register, so having a set
20120 prefix doesn't work. (We only use one of the save routines at
20121 the moment, though.)
20123 - PPC32 elf targets have "exit" versions of the restore routines
20124 that restore the link register and can save some extra space.
20125 These require an extra suffix. (There are also "tail" versions
20126 of the restore routines and "GOT" versions of the save routines,
20127 but we don't generate those at present. Same problems apply,
20130 We deal with all this by synthesizing our own prefix/suffix and
20131 using that for the simple sprintf call shown above. */
20134 /* No floating point saves on the SPE. */
20138 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20140 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20145 else if (DEFAULT_ABI == ABI_V4)
20151 prefix = savep ? "_savegpr_" : "_restgpr_";
20153 prefix = savep ? "_savefpr_" : "_restfpr_";
20158 else if (DEFAULT_ABI == ABI_AIX)
20160 #ifndef POWERPC_LINUX
20161 /* No out-of-line save/restore routines for GPRs on AIX. */
20162 gcc_assert (!TARGET_AIX || !gpr);
20168 ? (lr ? "_savegpr0_" : "_savegpr1_")
20169 : (lr ? "_restgpr0_" : "_restgpr1_"));
20170 #ifdef POWERPC_LINUX
20172 prefix = (savep ? "_savefpr_" : "_restfpr_");
20176 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20177 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20180 else if (DEFAULT_ABI == ABI_DARWIN)
20181 sorry ("out-of-line save/restore routines not supported on Darwin");
20183 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20185 return savres_routine_name;
20188 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20189 We are saving/restoring GPRs if GPR is true. */
20192 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20195 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20197 int select = ((savep ? 1 : 0) << 2
20199 /* On the SPE, we never have any FPRs, but we do have
20200 32/64-bit versions of the routines. */
20201 ? (info->spe_64bit_regs_used ? 1 : 0)
20202 : (gpr ? 1 : 0)) << 1)
20205 /* Don't generate bogus routine names. */
20206 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20207 && regno <= LAST_SAVRES_REGISTER);
20209 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20215 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20217 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20218 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20219 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20225 /* Emit a sequence of insns, including a stack tie if needed, for
20226 resetting the stack pointer. If SAVRES is true, then don't reset the
20227 stack pointer, but move the base of the frame into r11 for use by
20228 out-of-line register restore routines. */
20231 rs6000_emit_stack_reset (rs6000_stack_t *info,
20232 rtx sp_reg_rtx, rtx frame_reg_rtx,
20233 int sp_offset, bool savres)
20235 /* This blockage is needed so that sched doesn't decide to move
20236 the sp change before the register restores. */
20237 if (frame_reg_rtx != sp_reg_rtx
20239 && info->spe_64bit_regs_used != 0
20240 && info->first_gp_reg_save != 32))
20241 rs6000_emit_stack_tie ();
20243 if (frame_reg_rtx != sp_reg_rtx)
20245 if (sp_offset != 0)
20247 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20248 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20249 GEN_INT (sp_offset)));
20252 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20254 else if (sp_offset != 0)
20256 /* If we are restoring registers out-of-line, we will be using the
20257 "exit" variants of the restore routines, which will reset the
20258 stack for us. But we do need to point r11 into the right place
20259 for those routines. */
20260 rtx dest_reg = (savres
20261 ? gen_rtx_REG (Pmode, 11)
20264 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20265 GEN_INT (sp_offset)));
20272 /* Construct a parallel rtx describing the effect of a call to an
20273 out-of-line register save/restore routine. */
20276 rs6000_make_savres_rtx (rs6000_stack_t *info,
20277 rtx frame_reg_rtx, int save_area_offset,
20278 enum machine_mode reg_mode,
20279 bool savep, bool gpr, bool lr)
20282 int offset, start_reg, end_reg, n_regs;
20283 int reg_size = GET_MODE_SIZE (reg_mode);
20289 ? info->first_gp_reg_save
20290 : info->first_fp_reg_save);
20291 end_reg = gpr ? 32 : 64;
20292 n_regs = end_reg - start_reg;
20293 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20296 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20298 RTVEC_ELT (p, offset++)
20299 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20301 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20302 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20303 RTVEC_ELT (p, offset++)
20304 = gen_rtx_USE (VOIDmode,
20305 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20309 for (i = 0; i < end_reg - start_reg; i++)
20311 rtx addr, reg, mem;
20312 reg = gen_rtx_REG (reg_mode, start_reg + i);
20313 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20314 GEN_INT (save_area_offset + reg_size*i));
20315 mem = gen_frame_mem (reg_mode, addr);
20317 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20319 savep ? reg : mem);
20324 rtx addr, reg, mem;
20325 reg = gen_rtx_REG (Pmode, 0);
20326 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20327 GEN_INT (info->lr_save_offset));
20328 mem = gen_frame_mem (Pmode, addr);
20329 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20332 return gen_rtx_PARALLEL (VOIDmode, p);
20335 /* Determine whether the gp REG is really used. */
20338 rs6000_reg_live_or_pic_offset_p (int reg)
20340 /* If the function calls eh_return, claim used all the registers that would
20341 be checked for liveness otherwise. This is required for the PIC offset
20342 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20343 register allocation purposes in this case. */
20345 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20346 && (!call_used_regs[reg]
20347 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20348 && !TARGET_SINGLE_PIC_BASE
20349 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20350 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20351 && !TARGET_SINGLE_PIC_BASE
20352 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20353 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20356 /* Emit function prologue as insns. */
20359 rs6000_emit_prologue (void)
20361 rs6000_stack_t *info = rs6000_stack_info ();
20362 enum machine_mode reg_mode = Pmode;
20363 int reg_size = TARGET_32BIT ? 4 : 8;
20364 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20365 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20366 rtx frame_reg_rtx = sp_reg_rtx;
20367 rtx cr_save_rtx = NULL_RTX;
20370 int saving_FPRs_inline;
20371 int saving_GPRs_inline;
20372 int using_store_multiple;
20373 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20374 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20375 && call_used_regs[STATIC_CHAIN_REGNUM]);
20376 HOST_WIDE_INT sp_offset = 0;
20378 if (flag_stack_usage)
20379 current_function_static_stack_size = info->total_size;
20381 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20382 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20384 if (TARGET_FIX_AND_CONTINUE)
20386 /* gdb on darwin arranges to forward a function from the old
20387 address by modifying the first 5 instructions of the function
20388 to branch to the overriding function. This is necessary to
20389 permit function pointers that point to the old function to
20390 actually forward to the new function. */
20391 emit_insn (gen_nop ());
20392 emit_insn (gen_nop ());
20393 emit_insn (gen_nop ());
20394 emit_insn (gen_nop ());
20395 emit_insn (gen_nop ());
20398 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20400 reg_mode = V2SImode;
20404 strategy = info->savres_strategy;
20405 using_store_multiple = strategy & SAVRES_MULTIPLE;
20406 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20407 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20409 /* For V.4, update stack before we do any saving and set back pointer. */
20410 if (! WORLD_SAVE_P (info)
20412 && (DEFAULT_ABI == ABI_V4
20413 || crtl->calls_eh_return))
20415 bool need_r11 = (TARGET_SPE
20416 ? (!saving_GPRs_inline
20417 && info->spe_64bit_regs_used == 0)
20418 : (!saving_FPRs_inline || !saving_GPRs_inline));
20419 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20421 if (info->total_size < 32767)
20422 sp_offset = info->total_size;
20424 frame_reg_rtx = copy_reg;
20425 else if (info->cr_save_p
20427 || info->first_fp_reg_save < 64
20428 || info->first_gp_reg_save < 32
20429 || info->altivec_size != 0
20430 || info->vrsave_mask != 0
20431 || crtl->calls_eh_return)
20433 copy_reg = frame_ptr_rtx;
20434 frame_reg_rtx = copy_reg;
20438 /* The prologue won't be saving any regs so there is no need
20439 to set up a frame register to access any frame save area.
20440 We also won't be using sp_offset anywhere below, but set
20441 the correct value anyway to protect against future
20442 changes to this function. */
20443 sp_offset = info->total_size;
20445 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20446 if (frame_reg_rtx != sp_reg_rtx)
20447 rs6000_emit_stack_tie ();
20450 /* Handle world saves specially here. */
20451 if (WORLD_SAVE_P (info))
20458 /* save_world expects lr in r0. */
20459 reg0 = gen_rtx_REG (Pmode, 0);
20460 if (info->lr_save_p)
20462 insn = emit_move_insn (reg0,
20463 gen_rtx_REG (Pmode, LR_REGNO));
20464 RTX_FRAME_RELATED_P (insn) = 1;
20467 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20468 assumptions about the offsets of various bits of the stack
20470 gcc_assert (info->gp_save_offset == -220
20471 && info->fp_save_offset == -144
20472 && info->lr_save_offset == 8
20473 && info->cr_save_offset == 4
20476 && (!crtl->calls_eh_return
20477 || info->ehrd_offset == -432)
20478 && info->vrsave_save_offset == -224
20479 && info->altivec_save_offset == -416);
20481 treg = gen_rtx_REG (SImode, 11);
20482 emit_move_insn (treg, GEN_INT (-info->total_size));
20484 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20485 in R11. It also clobbers R12, so beware! */
20487 /* Preserve CR2 for save_world prologues */
20489 sz += 32 - info->first_gp_reg_save;
20490 sz += 64 - info->first_fp_reg_save;
20491 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20492 p = rtvec_alloc (sz);
20494 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20495 gen_rtx_REG (SImode,
20497 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20498 gen_rtx_SYMBOL_REF (Pmode,
20500 /* We do floats first so that the instruction pattern matches
20502 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20504 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20505 ? DFmode : SFmode),
20506 info->first_fp_reg_save + i);
20507 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20508 GEN_INT (info->fp_save_offset
20509 + sp_offset + 8 * i));
20510 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20511 ? DFmode : SFmode), addr);
20513 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20515 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20517 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20518 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20519 GEN_INT (info->altivec_save_offset
20520 + sp_offset + 16 * i));
20521 rtx mem = gen_frame_mem (V4SImode, addr);
20523 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20525 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20527 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20528 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20529 GEN_INT (info->gp_save_offset
20530 + sp_offset + reg_size * i));
20531 rtx mem = gen_frame_mem (reg_mode, addr);
20533 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20537 /* CR register traditionally saved as CR2. */
20538 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20539 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20540 GEN_INT (info->cr_save_offset
20542 rtx mem = gen_frame_mem (reg_mode, addr);
20544 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20546 /* Explain about use of R0. */
20547 if (info->lr_save_p)
20549 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20550 GEN_INT (info->lr_save_offset
20552 rtx mem = gen_frame_mem (reg_mode, addr);
20554 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20556 /* Explain what happens to the stack pointer. */
20558 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20559 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20562 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20563 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20564 treg, GEN_INT (-info->total_size));
20565 sp_offset = info->total_size;
20568 /* If we use the link register, get it into r0. */
20569 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20571 rtx addr, reg, mem;
20573 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20574 gen_rtx_REG (Pmode, LR_REGNO));
20575 RTX_FRAME_RELATED_P (insn) = 1;
20577 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20578 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20580 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20581 GEN_INT (info->lr_save_offset + sp_offset));
20582 reg = gen_rtx_REG (Pmode, 0);
20583 mem = gen_rtx_MEM (Pmode, addr);
20584 /* This should not be of rs6000_sr_alias_set, because of
20585 __builtin_return_address. */
20587 insn = emit_move_insn (mem, reg);
20588 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20589 NULL_RTX, NULL_RTX);
20593 /* If we need to save CR, put it into r12 or r11. */
20594 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20599 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20601 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20602 RTX_FRAME_RELATED_P (insn) = 1;
20603 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20604 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20605 But that's OK. All we have to do is specify that _one_ condition
20606 code register is saved in this stack slot. The thrower's epilogue
20607 will then restore all the call-saved registers.
20608 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20609 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20610 gen_rtx_REG (SImode, CR2_REGNO));
20611 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20614 /* Do any required saving of fpr's. If only one or two to save, do
20615 it ourselves. Otherwise, call function. */
20616 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20619 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20620 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20621 && ! call_used_regs[info->first_fp_reg_save+i]))
20622 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20623 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20625 info->first_fp_reg_save + i,
20626 info->fp_save_offset + sp_offset + 8 * i,
20629 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20633 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20634 info->fp_save_offset + sp_offset,
20636 /*savep=*/true, /*gpr=*/false,
20638 & SAVE_NOINLINE_FPRS_SAVES_LR)
20640 insn = emit_insn (par);
20641 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20642 NULL_RTX, NULL_RTX);
20645 /* Save GPRs. This is done as a PARALLEL if we are using
20646 the store-multiple instructions. */
20647 if (!WORLD_SAVE_P (info)
20649 && info->spe_64bit_regs_used != 0
20650 && info->first_gp_reg_save != 32)
20653 rtx spe_save_area_ptr;
20655 /* Determine whether we can address all of the registers that need
20656 to be saved with an offset from the stack pointer that fits in
20657 the small const field for SPE memory instructions. */
20658 int spe_regs_addressable_via_sp
20659 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20660 + (32 - info->first_gp_reg_save - 1) * reg_size)
20661 && saving_GPRs_inline);
20664 if (spe_regs_addressable_via_sp)
20666 spe_save_area_ptr = frame_reg_rtx;
20667 spe_offset = info->spe_gp_save_offset + sp_offset;
20671 /* Make r11 point to the start of the SPE save area. We need
20672 to be careful here if r11 is holding the static chain. If
20673 it is, then temporarily save it in r0. We would use r0 as
20674 our base register here, but using r0 as a base register in
20675 loads and stores means something different from what we
20677 int ool_adjust = (saving_GPRs_inline
20679 : (info->first_gp_reg_save
20680 - (FIRST_SAVRES_REGISTER+1))*8);
20681 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20682 + sp_offset - ool_adjust);
20684 if (using_static_chain_p)
20686 rtx r0 = gen_rtx_REG (Pmode, 0);
20687 gcc_assert (info->first_gp_reg_save > 11);
20689 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20692 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20693 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20695 GEN_INT (offset)));
20696 /* We need to make sure the move to r11 gets noted for
20697 properly outputting unwind information. */
20698 if (!saving_GPRs_inline)
20699 rs6000_frame_related (insn, frame_reg_rtx, offset,
20700 NULL_RTX, NULL_RTX);
20704 if (saving_GPRs_inline)
20706 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20707 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20709 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20710 rtx offset, addr, mem;
20712 /* We're doing all this to ensure that the offset fits into
20713 the immediate offset of 'evstdd'. */
20714 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20716 offset = GEN_INT (reg_size * i + spe_offset);
20717 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20718 mem = gen_rtx_MEM (V2SImode, addr);
20720 insn = emit_move_insn (mem, reg);
20722 rs6000_frame_related (insn, spe_save_area_ptr,
20723 info->spe_gp_save_offset
20724 + sp_offset + reg_size * i,
20725 offset, const0_rtx);
20732 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20734 /*savep=*/true, /*gpr=*/true,
20736 insn = emit_insn (par);
20737 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20738 NULL_RTX, NULL_RTX);
20742 /* Move the static chain pointer back. */
20743 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20744 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20746 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20750 /* Need to adjust r11 (r12) if we saved any FPRs. */
20751 if (info->first_fp_reg_save != 64)
20753 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20755 rtx offset = GEN_INT (sp_offset
20756 + (-8 * (64-info->first_fp_reg_save)));
20757 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20760 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20761 info->gp_save_offset + sp_offset,
20763 /*savep=*/true, /*gpr=*/true,
20765 & SAVE_NOINLINE_GPRS_SAVES_LR)
20767 insn = emit_insn (par);
20768 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20769 NULL_RTX, NULL_RTX);
20771 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20775 p = rtvec_alloc (32 - info->first_gp_reg_save);
20776 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20778 rtx addr, reg, mem;
20779 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20780 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20781 GEN_INT (info->gp_save_offset
20784 mem = gen_frame_mem (reg_mode, addr);
20786 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20788 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20789 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20790 NULL_RTX, NULL_RTX);
20792 else if (!WORLD_SAVE_P (info))
20795 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20796 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20798 rtx addr, reg, mem;
20799 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20801 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20802 GEN_INT (info->gp_save_offset
20805 mem = gen_frame_mem (reg_mode, addr);
20807 insn = emit_move_insn (mem, reg);
20808 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20809 NULL_RTX, NULL_RTX);
20813 /* ??? There's no need to emit actual instructions here, but it's the
20814 easiest way to get the frame unwind information emitted. */
20815 if (crtl->calls_eh_return)
20817 unsigned int i, regno;
20821 regno = EH_RETURN_DATA_REGNO (i);
20822 if (regno == INVALID_REGNUM)
20825 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20826 info->ehrd_offset + sp_offset
20827 + reg_size * (int) i,
20832 /* In AIX ABI we need to make sure r2 is really saved. */
20833 if (TARGET_AIX && crtl->calls_eh_return)
20835 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20836 long toc_restore_insn;
20838 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20839 || frame_reg_rtx == sp_reg_rtx);
20840 tmp_reg = gen_rtx_REG (Pmode, 11);
20841 tmp_reg_si = gen_rtx_REG (SImode, 11);
20842 if (using_static_chain_p)
20843 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20844 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20845 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20846 /* Peek at instruction to which this function returns. If it's
20847 restoring r2, then we know we've already saved r2. We can't
20848 unconditionally save r2 because the value we have will already
20849 be updated if we arrived at this function via a plt call or
20850 toc adjusting stub. */
20851 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20852 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20853 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20854 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20855 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20856 validate_condition_mode (EQ, CCUNSmode);
20857 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20858 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20859 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20860 toc_save_done = gen_label_rtx ();
20861 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20862 gen_rtx_EQ (VOIDmode, compare_result,
20864 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20866 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20867 JUMP_LABEL (jump) = toc_save_done;
20868 LABEL_NUSES (toc_save_done) += 1;
20870 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20871 sp_offset + 5 * reg_size, info->total_size);
20872 emit_label (toc_save_done);
20873 if (using_static_chain_p)
20874 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20877 /* Save CR if we use any that must be preserved. */
20878 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20880 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20881 GEN_INT (info->cr_save_offset + sp_offset));
20882 rtx mem = gen_frame_mem (SImode, addr);
20883 /* See the large comment above about why CR2_REGNO is used. */
20884 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20886 /* If r12 was used to hold the original sp, copy cr into r0 now
20888 if (REGNO (frame_reg_rtx) == 12)
20892 cr_save_rtx = gen_rtx_REG (SImode, 0);
20893 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20894 RTX_FRAME_RELATED_P (insn) = 1;
20895 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20896 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20898 insn = emit_move_insn (mem, cr_save_rtx);
20900 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20901 NULL_RTX, NULL_RTX);
20904 /* Update stack and set back pointer unless this is V.4,
20905 for which it was done previously. */
20906 if (!WORLD_SAVE_P (info) && info->push_p
20907 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20909 rtx copy_reg = NULL;
20911 if (info->total_size < 32767)
20912 sp_offset = info->total_size;
20913 else if (info->altivec_size != 0
20914 || info->vrsave_mask != 0)
20916 copy_reg = frame_ptr_rtx;
20917 frame_reg_rtx = copy_reg;
20920 sp_offset = info->total_size;
20921 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20922 if (frame_reg_rtx != sp_reg_rtx)
20923 rs6000_emit_stack_tie ();
20926 /* Set frame pointer, if needed. */
20927 if (frame_pointer_needed)
20929 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20931 RTX_FRAME_RELATED_P (insn) = 1;
20934 /* Save AltiVec registers if needed. Save here because the red zone does
20935 not include AltiVec registers. */
20936 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20940 /* There should be a non inline version of this, for when we
20941 are saving lots of vector registers. */
20942 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20943 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20945 rtx areg, savereg, mem;
20948 offset = info->altivec_save_offset + sp_offset
20949 + 16 * (i - info->first_altivec_reg_save);
20951 savereg = gen_rtx_REG (V4SImode, i);
20953 areg = gen_rtx_REG (Pmode, 0);
20954 emit_move_insn (areg, GEN_INT (offset));
20956 /* AltiVec addressing mode is [reg+reg]. */
20957 mem = gen_frame_mem (V4SImode,
20958 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20960 insn = emit_move_insn (mem, savereg);
20962 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20963 areg, GEN_INT (offset));
20967 /* VRSAVE is a bit vector representing which AltiVec registers
20968 are used. The OS uses this to determine which vector
20969 registers to save on a context switch. We need to save
20970 VRSAVE on the stack frame, add whatever AltiVec registers we
20971 used in this function, and do the corresponding magic in the
20974 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20975 && info->vrsave_mask != 0)
20977 rtx reg, mem, vrsave;
20980 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20981 as frame_reg_rtx and r11 as the static chain pointer for
20982 nested functions. */
20983 reg = gen_rtx_REG (SImode, 0);
20984 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20986 emit_insn (gen_get_vrsave_internal (reg));
20988 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20990 if (!WORLD_SAVE_P (info))
20993 offset = info->vrsave_save_offset + sp_offset;
20994 mem = gen_frame_mem (SImode,
20995 gen_rtx_PLUS (Pmode, frame_reg_rtx,
20996 GEN_INT (offset)));
20997 insn = emit_move_insn (mem, reg);
21000 /* Include the registers in the mask. */
21001 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
21003 insn = emit_insn (generate_set_vrsave (reg, info, 0));
21006 if (TARGET_SINGLE_PIC_BASE)
21007 return; /* Do not set PIC register */
21009 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
21010 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
21011 || (DEFAULT_ABI == ABI_V4
21012 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
21013 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
21015 /* If emit_load_toc_table will use the link register, we need to save
21016 it. We use R12 for this purpose because emit_load_toc_table
21017 can use register 0. This allows us to use a plain 'blr' to return
21018 from the procedure more often. */
21019 int save_LR_around_toc_setup = (TARGET_ELF
21020 && DEFAULT_ABI != ABI_AIX
21022 && ! info->lr_save_p
21023 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21024 if (save_LR_around_toc_setup)
21026 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21028 insn = emit_move_insn (frame_ptr_rtx, lr);
21029 RTX_FRAME_RELATED_P (insn) = 1;
21031 rs6000_emit_load_toc_table (TRUE);
21033 insn = emit_move_insn (lr, frame_ptr_rtx);
21034 RTX_FRAME_RELATED_P (insn) = 1;
21037 rs6000_emit_load_toc_table (TRUE);
21041 if (DEFAULT_ABI == ABI_DARWIN
21042 && flag_pic && crtl->uses_pic_offset_table)
21044 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21045 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21047 /* Save and restore LR locally around this call (in R0). */
21048 if (!info->lr_save_p)
21049 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21051 emit_insn (gen_load_macho_picbase (src));
21053 emit_move_insn (gen_rtx_REG (Pmode,
21054 RS6000_PIC_OFFSET_TABLE_REGNUM),
21057 if (!info->lr_save_p)
21058 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21063 /* Write function prologue. */
21066 rs6000_output_function_prologue (FILE *file,
21067 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21069 rs6000_stack_t *info = rs6000_stack_info ();
21071 if (TARGET_DEBUG_STACK)
21072 debug_stack_info (info);
21074 /* Write .extern for any function we will call to save and restore
21076 if (info->first_fp_reg_save < 64)
21079 int regno = info->first_fp_reg_save - 32;
21081 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21083 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21084 /*gpr=*/false, /*lr=*/false);
21085 fprintf (file, "\t.extern %s\n", name);
21087 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21089 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21090 /*gpr=*/false, /*lr=*/true);
21091 fprintf (file, "\t.extern %s\n", name);
21095 /* Write .extern for AIX common mode routines, if needed. */
21096 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21098 fputs ("\t.extern __mulh\n", file);
21099 fputs ("\t.extern __mull\n", file);
21100 fputs ("\t.extern __divss\n", file);
21101 fputs ("\t.extern __divus\n", file);
21102 fputs ("\t.extern __quoss\n", file);
21103 fputs ("\t.extern __quous\n", file);
21104 common_mode_defined = 1;
21107 if (! HAVE_prologue)
21113 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21114 the "toplevel" insn chain. */
21115 emit_note (NOTE_INSN_DELETED);
21116 rs6000_emit_prologue ();
21117 emit_note (NOTE_INSN_DELETED);
21119 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21123 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21125 INSN_ADDRESSES_NEW (insn, addr);
21130 prologue = get_insns ();
21133 if (TARGET_DEBUG_STACK)
21134 debug_rtx_list (prologue, 100);
21136 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21140 rs6000_pic_labelno++;
21143 /* Non-zero if vmx regs are restored before the frame pop, zero if
21144 we restore after the pop when possible. */
21145 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21147 /* Reload CR from REG. */
21150 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21155 if (using_mfcr_multiple)
21157 for (i = 0; i < 8; i++)
21158 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21160 gcc_assert (count);
21163 if (using_mfcr_multiple && count > 1)
21168 p = rtvec_alloc (count);
21171 for (i = 0; i < 8; i++)
21172 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21174 rtvec r = rtvec_alloc (2);
21175 RTVEC_ELT (r, 0) = reg;
21176 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21177 RTVEC_ELT (p, ndx) =
21178 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21179 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21182 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21183 gcc_assert (ndx == count);
21186 for (i = 0; i < 8; i++)
21187 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21189 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21195 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21196 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21197 below stack pointer not cloberred by signals. */
21200 offset_below_red_zone_p (HOST_WIDE_INT offset)
21202 return offset < (DEFAULT_ABI == ABI_V4
21204 : TARGET_32BIT ? -220 : -288);
21207 /* Emit function epilogue as insns. */
21210 rs6000_emit_epilogue (int sibcall)
21212 rs6000_stack_t *info;
21213 int restoring_GPRs_inline;
21214 int restoring_FPRs_inline;
21215 int using_load_multiple;
21216 int using_mtcr_multiple;
21217 int use_backchain_to_restore_sp;
21221 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21222 rtx frame_reg_rtx = sp_reg_rtx;
21223 rtx cfa_restores = NULL_RTX;
21225 rtx cr_save_reg = NULL_RTX;
21226 enum machine_mode reg_mode = Pmode;
21227 int reg_size = TARGET_32BIT ? 4 : 8;
21230 info = rs6000_stack_info ();
21232 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21234 reg_mode = V2SImode;
21238 strategy = info->savres_strategy;
21239 using_load_multiple = strategy & SAVRES_MULTIPLE;
21240 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21241 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21242 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21243 || rs6000_cpu == PROCESSOR_PPC603
21244 || rs6000_cpu == PROCESSOR_PPC750
21246 /* Restore via the backchain when we have a large frame, since this
21247 is more efficient than an addis, addi pair. The second condition
21248 here will not trigger at the moment; We don't actually need a
21249 frame pointer for alloca, but the generic parts of the compiler
21250 give us one anyway. */
21251 use_backchain_to_restore_sp = (info->total_size > 32767
21252 || info->total_size
21253 + (info->lr_save_p ? info->lr_save_offset : 0)
21255 || (cfun->calls_alloca
21256 && !frame_pointer_needed));
21257 restore_lr = (info->lr_save_p
21258 && (restoring_FPRs_inline
21259 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21260 && (restoring_GPRs_inline
21261 || info->first_fp_reg_save < 64));
21263 if (WORLD_SAVE_P (info))
21267 const char *alloc_rname;
21270 /* eh_rest_world_r10 will return to the location saved in the LR
21271 stack slot (which is not likely to be our caller.)
21272 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21273 rest_world is similar, except any R10 parameter is ignored.
21274 The exception-handling stuff that was here in 2.95 is no
21275 longer necessary. */
21279 + 32 - info->first_gp_reg_save
21280 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21281 + 63 + 1 - info->first_fp_reg_save);
21283 strcpy (rname, ((crtl->calls_eh_return) ?
21284 "*eh_rest_world_r10" : "*rest_world"));
21285 alloc_rname = ggc_strdup (rname);
21288 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21289 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21290 gen_rtx_REG (Pmode,
21293 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21294 /* The instruction pattern requires a clobber here;
21295 it is shared with the restVEC helper. */
21297 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21300 /* CR register traditionally saved as CR2. */
21301 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21302 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21303 GEN_INT (info->cr_save_offset));
21304 rtx mem = gen_frame_mem (reg_mode, addr);
21306 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21309 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21311 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21312 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21313 GEN_INT (info->gp_save_offset
21315 rtx mem = gen_frame_mem (reg_mode, addr);
21317 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21319 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21321 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21322 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21323 GEN_INT (info->altivec_save_offset
21325 rtx mem = gen_frame_mem (V4SImode, addr);
21327 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21329 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21331 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21332 ? DFmode : SFmode),
21333 info->first_fp_reg_save + i);
21334 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21335 GEN_INT (info->fp_save_offset
21337 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21338 ? DFmode : SFmode), addr);
21340 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21343 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21345 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21347 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21349 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21351 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21352 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21357 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21359 sp_offset = info->total_size;
21361 /* Restore AltiVec registers if we must do so before adjusting the
21363 if (TARGET_ALTIVEC_ABI
21364 && info->altivec_size != 0
21365 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21366 || (DEFAULT_ABI != ABI_V4
21367 && offset_below_red_zone_p (info->altivec_save_offset))))
21371 if (use_backchain_to_restore_sp)
21373 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21374 emit_move_insn (frame_reg_rtx,
21375 gen_rtx_MEM (Pmode, sp_reg_rtx));
21378 else if (frame_pointer_needed)
21379 frame_reg_rtx = hard_frame_pointer_rtx;
21381 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21382 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21384 rtx addr, areg, mem, reg;
21386 areg = gen_rtx_REG (Pmode, 0);
21388 (areg, GEN_INT (info->altivec_save_offset
21390 + 16 * (i - info->first_altivec_reg_save)));
21392 /* AltiVec addressing mode is [reg+reg]. */
21393 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21394 mem = gen_frame_mem (V4SImode, addr);
21396 reg = gen_rtx_REG (V4SImode, i);
21397 emit_move_insn (reg, mem);
21398 if (offset_below_red_zone_p (info->altivec_save_offset
21399 + (i - info->first_altivec_reg_save)
21401 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21406 /* Restore VRSAVE if we must do so before adjusting the stack. */
21408 && TARGET_ALTIVEC_VRSAVE
21409 && info->vrsave_mask != 0
21410 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21411 || (DEFAULT_ABI != ABI_V4
21412 && offset_below_red_zone_p (info->vrsave_save_offset))))
21414 rtx addr, mem, reg;
21416 if (frame_reg_rtx == sp_reg_rtx)
21418 if (use_backchain_to_restore_sp)
21420 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21421 emit_move_insn (frame_reg_rtx,
21422 gen_rtx_MEM (Pmode, sp_reg_rtx));
21425 else if (frame_pointer_needed)
21426 frame_reg_rtx = hard_frame_pointer_rtx;
21429 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21430 GEN_INT (info->vrsave_save_offset + sp_offset));
21431 mem = gen_frame_mem (SImode, addr);
21432 reg = gen_rtx_REG (SImode, 12);
21433 emit_move_insn (reg, mem);
21435 emit_insn (generate_set_vrsave (reg, info, 1));
21439 /* If we have a large stack frame, restore the old stack pointer
21440 using the backchain. */
21441 if (use_backchain_to_restore_sp)
21443 if (frame_reg_rtx == sp_reg_rtx)
21445 /* Under V.4, don't reset the stack pointer until after we're done
21446 loading the saved registers. */
21447 if (DEFAULT_ABI == ABI_V4)
21448 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21450 insn = emit_move_insn (frame_reg_rtx,
21451 gen_rtx_MEM (Pmode, sp_reg_rtx));
21454 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21455 && DEFAULT_ABI == ABI_V4)
21456 /* frame_reg_rtx has been set up by the altivec restore. */
21460 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21461 frame_reg_rtx = sp_reg_rtx;
21464 /* If we have a frame pointer, we can restore the old stack pointer
21466 else if (frame_pointer_needed)
21468 frame_reg_rtx = sp_reg_rtx;
21469 if (DEFAULT_ABI == ABI_V4)
21470 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21471 /* Prevent reordering memory accesses against stack pointer restore. */
21472 else if (cfun->calls_alloca
21473 || offset_below_red_zone_p (-info->total_size))
21475 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21476 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21477 MEM_NOTRAP_P (mem1) = 1;
21478 MEM_NOTRAP_P (mem2) = 1;
21479 emit_insn (gen_frame_tie (mem1, mem2));
21482 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21483 GEN_INT (info->total_size)));
21486 else if (info->push_p
21487 && DEFAULT_ABI != ABI_V4
21488 && !crtl->calls_eh_return)
21490 /* Prevent reordering memory accesses against stack pointer restore. */
21491 if (cfun->calls_alloca
21492 || offset_below_red_zone_p (-info->total_size))
21494 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21495 MEM_NOTRAP_P (mem) = 1;
21496 emit_insn (gen_stack_tie (mem));
21498 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21499 GEN_INT (info->total_size)));
21502 if (insn && frame_reg_rtx == sp_reg_rtx)
21506 REG_NOTES (insn) = cfa_restores;
21507 cfa_restores = NULL_RTX;
21509 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21510 RTX_FRAME_RELATED_P (insn) = 1;
21513 /* Restore AltiVec registers if we have not done so already. */
21514 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21515 && TARGET_ALTIVEC_ABI
21516 && info->altivec_size != 0
21517 && (DEFAULT_ABI == ABI_V4
21518 || !offset_below_red_zone_p (info->altivec_save_offset)))
21522 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21523 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21525 rtx addr, areg, mem, reg;
21527 areg = gen_rtx_REG (Pmode, 0);
21529 (areg, GEN_INT (info->altivec_save_offset
21531 + 16 * (i - info->first_altivec_reg_save)));
21533 /* AltiVec addressing mode is [reg+reg]. */
21534 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21535 mem = gen_frame_mem (V4SImode, addr);
21537 reg = gen_rtx_REG (V4SImode, i);
21538 emit_move_insn (reg, mem);
21539 if (DEFAULT_ABI == ABI_V4)
21540 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21545 /* Restore VRSAVE if we have not done so already. */
21546 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21548 && TARGET_ALTIVEC_VRSAVE
21549 && info->vrsave_mask != 0
21550 && (DEFAULT_ABI == ABI_V4
21551 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21553 rtx addr, mem, reg;
21555 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21556 GEN_INT (info->vrsave_save_offset + sp_offset));
21557 mem = gen_frame_mem (SImode, addr);
21558 reg = gen_rtx_REG (SImode, 12);
21559 emit_move_insn (reg, mem);
21561 emit_insn (generate_set_vrsave (reg, info, 1));
21564 /* Get the old lr if we saved it. If we are restoring registers
21565 out-of-line, then the out-of-line routines can do this for us. */
21566 if (restore_lr && restoring_GPRs_inline)
21568 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21569 info->lr_save_offset + sp_offset);
21571 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21574 /* Get the old cr if we saved it. */
21575 if (info->cr_save_p)
21577 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21578 GEN_INT (info->cr_save_offset + sp_offset));
21579 rtx mem = gen_frame_mem (SImode, addr);
21581 cr_save_reg = gen_rtx_REG (SImode,
21582 DEFAULT_ABI == ABI_AIX
21583 && !restoring_GPRs_inline
21584 && info->first_fp_reg_save < 64
21586 emit_move_insn (cr_save_reg, mem);
21589 /* Set LR here to try to overlap restores below. LR is always saved
21590 above incoming stack, so it never needs REG_CFA_RESTORE. */
21591 if (restore_lr && restoring_GPRs_inline)
21592 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21593 gen_rtx_REG (Pmode, 0));
21595 /* Load exception handler data registers, if needed. */
21596 if (crtl->calls_eh_return)
21598 unsigned int i, regno;
21602 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21603 GEN_INT (sp_offset + 5 * reg_size));
21604 rtx mem = gen_frame_mem (reg_mode, addr);
21606 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21613 regno = EH_RETURN_DATA_REGNO (i);
21614 if (regno == INVALID_REGNUM)
21617 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21618 info->ehrd_offset + sp_offset
21619 + reg_size * (int) i);
21621 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21625 /* Restore GPRs. This is done as a PARALLEL if we are using
21626 the load-multiple instructions. */
21628 && info->spe_64bit_regs_used != 0
21629 && info->first_gp_reg_save != 32)
21631 /* Determine whether we can address all of the registers that need
21632 to be saved with an offset from the stack pointer that fits in
21633 the small const field for SPE memory instructions. */
21634 int spe_regs_addressable_via_sp
21635 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21636 + (32 - info->first_gp_reg_save - 1) * reg_size)
21637 && restoring_GPRs_inline);
21640 if (spe_regs_addressable_via_sp)
21641 spe_offset = info->spe_gp_save_offset + sp_offset;
21644 rtx old_frame_reg_rtx = frame_reg_rtx;
21645 /* Make r11 point to the start of the SPE save area. We worried about
21646 not clobbering it when we were saving registers in the prologue.
21647 There's no need to worry here because the static chain is passed
21648 anew to every function. */
21649 int ool_adjust = (restoring_GPRs_inline
21651 : (info->first_gp_reg_save
21652 - (FIRST_SAVRES_REGISTER+1))*8);
21654 if (frame_reg_rtx == sp_reg_rtx)
21655 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21656 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21657 GEN_INT (info->spe_gp_save_offset
21660 /* Keep the invariant that frame_reg_rtx + sp_offset points
21661 at the top of the stack frame. */
21662 sp_offset = -info->spe_gp_save_offset;
21667 if (restoring_GPRs_inline)
21669 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21670 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21672 rtx offset, addr, mem, reg;
21674 /* We're doing all this to ensure that the immediate offset
21675 fits into the immediate field of 'evldd'. */
21676 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21678 offset = GEN_INT (spe_offset + reg_size * i);
21679 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21680 mem = gen_rtx_MEM (V2SImode, addr);
21681 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21683 insn = emit_move_insn (reg, mem);
21684 if (DEFAULT_ABI == ABI_V4)
21686 if (frame_pointer_needed
21687 && info->first_gp_reg_save + i
21688 == HARD_FRAME_POINTER_REGNUM)
21690 add_reg_note (insn, REG_CFA_DEF_CFA,
21691 plus_constant (frame_reg_rtx,
21693 RTX_FRAME_RELATED_P (insn) = 1;
21696 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21705 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21707 /*savep=*/false, /*gpr=*/true,
21709 emit_jump_insn (par);
21710 /* We don't want anybody else emitting things after we jumped
21715 else if (!restoring_GPRs_inline)
21717 /* We are jumping to an out-of-line function. */
21718 bool can_use_exit = info->first_fp_reg_save == 64;
21721 /* Emit stack reset code if we need it. */
21723 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21724 sp_offset, can_use_exit);
21727 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21730 GEN_INT (sp_offset - info->fp_size)));
21731 if (REGNO (frame_reg_rtx) == 11)
21732 sp_offset += info->fp_size;
21735 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21736 info->gp_save_offset, reg_mode,
21737 /*savep=*/false, /*gpr=*/true,
21738 /*lr=*/can_use_exit);
21742 if (info->cr_save_p)
21744 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21745 if (DEFAULT_ABI == ABI_V4)
21747 = alloc_reg_note (REG_CFA_RESTORE,
21748 gen_rtx_REG (SImode, CR2_REGNO),
21752 emit_jump_insn (par);
21754 /* We don't want anybody else emitting things after we jumped
21759 insn = emit_insn (par);
21760 if (DEFAULT_ABI == ABI_V4)
21762 if (frame_pointer_needed)
21764 add_reg_note (insn, REG_CFA_DEF_CFA,
21765 plus_constant (frame_reg_rtx, sp_offset));
21766 RTX_FRAME_RELATED_P (insn) = 1;
21769 for (i = info->first_gp_reg_save; i < 32; i++)
21771 = alloc_reg_note (REG_CFA_RESTORE,
21772 gen_rtx_REG (reg_mode, i), cfa_restores);
21775 else if (using_load_multiple)
21778 p = rtvec_alloc (32 - info->first_gp_reg_save);
21779 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21781 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21782 GEN_INT (info->gp_save_offset
21785 rtx mem = gen_frame_mem (reg_mode, addr);
21786 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21788 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21789 if (DEFAULT_ABI == ABI_V4)
21790 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21793 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21794 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21796 add_reg_note (insn, REG_CFA_DEF_CFA,
21797 plus_constant (frame_reg_rtx, sp_offset));
21798 RTX_FRAME_RELATED_P (insn) = 1;
21803 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21804 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21806 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21807 GEN_INT (info->gp_save_offset
21810 rtx mem = gen_frame_mem (reg_mode, addr);
21811 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21813 insn = emit_move_insn (reg, mem);
21814 if (DEFAULT_ABI == ABI_V4)
21816 if (frame_pointer_needed
21817 && info->first_gp_reg_save + i
21818 == HARD_FRAME_POINTER_REGNUM)
21820 add_reg_note (insn, REG_CFA_DEF_CFA,
21821 plus_constant (frame_reg_rtx, sp_offset));
21822 RTX_FRAME_RELATED_P (insn) = 1;
21825 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21831 if (restore_lr && !restoring_GPRs_inline)
21833 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21834 info->lr_save_offset + sp_offset);
21836 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21837 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21838 gen_rtx_REG (Pmode, 0));
21841 /* Restore fpr's if we need to do it without calling a function. */
21842 if (restoring_FPRs_inline)
21843 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21844 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21845 && ! call_used_regs[info->first_fp_reg_save+i]))
21847 rtx addr, mem, reg;
21848 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21849 GEN_INT (info->fp_save_offset
21852 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21853 ? DFmode : SFmode), addr);
21854 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21855 ? DFmode : SFmode),
21856 info->first_fp_reg_save + i);
21858 emit_move_insn (reg, mem);
21859 if (DEFAULT_ABI == ABI_V4)
21860 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21864 /* If we saved cr, restore it here. Just those that were used. */
21865 if (info->cr_save_p)
21867 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21868 if (DEFAULT_ABI == ABI_V4)
21870 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21874 /* If this is V.4, unwind the stack pointer after all of the loads
21876 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21877 sp_offset, !restoring_FPRs_inline);
21882 REG_NOTES (insn) = cfa_restores;
21883 cfa_restores = NULL_RTX;
21885 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21886 RTX_FRAME_RELATED_P (insn) = 1;
21889 if (crtl->calls_eh_return)
21891 rtx sa = EH_RETURN_STACKADJ_RTX;
21892 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21898 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21899 if (! restoring_FPRs_inline)
21900 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21902 p = rtvec_alloc (2);
21904 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21905 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21906 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21907 : gen_rtx_CLOBBER (VOIDmode,
21908 gen_rtx_REG (Pmode, 65)));
21910 /* If we have to restore more than two FP registers, branch to the
21911 restore function. It will return to our caller. */
21912 if (! restoring_FPRs_inline)
21917 sym = rs6000_savres_routine_sym (info,
21921 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21922 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21923 gen_rtx_REG (Pmode,
21924 DEFAULT_ABI == ABI_AIX
21926 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21929 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21930 GEN_INT (info->fp_save_offset + 8*i));
21931 mem = gen_frame_mem (DFmode, addr);
21933 RTVEC_ELT (p, i+4) =
21934 gen_rtx_SET (VOIDmode,
21935 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21940 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21944 /* Write function epilogue. */
21947 rs6000_output_function_epilogue (FILE *file,
21948 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21950 if (! HAVE_epilogue)
21952 rtx insn = get_last_insn ();
21953 /* If the last insn was a BARRIER, we don't have to write anything except
21954 the trace table. */
21955 if (GET_CODE (insn) == NOTE)
21956 insn = prev_nonnote_insn (insn);
21957 if (insn == 0 || GET_CODE (insn) != BARRIER)
21959 /* This is slightly ugly, but at least we don't have two
21960 copies of the epilogue-emitting code. */
21963 /* A NOTE_INSN_DELETED is supposed to be at the start
21964 and end of the "toplevel" insn chain. */
21965 emit_note (NOTE_INSN_DELETED);
21966 rs6000_emit_epilogue (FALSE);
21967 emit_note (NOTE_INSN_DELETED);
21969 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21973 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21975 INSN_ADDRESSES_NEW (insn, addr);
21980 if (TARGET_DEBUG_STACK)
21981 debug_rtx_list (get_insns (), 100);
21982 final (get_insns (), file, FALSE);
21988 macho_branch_islands ();
21989 /* Mach-O doesn't support labels at the end of objects, so if
21990 it looks like we might want one, insert a NOP. */
21992 rtx insn = get_last_insn ();
21995 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
21996 insn = PREV_INSN (insn);
22000 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
22001 fputs ("\tnop\n", file);
22005 /* Output a traceback table here. See /usr/include/sys/debug.h for info
22008 We don't output a traceback table if -finhibit-size-directive was
22009 used. The documentation for -finhibit-size-directive reads
22010 ``don't output a @code{.size} assembler directive, or anything
22011 else that would cause trouble if the function is split in the
22012 middle, and the two halves are placed at locations far apart in
22013 memory.'' The traceback table has this property, since it
22014 includes the offset from the start of the function to the
22015 traceback table itself.
22017 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22018 different traceback table. */
22019 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
22020 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22022 const char *fname = NULL;
22023 const char *language_string = lang_hooks.name;
22024 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22026 int optional_tbtab;
22027 rs6000_stack_t *info = rs6000_stack_info ();
22029 if (rs6000_traceback == traceback_full)
22030 optional_tbtab = 1;
22031 else if (rs6000_traceback == traceback_part)
22032 optional_tbtab = 0;
22034 optional_tbtab = !optimize_size && !TARGET_ELF;
22036 if (optional_tbtab)
22038 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22039 while (*fname == '.') /* V.4 encodes . in the name */
22042 /* Need label immediately before tbtab, so we can compute
22043 its offset from the function start. */
22044 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22045 ASM_OUTPUT_LABEL (file, fname);
22048 /* The .tbtab pseudo-op can only be used for the first eight
22049 expressions, since it can't handle the possibly variable
22050 length fields that follow. However, if you omit the optional
22051 fields, the assembler outputs zeros for all optional fields
22052 anyways, giving each variable length field is minimum length
22053 (as defined in sys/debug.h). Thus we can not use the .tbtab
22054 pseudo-op at all. */
22056 /* An all-zero word flags the start of the tbtab, for debuggers
22057 that have to find it by searching forward from the entry
22058 point or from the current pc. */
22059 fputs ("\t.long 0\n", file);
22061 /* Tbtab format type. Use format type 0. */
22062 fputs ("\t.byte 0,", file);
22064 /* Language type. Unfortunately, there does not seem to be any
22065 official way to discover the language being compiled, so we
22066 use language_string.
22067 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22068 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22069 a number, so for now use 9. LTO and Go aren't assigned numbers
22070 either, so for now use 0. */
22071 if (! strcmp (language_string, "GNU C")
22072 || ! strcmp (language_string, "GNU GIMPLE")
22073 || ! strcmp (language_string, "GNU Go"))
22075 else if (! strcmp (language_string, "GNU F77")
22076 || ! strcmp (language_string, "GNU Fortran"))
22078 else if (! strcmp (language_string, "GNU Pascal"))
22080 else if (! strcmp (language_string, "GNU Ada"))
22082 else if (! strcmp (language_string, "GNU C++")
22083 || ! strcmp (language_string, "GNU Objective-C++"))
22085 else if (! strcmp (language_string, "GNU Java"))
22087 else if (! strcmp (language_string, "GNU Objective-C"))
22090 gcc_unreachable ();
22091 fprintf (file, "%d,", i);
22093 /* 8 single bit fields: global linkage (not set for C extern linkage,
22094 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22095 from start of procedure stored in tbtab, internal function, function
22096 has controlled storage, function has no toc, function uses fp,
22097 function logs/aborts fp operations. */
22098 /* Assume that fp operations are used if any fp reg must be saved. */
22099 fprintf (file, "%d,",
22100 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22102 /* 6 bitfields: function is interrupt handler, name present in
22103 proc table, function calls alloca, on condition directives
22104 (controls stack walks, 3 bits), saves condition reg, saves
22106 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22107 set up as a frame pointer, even when there is no alloca call. */
22108 fprintf (file, "%d,",
22109 ((optional_tbtab << 6)
22110 | ((optional_tbtab & frame_pointer_needed) << 5)
22111 | (info->cr_save_p << 1)
22112 | (info->lr_save_p)));
22114 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22116 fprintf (file, "%d,",
22117 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22119 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22120 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22122 if (optional_tbtab)
22124 /* Compute the parameter info from the function decl argument
22127 int next_parm_info_bit = 31;
22129 for (decl = DECL_ARGUMENTS (current_function_decl);
22130 decl; decl = DECL_CHAIN (decl))
22132 rtx parameter = DECL_INCOMING_RTL (decl);
22133 enum machine_mode mode = GET_MODE (parameter);
22135 if (GET_CODE (parameter) == REG)
22137 if (SCALAR_FLOAT_MODE_P (mode))
22158 gcc_unreachable ();
22161 /* If only one bit will fit, don't or in this entry. */
22162 if (next_parm_info_bit > 0)
22163 parm_info |= (bits << (next_parm_info_bit - 1));
22164 next_parm_info_bit -= 2;
22168 fixed_parms += ((GET_MODE_SIZE (mode)
22169 + (UNITS_PER_WORD - 1))
22171 next_parm_info_bit -= 1;
22177 /* Number of fixed point parameters. */
22178 /* This is actually the number of words of fixed point parameters; thus
22179 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22180 fprintf (file, "%d,", fixed_parms);
22182 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22184 /* This is actually the number of fp registers that hold parameters;
22185 and thus the maximum value is 13. */
22186 /* Set parameters on stack bit if parameters are not in their original
22187 registers, regardless of whether they are on the stack? Xlc
22188 seems to set the bit when not optimizing. */
22189 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22191 if (! optional_tbtab)
22194 /* Optional fields follow. Some are variable length. */
22196 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22197 11 double float. */
22198 /* There is an entry for each parameter in a register, in the order that
22199 they occur in the parameter list. Any intervening arguments on the
22200 stack are ignored. If the list overflows a long (max possible length
22201 34 bits) then completely leave off all elements that don't fit. */
22202 /* Only emit this long if there was at least one parameter. */
22203 if (fixed_parms || float_parms)
22204 fprintf (file, "\t.long %d\n", parm_info);
22206 /* Offset from start of code to tb table. */
22207 fputs ("\t.long ", file);
22208 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22209 RS6000_OUTPUT_BASENAME (file, fname);
22211 rs6000_output_function_entry (file, fname);
22214 /* Interrupt handler mask. */
22215 /* Omit this long, since we never set the interrupt handler bit
22218 /* Number of CTL (controlled storage) anchors. */
22219 /* Omit this long, since the has_ctl bit is never set above. */
22221 /* Displacement into stack of each CTL anchor. */
22222 /* Omit this list of longs, because there are no CTL anchors. */
22224 /* Length of function name. */
22227 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22229 /* Function name. */
22230 assemble_string (fname, strlen (fname));
22232 /* Register for alloca automatic storage; this is always reg 31.
22233 Only emit this if the alloca bit was set above. */
22234 if (frame_pointer_needed)
22235 fputs ("\t.byte 31\n", file);
22237 fputs ("\t.align 2\n", file);
22241 /* A C compound statement that outputs the assembler code for a thunk
22242 function, used to implement C++ virtual function calls with
22243 multiple inheritance. The thunk acts as a wrapper around a virtual
22244 function, adjusting the implicit object parameter before handing
22245 control off to the real function.
22247 First, emit code to add the integer DELTA to the location that
22248 contains the incoming first argument. Assume that this argument
22249 contains a pointer, and is the one used to pass the `this' pointer
22250 in C++. This is the incoming argument *before* the function
22251 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22252 values of all other incoming arguments.
22254 After the addition, emit code to jump to FUNCTION, which is a
22255 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22256 not touch the return address. Hence returning from FUNCTION will
22257 return to whoever called the current `thunk'.
22259 The effect must be as if FUNCTION had been called directly with the
22260 adjusted first argument. This macro is responsible for emitting
22261 all of the code for a thunk function; output_function_prologue()
22262 and output_function_epilogue() are not invoked.
22264 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22265 been extracted from it.) It might possibly be useful on some
22266 targets, but probably not.
22268 If you do not define this macro, the target-independent code in the
22269 C++ frontend will generate a less efficient heavyweight thunk that
22270 calls FUNCTION instead of jumping to it. The generic approach does
22271 not support varargs. */
22274 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22275 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22278 rtx this_rtx, insn, funexp;
22280 reload_completed = 1;
22281 epilogue_completed = 1;
22283 /* Mark the end of the (empty) prologue. */
22284 emit_note (NOTE_INSN_PROLOGUE_END);
22286 /* Find the "this" pointer. If the function returns a structure,
22287 the structure return pointer is in r3. */
22288 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22289 this_rtx = gen_rtx_REG (Pmode, 4);
22291 this_rtx = gen_rtx_REG (Pmode, 3);
22293 /* Apply the constant offset, if required. */
22295 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22297 /* Apply the offset from the vtable, if required. */
22300 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22301 rtx tmp = gen_rtx_REG (Pmode, 12);
22303 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22304 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22306 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22307 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22311 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22313 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22315 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22318 /* Generate a tail call to the target function. */
22319 if (!TREE_USED (function))
22321 assemble_external (function);
22322 TREE_USED (function) = 1;
22324 funexp = XEXP (DECL_RTL (function), 0);
22325 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22328 if (MACHOPIC_INDIRECT)
22329 funexp = machopic_indirect_call_target (funexp);
22332 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22333 generate sibcall RTL explicitly. */
22334 insn = emit_call_insn (
22335 gen_rtx_PARALLEL (VOIDmode,
22337 gen_rtx_CALL (VOIDmode,
22338 funexp, const0_rtx),
22339 gen_rtx_USE (VOIDmode, const0_rtx),
22340 gen_rtx_USE (VOIDmode,
22341 gen_rtx_REG (SImode,
22343 gen_rtx_RETURN (VOIDmode))));
22344 SIBLING_CALL_P (insn) = 1;
22347 /* Run just enough of rest_of_compilation to get the insns emitted.
22348 There's not really enough bulk here to make other passes such as
22349 instruction scheduling worth while. Note that use_thunk calls
22350 assemble_start_function and assemble_end_function. */
22351 insn = get_insns ();
22352 insn_locators_alloc ();
22353 shorten_branches (insn);
22354 final_start_function (insn, file, 1);
22355 final (insn, file, 1);
22356 final_end_function ();
22358 reload_completed = 0;
22359 epilogue_completed = 0;
22362 /* A quick summary of the various types of 'constant-pool tables'
22365 Target Flags Name One table per
22366 AIX (none) AIX TOC object file
22367 AIX -mfull-toc AIX TOC object file
22368 AIX -mminimal-toc AIX minimal TOC translation unit
22369 SVR4/EABI (none) SVR4 SDATA object file
22370 SVR4/EABI -fpic SVR4 pic object file
22371 SVR4/EABI -fPIC SVR4 PIC translation unit
22372 SVR4/EABI -mrelocatable EABI TOC function
22373 SVR4/EABI -maix AIX TOC object file
22374 SVR4/EABI -maix -mminimal-toc
22375 AIX minimal TOC translation unit
22377 Name Reg. Set by entries contains:
22378 made by addrs? fp? sum?
22380 AIX TOC 2 crt0 as Y option option
22381 AIX minimal TOC 30 prolog gcc Y Y option
22382 SVR4 SDATA 13 crt0 gcc N Y N
22383 SVR4 pic 30 prolog ld Y not yet N
22384 SVR4 PIC 30 prolog gcc Y option option
22385 EABI TOC 30 prolog gcc Y option option
22389 /* Hash functions for the hash table. */
22392 rs6000_hash_constant (rtx k)
22394 enum rtx_code code = GET_CODE (k);
22395 enum machine_mode mode = GET_MODE (k);
22396 unsigned result = (code << 3) ^ mode;
22397 const char *format;
22400 format = GET_RTX_FORMAT (code);
22401 flen = strlen (format);
22407 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22410 if (mode != VOIDmode)
22411 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22423 for (; fidx < flen; fidx++)
22424 switch (format[fidx])
22429 const char *str = XSTR (k, fidx);
22430 len = strlen (str);
22431 result = result * 613 + len;
22432 for (i = 0; i < len; i++)
22433 result = result * 613 + (unsigned) str[i];
22438 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22442 result = result * 613 + (unsigned) XINT (k, fidx);
22445 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22446 result = result * 613 + (unsigned) XWINT (k, fidx);
22450 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22451 result = result * 613 + (unsigned) (XWINT (k, fidx)
22458 gcc_unreachable ();
22465 toc_hash_function (const void *hash_entry)
22467 const struct toc_hash_struct *thc =
22468 (const struct toc_hash_struct *) hash_entry;
22469 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22472 /* Compare H1 and H2 for equivalence. */
22475 toc_hash_eq (const void *h1, const void *h2)
22477 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22478 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22480 if (((const struct toc_hash_struct *) h1)->key_mode
22481 != ((const struct toc_hash_struct *) h2)->key_mode)
22484 return rtx_equal_p (r1, r2);
22487 /* These are the names given by the C++ front-end to vtables, and
22488 vtable-like objects. Ideally, this logic should not be here;
22489 instead, there should be some programmatic way of inquiring as
22490 to whether or not an object is a vtable. */
22492 #define VTABLE_NAME_P(NAME) \
22493 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22494 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22495 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22496 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22497 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22499 #ifdef NO_DOLLAR_IN_LABEL
22500 /* Return a GGC-allocated character string translating dollar signs in
22501 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22504 rs6000_xcoff_strip_dollar (const char *name)
22509 p = strchr (name, '$');
22511 if (p == 0 || p == name)
22514 len = strlen (name);
22515 strip = (char *) alloca (len + 1);
22516 strcpy (strip, name);
22517 p = strchr (strip, '$');
22521 p = strchr (p + 1, '$');
22524 return ggc_alloc_string (strip, len);
22529 rs6000_output_symbol_ref (FILE *file, rtx x)
22531 /* Currently C++ toc references to vtables can be emitted before it
22532 is decided whether the vtable is public or private. If this is
22533 the case, then the linker will eventually complain that there is
22534 a reference to an unknown section. Thus, for vtables only,
22535 we emit the TOC reference to reference the symbol and not the
22537 const char *name = XSTR (x, 0);
22539 if (VTABLE_NAME_P (name))
22541 RS6000_OUTPUT_BASENAME (file, name);
22544 assemble_name (file, name);
22547 /* Output a TOC entry. We derive the entry name from what is being
22551 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22554 const char *name = buf;
22556 HOST_WIDE_INT offset = 0;
22558 gcc_assert (!TARGET_NO_TOC);
22560 /* When the linker won't eliminate them, don't output duplicate
22561 TOC entries (this happens on AIX if there is any kind of TOC,
22562 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22564 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22566 struct toc_hash_struct *h;
22569 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22570 time because GGC is not initialized at that point. */
22571 if (toc_hash_table == NULL)
22572 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22573 toc_hash_eq, NULL);
22575 h = ggc_alloc_toc_hash_struct ();
22577 h->key_mode = mode;
22578 h->labelno = labelno;
22580 found = htab_find_slot (toc_hash_table, h, INSERT);
22581 if (*found == NULL)
22583 else /* This is indeed a duplicate.
22584 Set this label equal to that label. */
22586 fputs ("\t.set ", file);
22587 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22588 fprintf (file, "%d,", labelno);
22589 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22590 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22596 /* If we're going to put a double constant in the TOC, make sure it's
22597 aligned properly when strict alignment is on. */
22598 if (GET_CODE (x) == CONST_DOUBLE
22599 && STRICT_ALIGNMENT
22600 && GET_MODE_BITSIZE (mode) >= 64
22601 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22602 ASM_OUTPUT_ALIGN (file, 3);
22605 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22607 /* Handle FP constants specially. Note that if we have a minimal
22608 TOC, things we put here aren't actually in the TOC, so we can allow
22610 if (GET_CODE (x) == CONST_DOUBLE &&
22611 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22613 REAL_VALUE_TYPE rv;
22616 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22617 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22618 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22620 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22624 if (TARGET_MINIMAL_TOC)
22625 fputs (DOUBLE_INT_ASM_OP, file);
22627 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22628 k[0] & 0xffffffff, k[1] & 0xffffffff,
22629 k[2] & 0xffffffff, k[3] & 0xffffffff);
22630 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22631 k[0] & 0xffffffff, k[1] & 0xffffffff,
22632 k[2] & 0xffffffff, k[3] & 0xffffffff);
22637 if (TARGET_MINIMAL_TOC)
22638 fputs ("\t.long ", file);
22640 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22641 k[0] & 0xffffffff, k[1] & 0xffffffff,
22642 k[2] & 0xffffffff, k[3] & 0xffffffff);
22643 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22644 k[0] & 0xffffffff, k[1] & 0xffffffff,
22645 k[2] & 0xffffffff, k[3] & 0xffffffff);
22649 else if (GET_CODE (x) == CONST_DOUBLE &&
22650 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22652 REAL_VALUE_TYPE rv;
22655 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22657 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22658 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22660 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22664 if (TARGET_MINIMAL_TOC)
22665 fputs (DOUBLE_INT_ASM_OP, file);
22667 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22668 k[0] & 0xffffffff, k[1] & 0xffffffff);
22669 fprintf (file, "0x%lx%08lx\n",
22670 k[0] & 0xffffffff, k[1] & 0xffffffff);
22675 if (TARGET_MINIMAL_TOC)
22676 fputs ("\t.long ", file);
22678 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22679 k[0] & 0xffffffff, k[1] & 0xffffffff);
22680 fprintf (file, "0x%lx,0x%lx\n",
22681 k[0] & 0xffffffff, k[1] & 0xffffffff);
22685 else if (GET_CODE (x) == CONST_DOUBLE &&
22686 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22688 REAL_VALUE_TYPE rv;
22691 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22692 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22693 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22695 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22699 if (TARGET_MINIMAL_TOC)
22700 fputs (DOUBLE_INT_ASM_OP, file);
22702 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22703 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22708 if (TARGET_MINIMAL_TOC)
22709 fputs ("\t.long ", file);
22711 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22712 fprintf (file, "0x%lx\n", l & 0xffffffff);
22716 else if (GET_MODE (x) == VOIDmode
22717 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22719 unsigned HOST_WIDE_INT low;
22720 HOST_WIDE_INT high;
22722 if (GET_CODE (x) == CONST_DOUBLE)
22724 low = CONST_DOUBLE_LOW (x);
22725 high = CONST_DOUBLE_HIGH (x);
22728 #if HOST_BITS_PER_WIDE_INT == 32
22731 high = (low & 0x80000000) ? ~0 : 0;
22735 low = INTVAL (x) & 0xffffffff;
22736 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22740 /* TOC entries are always Pmode-sized, but since this
22741 is a bigendian machine then if we're putting smaller
22742 integer constants in the TOC we have to pad them.
22743 (This is still a win over putting the constants in
22744 a separate constant pool, because then we'd have
22745 to have both a TOC entry _and_ the actual constant.)
22747 For a 32-bit target, CONST_INT values are loaded and shifted
22748 entirely within `low' and can be stored in one TOC entry. */
22750 /* It would be easy to make this work, but it doesn't now. */
22751 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22753 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22755 #if HOST_BITS_PER_WIDE_INT == 32
22756 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22757 POINTER_SIZE, &low, &high, 0);
22760 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22761 high = (HOST_WIDE_INT) low >> 32;
22768 if (TARGET_MINIMAL_TOC)
22769 fputs (DOUBLE_INT_ASM_OP, file);
22771 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22772 (long) high & 0xffffffff, (long) low & 0xffffffff);
22773 fprintf (file, "0x%lx%08lx\n",
22774 (long) high & 0xffffffff, (long) low & 0xffffffff);
22779 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22781 if (TARGET_MINIMAL_TOC)
22782 fputs ("\t.long ", file);
22784 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22785 (long) high & 0xffffffff, (long) low & 0xffffffff);
22786 fprintf (file, "0x%lx,0x%lx\n",
22787 (long) high & 0xffffffff, (long) low & 0xffffffff);
22791 if (TARGET_MINIMAL_TOC)
22792 fputs ("\t.long ", file);
22794 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22795 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22801 if (GET_CODE (x) == CONST)
22803 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22804 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22806 base = XEXP (XEXP (x, 0), 0);
22807 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22810 switch (GET_CODE (base))
22813 name = XSTR (base, 0);
22817 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22818 CODE_LABEL_NUMBER (XEXP (base, 0)));
22822 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22826 gcc_unreachable ();
22829 if (TARGET_MINIMAL_TOC)
22830 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22833 fputs ("\t.tc ", file);
22834 RS6000_OUTPUT_BASENAME (file, name);
22837 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22839 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22841 fputs ("[TC],", file);
22844 /* Currently C++ toc references to vtables can be emitted before it
22845 is decided whether the vtable is public or private. If this is
22846 the case, then the linker will eventually complain that there is
22847 a TOC reference to an unknown section. Thus, for vtables only,
22848 we emit the TOC reference to reference the symbol and not the
22850 if (VTABLE_NAME_P (name))
22852 RS6000_OUTPUT_BASENAME (file, name);
22854 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22855 else if (offset > 0)
22856 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22859 output_addr_const (file, x);
22863 /* Output an assembler pseudo-op to write an ASCII string of N characters
22864 starting at P to FILE.
22866 On the RS/6000, we have to do this using the .byte operation and
22867 write out special characters outside the quoted string.
22868 Also, the assembler is broken; very long strings are truncated,
22869 so we must artificially break them up early. */
22872 output_ascii (FILE *file, const char *p, int n)
22875 int i, count_string;
22876 const char *for_string = "\t.byte \"";
22877 const char *for_decimal = "\t.byte ";
22878 const char *to_close = NULL;
22881 for (i = 0; i < n; i++)
22884 if (c >= ' ' && c < 0177)
22887 fputs (for_string, file);
22890 /* Write two quotes to get one. */
22898 for_decimal = "\"\n\t.byte ";
22902 if (count_string >= 512)
22904 fputs (to_close, file);
22906 for_string = "\t.byte \"";
22907 for_decimal = "\t.byte ";
22915 fputs (for_decimal, file);
22916 fprintf (file, "%d", c);
22918 for_string = "\n\t.byte \"";
22919 for_decimal = ", ";
22925 /* Now close the string if we have written one. Then end the line. */
22927 fputs (to_close, file);
22930 /* Generate a unique section name for FILENAME for a section type
22931 represented by SECTION_DESC. Output goes into BUF.
22933 SECTION_DESC can be any string, as long as it is different for each
22934 possible section type.
22936 We name the section in the same manner as xlc. The name begins with an
22937 underscore followed by the filename (after stripping any leading directory
22938 names) with the last period replaced by the string SECTION_DESC. If
22939 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22943 rs6000_gen_section_name (char **buf, const char *filename,
22944 const char *section_desc)
22946 const char *q, *after_last_slash, *last_period = 0;
22950 after_last_slash = filename;
22951 for (q = filename; *q; q++)
22954 after_last_slash = q + 1;
22955 else if (*q == '.')
22959 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22960 *buf = (char *) xmalloc (len);
22965 for (q = after_last_slash; *q; q++)
22967 if (q == last_period)
22969 strcpy (p, section_desc);
22970 p += strlen (section_desc);
22974 else if (ISALNUM (*q))
22978 if (last_period == 0)
22979 strcpy (p, section_desc);
22984 /* Emit profile function. */
22987 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22989 /* Non-standard profiling for kernels, which just saves LR then calls
22990 _mcount without worrying about arg saves. The idea is to change
22991 the function prologue as little as possible as it isn't easy to
22992 account for arg save/restore code added just for _mcount. */
22993 if (TARGET_PROFILE_KERNEL)
22996 if (DEFAULT_ABI == ABI_AIX)
22998 #ifndef NO_PROFILE_COUNTERS
22999 # define NO_PROFILE_COUNTERS 0
23001 if (NO_PROFILE_COUNTERS)
23002 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23003 LCT_NORMAL, VOIDmode, 0);
23007 const char *label_name;
23010 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23011 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
23012 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
23014 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23015 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
23018 else if (DEFAULT_ABI == ABI_DARWIN)
23020 const char *mcount_name = RS6000_MCOUNT;
23021 int caller_addr_regno = LR_REGNO;
23023 /* Be conservative and always set this, at least for now. */
23024 crtl->uses_pic_offset_table = 1;
23027 /* For PIC code, set up a stub and collect the caller's address
23028 from r0, which is where the prologue puts it. */
23029 if (MACHOPIC_INDIRECT
23030 && crtl->uses_pic_offset_table)
23031 caller_addr_regno = 0;
23033 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23034 LCT_NORMAL, VOIDmode, 1,
23035 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23039 /* Write function profiler code. */
23042 output_function_profiler (FILE *file, int labelno)
23046 switch (DEFAULT_ABI)
23049 gcc_unreachable ();
23054 warning (0, "no profiling of 64-bit code for this ABI");
23057 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23058 fprintf (file, "\tmflr %s\n", reg_names[0]);
23059 if (NO_PROFILE_COUNTERS)
23061 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23062 reg_names[0], reg_names[1]);
23064 else if (TARGET_SECURE_PLT && flag_pic)
23066 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23067 reg_names[0], reg_names[1]);
23068 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23069 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23070 reg_names[12], reg_names[12]);
23071 assemble_name (file, buf);
23072 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23073 assemble_name (file, buf);
23074 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23076 else if (flag_pic == 1)
23078 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23079 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23080 reg_names[0], reg_names[1]);
23081 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23082 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23083 assemble_name (file, buf);
23084 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23086 else if (flag_pic > 1)
23088 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23089 reg_names[0], reg_names[1]);
23090 /* Now, we need to get the address of the label. */
23091 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23092 assemble_name (file, buf);
23093 fputs ("-.\n1:", file);
23094 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23095 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23096 reg_names[0], reg_names[11]);
23097 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23098 reg_names[0], reg_names[0], reg_names[11]);
23102 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23103 assemble_name (file, buf);
23104 fputs ("@ha\n", file);
23105 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23106 reg_names[0], reg_names[1]);
23107 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23108 assemble_name (file, buf);
23109 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23112 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23113 fprintf (file, "\tbl %s%s\n",
23114 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23119 if (!TARGET_PROFILE_KERNEL)
23121 /* Don't do anything, done in output_profile_hook (). */
23125 gcc_assert (!TARGET_32BIT);
23127 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23128 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23130 if (cfun->static_chain_decl != NULL)
23132 asm_fprintf (file, "\tstd %s,24(%s)\n",
23133 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23134 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23135 asm_fprintf (file, "\tld %s,24(%s)\n",
23136 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23139 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23147 /* The following variable value is the last issued insn. */
23149 static rtx last_scheduled_insn;
23151 /* The following variable helps to balance issuing of load and
23152 store instructions */
23154 static int load_store_pendulum;
23156 /* Power4 load update and store update instructions are cracked into a
23157 load or store and an integer insn which are executed in the same cycle.
23158 Branches have their own dispatch slot which does not count against the
23159 GCC issue rate, but it changes the program flow so there are no other
23160 instructions to issue in this cycle. */
23163 rs6000_variable_issue_1 (rtx insn, int more)
23165 last_scheduled_insn = insn;
23166 if (GET_CODE (PATTERN (insn)) == USE
23167 || GET_CODE (PATTERN (insn)) == CLOBBER)
23169 cached_can_issue_more = more;
23170 return cached_can_issue_more;
23173 if (insn_terminates_group_p (insn, current_group))
23175 cached_can_issue_more = 0;
23176 return cached_can_issue_more;
23179 /* If no reservation, but reach here */
23180 if (recog_memoized (insn) < 0)
23183 if (rs6000_sched_groups)
23185 if (is_microcoded_insn (insn))
23186 cached_can_issue_more = 0;
23187 else if (is_cracked_insn (insn))
23188 cached_can_issue_more = more > 2 ? more - 2 : 0;
23190 cached_can_issue_more = more - 1;
23192 return cached_can_issue_more;
23195 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23198 cached_can_issue_more = more - 1;
23199 return cached_can_issue_more;
23203 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23205 int r = rs6000_variable_issue_1 (insn, more);
23207 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23211 /* Adjust the cost of a scheduling dependency. Return the new cost of
23212 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23215 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23217 enum attr_type attr_type;
23219 if (! recog_memoized (insn))
23222 switch (REG_NOTE_KIND (link))
23226 /* Data dependency; DEP_INSN writes a register that INSN reads
23227 some cycles later. */
23229 /* Separate a load from a narrower, dependent store. */
23230 if (rs6000_sched_groups
23231 && GET_CODE (PATTERN (insn)) == SET
23232 && GET_CODE (PATTERN (dep_insn)) == SET
23233 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23234 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23235 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23236 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23239 attr_type = get_attr_type (insn);
23244 /* Tell the first scheduling pass about the latency between
23245 a mtctr and bctr (and mtlr and br/blr). The first
23246 scheduling pass will not know about this latency since
23247 the mtctr instruction, which has the latency associated
23248 to it, will be generated by reload. */
23249 return TARGET_POWER ? 5 : 4;
23251 /* Leave some extra cycles between a compare and its
23252 dependent branch, to inhibit expensive mispredicts. */
23253 if ((rs6000_cpu_attr == CPU_PPC603
23254 || rs6000_cpu_attr == CPU_PPC604
23255 || rs6000_cpu_attr == CPU_PPC604E
23256 || rs6000_cpu_attr == CPU_PPC620
23257 || rs6000_cpu_attr == CPU_PPC630
23258 || rs6000_cpu_attr == CPU_PPC750
23259 || rs6000_cpu_attr == CPU_PPC7400
23260 || rs6000_cpu_attr == CPU_PPC7450
23261 || rs6000_cpu_attr == CPU_POWER4
23262 || rs6000_cpu_attr == CPU_POWER5
23263 || rs6000_cpu_attr == CPU_POWER7
23264 || rs6000_cpu_attr == CPU_CELL)
23265 && recog_memoized (dep_insn)
23266 && (INSN_CODE (dep_insn) >= 0))
23268 switch (get_attr_type (dep_insn))
23272 case TYPE_DELAYED_COMPARE:
23273 case TYPE_IMUL_COMPARE:
23274 case TYPE_LMUL_COMPARE:
23275 case TYPE_FPCOMPARE:
23276 case TYPE_CR_LOGICAL:
23277 case TYPE_DELAYED_CR:
23286 case TYPE_STORE_UX:
23288 case TYPE_FPSTORE_U:
23289 case TYPE_FPSTORE_UX:
23290 if ((rs6000_cpu == PROCESSOR_POWER6)
23291 && recog_memoized (dep_insn)
23292 && (INSN_CODE (dep_insn) >= 0))
23295 if (GET_CODE (PATTERN (insn)) != SET)
23296 /* If this happens, we have to extend this to schedule
23297 optimally. Return default for now. */
23300 /* Adjust the cost for the case where the value written
23301 by a fixed point operation is used as the address
23302 gen value on a store. */
23303 switch (get_attr_type (dep_insn))
23310 if (! store_data_bypass_p (dep_insn, insn))
23314 case TYPE_LOAD_EXT:
23315 case TYPE_LOAD_EXT_U:
23316 case TYPE_LOAD_EXT_UX:
23317 case TYPE_VAR_SHIFT_ROTATE:
23318 case TYPE_VAR_DELAYED_COMPARE:
23320 if (! store_data_bypass_p (dep_insn, insn))
23326 case TYPE_FAST_COMPARE:
23329 case TYPE_INSERT_WORD:
23330 case TYPE_INSERT_DWORD:
23331 case TYPE_FPLOAD_U:
23332 case TYPE_FPLOAD_UX:
23334 case TYPE_STORE_UX:
23335 case TYPE_FPSTORE_U:
23336 case TYPE_FPSTORE_UX:
23338 if (! store_data_bypass_p (dep_insn, insn))
23346 case TYPE_IMUL_COMPARE:
23347 case TYPE_LMUL_COMPARE:
23349 if (! store_data_bypass_p (dep_insn, insn))
23355 if (! store_data_bypass_p (dep_insn, insn))
23361 if (! store_data_bypass_p (dep_insn, insn))
23374 case TYPE_LOAD_EXT:
23375 case TYPE_LOAD_EXT_U:
23376 case TYPE_LOAD_EXT_UX:
23377 if ((rs6000_cpu == PROCESSOR_POWER6)
23378 && recog_memoized (dep_insn)
23379 && (INSN_CODE (dep_insn) >= 0))
23382 /* Adjust the cost for the case where the value written
23383 by a fixed point instruction is used within the address
23384 gen portion of a subsequent load(u)(x) */
23385 switch (get_attr_type (dep_insn))
23392 if (set_to_load_agen (dep_insn, insn))
23396 case TYPE_LOAD_EXT:
23397 case TYPE_LOAD_EXT_U:
23398 case TYPE_LOAD_EXT_UX:
23399 case TYPE_VAR_SHIFT_ROTATE:
23400 case TYPE_VAR_DELAYED_COMPARE:
23402 if (set_to_load_agen (dep_insn, insn))
23408 case TYPE_FAST_COMPARE:
23411 case TYPE_INSERT_WORD:
23412 case TYPE_INSERT_DWORD:
23413 case TYPE_FPLOAD_U:
23414 case TYPE_FPLOAD_UX:
23416 case TYPE_STORE_UX:
23417 case TYPE_FPSTORE_U:
23418 case TYPE_FPSTORE_UX:
23420 if (set_to_load_agen (dep_insn, insn))
23428 case TYPE_IMUL_COMPARE:
23429 case TYPE_LMUL_COMPARE:
23431 if (set_to_load_agen (dep_insn, insn))
23437 if (set_to_load_agen (dep_insn, insn))
23443 if (set_to_load_agen (dep_insn, insn))
23454 if ((rs6000_cpu == PROCESSOR_POWER6)
23455 && recog_memoized (dep_insn)
23456 && (INSN_CODE (dep_insn) >= 0)
23457 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23464 /* Fall out to return default cost. */
23468 case REG_DEP_OUTPUT:
23469 /* Output dependency; DEP_INSN writes a register that INSN writes some
23471 if ((rs6000_cpu == PROCESSOR_POWER6)
23472 && recog_memoized (dep_insn)
23473 && (INSN_CODE (dep_insn) >= 0))
23475 attr_type = get_attr_type (insn);
23480 if (get_attr_type (dep_insn) == TYPE_FP)
23484 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23492 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23497 gcc_unreachable ();
23503 /* Debug version of rs6000_adjust_cost. */
23506 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23508 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23514 switch (REG_NOTE_KIND (link))
23516 default: dep = "unknown depencency"; break;
23517 case REG_DEP_TRUE: dep = "data dependency"; break;
23518 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23519 case REG_DEP_ANTI: dep = "anti depencency"; break;
23523 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23524 "%s, insn:\n", ret, cost, dep);
23532 /* The function returns a true if INSN is microcoded.
23533 Return false otherwise. */
23536 is_microcoded_insn (rtx insn)
23538 if (!insn || !NONDEBUG_INSN_P (insn)
23539 || GET_CODE (PATTERN (insn)) == USE
23540 || GET_CODE (PATTERN (insn)) == CLOBBER)
23543 if (rs6000_cpu_attr == CPU_CELL)
23544 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23546 if (rs6000_sched_groups)
23548 enum attr_type type = get_attr_type (insn);
23549 if (type == TYPE_LOAD_EXT_U
23550 || type == TYPE_LOAD_EXT_UX
23551 || type == TYPE_LOAD_UX
23552 || type == TYPE_STORE_UX
23553 || type == TYPE_MFCR)
23560 /* The function returns true if INSN is cracked into 2 instructions
23561 by the processor (and therefore occupies 2 issue slots). */
23564 is_cracked_insn (rtx insn)
23566 if (!insn || !NONDEBUG_INSN_P (insn)
23567 || GET_CODE (PATTERN (insn)) == USE
23568 || GET_CODE (PATTERN (insn)) == CLOBBER)
23571 if (rs6000_sched_groups)
23573 enum attr_type type = get_attr_type (insn);
23574 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23575 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23576 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23577 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23578 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23579 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23580 || type == TYPE_IDIV || type == TYPE_LDIV
23581 || type == TYPE_INSERT_WORD)
23588 /* The function returns true if INSN can be issued only from
23589 the branch slot. */
23592 is_branch_slot_insn (rtx insn)
23594 if (!insn || !NONDEBUG_INSN_P (insn)
23595 || GET_CODE (PATTERN (insn)) == USE
23596 || GET_CODE (PATTERN (insn)) == CLOBBER)
23599 if (rs6000_sched_groups)
23601 enum attr_type type = get_attr_type (insn);
23602 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23610 /* The function returns true if out_inst sets a value that is
23611 used in the address generation computation of in_insn */
23613 set_to_load_agen (rtx out_insn, rtx in_insn)
23615 rtx out_set, in_set;
23617 /* For performance reasons, only handle the simple case where
23618 both loads are a single_set. */
23619 out_set = single_set (out_insn);
23622 in_set = single_set (in_insn);
23624 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23630 /* The function returns true if the target storage location of
23631 out_insn is adjacent to the target storage location of in_insn */
23632 /* Return 1 if memory locations are adjacent. */
23635 adjacent_mem_locations (rtx insn1, rtx insn2)
23638 rtx a = get_store_dest (PATTERN (insn1));
23639 rtx b = get_store_dest (PATTERN (insn2));
23641 if ((GET_CODE (XEXP (a, 0)) == REG
23642 || (GET_CODE (XEXP (a, 0)) == PLUS
23643 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23644 && (GET_CODE (XEXP (b, 0)) == REG
23645 || (GET_CODE (XEXP (b, 0)) == PLUS
23646 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23648 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23651 if (GET_CODE (XEXP (a, 0)) == PLUS)
23653 reg0 = XEXP (XEXP (a, 0), 0);
23654 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23657 reg0 = XEXP (a, 0);
23659 if (GET_CODE (XEXP (b, 0)) == PLUS)
23661 reg1 = XEXP (XEXP (b, 0), 0);
23662 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23665 reg1 = XEXP (b, 0);
23667 val_diff = val1 - val0;
23669 return ((REGNO (reg0) == REGNO (reg1))
23670 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23671 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23677 /* A C statement (sans semicolon) to update the integer scheduling
23678 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23679 INSN earlier, reduce the priority to execute INSN later. Do not
23680 define this macro if you do not need to adjust the scheduling
23681 priorities of insns. */
23684 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23686 /* On machines (like the 750) which have asymmetric integer units,
23687 where one integer unit can do multiply and divides and the other
23688 can't, reduce the priority of multiply/divide so it is scheduled
23689 before other integer operations. */
23692 if (! INSN_P (insn))
23695 if (GET_CODE (PATTERN (insn)) == USE)
23698 switch (rs6000_cpu_attr) {
23700 switch (get_attr_type (insn))
23707 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23708 priority, priority);
23709 if (priority >= 0 && priority < 0x01000000)
23716 if (insn_must_be_first_in_group (insn)
23717 && reload_completed
23718 && current_sched_info->sched_max_insns_priority
23719 && rs6000_sched_restricted_insns_priority)
23722 /* Prioritize insns that can be dispatched only in the first
23724 if (rs6000_sched_restricted_insns_priority == 1)
23725 /* Attach highest priority to insn. This means that in
23726 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23727 precede 'priority' (critical path) considerations. */
23728 return current_sched_info->sched_max_insns_priority;
23729 else if (rs6000_sched_restricted_insns_priority == 2)
23730 /* Increase priority of insn by a minimal amount. This means that in
23731 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23732 considerations precede dispatch-slot restriction considerations. */
23733 return (priority + 1);
23736 if (rs6000_cpu == PROCESSOR_POWER6
23737 && ((load_store_pendulum == -2 && is_load_insn (insn))
23738 || (load_store_pendulum == 2 && is_store_insn (insn))))
23739 /* Attach highest priority to insn if the scheduler has just issued two
23740 stores and this instruction is a load, or two loads and this instruction
23741 is a store. Power6 wants loads and stores scheduled alternately
23743 return current_sched_info->sched_max_insns_priority;
23748 /* Return true if the instruction is nonpipelined on the Cell. */
23750 is_nonpipeline_insn (rtx insn)
23752 enum attr_type type;
23753 if (!insn || !NONDEBUG_INSN_P (insn)
23754 || GET_CODE (PATTERN (insn)) == USE
23755 || GET_CODE (PATTERN (insn)) == CLOBBER)
23758 type = get_attr_type (insn);
23759 if (type == TYPE_IMUL
23760 || type == TYPE_IMUL2
23761 || type == TYPE_IMUL3
23762 || type == TYPE_LMUL
23763 || type == TYPE_IDIV
23764 || type == TYPE_LDIV
23765 || type == TYPE_SDIV
23766 || type == TYPE_DDIV
23767 || type == TYPE_SSQRT
23768 || type == TYPE_DSQRT
23769 || type == TYPE_MFCR
23770 || type == TYPE_MFCRF
23771 || type == TYPE_MFJMPR)
23779 /* Return how many instructions the machine can issue per cycle. */
23782 rs6000_issue_rate (void)
23784 /* Unless scheduling for register pressure, use issue rate of 1 for
23785 first scheduling pass to decrease degradation. */
23786 if (!reload_completed && !flag_sched_pressure)
23789 switch (rs6000_cpu_attr) {
23790 case CPU_RIOS1: /* ? */
23792 case CPU_PPC601: /* ? */
23801 case CPU_PPCE300C2:
23802 case CPU_PPCE300C3:
23803 case CPU_PPCE500MC:
23804 case CPU_PPCE500MC64:
23824 /* Return how many instructions to look ahead for better insn
23828 rs6000_use_sched_lookahead (void)
23830 if (rs6000_cpu_attr == CPU_PPC8540)
23832 if (rs6000_cpu_attr == CPU_CELL)
23833 return (reload_completed ? 8 : 0);
23837 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23839 rs6000_use_sched_lookahead_guard (rtx insn)
23841 if (rs6000_cpu_attr != CPU_CELL)
23844 if (insn == NULL_RTX || !INSN_P (insn))
23847 if (!reload_completed
23848 || is_nonpipeline_insn (insn)
23849 || is_microcoded_insn (insn))
23855 /* Determine is PAT refers to memory. */
23858 is_mem_ref (rtx pat)
23864 /* stack_tie does not produce any real memory traffic. */
23865 if (GET_CODE (pat) == UNSPEC
23866 && XINT (pat, 1) == UNSPEC_TIE)
23869 if (GET_CODE (pat) == MEM)
23872 /* Recursively process the pattern. */
23873 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23875 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23878 ret |= is_mem_ref (XEXP (pat, i));
23879 else if (fmt[i] == 'E')
23880 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23881 ret |= is_mem_ref (XVECEXP (pat, i, j));
23887 /* Determine if PAT is a PATTERN of a load insn. */
23890 is_load_insn1 (rtx pat)
23892 if (!pat || pat == NULL_RTX)
23895 if (GET_CODE (pat) == SET)
23896 return is_mem_ref (SET_SRC (pat));
23898 if (GET_CODE (pat) == PARALLEL)
23902 for (i = 0; i < XVECLEN (pat, 0); i++)
23903 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23910 /* Determine if INSN loads from memory. */
23913 is_load_insn (rtx insn)
23915 if (!insn || !INSN_P (insn))
23918 if (GET_CODE (insn) == CALL_INSN)
23921 return is_load_insn1 (PATTERN (insn));
23924 /* Determine if PAT is a PATTERN of a store insn. */
23927 is_store_insn1 (rtx pat)
23929 if (!pat || pat == NULL_RTX)
23932 if (GET_CODE (pat) == SET)
23933 return is_mem_ref (SET_DEST (pat));
23935 if (GET_CODE (pat) == PARALLEL)
23939 for (i = 0; i < XVECLEN (pat, 0); i++)
23940 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23947 /* Determine if INSN stores to memory. */
23950 is_store_insn (rtx insn)
23952 if (!insn || !INSN_P (insn))
23955 return is_store_insn1 (PATTERN (insn));
23958 /* Return the dest of a store insn. */
23961 get_store_dest (rtx pat)
23963 gcc_assert (is_store_insn1 (pat));
23965 if (GET_CODE (pat) == SET)
23966 return SET_DEST (pat);
23967 else if (GET_CODE (pat) == PARALLEL)
23971 for (i = 0; i < XVECLEN (pat, 0); i++)
23973 rtx inner_pat = XVECEXP (pat, 0, i);
23974 if (GET_CODE (inner_pat) == SET
23975 && is_mem_ref (SET_DEST (inner_pat)))
23979 /* We shouldn't get here, because we should have either a simple
23980 store insn or a store with update which are covered above. */
23984 /* Returns whether the dependence between INSN and NEXT is considered
23985 costly by the given target. */
23988 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
23993 /* If the flag is not enabled - no dependence is considered costly;
23994 allow all dependent insns in the same group.
23995 This is the most aggressive option. */
23996 if (rs6000_sched_costly_dep == no_dep_costly)
23999 /* If the flag is set to 1 - a dependence is always considered costly;
24000 do not allow dependent instructions in the same group.
24001 This is the most conservative option. */
24002 if (rs6000_sched_costly_dep == all_deps_costly)
24005 insn = DEP_PRO (dep);
24006 next = DEP_CON (dep);
24008 if (rs6000_sched_costly_dep == store_to_load_dep_costly
24009 && is_load_insn (next)
24010 && is_store_insn (insn))
24011 /* Prevent load after store in the same group. */
24014 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
24015 && is_load_insn (next)
24016 && is_store_insn (insn)
24017 && DEP_TYPE (dep) == REG_DEP_TRUE)
24018 /* Prevent load after store in the same group if it is a true
24022 /* The flag is set to X; dependences with latency >= X are considered costly,
24023 and will not be scheduled in the same group. */
24024 if (rs6000_sched_costly_dep <= max_dep_latency
24025 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24031 /* Return the next insn after INSN that is found before TAIL is reached,
24032 skipping any "non-active" insns - insns that will not actually occupy
24033 an issue slot. Return NULL_RTX if such an insn is not found. */
24036 get_next_active_insn (rtx insn, rtx tail)
24038 if (insn == NULL_RTX || insn == tail)
24043 insn = NEXT_INSN (insn);
24044 if (insn == NULL_RTX || insn == tail)
24049 || (NONJUMP_INSN_P (insn)
24050 && GET_CODE (PATTERN (insn)) != USE
24051 && GET_CODE (PATTERN (insn)) != CLOBBER
24052 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24058 /* We are about to begin issuing insns for this clock cycle. */
24061 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24062 rtx *ready ATTRIBUTE_UNUSED,
24063 int *pn_ready ATTRIBUTE_UNUSED,
24064 int clock_var ATTRIBUTE_UNUSED)
24066 int n_ready = *pn_ready;
24069 fprintf (dump, "// rs6000_sched_reorder :\n");
24071 /* Reorder the ready list, if the second to last ready insn
24072 is a nonepipeline insn. */
24073 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24075 if (is_nonpipeline_insn (ready[n_ready - 1])
24076 && (recog_memoized (ready[n_ready - 2]) > 0))
24077 /* Simply swap first two insns. */
24079 rtx tmp = ready[n_ready - 1];
24080 ready[n_ready - 1] = ready[n_ready - 2];
24081 ready[n_ready - 2] = tmp;
24085 if (rs6000_cpu == PROCESSOR_POWER6)
24086 load_store_pendulum = 0;
24088 return rs6000_issue_rate ();
24091 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24094 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24095 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24098 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24100 /* For Power6, we need to handle some special cases to try and keep the
24101 store queue from overflowing and triggering expensive flushes.
24103 This code monitors how load and store instructions are being issued
24104 and skews the ready list one way or the other to increase the likelihood
24105 that a desired instruction is issued at the proper time.
24107 A couple of things are done. First, we maintain a "load_store_pendulum"
24108 to track the current state of load/store issue.
24110 - If the pendulum is at zero, then no loads or stores have been
24111 issued in the current cycle so we do nothing.
24113 - If the pendulum is 1, then a single load has been issued in this
24114 cycle and we attempt to locate another load in the ready list to
24117 - If the pendulum is -2, then two stores have already been
24118 issued in this cycle, so we increase the priority of the first load
24119 in the ready list to increase it's likelihood of being chosen first
24122 - If the pendulum is -1, then a single store has been issued in this
24123 cycle and we attempt to locate another store in the ready list to
24124 issue with it, preferring a store to an adjacent memory location to
24125 facilitate store pairing in the store queue.
24127 - If the pendulum is 2, then two loads have already been
24128 issued in this cycle, so we increase the priority of the first store
24129 in the ready list to increase it's likelihood of being chosen first
24132 - If the pendulum < -2 or > 2, then do nothing.
24134 Note: This code covers the most common scenarios. There exist non
24135 load/store instructions which make use of the LSU and which
24136 would need to be accounted for to strictly model the behavior
24137 of the machine. Those instructions are currently unaccounted
24138 for to help minimize compile time overhead of this code.
24140 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24146 if (is_store_insn (last_scheduled_insn))
24147 /* Issuing a store, swing the load_store_pendulum to the left */
24148 load_store_pendulum--;
24149 else if (is_load_insn (last_scheduled_insn))
24150 /* Issuing a load, swing the load_store_pendulum to the right */
24151 load_store_pendulum++;
24153 return cached_can_issue_more;
24155 /* If the pendulum is balanced, or there is only one instruction on
24156 the ready list, then all is well, so return. */
24157 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24158 return cached_can_issue_more;
24160 if (load_store_pendulum == 1)
24162 /* A load has been issued in this cycle. Scan the ready list
24163 for another load to issue with it */
24168 if (is_load_insn (ready[pos]))
24170 /* Found a load. Move it to the head of the ready list,
24171 and adjust it's priority so that it is more likely to
24174 for (i=pos; i<*pn_ready-1; i++)
24175 ready[i] = ready[i + 1];
24176 ready[*pn_ready-1] = tmp;
24178 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24179 INSN_PRIORITY (tmp)++;
24185 else if (load_store_pendulum == -2)
24187 /* Two stores have been issued in this cycle. Increase the
24188 priority of the first load in the ready list to favor it for
24189 issuing in the next cycle. */
24194 if (is_load_insn (ready[pos])
24196 && INSN_PRIORITY_KNOWN (ready[pos]))
24198 INSN_PRIORITY (ready[pos])++;
24200 /* Adjust the pendulum to account for the fact that a load
24201 was found and increased in priority. This is to prevent
24202 increasing the priority of multiple loads */
24203 load_store_pendulum--;
24210 else if (load_store_pendulum == -1)
24212 /* A store has been issued in this cycle. Scan the ready list for
24213 another store to issue with it, preferring a store to an adjacent
24215 int first_store_pos = -1;
24221 if (is_store_insn (ready[pos]))
24223 /* Maintain the index of the first store found on the
24225 if (first_store_pos == -1)
24226 first_store_pos = pos;
24228 if (is_store_insn (last_scheduled_insn)
24229 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24231 /* Found an adjacent store. Move it to the head of the
24232 ready list, and adjust it's priority so that it is
24233 more likely to stay there */
24235 for (i=pos; i<*pn_ready-1; i++)
24236 ready[i] = ready[i + 1];
24237 ready[*pn_ready-1] = tmp;
24239 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24240 INSN_PRIORITY (tmp)++;
24242 first_store_pos = -1;
24250 if (first_store_pos >= 0)
24252 /* An adjacent store wasn't found, but a non-adjacent store was,
24253 so move the non-adjacent store to the front of the ready
24254 list, and adjust its priority so that it is more likely to
24256 tmp = ready[first_store_pos];
24257 for (i=first_store_pos; i<*pn_ready-1; i++)
24258 ready[i] = ready[i + 1];
24259 ready[*pn_ready-1] = tmp;
24260 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24261 INSN_PRIORITY (tmp)++;
24264 else if (load_store_pendulum == 2)
24266 /* Two loads have been issued in this cycle. Increase the priority
24267 of the first store in the ready list to favor it for issuing in
24273 if (is_store_insn (ready[pos])
24275 && INSN_PRIORITY_KNOWN (ready[pos]))
24277 INSN_PRIORITY (ready[pos])++;
24279 /* Adjust the pendulum to account for the fact that a store
24280 was found and increased in priority. This is to prevent
24281 increasing the priority of multiple stores */
24282 load_store_pendulum++;
24291 return cached_can_issue_more;
24294 /* Return whether the presence of INSN causes a dispatch group termination
24295 of group WHICH_GROUP.
24297 If WHICH_GROUP == current_group, this function will return true if INSN
24298 causes the termination of the current group (i.e, the dispatch group to
24299 which INSN belongs). This means that INSN will be the last insn in the
24300 group it belongs to.
24302 If WHICH_GROUP == previous_group, this function will return true if INSN
24303 causes the termination of the previous group (i.e, the dispatch group that
24304 precedes the group to which INSN belongs). This means that INSN will be
24305 the first insn in the group it belongs to). */
24308 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24315 first = insn_must_be_first_in_group (insn);
24316 last = insn_must_be_last_in_group (insn);
24321 if (which_group == current_group)
24323 else if (which_group == previous_group)
24331 insn_must_be_first_in_group (rtx insn)
24333 enum attr_type type;
24336 || GET_CODE (insn) == NOTE
24337 || DEBUG_INSN_P (insn)
24338 || GET_CODE (PATTERN (insn)) == USE
24339 || GET_CODE (PATTERN (insn)) == CLOBBER)
24342 switch (rs6000_cpu)
24344 case PROCESSOR_POWER5:
24345 if (is_cracked_insn (insn))
24347 case PROCESSOR_POWER4:
24348 if (is_microcoded_insn (insn))
24351 if (!rs6000_sched_groups)
24354 type = get_attr_type (insn);
24361 case TYPE_DELAYED_CR:
24362 case TYPE_CR_LOGICAL:
24376 case PROCESSOR_POWER6:
24377 type = get_attr_type (insn);
24381 case TYPE_INSERT_DWORD:
24385 case TYPE_VAR_SHIFT_ROTATE:
24392 case TYPE_INSERT_WORD:
24393 case TYPE_DELAYED_COMPARE:
24394 case TYPE_IMUL_COMPARE:
24395 case TYPE_LMUL_COMPARE:
24396 case TYPE_FPCOMPARE:
24407 case TYPE_LOAD_EXT_UX:
24409 case TYPE_STORE_UX:
24410 case TYPE_FPLOAD_U:
24411 case TYPE_FPLOAD_UX:
24412 case TYPE_FPSTORE_U:
24413 case TYPE_FPSTORE_UX:
24419 case PROCESSOR_POWER7:
24420 type = get_attr_type (insn);
24424 case TYPE_CR_LOGICAL:
24431 case TYPE_DELAYED_COMPARE:
24432 case TYPE_VAR_DELAYED_COMPARE:
24438 case TYPE_LOAD_EXT:
24439 case TYPE_LOAD_EXT_U:
24440 case TYPE_LOAD_EXT_UX:
24442 case TYPE_STORE_UX:
24443 case TYPE_FPLOAD_U:
24444 case TYPE_FPLOAD_UX:
24445 case TYPE_FPSTORE_U:
24446 case TYPE_FPSTORE_UX:
24462 insn_must_be_last_in_group (rtx insn)
24464 enum attr_type type;
24467 || GET_CODE (insn) == NOTE
24468 || DEBUG_INSN_P (insn)
24469 || GET_CODE (PATTERN (insn)) == USE
24470 || GET_CODE (PATTERN (insn)) == CLOBBER)
24473 switch (rs6000_cpu) {
24474 case PROCESSOR_POWER4:
24475 case PROCESSOR_POWER5:
24476 if (is_microcoded_insn (insn))
24479 if (is_branch_slot_insn (insn))
24483 case PROCESSOR_POWER6:
24484 type = get_attr_type (insn);
24491 case TYPE_VAR_SHIFT_ROTATE:
24498 case TYPE_DELAYED_COMPARE:
24499 case TYPE_IMUL_COMPARE:
24500 case TYPE_LMUL_COMPARE:
24501 case TYPE_FPCOMPARE:
24515 case PROCESSOR_POWER7:
24516 type = get_attr_type (insn);
24524 case TYPE_LOAD_EXT_U:
24525 case TYPE_LOAD_EXT_UX:
24526 case TYPE_STORE_UX:
24539 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24540 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24543 is_costly_group (rtx *group_insns, rtx next_insn)
24546 int issue_rate = rs6000_issue_rate ();
24548 for (i = 0; i < issue_rate; i++)
24550 sd_iterator_def sd_it;
24552 rtx insn = group_insns[i];
24557 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24559 rtx next = DEP_CON (dep);
24561 if (next == next_insn
24562 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24570 /* Utility of the function redefine_groups.
24571 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24572 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24573 to keep it "far" (in a separate group) from GROUP_INSNS, following
24574 one of the following schemes, depending on the value of the flag
24575 -minsert_sched_nops = X:
24576 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24577 in order to force NEXT_INSN into a separate group.
24578 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24579 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24580 insertion (has a group just ended, how many vacant issue slots remain in the
24581 last group, and how many dispatch groups were encountered so far). */
24584 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24585 rtx next_insn, bool *group_end, int can_issue_more,
24590 int issue_rate = rs6000_issue_rate ();
24591 bool end = *group_end;
24594 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24595 return can_issue_more;
24597 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24598 return can_issue_more;
24600 force = is_costly_group (group_insns, next_insn);
24602 return can_issue_more;
24604 if (sched_verbose > 6)
24605 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24606 *group_count ,can_issue_more);
24608 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24611 can_issue_more = 0;
24613 /* Since only a branch can be issued in the last issue_slot, it is
24614 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24615 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24616 in this case the last nop will start a new group and the branch
24617 will be forced to the new group. */
24618 if (can_issue_more && !is_branch_slot_insn (next_insn))
24621 while (can_issue_more > 0)
24624 emit_insn_before (nop, next_insn);
24632 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24634 int n_nops = rs6000_sched_insert_nops;
24636 /* Nops can't be issued from the branch slot, so the effective
24637 issue_rate for nops is 'issue_rate - 1'. */
24638 if (can_issue_more == 0)
24639 can_issue_more = issue_rate;
24641 if (can_issue_more == 0)
24643 can_issue_more = issue_rate - 1;
24646 for (i = 0; i < issue_rate; i++)
24648 group_insns[i] = 0;
24655 emit_insn_before (nop, next_insn);
24656 if (can_issue_more == issue_rate - 1) /* new group begins */
24659 if (can_issue_more == 0)
24661 can_issue_more = issue_rate - 1;
24664 for (i = 0; i < issue_rate; i++)
24666 group_insns[i] = 0;
24672 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24675 /* Is next_insn going to start a new group? */
24678 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24679 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24680 || (can_issue_more < issue_rate &&
24681 insn_terminates_group_p (next_insn, previous_group)));
24682 if (*group_end && end)
24685 if (sched_verbose > 6)
24686 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24687 *group_count, can_issue_more);
24688 return can_issue_more;
24691 return can_issue_more;
24694 /* This function tries to synch the dispatch groups that the compiler "sees"
24695 with the dispatch groups that the processor dispatcher is expected to
24696 form in practice. It tries to achieve this synchronization by forcing the
24697 estimated processor grouping on the compiler (as opposed to the function
24698 'pad_goups' which tries to force the scheduler's grouping on the processor).
24700 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24701 examines the (estimated) dispatch groups that will be formed by the processor
24702 dispatcher. It marks these group boundaries to reflect the estimated
24703 processor grouping, overriding the grouping that the scheduler had marked.
24704 Depending on the value of the flag '-minsert-sched-nops' this function can
24705 force certain insns into separate groups or force a certain distance between
24706 them by inserting nops, for example, if there exists a "costly dependence"
24709 The function estimates the group boundaries that the processor will form as
24710 follows: It keeps track of how many vacant issue slots are available after
24711 each insn. A subsequent insn will start a new group if one of the following
24713 - no more vacant issue slots remain in the current dispatch group.
24714 - only the last issue slot, which is the branch slot, is vacant, but the next
24715 insn is not a branch.
24716 - only the last 2 or less issue slots, including the branch slot, are vacant,
24717 which means that a cracked insn (which occupies two issue slots) can't be
24718 issued in this group.
24719 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24720 start a new group. */
24723 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24725 rtx insn, next_insn;
24727 int can_issue_more;
24730 int group_count = 0;
24734 issue_rate = rs6000_issue_rate ();
24735 group_insns = XALLOCAVEC (rtx, issue_rate);
24736 for (i = 0; i < issue_rate; i++)
24738 group_insns[i] = 0;
24740 can_issue_more = issue_rate;
24742 insn = get_next_active_insn (prev_head_insn, tail);
24745 while (insn != NULL_RTX)
24747 slot = (issue_rate - can_issue_more);
24748 group_insns[slot] = insn;
24750 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24751 if (insn_terminates_group_p (insn, current_group))
24752 can_issue_more = 0;
24754 next_insn = get_next_active_insn (insn, tail);
24755 if (next_insn == NULL_RTX)
24756 return group_count + 1;
24758 /* Is next_insn going to start a new group? */
24760 = (can_issue_more == 0
24761 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24762 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24763 || (can_issue_more < issue_rate &&
24764 insn_terminates_group_p (next_insn, previous_group)));
24766 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24767 next_insn, &group_end, can_issue_more,
24773 can_issue_more = 0;
24774 for (i = 0; i < issue_rate; i++)
24776 group_insns[i] = 0;
24780 if (GET_MODE (next_insn) == TImode && can_issue_more)
24781 PUT_MODE (next_insn, VOIDmode);
24782 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24783 PUT_MODE (next_insn, TImode);
24786 if (can_issue_more == 0)
24787 can_issue_more = issue_rate;
24790 return group_count;
24793 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24794 dispatch group boundaries that the scheduler had marked. Pad with nops
24795 any dispatch groups which have vacant issue slots, in order to force the
24796 scheduler's grouping on the processor dispatcher. The function
24797 returns the number of dispatch groups found. */
24800 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24802 rtx insn, next_insn;
24805 int can_issue_more;
24807 int group_count = 0;
24809 /* Initialize issue_rate. */
24810 issue_rate = rs6000_issue_rate ();
24811 can_issue_more = issue_rate;
24813 insn = get_next_active_insn (prev_head_insn, tail);
24814 next_insn = get_next_active_insn (insn, tail);
24816 while (insn != NULL_RTX)
24819 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24821 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24823 if (next_insn == NULL_RTX)
24828 /* If the scheduler had marked group termination at this location
24829 (between insn and next_insn), and neither insn nor next_insn will
24830 force group termination, pad the group with nops to force group
24833 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24834 && !insn_terminates_group_p (insn, current_group)
24835 && !insn_terminates_group_p (next_insn, previous_group))
24837 if (!is_branch_slot_insn (next_insn))
24840 while (can_issue_more)
24843 emit_insn_before (nop, next_insn);
24848 can_issue_more = issue_rate;
24853 next_insn = get_next_active_insn (insn, tail);
24856 return group_count;
24859 /* We're beginning a new block. Initialize data structures as necessary. */
24862 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24863 int sched_verbose ATTRIBUTE_UNUSED,
24864 int max_ready ATTRIBUTE_UNUSED)
24866 last_scheduled_insn = NULL_RTX;
24867 load_store_pendulum = 0;
24870 /* The following function is called at the end of scheduling BB.
24871 After reload, it inserts nops at insn group bundling. */
24874 rs6000_sched_finish (FILE *dump, int sched_verbose)
24879 fprintf (dump, "=== Finishing schedule.\n");
24881 if (reload_completed && rs6000_sched_groups)
24883 /* Do not run sched_finish hook when selective scheduling enabled. */
24884 if (sel_sched_p ())
24887 if (rs6000_sched_insert_nops == sched_finish_none)
24890 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24891 n_groups = pad_groups (dump, sched_verbose,
24892 current_sched_info->prev_head,
24893 current_sched_info->next_tail);
24895 n_groups = redefine_groups (dump, sched_verbose,
24896 current_sched_info->prev_head,
24897 current_sched_info->next_tail);
24899 if (sched_verbose >= 6)
24901 fprintf (dump, "ngroups = %d\n", n_groups);
24902 print_rtl (dump, current_sched_info->prev_head);
24903 fprintf (dump, "Done finish_sched\n");
24908 struct _rs6000_sched_context
24910 short cached_can_issue_more;
24911 rtx last_scheduled_insn;
24912 int load_store_pendulum;
24915 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24916 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24918 /* Allocate store for new scheduling context. */
24920 rs6000_alloc_sched_context (void)
24922 return xmalloc (sizeof (rs6000_sched_context_def));
24925 /* If CLEAN_P is true then initializes _SC with clean data,
24926 and from the global context otherwise. */
24928 rs6000_init_sched_context (void *_sc, bool clean_p)
24930 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24934 sc->cached_can_issue_more = 0;
24935 sc->last_scheduled_insn = NULL_RTX;
24936 sc->load_store_pendulum = 0;
24940 sc->cached_can_issue_more = cached_can_issue_more;
24941 sc->last_scheduled_insn = last_scheduled_insn;
24942 sc->load_store_pendulum = load_store_pendulum;
24946 /* Sets the global scheduling context to the one pointed to by _SC. */
24948 rs6000_set_sched_context (void *_sc)
24950 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24952 gcc_assert (sc != NULL);
24954 cached_can_issue_more = sc->cached_can_issue_more;
24955 last_scheduled_insn = sc->last_scheduled_insn;
24956 load_store_pendulum = sc->load_store_pendulum;
24961 rs6000_free_sched_context (void *_sc)
24963 gcc_assert (_sc != NULL);
24969 /* Length in units of the trampoline for entering a nested function. */
24972 rs6000_trampoline_size (void)
24976 switch (DEFAULT_ABI)
24979 gcc_unreachable ();
24982 ret = (TARGET_32BIT) ? 12 : 24;
24987 ret = (TARGET_32BIT) ? 40 : 48;
24994 /* Emit RTL insns to initialize the variable parts of a trampoline.
24995 FNADDR is an RTX for the address of the function's pure code.
24996 CXT is an RTX for the static chain value for the function. */
24999 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
25001 int regsize = (TARGET_32BIT) ? 4 : 8;
25002 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
25003 rtx ctx_reg = force_reg (Pmode, cxt);
25004 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
25006 switch (DEFAULT_ABI)
25009 gcc_unreachable ();
25011 /* Under AIX, just build the 3 word function descriptor */
25014 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
25015 rtx fn_reg = gen_reg_rtx (Pmode);
25016 rtx toc_reg = gen_reg_rtx (Pmode);
25018 /* Macro to shorten the code expansions below. */
25019 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25021 m_tramp = replace_equiv_address (m_tramp, addr);
25023 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25024 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25025 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25026 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25027 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25033 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25036 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25037 LCT_NORMAL, VOIDmode, 4,
25039 GEN_INT (rs6000_trampoline_size ()), SImode,
25047 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25048 identifier as an argument, so the front end shouldn't look it up. */
25051 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25053 return is_attribute_p ("altivec", attr_id);
25056 /* Handle the "altivec" attribute. The attribute may have
25057 arguments as follows:
25059 __attribute__((altivec(vector__)))
25060 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25061 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25063 and may appear more than once (e.g., 'vector bool char') in a
25064 given declaration. */
25067 rs6000_handle_altivec_attribute (tree *node,
25068 tree name ATTRIBUTE_UNUSED,
25070 int flags ATTRIBUTE_UNUSED,
25071 bool *no_add_attrs)
25073 tree type = *node, result = NULL_TREE;
25074 enum machine_mode mode;
25077 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25078 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25079 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25082 while (POINTER_TYPE_P (type)
25083 || TREE_CODE (type) == FUNCTION_TYPE
25084 || TREE_CODE (type) == METHOD_TYPE
25085 || TREE_CODE (type) == ARRAY_TYPE)
25086 type = TREE_TYPE (type);
25088 mode = TYPE_MODE (type);
25090 /* Check for invalid AltiVec type qualifiers. */
25091 if (type == long_double_type_node)
25092 error ("use of %<long double%> in AltiVec types is invalid");
25093 else if (type == boolean_type_node)
25094 error ("use of boolean types in AltiVec types is invalid");
25095 else if (TREE_CODE (type) == COMPLEX_TYPE)
25096 error ("use of %<complex%> in AltiVec types is invalid");
25097 else if (DECIMAL_FLOAT_MODE_P (mode))
25098 error ("use of decimal floating point types in AltiVec types is invalid");
25099 else if (!TARGET_VSX)
25101 if (type == long_unsigned_type_node || type == long_integer_type_node)
25104 error ("use of %<long%> in AltiVec types is invalid for "
25105 "64-bit code without -mvsx");
25106 else if (rs6000_warn_altivec_long)
25107 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25110 else if (type == long_long_unsigned_type_node
25111 || type == long_long_integer_type_node)
25112 error ("use of %<long long%> in AltiVec types is invalid without "
25114 else if (type == double_type_node)
25115 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25118 switch (altivec_type)
25121 unsigned_p = TYPE_UNSIGNED (type);
25125 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25128 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25131 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25134 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25136 case SFmode: result = V4SF_type_node; break;
25137 case DFmode: result = V2DF_type_node; break;
25138 /* If the user says 'vector int bool', we may be handed the 'bool'
25139 attribute _before_ the 'vector' attribute, and so select the
25140 proper type in the 'b' case below. */
25141 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25142 case V2DImode: case V2DFmode:
25150 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25151 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25152 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25153 case QImode: case V16QImode: result = bool_V16QI_type_node;
25160 case V8HImode: result = pixel_V8HI_type_node;
25166 /* Propagate qualifiers attached to the element type
25167 onto the vector type. */
25168 if (result && result != type && TYPE_QUALS (type))
25169 result = build_qualified_type (result, TYPE_QUALS (type));
25171 *no_add_attrs = true; /* No need to hang on to the attribute. */
25174 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25179 /* AltiVec defines four built-in scalar types that serve as vector
25180 elements; we must teach the compiler how to mangle them. */
25182 static const char *
25183 rs6000_mangle_type (const_tree type)
25185 type = TYPE_MAIN_VARIANT (type);
25187 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25188 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25191 if (type == bool_char_type_node) return "U6__boolc";
25192 if (type == bool_short_type_node) return "U6__bools";
25193 if (type == pixel_type_node) return "u7__pixel";
25194 if (type == bool_int_type_node) return "U6__booli";
25195 if (type == bool_long_type_node) return "U6__booll";
25197 /* Mangle IBM extended float long double as `g' (__float128) on
25198 powerpc*-linux where long-double-64 previously was the default. */
25199 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25201 && TARGET_LONG_DOUBLE_128
25202 && !TARGET_IEEEQUAD)
25205 /* For all other types, use normal C++ mangling. */
25209 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25210 struct attribute_spec.handler. */
25213 rs6000_handle_longcall_attribute (tree *node, tree name,
25214 tree args ATTRIBUTE_UNUSED,
25215 int flags ATTRIBUTE_UNUSED,
25216 bool *no_add_attrs)
25218 if (TREE_CODE (*node) != FUNCTION_TYPE
25219 && TREE_CODE (*node) != FIELD_DECL
25220 && TREE_CODE (*node) != TYPE_DECL)
25222 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25224 *no_add_attrs = true;
25230 /* Set longcall attributes on all functions declared when
25231 rs6000_default_long_calls is true. */
25233 rs6000_set_default_type_attributes (tree type)
25235 if (rs6000_default_long_calls
25236 && (TREE_CODE (type) == FUNCTION_TYPE
25237 || TREE_CODE (type) == METHOD_TYPE))
25238 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25240 TYPE_ATTRIBUTES (type));
25243 darwin_set_default_type_attributes (type);
25247 /* Return a reference suitable for calling a function with the
25248 longcall attribute. */
25251 rs6000_longcall_ref (rtx call_ref)
25253 const char *call_name;
25256 if (GET_CODE (call_ref) != SYMBOL_REF)
25259 /* System V adds '.' to the internal name, so skip them. */
25260 call_name = XSTR (call_ref, 0);
25261 if (*call_name == '.')
25263 while (*call_name == '.')
25266 node = get_identifier (call_name);
25267 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25270 return force_reg (Pmode, call_ref);
25273 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25274 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25277 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25278 struct attribute_spec.handler. */
25280 rs6000_handle_struct_attribute (tree *node, tree name,
25281 tree args ATTRIBUTE_UNUSED,
25282 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25285 if (DECL_P (*node))
25287 if (TREE_CODE (*node) == TYPE_DECL)
25288 type = &TREE_TYPE (*node);
25293 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25294 || TREE_CODE (*type) == UNION_TYPE)))
25296 warning (OPT_Wattributes, "%qE attribute ignored", name);
25297 *no_add_attrs = true;
25300 else if ((is_attribute_p ("ms_struct", name)
25301 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25302 || ((is_attribute_p ("gcc_struct", name)
25303 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25305 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25307 *no_add_attrs = true;
25314 rs6000_ms_bitfield_layout_p (const_tree record_type)
25316 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25317 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25318 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25321 #ifdef USING_ELFOS_H
25323 /* A get_unnamed_section callback, used for switching to toc_section. */
25326 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25328 if (DEFAULT_ABI == ABI_AIX
25329 && TARGET_MINIMAL_TOC
25330 && !TARGET_RELOCATABLE)
25332 if (!toc_initialized)
25334 toc_initialized = 1;
25335 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25336 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25337 fprintf (asm_out_file, "\t.tc ");
25338 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25339 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25340 fprintf (asm_out_file, "\n");
25342 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25343 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25344 fprintf (asm_out_file, " = .+32768\n");
25347 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25349 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25350 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25353 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25354 if (!toc_initialized)
25356 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25357 fprintf (asm_out_file, " = .+32768\n");
25358 toc_initialized = 1;
25363 /* Implement TARGET_ASM_INIT_SECTIONS. */
25366 rs6000_elf_asm_init_sections (void)
25369 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25372 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25373 SDATA2_SECTION_ASM_OP);
25376 /* Implement TARGET_SELECT_RTX_SECTION. */
25379 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25380 unsigned HOST_WIDE_INT align)
25382 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25383 return toc_section;
25385 return default_elf_select_rtx_section (mode, x, align);
25388 /* For a SYMBOL_REF, set generic flags and then perform some
25389 target-specific processing.
25391 When the AIX ABI is requested on a non-AIX system, replace the
25392 function name with the real name (with a leading .) rather than the
25393 function descriptor name. This saves a lot of overriding code to
25394 read the prefixes. */
25397 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25399 default_encode_section_info (decl, rtl, first);
25402 && TREE_CODE (decl) == FUNCTION_DECL
25404 && DEFAULT_ABI == ABI_AIX)
25406 rtx sym_ref = XEXP (rtl, 0);
25407 size_t len = strlen (XSTR (sym_ref, 0));
25408 char *str = XALLOCAVEC (char, len + 2);
25410 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25411 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25416 compare_section_name (const char *section, const char *templ)
25420 len = strlen (templ);
25421 return (strncmp (section, templ, len) == 0
25422 && (section[len] == 0 || section[len] == '.'));
25426 rs6000_elf_in_small_data_p (const_tree decl)
25428 if (rs6000_sdata == SDATA_NONE)
25431 /* We want to merge strings, so we never consider them small data. */
25432 if (TREE_CODE (decl) == STRING_CST)
25435 /* Functions are never in the small data area. */
25436 if (TREE_CODE (decl) == FUNCTION_DECL)
25439 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25441 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25442 if (compare_section_name (section, ".sdata")
25443 || compare_section_name (section, ".sdata2")
25444 || compare_section_name (section, ".gnu.linkonce.s")
25445 || compare_section_name (section, ".sbss")
25446 || compare_section_name (section, ".sbss2")
25447 || compare_section_name (section, ".gnu.linkonce.sb")
25448 || strcmp (section, ".PPC.EMB.sdata0") == 0
25449 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25454 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25457 && size <= g_switch_value
25458 /* If it's not public, and we're not going to reference it there,
25459 there's no need to put it in the small data section. */
25460 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25467 #endif /* USING_ELFOS_H */
25469 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25472 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25474 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25477 /* Return a REG that occurs in ADDR with coefficient 1.
25478 ADDR can be effectively incremented by incrementing REG.
25480 r0 is special and we must not select it as an address
25481 register by this routine since our caller will try to
25482 increment the returned register via an "la" instruction. */
25485 find_addr_reg (rtx addr)
25487 while (GET_CODE (addr) == PLUS)
25489 if (GET_CODE (XEXP (addr, 0)) == REG
25490 && REGNO (XEXP (addr, 0)) != 0)
25491 addr = XEXP (addr, 0);
25492 else if (GET_CODE (XEXP (addr, 1)) == REG
25493 && REGNO (XEXP (addr, 1)) != 0)
25494 addr = XEXP (addr, 1);
25495 else if (CONSTANT_P (XEXP (addr, 0)))
25496 addr = XEXP (addr, 1);
25497 else if (CONSTANT_P (XEXP (addr, 1)))
25498 addr = XEXP (addr, 0);
25500 gcc_unreachable ();
25502 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25507 rs6000_fatal_bad_address (rtx op)
25509 fatal_insn ("bad address", op);
25514 typedef struct branch_island_d {
25515 tree function_name;
25520 DEF_VEC_O(branch_island);
25521 DEF_VEC_ALLOC_O(branch_island,gc);
25523 static VEC(branch_island,gc) *branch_islands;
25525 /* Remember to generate a branch island for far calls to the given
25529 add_compiler_branch_island (tree label_name, tree function_name,
25532 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25534 bi->function_name = function_name;
25535 bi->label_name = label_name;
25536 bi->line_number = line_number;
25539 /* Generate far-jump branch islands for everything recorded in
25540 branch_islands. Invoked immediately after the last instruction of
25541 the epilogue has been emitted; the branch islands must be appended
25542 to, and contiguous with, the function body. Mach-O stubs are
25543 generated in machopic_output_stub(). */
25546 macho_branch_islands (void)
25550 while (!VEC_empty (branch_island, branch_islands))
25552 branch_island *bi = VEC_last (branch_island, branch_islands);
25553 const char *label = IDENTIFIER_POINTER (bi->label_name);
25554 const char *name = IDENTIFIER_POINTER (bi->function_name);
25555 char name_buf[512];
25556 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25557 if (name[0] == '*' || name[0] == '&')
25558 strcpy (name_buf, name+1);
25562 strcpy (name_buf+1, name);
25564 strcpy (tmp_buf, "\n");
25565 strcat (tmp_buf, label);
25566 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25567 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25568 dbxout_stabd (N_SLINE, bi->line_number);
25569 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25572 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25573 strcat (tmp_buf, label);
25574 strcat (tmp_buf, "_pic\n");
25575 strcat (tmp_buf, label);
25576 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25578 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25579 strcat (tmp_buf, name_buf);
25580 strcat (tmp_buf, " - ");
25581 strcat (tmp_buf, label);
25582 strcat (tmp_buf, "_pic)\n");
25584 strcat (tmp_buf, "\tmtlr r0\n");
25586 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25587 strcat (tmp_buf, name_buf);
25588 strcat (tmp_buf, " - ");
25589 strcat (tmp_buf, label);
25590 strcat (tmp_buf, "_pic)\n");
25592 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25596 strcat (tmp_buf, ":\nlis r12,hi16(");
25597 strcat (tmp_buf, name_buf);
25598 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25599 strcat (tmp_buf, name_buf);
25600 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25602 output_asm_insn (tmp_buf, 0);
25603 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25604 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25605 dbxout_stabd (N_SLINE, bi->line_number);
25606 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25607 VEC_pop (branch_island, branch_islands);
25611 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25612 already there or not. */
25615 no_previous_def (tree function_name)
25620 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25621 if (function_name == bi->function_name)
25626 /* GET_PREV_LABEL gets the label name from the previous definition of
25630 get_prev_label (tree function_name)
25635 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25636 if (function_name == bi->function_name)
25637 return bi->label_name;
25641 /* INSN is either a function call or a millicode call. It may have an
25642 unconditional jump in its delay slot.
25644 CALL_DEST is the routine we are calling. */
25647 output_call (rtx insn, rtx *operands, int dest_operand_number,
25648 int cookie_operand_number)
25650 static char buf[256];
25651 if (darwin_emit_branch_islands
25652 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25653 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25656 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25658 if (no_previous_def (funname))
25660 rtx label_rtx = gen_label_rtx ();
25661 char *label_buf, temp_buf[256];
25662 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25663 CODE_LABEL_NUMBER (label_rtx));
25664 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25665 labelname = get_identifier (label_buf);
25666 add_compiler_branch_island (labelname, funname, insn_line (insn));
25669 labelname = get_prev_label (funname);
25671 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25672 instruction will reach 'foo', otherwise link as 'bl L42'".
25673 "L42" should be a 'branch island', that will do a far jump to
25674 'foo'. Branch islands are generated in
25675 macho_branch_islands(). */
25676 sprintf (buf, "jbsr %%z%d,%.246s",
25677 dest_operand_number, IDENTIFIER_POINTER (labelname));
25680 sprintf (buf, "bl %%z%d", dest_operand_number);
25684 /* Generate PIC and indirect symbol stubs. */
25687 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25689 unsigned int length;
25690 char *symbol_name, *lazy_ptr_name;
25691 char *local_label_0;
25692 static int label = 0;
25694 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25695 symb = (*targetm.strip_name_encoding) (symb);
25698 length = strlen (symb);
25699 symbol_name = XALLOCAVEC (char, length + 32);
25700 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25702 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25703 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25706 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25708 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25712 fprintf (file, "\t.align 5\n");
25714 fprintf (file, "%s:\n", stub);
25715 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25718 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25719 sprintf (local_label_0, "\"L%011d$spb\"", label);
25721 fprintf (file, "\tmflr r0\n");
25722 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25723 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25724 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25725 lazy_ptr_name, local_label_0);
25726 fprintf (file, "\tmtlr r0\n");
25727 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25728 (TARGET_64BIT ? "ldu" : "lwzu"),
25729 lazy_ptr_name, local_label_0);
25730 fprintf (file, "\tmtctr r12\n");
25731 fprintf (file, "\tbctr\n");
25735 fprintf (file, "\t.align 4\n");
25737 fprintf (file, "%s:\n", stub);
25738 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25740 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25741 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25742 (TARGET_64BIT ? "ldu" : "lwzu"),
25744 fprintf (file, "\tmtctr r12\n");
25745 fprintf (file, "\tbctr\n");
25748 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25749 fprintf (file, "%s:\n", lazy_ptr_name);
25750 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25751 fprintf (file, "%sdyld_stub_binding_helper\n",
25752 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25755 /* Legitimize PIC addresses. If the address is already
25756 position-independent, we return ORIG. Newly generated
25757 position-independent addresses go into a reg. This is REG if non
25758 zero, otherwise we allocate register(s) as necessary. */
25760 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25763 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25768 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25769 reg = gen_reg_rtx (Pmode);
25771 if (GET_CODE (orig) == CONST)
25775 if (GET_CODE (XEXP (orig, 0)) == PLUS
25776 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25779 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25781 /* Use a different reg for the intermediate value, as
25782 it will be marked UNCHANGING. */
25783 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25784 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25787 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25790 if (GET_CODE (offset) == CONST_INT)
25792 if (SMALL_INT (offset))
25793 return plus_constant (base, INTVAL (offset));
25794 else if (! reload_in_progress && ! reload_completed)
25795 offset = force_reg (Pmode, offset);
25798 rtx mem = force_const_mem (Pmode, orig);
25799 return machopic_legitimize_pic_address (mem, Pmode, reg);
25802 return gen_rtx_PLUS (Pmode, base, offset);
25805 /* Fall back on generic machopic code. */
25806 return machopic_legitimize_pic_address (orig, mode, reg);
25809 /* Output a .machine directive for the Darwin assembler, and call
25810 the generic start_file routine. */
25813 rs6000_darwin_file_start (void)
25815 static const struct
25821 { "ppc64", "ppc64", MASK_64BIT },
25822 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25823 { "power4", "ppc970", 0 },
25824 { "G5", "ppc970", 0 },
25825 { "7450", "ppc7450", 0 },
25826 { "7400", "ppc7400", MASK_ALTIVEC },
25827 { "G4", "ppc7400", 0 },
25828 { "750", "ppc750", 0 },
25829 { "740", "ppc750", 0 },
25830 { "G3", "ppc750", 0 },
25831 { "604e", "ppc604e", 0 },
25832 { "604", "ppc604", 0 },
25833 { "603e", "ppc603", 0 },
25834 { "603", "ppc603", 0 },
25835 { "601", "ppc601", 0 },
25836 { NULL, "ppc", 0 } };
25837 const char *cpu_id = "";
25840 rs6000_file_start ();
25841 darwin_file_start ();
25843 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25844 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25845 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25846 && rs6000_select[i].string[0] != '\0')
25847 cpu_id = rs6000_select[i].string;
25849 /* Look through the mapping array. Pick the first name that either
25850 matches the argument, has a bit set in IF_SET that is also set
25851 in the target flags, or has a NULL name. */
25854 while (mapping[i].arg != NULL
25855 && strcmp (mapping[i].arg, cpu_id) != 0
25856 && (mapping[i].if_set & target_flags) == 0)
25859 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25862 #endif /* TARGET_MACHO */
25866 rs6000_elf_reloc_rw_mask (void)
25870 else if (DEFAULT_ABI == ABI_AIX)
25876 /* Record an element in the table of global constructors. SYMBOL is
25877 a SYMBOL_REF of the function to be called; PRIORITY is a number
25878 between 0 and MAX_INIT_PRIORITY.
25880 This differs from default_named_section_asm_out_constructor in
25881 that we have special handling for -mrelocatable. */
25884 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25886 const char *section = ".ctors";
25889 if (priority != DEFAULT_INIT_PRIORITY)
25891 sprintf (buf, ".ctors.%.5u",
25892 /* Invert the numbering so the linker puts us in the proper
25893 order; constructors are run from right to left, and the
25894 linker sorts in increasing order. */
25895 MAX_INIT_PRIORITY - priority);
25899 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25900 assemble_align (POINTER_SIZE);
25902 if (TARGET_RELOCATABLE)
25904 fputs ("\t.long (", asm_out_file);
25905 output_addr_const (asm_out_file, symbol);
25906 fputs (")@fixup\n", asm_out_file);
25909 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25913 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25915 const char *section = ".dtors";
25918 if (priority != DEFAULT_INIT_PRIORITY)
25920 sprintf (buf, ".dtors.%.5u",
25921 /* Invert the numbering so the linker puts us in the proper
25922 order; constructors are run from right to left, and the
25923 linker sorts in increasing order. */
25924 MAX_INIT_PRIORITY - priority);
25928 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25929 assemble_align (POINTER_SIZE);
25931 if (TARGET_RELOCATABLE)
25933 fputs ("\t.long (", asm_out_file);
25934 output_addr_const (asm_out_file, symbol);
25935 fputs (")@fixup\n", asm_out_file);
25938 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25942 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25946 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25947 ASM_OUTPUT_LABEL (file, name);
25948 fputs (DOUBLE_INT_ASM_OP, file);
25949 rs6000_output_function_entry (file, name);
25950 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25953 fputs ("\t.size\t", file);
25954 assemble_name (file, name);
25955 fputs (",24\n\t.type\t.", file);
25956 assemble_name (file, name);
25957 fputs (",@function\n", file);
25958 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25960 fputs ("\t.globl\t.", file);
25961 assemble_name (file, name);
25966 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25967 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25968 rs6000_output_function_entry (file, name);
25969 fputs (":\n", file);
25973 if (TARGET_RELOCATABLE
25974 && !TARGET_SECURE_PLT
25975 && (get_pool_size () != 0 || crtl->profile)
25980 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25982 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25983 fprintf (file, "\t.long ");
25984 assemble_name (file, buf);
25986 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25987 assemble_name (file, buf);
25991 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25992 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25994 if (DEFAULT_ABI == ABI_AIX)
25996 const char *desc_name, *orig_name;
25998 orig_name = (*targetm.strip_name_encoding) (name);
25999 desc_name = orig_name;
26000 while (*desc_name == '.')
26003 if (TREE_PUBLIC (decl))
26004 fprintf (file, "\t.globl %s\n", desc_name);
26006 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
26007 fprintf (file, "%s:\n", desc_name);
26008 fprintf (file, "\t.long %s\n", orig_name);
26009 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
26010 if (DEFAULT_ABI == ABI_AIX)
26011 fputs ("\t.long 0\n", file);
26012 fprintf (file, "\t.previous\n");
26014 ASM_OUTPUT_LABEL (file, name);
26018 rs6000_elf_file_end (void)
26020 #ifdef HAVE_AS_GNU_ATTRIBUTE
26021 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26023 if (rs6000_passes_float)
26024 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26025 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26026 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26028 if (rs6000_passes_vector)
26029 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26030 (TARGET_ALTIVEC_ABI ? 2
26031 : TARGET_SPE_ABI ? 3
26033 if (rs6000_returns_struct)
26034 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26035 aix_struct_return ? 2 : 1);
26038 #ifdef POWERPC_LINUX
26040 file_end_indicate_exec_stack ();
26047 rs6000_xcoff_asm_output_anchor (rtx symbol)
26051 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26052 SYMBOL_REF_BLOCK_OFFSET (symbol));
26053 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26057 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26059 fputs (GLOBAL_ASM_OP, stream);
26060 RS6000_OUTPUT_BASENAME (stream, name);
26061 putc ('\n', stream);
26064 /* A get_unnamed_decl callback, used for read-only sections. PTR
26065 points to the section string variable. */
26068 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26070 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26071 *(const char *const *) directive,
26072 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26075 /* Likewise for read-write sections. */
26078 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26080 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26081 *(const char *const *) directive,
26082 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26085 /* A get_unnamed_section callback, used for switching to toc_section. */
26088 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26090 if (TARGET_MINIMAL_TOC)
26092 /* toc_section is always selected at least once from
26093 rs6000_xcoff_file_start, so this is guaranteed to
26094 always be defined once and only once in each file. */
26095 if (!toc_initialized)
26097 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26098 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26099 toc_initialized = 1;
26101 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26102 (TARGET_32BIT ? "" : ",3"));
26105 fputs ("\t.toc\n", asm_out_file);
26108 /* Implement TARGET_ASM_INIT_SECTIONS. */
26111 rs6000_xcoff_asm_init_sections (void)
26113 read_only_data_section
26114 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26115 &xcoff_read_only_section_name);
26117 private_data_section
26118 = get_unnamed_section (SECTION_WRITE,
26119 rs6000_xcoff_output_readwrite_section_asm_op,
26120 &xcoff_private_data_section_name);
26122 read_only_private_data_section
26123 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26124 &xcoff_private_data_section_name);
26127 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26129 readonly_data_section = read_only_data_section;
26130 exception_section = data_section;
26134 rs6000_xcoff_reloc_rw_mask (void)
26140 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26141 tree decl ATTRIBUTE_UNUSED)
26144 static const char * const suffix[3] = { "PR", "RO", "RW" };
26146 if (flags & SECTION_CODE)
26148 else if (flags & SECTION_WRITE)
26153 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26154 (flags & SECTION_CODE) ? "." : "",
26155 name, suffix[smclass], flags & SECTION_ENTSIZE);
26159 rs6000_xcoff_select_section (tree decl, int reloc,
26160 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26162 if (decl_readonly_section (decl, reloc))
26164 if (TREE_PUBLIC (decl))
26165 return read_only_data_section;
26167 return read_only_private_data_section;
26171 if (TREE_PUBLIC (decl))
26172 return data_section;
26174 return private_data_section;
26179 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26183 /* Use select_section for private and uninitialized data. */
26184 if (!TREE_PUBLIC (decl)
26185 || DECL_COMMON (decl)
26186 || DECL_INITIAL (decl) == NULL_TREE
26187 || DECL_INITIAL (decl) == error_mark_node
26188 || (flag_zero_initialized_in_bss
26189 && initializer_zerop (DECL_INITIAL (decl))))
26192 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26193 name = (*targetm.strip_name_encoding) (name);
26194 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26197 /* Select section for constant in constant pool.
26199 On RS/6000, all constants are in the private read-only data area.
26200 However, if this is being placed in the TOC it must be output as a
26204 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26205 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26207 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26208 return toc_section;
26210 return read_only_private_data_section;
26213 /* Remove any trailing [DS] or the like from the symbol name. */
26215 static const char *
26216 rs6000_xcoff_strip_name_encoding (const char *name)
26221 len = strlen (name);
26222 if (name[len - 1] == ']')
26223 return ggc_alloc_string (name, len - 4);
26228 /* Section attributes. AIX is always PIC. */
26230 static unsigned int
26231 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26233 unsigned int align;
26234 unsigned int flags = default_section_type_flags (decl, name, reloc);
26236 /* Align to at least UNIT size. */
26237 if (flags & SECTION_CODE)
26238 align = MIN_UNITS_PER_WORD;
26240 /* Increase alignment of large objects if not already stricter. */
26241 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26242 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26243 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26245 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26248 /* Output at beginning of assembler file.
26250 Initialize the section names for the RS/6000 at this point.
26252 Specify filename, including full path, to assembler.
26254 We want to go into the TOC section so at least one .toc will be emitted.
26255 Also, in order to output proper .bs/.es pairs, we need at least one static
26256 [RW] section emitted.
26258 Finally, declare mcount when profiling to make the assembler happy. */
26261 rs6000_xcoff_file_start (void)
26263 rs6000_gen_section_name (&xcoff_bss_section_name,
26264 main_input_filename, ".bss_");
26265 rs6000_gen_section_name (&xcoff_private_data_section_name,
26266 main_input_filename, ".rw_");
26267 rs6000_gen_section_name (&xcoff_read_only_section_name,
26268 main_input_filename, ".ro_");
26270 fputs ("\t.file\t", asm_out_file);
26271 output_quoted_string (asm_out_file, main_input_filename);
26272 fputc ('\n', asm_out_file);
26273 if (write_symbols != NO_DEBUG)
26274 switch_to_section (private_data_section);
26275 switch_to_section (text_section);
26277 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26278 rs6000_file_start ();
26281 /* Output at end of assembler file.
26282 On the RS/6000, referencing data should automatically pull in text. */
26285 rs6000_xcoff_file_end (void)
26287 switch_to_section (text_section);
26288 fputs ("_section_.text:\n", asm_out_file);
26289 switch_to_section (data_section);
26290 fputs (TARGET_32BIT
26291 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26294 #endif /* TARGET_XCOFF */
26296 /* Compute a (partial) cost for rtx X. Return true if the complete
26297 cost has been computed, and false if subexpressions should be
26298 scanned. In either case, *TOTAL contains the cost result. */
26301 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26304 enum machine_mode mode = GET_MODE (x);
26308 /* On the RS/6000, if it is valid in the insn, it is free. */
26310 if (((outer_code == SET
26311 || outer_code == PLUS
26312 || outer_code == MINUS)
26313 && (satisfies_constraint_I (x)
26314 || satisfies_constraint_L (x)))
26315 || (outer_code == AND
26316 && (satisfies_constraint_K (x)
26318 ? satisfies_constraint_L (x)
26319 : satisfies_constraint_J (x))
26320 || mask_operand (x, mode)
26322 && mask64_operand (x, DImode))))
26323 || ((outer_code == IOR || outer_code == XOR)
26324 && (satisfies_constraint_K (x)
26326 ? satisfies_constraint_L (x)
26327 : satisfies_constraint_J (x))))
26328 || outer_code == ASHIFT
26329 || outer_code == ASHIFTRT
26330 || outer_code == LSHIFTRT
26331 || outer_code == ROTATE
26332 || outer_code == ROTATERT
26333 || outer_code == ZERO_EXTRACT
26334 || (outer_code == MULT
26335 && satisfies_constraint_I (x))
26336 || ((outer_code == DIV || outer_code == UDIV
26337 || outer_code == MOD || outer_code == UMOD)
26338 && exact_log2 (INTVAL (x)) >= 0)
26339 || (outer_code == COMPARE
26340 && (satisfies_constraint_I (x)
26341 || satisfies_constraint_K (x)))
26342 || ((outer_code == EQ || outer_code == NE)
26343 && (satisfies_constraint_I (x)
26344 || satisfies_constraint_K (x)
26346 ? satisfies_constraint_L (x)
26347 : satisfies_constraint_J (x))))
26348 || (outer_code == GTU
26349 && satisfies_constraint_I (x))
26350 || (outer_code == LTU
26351 && satisfies_constraint_P (x)))
26356 else if ((outer_code == PLUS
26357 && reg_or_add_cint_operand (x, VOIDmode))
26358 || (outer_code == MINUS
26359 && reg_or_sub_cint_operand (x, VOIDmode))
26360 || ((outer_code == SET
26361 || outer_code == IOR
26362 || outer_code == XOR)
26364 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26366 *total = COSTS_N_INSNS (1);
26372 if (mode == DImode && code == CONST_DOUBLE)
26374 if ((outer_code == IOR || outer_code == XOR)
26375 && CONST_DOUBLE_HIGH (x) == 0
26376 && (CONST_DOUBLE_LOW (x)
26377 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26382 else if ((outer_code == AND && and64_2_operand (x, DImode))
26383 || ((outer_code == SET
26384 || outer_code == IOR
26385 || outer_code == XOR)
26386 && CONST_DOUBLE_HIGH (x) == 0))
26388 *total = COSTS_N_INSNS (1);
26398 /* When optimizing for size, MEM should be slightly more expensive
26399 than generating address, e.g., (plus (reg) (const)).
26400 L1 cache latency is about two instructions. */
26401 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26410 if (FLOAT_MODE_P (mode))
26411 *total = rs6000_cost->fp;
26413 *total = COSTS_N_INSNS (1);
26417 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26418 && satisfies_constraint_I (XEXP (x, 1)))
26420 if (INTVAL (XEXP (x, 1)) >= -256
26421 && INTVAL (XEXP (x, 1)) <= 255)
26422 *total = rs6000_cost->mulsi_const9;
26424 *total = rs6000_cost->mulsi_const;
26426 else if (mode == SFmode)
26427 *total = rs6000_cost->fp;
26428 else if (FLOAT_MODE_P (mode))
26429 *total = rs6000_cost->dmul;
26430 else if (mode == DImode)
26431 *total = rs6000_cost->muldi;
26433 *total = rs6000_cost->mulsi;
26437 if (mode == SFmode)
26438 *total = rs6000_cost->fp;
26440 *total = rs6000_cost->dmul;
26445 if (FLOAT_MODE_P (mode))
26447 *total = mode == DFmode ? rs6000_cost->ddiv
26448 : rs6000_cost->sdiv;
26455 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26456 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26458 if (code == DIV || code == MOD)
26460 *total = COSTS_N_INSNS (2);
26463 *total = COSTS_N_INSNS (1);
26467 if (GET_MODE (XEXP (x, 1)) == DImode)
26468 *total = rs6000_cost->divdi;
26470 *total = rs6000_cost->divsi;
26472 /* Add in shift and subtract for MOD. */
26473 if (code == MOD || code == UMOD)
26474 *total += COSTS_N_INSNS (2);
26479 *total = COSTS_N_INSNS (4);
26483 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26487 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26491 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26503 *total = COSTS_N_INSNS (1);
26511 /* Handle mul_highpart. */
26512 if (outer_code == TRUNCATE
26513 && GET_CODE (XEXP (x, 0)) == MULT)
26515 if (mode == DImode)
26516 *total = rs6000_cost->muldi;
26518 *total = rs6000_cost->mulsi;
26521 else if (outer_code == AND)
26524 *total = COSTS_N_INSNS (1);
26529 if (GET_CODE (XEXP (x, 0)) == MEM)
26532 *total = COSTS_N_INSNS (1);
26538 if (!FLOAT_MODE_P (mode))
26540 *total = COSTS_N_INSNS (1);
26546 case UNSIGNED_FLOAT:
26549 case FLOAT_TRUNCATE:
26550 *total = rs6000_cost->fp;
26554 if (mode == DFmode)
26557 *total = rs6000_cost->fp;
26561 switch (XINT (x, 1))
26564 *total = rs6000_cost->fp;
26576 *total = COSTS_N_INSNS (1);
26579 else if (FLOAT_MODE_P (mode)
26580 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26582 *total = rs6000_cost->fp;
26590 /* Carry bit requires mode == Pmode.
26591 NEG or PLUS already counted so only add one. */
26593 && (outer_code == NEG || outer_code == PLUS))
26595 *total = COSTS_N_INSNS (1);
26598 if (outer_code == SET)
26600 if (XEXP (x, 1) == const0_rtx)
26602 if (TARGET_ISEL && !TARGET_MFCRF)
26603 *total = COSTS_N_INSNS (8);
26605 *total = COSTS_N_INSNS (2);
26608 else if (mode == Pmode)
26610 *total = COSTS_N_INSNS (3);
26619 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26621 if (TARGET_ISEL && !TARGET_MFCRF)
26622 *total = COSTS_N_INSNS (8);
26624 *total = COSTS_N_INSNS (2);
26628 if (outer_code == COMPARE)
26642 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26645 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26648 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26651 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26652 "total = %d, speed = %s, x:\n",
26653 ret ? "complete" : "scan inner",
26654 GET_RTX_NAME (code),
26655 GET_RTX_NAME (outer_code),
26657 speed ? "true" : "false");
26664 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26667 rs6000_debug_address_cost (rtx x, bool speed)
26669 int ret = TARGET_ADDRESS_COST (x, speed);
26671 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26672 ret, speed ? "true" : "false");
26679 /* A C expression returning the cost of moving data from a register of class
26680 CLASS1 to one of CLASS2. */
26683 rs6000_register_move_cost (enum machine_mode mode,
26684 reg_class_t from, reg_class_t to)
26688 /* Moves from/to GENERAL_REGS. */
26689 if (reg_classes_intersect_p (to, GENERAL_REGS)
26690 || reg_classes_intersect_p (from, GENERAL_REGS))
26692 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26695 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26696 ret = (rs6000_memory_move_cost (mode, from, false)
26697 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26699 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26701 else if (from == CR_REGS)
26704 /* Power6 has slower LR/CTR moves so make them more expensive than
26705 memory in order to bias spills to memory .*/
26706 else if (rs6000_cpu == PROCESSOR_POWER6
26707 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26708 ret = 6 * hard_regno_nregs[0][mode];
26711 /* A move will cost one instruction per GPR moved. */
26712 ret = 2 * hard_regno_nregs[0][mode];
26715 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26716 else if (VECTOR_UNIT_VSX_P (mode)
26717 && reg_classes_intersect_p (to, VSX_REGS)
26718 && reg_classes_intersect_p (from, VSX_REGS))
26719 ret = 2 * hard_regno_nregs[32][mode];
26721 /* Moving between two similar registers is just one instruction. */
26722 else if (reg_classes_intersect_p (to, from))
26723 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26725 /* Everything else has to go through GENERAL_REGS. */
26727 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26728 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26730 if (TARGET_DEBUG_COST)
26732 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26733 ret, GET_MODE_NAME (mode), reg_class_names[from],
26734 reg_class_names[to]);
26739 /* A C expressions returning the cost of moving data of MODE from a register to
26743 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26744 bool in ATTRIBUTE_UNUSED)
26748 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26749 ret = 4 * hard_regno_nregs[0][mode];
26750 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26751 ret = 4 * hard_regno_nregs[32][mode];
26752 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26753 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26755 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26757 if (TARGET_DEBUG_COST)
26759 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26760 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26765 /* Returns a code for a target-specific builtin that implements
26766 reciprocal of the function, or NULL_TREE if not available. */
26769 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26770 bool sqrt ATTRIBUTE_UNUSED)
26772 if (optimize_insn_for_size_p ())
26778 case VSX_BUILTIN_XVSQRTDP:
26779 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26782 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26784 case VSX_BUILTIN_XVSQRTSP:
26785 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26788 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26797 case BUILT_IN_SQRT:
26798 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26801 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26803 case BUILT_IN_SQRTF:
26804 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26807 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26814 /* Load up a constant. If the mode is a vector mode, splat the value across
26815 all of the vector elements. */
26818 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26822 if (mode == SFmode || mode == DFmode)
26824 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26825 reg = force_reg (mode, d);
26827 else if (mode == V4SFmode)
26829 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26830 rtvec v = gen_rtvec (4, d, d, d, d);
26831 reg = gen_reg_rtx (mode);
26832 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26834 else if (mode == V2DFmode)
26836 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26837 rtvec v = gen_rtvec (2, d, d);
26838 reg = gen_reg_rtx (mode);
26839 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26842 gcc_unreachable ();
26847 /* Generate an FMA instruction. */
26850 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26852 enum machine_mode mode = GET_MODE (target);
26855 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26856 gcc_assert (dst != NULL);
26859 emit_move_insn (target, dst);
26862 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26865 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26867 enum machine_mode mode = GET_MODE (target);
26870 /* Altivec does not support fms directly;
26871 generate in terms of fma in that case. */
26872 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26873 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26876 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26877 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26879 gcc_assert (dst != NULL);
26882 emit_move_insn (target, dst);
26885 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26888 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26890 enum machine_mode mode = GET_MODE (dst);
26893 /* This is a tad more complicated, since the fnma_optab is for
26894 a different expression: fma(-m1, m2, a), which is the same
26895 thing except in the case of signed zeros.
26897 Fortunately we know that if FMA is supported that FNMSUB is
26898 also supported in the ISA. Just expand it directly. */
26900 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26902 r = gen_rtx_NEG (mode, a);
26903 r = gen_rtx_FMA (mode, m1, m2, r);
26904 r = gen_rtx_NEG (mode, r);
26905 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26908 /* Newton-Raphson approximation of floating point divide with just 2 passes
26909 (either single precision floating point, or newer machines with higher
26910 accuracy estimates). Support both scalar and vector divide. Assumes no
26911 trapping math and finite arguments. */
26914 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26916 enum machine_mode mode = GET_MODE (dst);
26917 rtx x0, e0, e1, y1, u0, v0;
26918 enum insn_code code = optab_handler (smul_optab, mode);
26919 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26920 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26922 gcc_assert (code != CODE_FOR_nothing);
26924 /* x0 = 1./d estimate */
26925 x0 = gen_reg_rtx (mode);
26926 emit_insn (gen_rtx_SET (VOIDmode, x0,
26927 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26930 e0 = gen_reg_rtx (mode);
26931 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26933 e1 = gen_reg_rtx (mode);
26934 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26936 y1 = gen_reg_rtx (mode);
26937 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26939 u0 = gen_reg_rtx (mode);
26940 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26942 v0 = gen_reg_rtx (mode);
26943 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26945 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26948 /* Newton-Raphson approximation of floating point divide that has a low
26949 precision estimate. Assumes no trapping math and finite arguments. */
26952 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26954 enum machine_mode mode = GET_MODE (dst);
26955 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26956 enum insn_code code = optab_handler (smul_optab, mode);
26957 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26959 gcc_assert (code != CODE_FOR_nothing);
26961 one = rs6000_load_constant_and_splat (mode, dconst1);
26963 /* x0 = 1./d estimate */
26964 x0 = gen_reg_rtx (mode);
26965 emit_insn (gen_rtx_SET (VOIDmode, x0,
26966 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26969 e0 = gen_reg_rtx (mode);
26970 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26972 y1 = gen_reg_rtx (mode);
26973 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26975 e1 = gen_reg_rtx (mode);
26976 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26978 y2 = gen_reg_rtx (mode);
26979 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26981 e2 = gen_reg_rtx (mode);
26982 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26984 y3 = gen_reg_rtx (mode);
26985 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26987 u0 = gen_reg_rtx (mode);
26988 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26990 v0 = gen_reg_rtx (mode);
26991 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
26993 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
26996 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
26997 add a reg_note saying that this was a division. Support both scalar and
26998 vector divide. Assumes no trapping math and finite arguments. */
27001 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
27003 enum machine_mode mode = GET_MODE (dst);
27005 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
27006 rs6000_emit_swdiv_high_precision (dst, n, d);
27008 rs6000_emit_swdiv_low_precision (dst, n, d);
27011 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
27014 /* Newton-Raphson approximation of single/double-precision floating point
27015 rsqrt. Assumes no trapping math and finite arguments. */
27018 rs6000_emit_swrsqrt (rtx dst, rtx src)
27020 enum machine_mode mode = GET_MODE (src);
27021 rtx x0 = gen_reg_rtx (mode);
27022 rtx y = gen_reg_rtx (mode);
27023 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27024 REAL_VALUE_TYPE dconst3_2;
27027 enum insn_code code = optab_handler (smul_optab, mode);
27028 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27030 gcc_assert (code != CODE_FOR_nothing);
27032 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27033 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27034 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27036 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27038 /* x0 = rsqrt estimate */
27039 emit_insn (gen_rtx_SET (VOIDmode, x0,
27040 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27043 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27044 rs6000_emit_msub (y, src, halfthree, src);
27046 for (i = 0; i < passes; i++)
27048 rtx x1 = gen_reg_rtx (mode);
27049 rtx u = gen_reg_rtx (mode);
27050 rtx v = gen_reg_rtx (mode);
27052 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27053 emit_insn (gen_mul (u, x0, x0));
27054 rs6000_emit_nmsub (v, y, u, halfthree);
27055 emit_insn (gen_mul (x1, x0, v));
27059 emit_move_insn (dst, x0);
27063 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27064 (Power7) targets. DST is the target, and SRC is the argument operand. */
27067 rs6000_emit_popcount (rtx dst, rtx src)
27069 enum machine_mode mode = GET_MODE (dst);
27072 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27073 if (TARGET_POPCNTD)
27075 if (mode == SImode)
27076 emit_insn (gen_popcntdsi2 (dst, src));
27078 emit_insn (gen_popcntddi2 (dst, src));
27082 tmp1 = gen_reg_rtx (mode);
27084 if (mode == SImode)
27086 emit_insn (gen_popcntbsi2 (tmp1, src));
27087 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27089 tmp2 = force_reg (SImode, tmp2);
27090 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27094 emit_insn (gen_popcntbdi2 (tmp1, src));
27095 tmp2 = expand_mult (DImode, tmp1,
27096 GEN_INT ((HOST_WIDE_INT)
27097 0x01010101 << 32 | 0x01010101),
27099 tmp2 = force_reg (DImode, tmp2);
27100 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27105 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27106 target, and SRC is the argument operand. */
27109 rs6000_emit_parity (rtx dst, rtx src)
27111 enum machine_mode mode = GET_MODE (dst);
27114 tmp = gen_reg_rtx (mode);
27116 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27119 if (mode == SImode)
27121 emit_insn (gen_popcntbsi2 (tmp, src));
27122 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27126 emit_insn (gen_popcntbdi2 (tmp, src));
27127 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27132 if (mode == SImode)
27134 /* Is mult+shift >= shift+xor+shift+xor? */
27135 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27137 rtx tmp1, tmp2, tmp3, tmp4;
27139 tmp1 = gen_reg_rtx (SImode);
27140 emit_insn (gen_popcntbsi2 (tmp1, src));
27142 tmp2 = gen_reg_rtx (SImode);
27143 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27144 tmp3 = gen_reg_rtx (SImode);
27145 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27147 tmp4 = gen_reg_rtx (SImode);
27148 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27149 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27152 rs6000_emit_popcount (tmp, src);
27153 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27157 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27158 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27160 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27162 tmp1 = gen_reg_rtx (DImode);
27163 emit_insn (gen_popcntbdi2 (tmp1, src));
27165 tmp2 = gen_reg_rtx (DImode);
27166 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27167 tmp3 = gen_reg_rtx (DImode);
27168 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27170 tmp4 = gen_reg_rtx (DImode);
27171 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27172 tmp5 = gen_reg_rtx (DImode);
27173 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27175 tmp6 = gen_reg_rtx (DImode);
27176 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27177 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27180 rs6000_emit_popcount (tmp, src);
27181 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27185 /* Return an RTX representing where to find the function value of a
27186 function returning MODE. */
27188 rs6000_complex_function_value (enum machine_mode mode)
27190 unsigned int regno;
27192 enum machine_mode inner = GET_MODE_INNER (mode);
27193 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27195 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27196 regno = FP_ARG_RETURN;
27199 regno = GP_ARG_RETURN;
27201 /* 32-bit is OK since it'll go in r3/r4. */
27202 if (TARGET_32BIT && inner_bytes >= 4)
27203 return gen_rtx_REG (mode, regno);
27206 if (inner_bytes >= 8)
27207 return gen_rtx_REG (mode, regno);
27209 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27211 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27212 GEN_INT (inner_bytes));
27213 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27216 /* Target hook for TARGET_FUNCTION_VALUE.
27218 On the SPE, both FPs and vectors are returned in r3.
27220 On RS/6000 an integer value is in r3 and a floating-point value is in
27221 fp1, unless -msoft-float. */
27224 rs6000_function_value (const_tree valtype,
27225 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27226 bool outgoing ATTRIBUTE_UNUSED)
27228 enum machine_mode mode;
27229 unsigned int regno;
27231 /* Special handling for structs in darwin64. */
27233 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27235 CUMULATIVE_ARGS valcum;
27239 valcum.fregno = FP_ARG_MIN_REG;
27240 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27241 /* Do a trial code generation as if this were going to be passed as
27242 an argument; if any part goes in memory, we return NULL. */
27243 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27246 /* Otherwise fall through to standard ABI rules. */
27249 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27251 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27252 return gen_rtx_PARALLEL (DImode,
27254 gen_rtx_EXPR_LIST (VOIDmode,
27255 gen_rtx_REG (SImode, GP_ARG_RETURN),
27257 gen_rtx_EXPR_LIST (VOIDmode,
27258 gen_rtx_REG (SImode,
27259 GP_ARG_RETURN + 1),
27262 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27264 return gen_rtx_PARALLEL (DCmode,
27266 gen_rtx_EXPR_LIST (VOIDmode,
27267 gen_rtx_REG (SImode, GP_ARG_RETURN),
27269 gen_rtx_EXPR_LIST (VOIDmode,
27270 gen_rtx_REG (SImode,
27271 GP_ARG_RETURN + 1),
27273 gen_rtx_EXPR_LIST (VOIDmode,
27274 gen_rtx_REG (SImode,
27275 GP_ARG_RETURN + 2),
27277 gen_rtx_EXPR_LIST (VOIDmode,
27278 gen_rtx_REG (SImode,
27279 GP_ARG_RETURN + 3),
27283 mode = TYPE_MODE (valtype);
27284 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27285 || POINTER_TYPE_P (valtype))
27286 mode = TARGET_32BIT ? SImode : DImode;
27288 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27289 /* _Decimal128 must use an even/odd register pair. */
27290 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27291 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27292 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27293 regno = FP_ARG_RETURN;
27294 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27295 && targetm.calls.split_complex_arg)
27296 return rs6000_complex_function_value (mode);
27297 else if (TREE_CODE (valtype) == VECTOR_TYPE
27298 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27299 && ALTIVEC_VECTOR_MODE (mode))
27300 regno = ALTIVEC_ARG_RETURN;
27301 else if (TREE_CODE (valtype) == VECTOR_TYPE
27302 && TARGET_VSX && TARGET_ALTIVEC_ABI
27303 && VSX_VECTOR_MODE (mode))
27304 regno = ALTIVEC_ARG_RETURN;
27305 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27306 && (mode == DFmode || mode == DCmode
27307 || mode == TFmode || mode == TCmode))
27308 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27310 regno = GP_ARG_RETURN;
27312 return gen_rtx_REG (mode, regno);
27315 /* Define how to find the value returned by a library function
27316 assuming the value has mode MODE. */
27318 rs6000_libcall_value (enum machine_mode mode)
27320 unsigned int regno;
27322 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27324 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27325 return gen_rtx_PARALLEL (DImode,
27327 gen_rtx_EXPR_LIST (VOIDmode,
27328 gen_rtx_REG (SImode, GP_ARG_RETURN),
27330 gen_rtx_EXPR_LIST (VOIDmode,
27331 gen_rtx_REG (SImode,
27332 GP_ARG_RETURN + 1),
27336 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27337 /* _Decimal128 must use an even/odd register pair. */
27338 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27339 else if (SCALAR_FLOAT_MODE_P (mode)
27340 && TARGET_HARD_FLOAT && TARGET_FPRS
27341 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27342 regno = FP_ARG_RETURN;
27343 else if (ALTIVEC_VECTOR_MODE (mode)
27344 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27345 regno = ALTIVEC_ARG_RETURN;
27346 else if (VSX_VECTOR_MODE (mode)
27347 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27348 regno = ALTIVEC_ARG_RETURN;
27349 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27350 return rs6000_complex_function_value (mode);
27351 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27352 && (mode == DFmode || mode == DCmode
27353 || mode == TFmode || mode == TCmode))
27354 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27356 regno = GP_ARG_RETURN;
27358 return gen_rtx_REG (mode, regno);
27362 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27363 Frame pointer elimination is automatically handled.
27365 For the RS/6000, if frame pointer elimination is being done, we would like
27366 to convert ap into fp, not sp.
27368 We need r30 if -mminimal-toc was specified, and there are constant pool
27372 rs6000_can_eliminate (const int from, const int to)
27374 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27375 ? ! frame_pointer_needed
27376 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27377 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27381 /* Define the offset between two registers, FROM to be eliminated and its
27382 replacement TO, at the start of a routine. */
27384 rs6000_initial_elimination_offset (int from, int to)
27386 rs6000_stack_t *info = rs6000_stack_info ();
27387 HOST_WIDE_INT offset;
27389 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27390 offset = info->push_p ? 0 : -info->total_size;
27391 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27393 offset = info->push_p ? 0 : -info->total_size;
27394 if (FRAME_GROWS_DOWNWARD)
27395 offset += info->fixed_size + info->vars_size + info->parm_size;
27397 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27398 offset = FRAME_GROWS_DOWNWARD
27399 ? info->fixed_size + info->vars_size + info->parm_size
27401 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27402 offset = info->total_size;
27403 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27404 offset = info->push_p ? info->total_size : 0;
27405 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27408 gcc_unreachable ();
27414 rs6000_dwarf_register_span (rtx reg)
27418 unsigned regno = REGNO (reg);
27419 enum machine_mode mode = GET_MODE (reg);
27423 && (SPE_VECTOR_MODE (GET_MODE (reg))
27424 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27425 && mode != SFmode && mode != SDmode && mode != SCmode)))
27430 regno = REGNO (reg);
27432 /* The duality of the SPE register size wreaks all kinds of havoc.
27433 This is a way of distinguishing r0 in 32-bits from r0 in
27435 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27436 gcc_assert (words <= 4);
27437 for (i = 0; i < words; i++, regno++)
27439 if (BYTES_BIG_ENDIAN)
27441 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27442 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27446 parts[2 * i] = gen_rtx_REG (SImode, regno);
27447 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27451 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27454 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27457 rs6000_init_dwarf_reg_sizes_extra (tree address)
27462 enum machine_mode mode = TYPE_MODE (char_type_node);
27463 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27464 rtx mem = gen_rtx_MEM (BLKmode, addr);
27465 rtx value = gen_int_mode (4, mode);
27467 for (i = 1201; i < 1232; i++)
27469 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27470 HOST_WIDE_INT offset
27471 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27473 emit_move_insn (adjust_address (mem, mode, offset), value);
27478 /* Map internal gcc register numbers to DWARF2 register numbers. */
27481 rs6000_dbx_register_number (unsigned int regno)
27483 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27485 if (regno == MQ_REGNO)
27487 if (regno == LR_REGNO)
27489 if (regno == CTR_REGNO)
27491 if (CR_REGNO_P (regno))
27492 return regno - CR0_REGNO + 86;
27493 if (regno == CA_REGNO)
27494 return 101; /* XER */
27495 if (ALTIVEC_REGNO_P (regno))
27496 return regno - FIRST_ALTIVEC_REGNO + 1124;
27497 if (regno == VRSAVE_REGNO)
27499 if (regno == VSCR_REGNO)
27501 if (regno == SPE_ACC_REGNO)
27503 if (regno == SPEFSCR_REGNO)
27505 /* SPE high reg number. We get these values of regno from
27506 rs6000_dwarf_register_span. */
27507 gcc_assert (regno >= 1200 && regno < 1232);
27511 /* target hook eh_return_filter_mode */
27512 static enum machine_mode
27513 rs6000_eh_return_filter_mode (void)
27515 return TARGET_32BIT ? SImode : word_mode;
27518 /* Target hook for scalar_mode_supported_p. */
27520 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27522 if (DECIMAL_FLOAT_MODE_P (mode))
27523 return default_decimal_float_supported_p ();
27525 return default_scalar_mode_supported_p (mode);
27528 /* Target hook for vector_mode_supported_p. */
27530 rs6000_vector_mode_supported_p (enum machine_mode mode)
27533 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27536 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27539 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27546 /* Target hook for invalid_arg_for_unprototyped_fn. */
27547 static const char *
27548 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27550 return (!rs6000_darwin64_abi
27552 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27553 && (funcdecl == NULL_TREE
27554 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27555 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27556 ? N_("AltiVec argument passed to unprototyped function")
27560 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27561 setup by using __stack_chk_fail_local hidden function instead of
27562 calling __stack_chk_fail directly. Otherwise it is better to call
27563 __stack_chk_fail directly. */
27566 rs6000_stack_protect_fail (void)
27568 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27569 ? default_hidden_stack_protect_fail ()
27570 : default_external_stack_protect_fail ();
27574 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27575 int num_operands ATTRIBUTE_UNUSED)
27577 if (rs6000_warn_cell_microcode)
27580 int insn_code_number = recog_memoized (insn);
27581 location_t location = locator_location (INSN_LOCATOR (insn));
27583 /* Punt on insns we cannot recognize. */
27584 if (insn_code_number < 0)
27587 temp = get_insn_template (insn_code_number, insn);
27589 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27590 warning_at (location, OPT_mwarn_cell_microcode,
27591 "emitting microcode insn %s\t[%s] #%d",
27592 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27593 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27594 warning_at (location, OPT_mwarn_cell_microcode,
27595 "emitting conditional microcode insn %s\t[%s] #%d",
27596 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27601 /* Mask options that we want to support inside of attribute((target)) and
27602 #pragma GCC target operations. Note, we do not include things like
27603 64/32-bit, endianess, hard/soft floating point, etc. that would have
27604 different calling sequences. */
27606 struct rs6000_opt_mask {
27607 const char *name; /* option name */
27608 int mask; /* mask to set */
27609 bool invert; /* invert sense of mask */
27610 bool valid_target; /* option is a target option */
27613 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27615 { "altivec", MASK_ALTIVEC, false, true },
27616 { "cmpb", MASK_CMPB, false, true },
27617 { "dlmzb", MASK_DLMZB, false, true },
27618 { "fprnd", MASK_FPRND, false, true },
27619 { "hard-dfp", MASK_DFP, false, true },
27620 { "isel", MASK_ISEL, false, true },
27621 { "mfcrf", MASK_MFCRF, false, true },
27622 { "mfpgpr", MASK_MFPGPR, false, true },
27623 { "mulhw", MASK_MULHW, false, true },
27624 { "multiple", MASK_MULTIPLE, false, true },
27625 { "update", MASK_NO_UPDATE, true , true },
27626 { "popcntb", MASK_POPCNTB, false, true },
27627 { "popcntd", MASK_POPCNTD, false, true },
27628 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27629 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27630 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27631 { "string", MASK_STRING, false, true },
27632 { "vsx", MASK_VSX, false, true },
27635 { "aix64", MASK_64BIT, false, false },
27636 { "aix32", MASK_64BIT, true, false },
27638 { "64", MASK_64BIT, false, false },
27639 { "32", MASK_64BIT, true, false },
27643 { "eabi", MASK_EABI, false, false },
27645 #ifdef MASK_LITTLE_ENDIAN
27646 { "little", MASK_LITTLE_ENDIAN, false, false },
27647 { "big", MASK_LITTLE_ENDIAN, true, false },
27649 #ifdef MASK_RELOCATABLE
27650 { "relocatable", MASK_RELOCATABLE, false, false },
27652 #ifdef MASK_STRICT_ALIGN
27653 { "strict-align", MASK_STRICT_ALIGN, false, false },
27655 { "power", MASK_POWER, false, false },
27656 { "power2", MASK_POWER2, false, false },
27657 { "powerpc", MASK_POWERPC, false, false },
27658 { "soft-float", MASK_SOFT_FLOAT, false, false },
27659 { "string", MASK_STRING, false, false },
27662 /* Option variables that we want to support inside attribute((target)) and
27663 #pragma GCC target operations. */
27665 struct rs6000_opt_var {
27666 const char *name; /* option name */
27667 size_t global_offset; /* offset of the option in global_options. */
27668 size_t target_offset; /* offset of the option in target optiosn. */
27671 static struct rs6000_opt_var const rs6000_opt_vars[] =
27674 offsetof (struct gcc_options, x_TARGET_FRIZ),
27675 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27676 { "avoid-indexed-addresses",
27677 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27678 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27680 offsetof (struct gcc_options, x_rs6000_paired_float),
27681 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27683 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27684 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27687 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27688 parsing. Return true if there were no errors. */
27691 rs6000_inner_target_options (tree args, bool attr_p)
27695 if (args == NULL_TREE)
27698 else if (TREE_CODE (args) == STRING_CST)
27700 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27703 while ((q = strtok (p, ",")) != NULL)
27705 bool error_p = false;
27706 bool not_valid_p = false;
27707 const char *cpu_opt = NULL;
27710 if (strncmp (q, "cpu=", 4) == 0)
27712 int cpu_index = rs6000_cpu_name_lookup (q+4);
27713 if (cpu_index >= 0)
27714 rs6000_cpu_index = cpu_index;
27721 else if (strncmp (q, "tune=", 5) == 0)
27723 int tune_index = rs6000_cpu_name_lookup (q+5);
27724 if (tune_index >= 0)
27725 rs6000_tune_index = tune_index;
27735 bool invert = false;
27739 if (strncmp (r, "no-", 3) == 0)
27745 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27746 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27748 int mask = rs6000_opt_masks[i].mask;
27750 if (!rs6000_opt_masks[i].valid_target)
27751 not_valid_p = true;
27755 target_flags_explicit |= mask;
27757 if (rs6000_opt_masks[i].invert)
27761 target_flags &= ~mask;
27763 target_flags |= mask;
27768 if (error_p && !not_valid_p)
27770 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27771 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27773 size_t j = rs6000_opt_vars[i].global_offset;
27774 ((int *) &global_options)[j] = !invert;
27783 const char *eprefix, *esuffix;
27788 eprefix = "__attribute__((__target__(";
27793 eprefix = "#pragma GCC target ";
27798 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27800 else if (not_valid_p)
27801 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27803 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27808 else if (TREE_CODE (args) == TREE_LIST)
27812 tree value = TREE_VALUE (args);
27815 bool ret2 = rs6000_inner_target_options (value, attr_p);
27819 args = TREE_CHAIN (args);
27821 while (args != NULL_TREE);
27825 gcc_unreachable ();
27830 /* Print out the target options as a list for -mdebug=target. */
27833 rs6000_debug_target_options (tree args, const char *prefix)
27835 if (args == NULL_TREE)
27836 fprintf (stderr, "%s<NULL>", prefix);
27838 else if (TREE_CODE (args) == STRING_CST)
27840 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27843 while ((q = strtok (p, ",")) != NULL)
27846 fprintf (stderr, "%s\"%s\"", prefix, q);
27851 else if (TREE_CODE (args) == TREE_LIST)
27855 tree value = TREE_VALUE (args);
27858 rs6000_debug_target_options (value, prefix);
27861 args = TREE_CHAIN (args);
27863 while (args != NULL_TREE);
27867 gcc_unreachable ();
27873 /* Hook to validate attribute((target("..."))). */
27876 rs6000_valid_attribute_p (tree fndecl,
27877 tree ARG_UNUSED (name),
27881 struct cl_target_option cur_target;
27883 tree old_optimize = build_optimization_node ();
27884 tree new_target, new_optimize;
27885 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27887 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27889 if (TARGET_DEBUG_TARGET)
27891 tree tname = DECL_NAME (fndecl);
27892 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27894 fprintf (stderr, "function: %.*s\n",
27895 (int) IDENTIFIER_LENGTH (tname),
27896 IDENTIFIER_POINTER (tname));
27898 fprintf (stderr, "function: unknown\n");
27900 fprintf (stderr, "args:");
27901 rs6000_debug_target_options (args, " ");
27902 fprintf (stderr, "\n");
27905 fprintf (stderr, "flags: 0x%x\n", flags);
27907 fprintf (stderr, "--------------------\n");
27910 old_optimize = build_optimization_node ();
27911 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27913 /* If the function changed the optimization levels as well as setting target
27914 options, start with the optimizations specified. */
27915 if (func_optimize && func_optimize != old_optimize)
27916 cl_optimization_restore (&global_options,
27917 TREE_OPTIMIZATION (func_optimize));
27919 /* The target attributes may also change some optimization flags, so update
27920 the optimization options if necessary. */
27921 cl_target_option_save (&cur_target, &global_options);
27922 rs6000_cpu_index = rs6000_tune_index = -1;
27923 ret = rs6000_inner_target_options (args, true);
27925 /* Set up any additional state. */
27928 ret = rs6000_option_override_internal (false);
27929 new_target = build_target_option_node ();
27934 new_optimize = build_optimization_node ();
27941 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27943 if (old_optimize != new_optimize)
27944 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27947 cl_target_option_restore (&global_options, &cur_target);
27949 if (old_optimize != new_optimize)
27950 cl_optimization_restore (&global_options,
27951 TREE_OPTIMIZATION (old_optimize));
27957 /* Hook to validate the current #pragma GCC target and set the state, and
27958 update the macros based on what was changed. If ARGS is NULL, then
27959 POP_TARGET is used to reset the options. */
27962 rs6000_pragma_target_parse (tree args, tree pop_target)
27967 if (TARGET_DEBUG_TARGET)
27969 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27970 fprintf (stderr, "args:");
27971 rs6000_debug_target_options (args, " ");
27972 fprintf (stderr, "\n");
27976 fprintf (stderr, "pop_target:\n");
27977 debug_tree (pop_target);
27980 fprintf (stderr, "pop_target: <NULL>\n");
27982 fprintf (stderr, "--------------------\n");
27988 cur_tree = ((pop_target)
27990 : target_option_default_node);
27991 cl_target_option_restore (&global_options,
27992 TREE_TARGET_OPTION (cur_tree));
27996 rs6000_cpu_index = rs6000_tune_index = -1;
27997 ret = rs6000_inner_target_options (args, false);
27998 cur_tree = build_target_option_node ();
28005 target_option_current_node = cur_tree;
28011 /* Remember the last target of rs6000_set_current_function. */
28012 static GTY(()) tree rs6000_previous_fndecl;
28014 /* Establish appropriate back-end context for processing the function
28015 FNDECL. The argument might be NULL to indicate processing at top
28016 level, outside of any function scope. */
28018 rs6000_set_current_function (tree fndecl)
28020 tree old_tree = (rs6000_previous_fndecl
28021 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28024 tree new_tree = (fndecl
28025 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28028 if (TARGET_DEBUG_TARGET)
28030 bool print_final = false;
28031 fprintf (stderr, "\n==================== rs6000_set_current_function");
28034 fprintf (stderr, ", fndecl %s (%p)",
28035 (DECL_NAME (fndecl)
28036 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28037 : "<unknown>"), (void *)fndecl);
28039 if (rs6000_previous_fndecl)
28040 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28042 fprintf (stderr, "\n");
28045 fprintf (stderr, "\nnew fndecl target specific options:\n");
28046 debug_tree (new_tree);
28047 print_final = true;
28052 fprintf (stderr, "\nold fndecl target specific options:\n");
28053 debug_tree (old_tree);
28054 print_final = true;
28058 fprintf (stderr, "--------------------\n");
28061 /* Only change the context if the function changes. This hook is called
28062 several times in the course of compiling a function, and we don't want to
28063 slow things down too much or call target_reinit when it isn't safe. */
28064 if (fndecl && fndecl != rs6000_previous_fndecl)
28066 rs6000_previous_fndecl = fndecl;
28067 if (old_tree == new_tree)
28072 cl_target_option_restore (&global_options,
28073 TREE_TARGET_OPTION (new_tree));
28079 struct cl_target_option *def
28080 = TREE_TARGET_OPTION (target_option_current_node);
28082 cl_target_option_restore (&global_options, def);
28089 /* Save the current options */
28092 rs6000_function_specific_save (struct cl_target_option *ptr)
28094 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28097 /* Restore the current options */
28100 rs6000_function_specific_restore (struct cl_target_option *ptr)
28102 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28103 (void) rs6000_option_override_internal (false);
28106 /* Print the current options */
28109 rs6000_function_specific_print (FILE *file, int indent,
28110 struct cl_target_option *ptr)
28113 int flags = ptr->x_target_flags;
28115 /* Print the various mask options. */
28116 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28117 if ((flags & rs6000_opt_masks[i].mask) != 0)
28119 flags &= ~ rs6000_opt_masks[i].mask;
28120 fprintf (file, "%*s-m%s%s\n", indent, "",
28121 rs6000_opt_masks[i].invert ? "no-" : "",
28122 rs6000_opt_masks[i].name);
28125 /* Print the various options that are variables. */
28126 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28128 size_t j = rs6000_opt_vars[i].target_offset;
28129 if (((signed char *) ptr)[j])
28130 fprintf (file, "%*s-m%s\n", indent, "",
28131 rs6000_opt_vars[i].name);
28136 /* Hook to determine if one function can safely inline another. */
28139 rs6000_can_inline_p (tree caller, tree callee)
28142 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28143 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28145 /* If callee has no option attributes, then it is ok to inline. */
28149 /* If caller has no option attributes, but callee does then it is not ok to
28151 else if (!caller_tree)
28156 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28157 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28159 /* Callee's options should a subset of the caller's, i.e. a vsx function
28160 can inline an altivec function but a non-vsx function can't inline a
28162 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28163 == callee_opts->x_target_flags)
28167 if (TARGET_DEBUG_TARGET)
28168 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28169 (DECL_NAME (caller)
28170 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28172 (DECL_NAME (callee)
28173 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28175 (ret ? "can" : "cannot"));
28180 /* Allocate a stack temp and fixup the address so it meets the particular
28181 memory requirements (either offetable or REG+REG addressing). */
28184 rs6000_allocate_stack_temp (enum machine_mode mode,
28185 bool offsettable_p,
28188 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28189 rtx addr = XEXP (stack, 0);
28190 int strict_p = (reload_in_progress || reload_completed);
28192 if (!legitimate_indirect_address_p (addr, strict_p))
28195 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28196 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28198 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28199 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28205 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28206 to such a form to deal with memory reference instructions like STFIWX that
28207 only take reg+reg addressing. */
28210 rs6000_address_for_fpconvert (rtx x)
28212 int strict_p = (reload_in_progress || reload_completed);
28215 gcc_assert (MEM_P (x));
28216 addr = XEXP (x, 0);
28217 if (! legitimate_indirect_address_p (addr, strict_p)
28218 && ! legitimate_indexed_address_p (addr, strict_p))
28220 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28222 rtx reg = XEXP (addr, 0);
28223 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28224 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28225 gcc_assert (REG_P (reg));
28226 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28229 else if (GET_CODE (addr) == PRE_MODIFY)
28231 rtx reg = XEXP (addr, 0);
28232 rtx expr = XEXP (addr, 1);
28233 gcc_assert (REG_P (reg));
28234 gcc_assert (GET_CODE (expr) == PLUS);
28235 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28239 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28245 /* Given a memory reference, if it is not in the form for altivec memory
28246 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28247 convert to the altivec format. */
28250 rs6000_address_for_altivec (rtx x)
28252 gcc_assert (MEM_P (x));
28253 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28255 rtx addr = XEXP (x, 0);
28256 int strict_p = (reload_in_progress || reload_completed);
28258 if (!legitimate_indexed_address_p (addr, strict_p)
28259 && !legitimate_indirect_address_p (addr, strict_p))
28260 addr = copy_to_mode_reg (Pmode, addr);
28262 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28263 x = change_address (x, GET_MODE (x), addr);
28270 #include "gt-rs6000.h"