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);
1215 static bool rs6000_cannot_force_const_mem (enum machine_mode, rtx);
1217 /* Hash table stuff for keeping track of TOC entries. */
1219 struct GTY(()) toc_hash_struct
1221 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1222 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1224 enum machine_mode key_mode;
1228 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1230 /* Hash table to keep track of the argument types for builtin functions. */
1232 struct GTY(()) builtin_hash_struct
1235 enum machine_mode mode[4]; /* return value + 3 arguments. */
1236 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1239 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1241 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1242 static void rs6000_function_specific_save (struct cl_target_option *);
1243 static void rs6000_function_specific_restore (struct cl_target_option *);
1244 static void rs6000_function_specific_print (FILE *, int,
1245 struct cl_target_option *);
1246 static bool rs6000_can_inline_p (tree, tree);
1247 static void rs6000_set_current_function (tree);
1250 /* Default register names. */
1251 char rs6000_reg_names[][8] =
1253 "0", "1", "2", "3", "4", "5", "6", "7",
1254 "8", "9", "10", "11", "12", "13", "14", "15",
1255 "16", "17", "18", "19", "20", "21", "22", "23",
1256 "24", "25", "26", "27", "28", "29", "30", "31",
1257 "0", "1", "2", "3", "4", "5", "6", "7",
1258 "8", "9", "10", "11", "12", "13", "14", "15",
1259 "16", "17", "18", "19", "20", "21", "22", "23",
1260 "24", "25", "26", "27", "28", "29", "30", "31",
1261 "mq", "lr", "ctr","ap",
1262 "0", "1", "2", "3", "4", "5", "6", "7",
1264 /* AltiVec registers. */
1265 "0", "1", "2", "3", "4", "5", "6", "7",
1266 "8", "9", "10", "11", "12", "13", "14", "15",
1267 "16", "17", "18", "19", "20", "21", "22", "23",
1268 "24", "25", "26", "27", "28", "29", "30", "31",
1270 /* SPE registers. */
1271 "spe_acc", "spefscr",
1272 /* Soft frame pointer. */
1276 #ifdef TARGET_REGNAMES
1277 static const char alt_reg_names[][8] =
1279 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1280 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1281 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1282 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1283 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1284 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1285 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1286 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1287 "mq", "lr", "ctr", "ap",
1288 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1290 /* AltiVec registers. */
1291 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1292 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1293 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1294 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1296 /* SPE registers. */
1297 "spe_acc", "spefscr",
1298 /* Soft frame pointer. */
1303 /* Table of valid machine attributes. */
1305 static const struct attribute_spec rs6000_attribute_table[] =
1307 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1308 affects_type_identity } */
1309 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1311 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1313 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1315 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1317 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1319 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1320 SUBTARGET_ATTRIBUTE_TABLE,
1322 { NULL, 0, 0, false, false, false, NULL, false }
1325 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1326 static const struct default_options rs6000_option_optimization_table[] =
1328 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1329 { OPT_LEVELS_NONE, 0, NULL, 0 }
1332 #ifndef MASK_STRICT_ALIGN
1333 #define MASK_STRICT_ALIGN 0
1335 #ifndef TARGET_PROFILE_KERNEL
1336 #define TARGET_PROFILE_KERNEL 0
1339 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1340 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1342 /* Initialize the GCC target structure. */
1343 #undef TARGET_ATTRIBUTE_TABLE
1344 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1345 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1346 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1347 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1348 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1350 #undef TARGET_ASM_ALIGNED_DI_OP
1351 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1353 /* Default unaligned ops are only provided for ELF. Find the ops needed
1354 for non-ELF systems. */
1355 #ifndef OBJECT_FORMAT_ELF
1357 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1359 #undef TARGET_ASM_UNALIGNED_HI_OP
1360 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1361 #undef TARGET_ASM_UNALIGNED_SI_OP
1362 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1363 #undef TARGET_ASM_UNALIGNED_DI_OP
1364 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1367 #undef TARGET_ASM_UNALIGNED_HI_OP
1368 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1369 #undef TARGET_ASM_UNALIGNED_SI_OP
1370 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1371 #undef TARGET_ASM_UNALIGNED_DI_OP
1372 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1373 #undef TARGET_ASM_ALIGNED_DI_OP
1374 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1378 /* This hook deals with fixups for relocatable code and DI-mode objects
1380 #undef TARGET_ASM_INTEGER
1381 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1383 #ifdef HAVE_GAS_HIDDEN
1384 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1385 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1388 #undef TARGET_HAVE_TLS
1389 #define TARGET_HAVE_TLS HAVE_AS_TLS
1391 #undef TARGET_CANNOT_FORCE_CONST_MEM
1392 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1394 #undef TARGET_DELEGITIMIZE_ADDRESS
1395 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1397 #undef TARGET_ASM_FUNCTION_PROLOGUE
1398 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1399 #undef TARGET_ASM_FUNCTION_EPILOGUE
1400 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1402 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1403 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1405 #undef TARGET_LEGITIMIZE_ADDRESS
1406 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1408 #undef TARGET_SCHED_VARIABLE_ISSUE
1409 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1411 #undef TARGET_SCHED_ISSUE_RATE
1412 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1413 #undef TARGET_SCHED_ADJUST_COST
1414 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1415 #undef TARGET_SCHED_ADJUST_PRIORITY
1416 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1417 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1418 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1419 #undef TARGET_SCHED_INIT
1420 #define TARGET_SCHED_INIT rs6000_sched_init
1421 #undef TARGET_SCHED_FINISH
1422 #define TARGET_SCHED_FINISH rs6000_sched_finish
1423 #undef TARGET_SCHED_REORDER
1424 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1425 #undef TARGET_SCHED_REORDER2
1426 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1428 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1429 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1431 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1432 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1434 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1435 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1436 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1437 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1438 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1439 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1440 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1441 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1443 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1444 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1445 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1446 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1447 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1448 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1449 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1450 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1451 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1452 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1453 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1454 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1455 rs6000_builtin_support_vector_misalignment
1456 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1457 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1458 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1459 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1460 rs6000_builtin_vectorization_cost
1461 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1462 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1463 rs6000_preferred_simd_mode
1465 #undef TARGET_INIT_BUILTINS
1466 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1467 #undef TARGET_BUILTIN_DECL
1468 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1470 #undef TARGET_EXPAND_BUILTIN
1471 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1473 #undef TARGET_MANGLE_TYPE
1474 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1476 #undef TARGET_INIT_LIBFUNCS
1477 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1480 #undef TARGET_BINDS_LOCAL_P
1481 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1484 #undef TARGET_MS_BITFIELD_LAYOUT_P
1485 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1487 #undef TARGET_ASM_OUTPUT_MI_THUNK
1488 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1490 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1491 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1493 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1494 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1496 #undef TARGET_INVALID_WITHIN_DOLOOP
1497 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1499 #undef TARGET_REGISTER_MOVE_COST
1500 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1501 #undef TARGET_MEMORY_MOVE_COST
1502 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1503 #undef TARGET_RTX_COSTS
1504 #define TARGET_RTX_COSTS rs6000_rtx_costs
1505 #undef TARGET_ADDRESS_COST
1506 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1508 #undef TARGET_DWARF_REGISTER_SPAN
1509 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1511 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1512 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1514 /* On rs6000, function arguments are promoted, as are function return
1516 #undef TARGET_PROMOTE_FUNCTION_MODE
1517 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1519 #undef TARGET_RETURN_IN_MEMORY
1520 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1522 #undef TARGET_SETUP_INCOMING_VARARGS
1523 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1525 /* Always strict argument naming on rs6000. */
1526 #undef TARGET_STRICT_ARGUMENT_NAMING
1527 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1528 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1529 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1530 #undef TARGET_SPLIT_COMPLEX_ARG
1531 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1532 #undef TARGET_MUST_PASS_IN_STACK
1533 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1534 #undef TARGET_PASS_BY_REFERENCE
1535 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1536 #undef TARGET_ARG_PARTIAL_BYTES
1537 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1538 #undef TARGET_FUNCTION_ARG_ADVANCE
1539 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1540 #undef TARGET_FUNCTION_ARG
1541 #define TARGET_FUNCTION_ARG rs6000_function_arg
1542 #undef TARGET_FUNCTION_ARG_BOUNDARY
1543 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1545 #undef TARGET_BUILD_BUILTIN_VA_LIST
1546 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1548 #undef TARGET_EXPAND_BUILTIN_VA_START
1549 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1551 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1552 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1554 #undef TARGET_EH_RETURN_FILTER_MODE
1555 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1557 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1558 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1560 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1561 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1563 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1564 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1566 #undef TARGET_HANDLE_OPTION
1567 #define TARGET_HANDLE_OPTION rs6000_handle_option
1569 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1570 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1572 #undef TARGET_OPTION_OVERRIDE
1573 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1575 #undef TARGET_OPTION_INIT_STRUCT
1576 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1578 #undef TARGET_OPTION_DEFAULT_PARAMS
1579 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1581 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1582 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1584 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1585 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1586 rs6000_builtin_vectorized_function
1588 #undef TARGET_DEFAULT_TARGET_FLAGS
1589 #define TARGET_DEFAULT_TARGET_FLAGS \
1592 #undef TARGET_STACK_PROTECT_FAIL
1593 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1595 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1596 The PowerPC architecture requires only weak consistency among
1597 processors--that is, memory accesses between processors need not be
1598 sequentially consistent and memory accesses among processors can occur
1599 in any order. The ability to order memory accesses weakly provides
1600 opportunities for more efficient use of the system bus. Unless a
1601 dependency exists, the 604e allows read operations to precede store
1603 #undef TARGET_RELAXED_ORDERING
1604 #define TARGET_RELAXED_ORDERING true
1607 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1608 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1611 /* Use a 32-bit anchor range. This leads to sequences like:
1613 addis tmp,anchor,high
1616 where tmp itself acts as an anchor, and can be shared between
1617 accesses to the same 64k page. */
1618 #undef TARGET_MIN_ANCHOR_OFFSET
1619 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1620 #undef TARGET_MAX_ANCHOR_OFFSET
1621 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1622 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1623 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1625 #undef TARGET_BUILTIN_RECIPROCAL
1626 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1628 #undef TARGET_EXPAND_TO_RTL_HOOK
1629 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1631 #undef TARGET_INSTANTIATE_DECLS
1632 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1634 #undef TARGET_SECONDARY_RELOAD
1635 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1637 #undef TARGET_LEGITIMATE_ADDRESS_P
1638 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1640 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1641 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1643 #undef TARGET_CAN_ELIMINATE
1644 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1646 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1647 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1649 #undef TARGET_TRAMPOLINE_INIT
1650 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1652 #undef TARGET_FUNCTION_VALUE
1653 #define TARGET_FUNCTION_VALUE rs6000_function_value
1655 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1656 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1658 #undef TARGET_OPTION_SAVE
1659 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1661 #undef TARGET_OPTION_RESTORE
1662 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1664 #undef TARGET_OPTION_PRINT
1665 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1667 #undef TARGET_CAN_INLINE_P
1668 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1670 #undef TARGET_SET_CURRENT_FUNCTION
1671 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1673 struct gcc_target targetm = TARGET_INITIALIZER;
1676 /* Simplifications for entries below. */
1679 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1680 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1683 /* Some OSs don't support saving the high part of 64-bit registers on context
1684 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1685 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1686 either, the user must explicitly specify them and we won't interfere with
1687 the user's specification. */
1690 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1691 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1692 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1693 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1694 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1695 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1696 | MASK_RECIP_PRECISION)
1699 /* Masks for instructions set at various powerpc ISAs. */
1701 ISA_2_1_MASKS = MASK_MFCRF,
1702 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1703 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1705 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1706 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1707 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1708 server and embedded. */
1709 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1710 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1711 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1713 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1714 altivec is a win so enable it. */
1715 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1716 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1720 /* This table occasionally claims that a processor does not support a
1721 particular feature even though it does, but the feature is slower than the
1722 alternative. Thus, it shouldn't be relied on as a complete description of
1723 the processor's support.
1725 Please keep this list in order, and don't forget to update the documentation
1726 in invoke.texi when adding a new processor or flag. */
1730 const char *const name; /* Canonical processor name. */
1731 const enum processor_type processor; /* Processor type enum value. */
1732 const int target_enable; /* Target flags to enable. */
1735 static struct rs6000_ptt const processor_target_table[] =
1737 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1738 {"403", PROCESSOR_PPC403,
1739 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1740 {"405", PROCESSOR_PPC405,
1741 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1742 {"405fp", PROCESSOR_PPC405,
1743 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1744 {"440", PROCESSOR_PPC440,
1745 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1746 {"440fp", PROCESSOR_PPC440,
1747 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1748 {"464", PROCESSOR_PPC440,
1749 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1750 {"464fp", PROCESSOR_PPC440,
1751 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1752 {"476", PROCESSOR_PPC476,
1753 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1754 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1755 {"476fp", PROCESSOR_PPC476,
1756 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1757 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1758 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1759 {"601", PROCESSOR_PPC601,
1760 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1761 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1762 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1763 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1764 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1765 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1766 {"620", PROCESSOR_PPC620,
1767 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1768 {"630", PROCESSOR_PPC630,
1769 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1770 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1771 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1772 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1773 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1774 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1775 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1776 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1777 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1779 /* 8548 has a dummy entry for now. */
1780 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1782 {"a2", PROCESSOR_PPCA2,
1783 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1784 | MASK_CMPB | MASK_NO_UPDATE },
1785 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1786 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1787 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1789 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1790 | MASK_PPC_GFXOPT | MASK_ISEL},
1791 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1792 {"970", PROCESSOR_POWER4,
1793 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1794 {"cell", PROCESSOR_CELL,
1795 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1796 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1797 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1798 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1799 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1800 {"G5", PROCESSOR_POWER4,
1801 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1802 {"titan", PROCESSOR_TITAN,
1803 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1804 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1805 {"power2", PROCESSOR_POWER,
1806 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1807 {"power3", PROCESSOR_PPC630,
1808 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1809 {"power4", PROCESSOR_POWER4,
1810 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1812 {"power5", PROCESSOR_POWER5,
1813 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1814 | MASK_MFCRF | MASK_POPCNTB},
1815 {"power5+", PROCESSOR_POWER5,
1816 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1817 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1818 {"power6", PROCESSOR_POWER6,
1819 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1820 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1821 | MASK_RECIP_PRECISION},
1822 {"power6x", PROCESSOR_POWER6,
1823 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1824 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1825 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1826 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1827 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1828 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1829 | MASK_VSX | MASK_RECIP_PRECISION},
1830 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1831 {"powerpc64", PROCESSOR_POWERPC64,
1832 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1833 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1834 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1835 {"rios2", PROCESSOR_RIOS2,
1836 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1837 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1838 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1839 {"rs64", PROCESSOR_RS64A,
1840 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1843 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1847 rs6000_cpu_name_lookup (const char *name)
1853 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1854 if (! strcmp (name, processor_target_table[i].name))
1862 /* Return number of consecutive hard regs needed starting at reg REGNO
1863 to hold something of mode MODE.
1864 This is ordinarily the length in words of a value of mode MODE
1865 but can be less for certain modes in special long registers.
1867 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1868 scalar instructions. The upper 32 bits are only available to the
1871 POWER and PowerPC GPRs hold 32 bits worth;
1872 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1875 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1877 unsigned HOST_WIDE_INT reg_size;
1879 if (FP_REGNO_P (regno))
1880 reg_size = (VECTOR_MEM_VSX_P (mode)
1881 ? UNITS_PER_VSX_WORD
1882 : UNITS_PER_FP_WORD);
1884 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1885 reg_size = UNITS_PER_SPE_WORD;
1887 else if (ALTIVEC_REGNO_P (regno))
1888 reg_size = UNITS_PER_ALTIVEC_WORD;
1890 /* The value returned for SCmode in the E500 double case is 2 for
1891 ABI compatibility; storing an SCmode value in a single register
1892 would require function_arg and rs6000_spe_function_arg to handle
1893 SCmode so as to pass the value correctly in a pair of
1895 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1896 && !DECIMAL_FLOAT_MODE_P (mode))
1897 reg_size = UNITS_PER_FP_WORD;
1900 reg_size = UNITS_PER_WORD;
1902 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1905 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1908 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1910 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1912 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1913 implementations. Don't allow an item to be split between a FP register
1914 and an Altivec register. */
1915 if (VECTOR_MEM_VSX_P (mode))
1917 if (FP_REGNO_P (regno))
1918 return FP_REGNO_P (last_regno);
1920 if (ALTIVEC_REGNO_P (regno))
1921 return ALTIVEC_REGNO_P (last_regno);
1924 /* The GPRs can hold any mode, but values bigger than one register
1925 cannot go past R31. */
1926 if (INT_REGNO_P (regno))
1927 return INT_REGNO_P (last_regno);
1929 /* The float registers (except for VSX vector modes) can only hold floating
1930 modes and DImode. This excludes the 32-bit decimal float mode for
1932 if (FP_REGNO_P (regno))
1934 if (SCALAR_FLOAT_MODE_P (mode)
1935 && (mode != TDmode || (regno % 2) == 0)
1936 && FP_REGNO_P (last_regno))
1939 if (GET_MODE_CLASS (mode) == MODE_INT
1940 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1943 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1944 && PAIRED_VECTOR_MODE (mode))
1950 /* The CR register can only hold CC modes. */
1951 if (CR_REGNO_P (regno))
1952 return GET_MODE_CLASS (mode) == MODE_CC;
1954 if (CA_REGNO_P (regno))
1955 return mode == BImode;
1957 /* AltiVec only in AldyVec registers. */
1958 if (ALTIVEC_REGNO_P (regno))
1959 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1961 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1962 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1965 /* We cannot put TImode anywhere except general register and it must be able
1966 to fit within the register set. In the future, allow TImode in the
1967 Altivec or VSX registers. */
1969 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1972 /* Print interesting facts about registers. */
1974 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1978 for (r = first_regno; r <= last_regno; ++r)
1980 const char *comma = "";
1983 if (first_regno == last_regno)
1984 fprintf (stderr, "%s:\t", reg_name);
1986 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1989 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1990 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1994 fprintf (stderr, ",\n\t");
1999 if (rs6000_hard_regno_nregs[m][r] > 1)
2000 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
2001 rs6000_hard_regno_nregs[m][r]);
2003 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2008 if (call_used_regs[r])
2012 fprintf (stderr, ",\n\t");
2017 len += fprintf (stderr, "%s%s", comma, "call-used");
2025 fprintf (stderr, ",\n\t");
2030 len += fprintf (stderr, "%s%s", comma, "fixed");
2036 fprintf (stderr, ",\n\t");
2040 fprintf (stderr, "%sregno = %d\n", comma, r);
2044 #define DEBUG_FMT_D "%-32s= %d\n"
2045 #define DEBUG_FMT_S "%-32s= %s\n"
2047 /* Print various interesting information with -mdebug=reg. */
2049 rs6000_debug_reg_global (void)
2051 static const char *const tf[2] = { "false", "true" };
2052 const char *nl = (const char *)0;
2054 char costly_num[20];
2056 const char *costly_str;
2057 const char *nop_str;
2058 const char *trace_str;
2059 const char *abi_str;
2060 const char *cmodel_str;
2062 /* Map enum rs6000_vector to string. */
2063 static const char *rs6000_debug_vector_unit[] = {
2072 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2073 LAST_VIRTUAL_REGISTER);
2074 rs6000_debug_reg_print (0, 31, "gr");
2075 rs6000_debug_reg_print (32, 63, "fp");
2076 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2079 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2080 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2081 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2082 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2083 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2084 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2085 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2086 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2087 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2091 "d reg_class = %s\n"
2092 "f reg_class = %s\n"
2093 "v reg_class = %s\n"
2094 "wa reg_class = %s\n"
2095 "wd reg_class = %s\n"
2096 "wf reg_class = %s\n"
2097 "ws reg_class = %s\n\n",
2098 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2099 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2100 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2101 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2102 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2103 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2104 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2106 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2107 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2110 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2112 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2113 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2119 if (rs6000_recip_control)
2121 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2123 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2124 if (rs6000_recip_bits[m])
2127 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2129 (RS6000_RECIP_AUTO_RE_P (m)
2131 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2132 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2134 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2137 fputs ("\n", stderr);
2140 if (rs6000_cpu_index >= 0)
2141 fprintf (stderr, DEBUG_FMT_S, "cpu",
2142 processor_target_table[rs6000_cpu_index].name);
2144 if (rs6000_tune_index >= 0)
2145 fprintf (stderr, DEBUG_FMT_S, "tune",
2146 processor_target_table[rs6000_tune_index].name);
2148 switch (rs6000_sched_costly_dep)
2150 case max_dep_latency:
2151 costly_str = "max_dep_latency";
2155 costly_str = "no_dep_costly";
2158 case all_deps_costly:
2159 costly_str = "all_deps_costly";
2162 case true_store_to_load_dep_costly:
2163 costly_str = "true_store_to_load_dep_costly";
2166 case store_to_load_dep_costly:
2167 costly_str = "store_to_load_dep_costly";
2171 costly_str = costly_num;
2172 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2176 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2178 switch (rs6000_sched_insert_nops)
2180 case sched_finish_regroup_exact:
2181 nop_str = "sched_finish_regroup_exact";
2184 case sched_finish_pad_groups:
2185 nop_str = "sched_finish_pad_groups";
2188 case sched_finish_none:
2189 nop_str = "sched_finish_none";
2194 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2198 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2200 switch (rs6000_sdata)
2207 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2211 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2215 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2220 switch (rs6000_traceback)
2222 case traceback_default: trace_str = "default"; break;
2223 case traceback_none: trace_str = "none"; break;
2224 case traceback_part: trace_str = "part"; break;
2225 case traceback_full: trace_str = "full"; break;
2226 default: trace_str = "unknown"; break;
2229 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2231 switch (rs6000_current_cmodel)
2233 case CMODEL_SMALL: cmodel_str = "small"; break;
2234 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2235 case CMODEL_LARGE: cmodel_str = "large"; break;
2236 default: cmodel_str = "unknown"; break;
2239 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2241 switch (rs6000_current_abi)
2243 case ABI_NONE: abi_str = "none"; break;
2244 case ABI_AIX: abi_str = "aix"; break;
2245 case ABI_V4: abi_str = "V4"; break;
2246 case ABI_DARWIN: abi_str = "darwin"; break;
2247 default: abi_str = "unknown"; break;
2250 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2252 if (rs6000_altivec_abi)
2253 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2256 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2258 if (rs6000_darwin64_abi)
2259 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2261 if (rs6000_float_gprs)
2262 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2264 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2265 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2266 tf[!!rs6000_align_branch_targets]);
2267 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2268 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2269 rs6000_long_double_type_size);
2270 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2271 (int)rs6000_sched_restricted_insns_priority);
2274 /* Initialize the various global tables that are based on register size. */
2276 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2282 /* Precalculate REGNO_REG_CLASS. */
2283 rs6000_regno_regclass[0] = GENERAL_REGS;
2284 for (r = 1; r < 32; ++r)
2285 rs6000_regno_regclass[r] = BASE_REGS;
2287 for (r = 32; r < 64; ++r)
2288 rs6000_regno_regclass[r] = FLOAT_REGS;
2290 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2291 rs6000_regno_regclass[r] = NO_REGS;
2293 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2294 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2296 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2297 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2298 rs6000_regno_regclass[r] = CR_REGS;
2300 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2301 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2302 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2303 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2304 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2305 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2306 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2307 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2308 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2309 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2311 /* Precalculate vector information, this must be set up before the
2312 rs6000_hard_regno_nregs_internal below. */
2313 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2315 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2316 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2317 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2320 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2321 rs6000_constraints[c] = NO_REGS;
2323 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2324 believes it can use native alignment or still uses 128-bit alignment. */
2325 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2336 /* V2DF mode, VSX only. */
2339 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2340 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2341 rs6000_vector_align[V2DFmode] = align64;
2344 /* V4SF mode, either VSX or Altivec. */
2347 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2348 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2349 rs6000_vector_align[V4SFmode] = align32;
2351 else if (TARGET_ALTIVEC)
2353 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2354 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2355 rs6000_vector_align[V4SFmode] = align32;
2358 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2362 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2363 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2364 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2365 rs6000_vector_align[V4SImode] = align32;
2366 rs6000_vector_align[V8HImode] = align32;
2367 rs6000_vector_align[V16QImode] = align32;
2371 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2372 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2373 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2377 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2378 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2379 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2383 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2384 Altivec doesn't have 64-bit support. */
2387 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2388 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2389 rs6000_vector_align[V2DImode] = align64;
2392 /* DFmode, see if we want to use the VSX unit. */
2393 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2395 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2396 rs6000_vector_mem[DFmode]
2397 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2398 rs6000_vector_align[DFmode] = align64;
2401 /* TODO add SPE and paired floating point vector support. */
2403 /* Register class constaints for the constraints that depend on compile
2405 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2406 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2408 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2409 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2413 /* At present, we just use VSX_REGS, but we have different constraints
2414 based on the use, in case we want to fine tune the default register
2415 class used. wa = any VSX register, wf = register class to use for
2416 V4SF, wd = register class to use for V2DF, and ws = register classs to
2417 use for DF scalars. */
2418 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2419 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2420 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2421 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2427 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2429 /* Set up the reload helper functions. */
2430 if (TARGET_VSX || TARGET_ALTIVEC)
2434 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2435 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2436 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2437 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2438 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2439 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2440 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2441 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2442 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2443 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2444 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2445 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2449 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2450 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2451 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2452 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2453 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2454 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2455 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2456 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2457 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2458 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2459 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2460 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2464 /* Precalculate HARD_REGNO_NREGS. */
2465 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2466 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2467 rs6000_hard_regno_nregs[m][r]
2468 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2470 /* Precalculate HARD_REGNO_MODE_OK. */
2471 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2472 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2473 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2474 rs6000_hard_regno_mode_ok_p[m][r] = true;
2476 /* Precalculate CLASS_MAX_NREGS sizes. */
2477 for (c = 0; c < LIM_REG_CLASSES; ++c)
2481 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2482 reg_size = UNITS_PER_VSX_WORD;
2484 else if (c == ALTIVEC_REGS)
2485 reg_size = UNITS_PER_ALTIVEC_WORD;
2487 else if (c == FLOAT_REGS)
2488 reg_size = UNITS_PER_FP_WORD;
2491 reg_size = UNITS_PER_WORD;
2493 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2494 rs6000_class_max_nregs[m][c]
2495 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2498 if (TARGET_E500_DOUBLE)
2499 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2501 /* Calculate which modes to automatically generate code to use a the
2502 reciprocal divide and square root instructions. In the future, possibly
2503 automatically generate the instructions even if the user did not specify
2504 -mrecip. The older machines double precision reciprocal sqrt estimate is
2505 not accurate enough. */
2506 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2508 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2510 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2511 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2512 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2513 if (VECTOR_UNIT_VSX_P (V2DFmode))
2514 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2516 if (TARGET_FRSQRTES)
2517 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2519 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2520 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2521 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2522 if (VECTOR_UNIT_VSX_P (V2DFmode))
2523 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2525 if (rs6000_recip_control)
2527 if (!flag_finite_math_only)
2528 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2529 if (flag_trapping_math)
2530 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2531 if (!flag_reciprocal_math)
2532 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2533 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2535 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2536 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2537 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2539 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2540 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2541 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2543 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2544 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2545 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2547 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2548 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2549 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2551 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2552 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2553 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2555 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2556 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2557 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2559 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2560 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2561 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2563 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2564 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2565 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2569 if (global_init_p || TARGET_DEBUG_TARGET)
2571 if (TARGET_DEBUG_REG)
2572 rs6000_debug_reg_global ();
2574 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2576 "SImode variable mult cost = %d\n"
2577 "SImode constant mult cost = %d\n"
2578 "SImode short constant mult cost = %d\n"
2579 "DImode multipliciation cost = %d\n"
2580 "SImode division cost = %d\n"
2581 "DImode division cost = %d\n"
2582 "Simple fp operation cost = %d\n"
2583 "DFmode multiplication cost = %d\n"
2584 "SFmode division cost = %d\n"
2585 "DFmode division cost = %d\n"
2586 "cache line size = %d\n"
2587 "l1 cache size = %d\n"
2588 "l2 cache size = %d\n"
2589 "simultaneous prefetches = %d\n"
2592 rs6000_cost->mulsi_const,
2593 rs6000_cost->mulsi_const9,
2601 rs6000_cost->cache_line_size,
2602 rs6000_cost->l1_cache_size,
2603 rs6000_cost->l2_cache_size,
2604 rs6000_cost->simultaneous_prefetches);
2609 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2612 darwin_rs6000_override_options (void)
2614 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2616 rs6000_altivec_abi = 1;
2617 TARGET_ALTIVEC_VRSAVE = 1;
2619 if (DEFAULT_ABI == ABI_DARWIN
2621 darwin_one_byte_bool = 1;
2623 if (TARGET_64BIT && ! TARGET_POWERPC64)
2625 target_flags |= MASK_POWERPC64;
2626 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2630 rs6000_default_long_calls = 1;
2631 target_flags |= MASK_SOFT_FLOAT;
2634 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2636 if (!flag_mkernel && !flag_apple_kext
2638 && ! (target_flags_explicit & MASK_ALTIVEC))
2639 target_flags |= MASK_ALTIVEC;
2641 /* Unless the user (not the configurer) has explicitly overridden
2642 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2643 G4 unless targetting the kernel. */
2646 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2647 && ! (target_flags_explicit & MASK_ALTIVEC)
2648 && ! rs6000_select[1].string)
2650 target_flags |= MASK_ALTIVEC;
2655 /* If not otherwise specified by a target, make 'long double' equivalent to
2658 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2659 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2662 /* Override command line options. Mostly we process the processor type and
2663 sometimes adjust other TARGET_ options. */
2666 rs6000_option_override_internal (bool global_init_p)
2669 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2673 struct cl_target_option *main_target_opt
2674 = ((global_init_p || target_option_default_node == NULL)
2675 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2677 /* Numerous experiment shows that IRA based loop pressure
2678 calculation works better for RTL loop invariant motion on targets
2679 with enough (>= 32) registers. It is an expensive optimization.
2680 So it is on only for peak performance. */
2681 if (optimize >= 3 && global_init_p)
2682 flag_ira_loop_pressure = 1;
2684 /* Set the pointer size. */
2687 rs6000_pmode = (int)DImode;
2688 rs6000_pointer_size = 64;
2692 rs6000_pmode = (int)SImode;
2693 rs6000_pointer_size = 32;
2696 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2697 #ifdef OS_MISSING_POWERPC64
2698 if (OS_MISSING_POWERPC64)
2699 set_masks &= ~MASK_POWERPC64;
2701 #ifdef OS_MISSING_ALTIVEC
2702 if (OS_MISSING_ALTIVEC)
2703 set_masks &= ~MASK_ALTIVEC;
2706 /* Don't override by the processor default if given explicitly. */
2707 set_masks &= ~target_flags_explicit;
2709 /* Identify the processor type. */
2712 if (TARGET_POWERPC64)
2713 default_cpu = "powerpc64";
2714 else if (TARGET_POWERPC)
2715 default_cpu = "powerpc";
2718 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2719 the cpu in a target attribute or pragma, but did not specify a tuning
2720 option, use the cpu for the tuning option rather than the option specified
2721 with -mtune on the command line. */
2722 if (rs6000_cpu_index > 0)
2723 cpu_index = rs6000_cpu_index;
2724 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2725 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2727 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2729 if (rs6000_tune_index > 0)
2730 tune_index = rs6000_tune_index;
2732 rs6000_tune_index = tune_index = cpu_index;
2736 target_flags &= ~set_masks;
2737 target_flags |= (processor_target_table[cpu_index].target_enable
2741 rs6000_cpu = ((tune_index >= 0)
2742 ? processor_target_table[tune_index].processor
2744 ? PROCESSOR_DEFAULT64
2745 : PROCESSOR_DEFAULT));
2747 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2748 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2751 error ("AltiVec not supported in this target");
2753 error ("SPE not supported in this target");
2756 /* Disable Cell microcode if we are optimizing for the Cell
2757 and not optimizing for size. */
2758 if (rs6000_gen_cell_microcode == -1)
2759 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2762 /* If we are optimizing big endian systems for space and it's OK to
2763 use instructions that would be microcoded on the Cell, use the
2764 load/store multiple and string instructions. */
2765 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2766 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2768 /* Don't allow -mmultiple or -mstring on little endian systems
2769 unless the cpu is a 750, because the hardware doesn't support the
2770 instructions used in little endian mode, and causes an alignment
2771 trap. The 750 does not cause an alignment trap (except when the
2772 target is unaligned). */
2774 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2776 if (TARGET_MULTIPLE)
2778 target_flags &= ~MASK_MULTIPLE;
2779 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2780 warning (0, "-mmultiple is not supported on little endian systems");
2785 target_flags &= ~MASK_STRING;
2786 if ((target_flags_explicit & MASK_STRING) != 0)
2787 warning (0, "-mstring is not supported on little endian systems");
2791 /* Add some warnings for VSX. */
2794 const char *msg = NULL;
2795 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2796 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2798 if (target_flags_explicit & MASK_VSX)
2799 msg = N_("-mvsx requires hardware floating point");
2801 target_flags &= ~ MASK_VSX;
2803 else if (TARGET_PAIRED_FLOAT)
2804 msg = N_("-mvsx and -mpaired are incompatible");
2805 /* The hardware will allow VSX and little endian, but until we make sure
2806 things like vector select, etc. work don't allow VSX on little endian
2807 systems at this point. */
2808 else if (!BYTES_BIG_ENDIAN)
2809 msg = N_("-mvsx used with little endian code");
2810 else if (TARGET_AVOID_XFORM > 0)
2811 msg = N_("-mvsx needs indexed addressing");
2812 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2814 if (target_flags_explicit & MASK_VSX)
2815 msg = N_("-mvsx and -mno-altivec are incompatible");
2817 msg = N_("-mno-altivec disables vsx");
2823 target_flags &= ~ MASK_VSX;
2824 target_flags_explicit |= MASK_VSX;
2828 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2829 unless the user explicitly used the -mno-<option> to disable the code. */
2831 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2832 else if (TARGET_POPCNTD)
2833 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2834 else if (TARGET_DFP)
2835 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2836 else if (TARGET_CMPB)
2837 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2838 else if (TARGET_FPRND)
2839 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2840 else if (TARGET_POPCNTB)
2841 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2842 else if (TARGET_ALTIVEC)
2843 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2845 /* E500mc does "better" if we inline more aggressively. Respect the
2846 user's opinion, though. */
2847 if (rs6000_block_move_inline_limit == 0
2848 && (rs6000_cpu == PROCESSOR_PPCE500MC
2849 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2850 rs6000_block_move_inline_limit = 128;
2852 /* store_one_arg depends on expand_block_move to handle at least the
2853 size of reg_parm_stack_space. */
2854 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2855 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2859 /* If the appropriate debug option is enabled, replace the target hooks
2860 with debug versions that call the real version and then prints
2861 debugging information. */
2862 if (TARGET_DEBUG_COST)
2864 targetm.rtx_costs = rs6000_debug_rtx_costs;
2865 targetm.address_cost = rs6000_debug_address_cost;
2866 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2869 if (TARGET_DEBUG_ADDR)
2871 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2872 targetm.legitimize_address = rs6000_debug_legitimize_address;
2873 rs6000_secondary_reload_class_ptr
2874 = rs6000_debug_secondary_reload_class;
2875 rs6000_secondary_memory_needed_ptr
2876 = rs6000_debug_secondary_memory_needed;
2877 rs6000_cannot_change_mode_class_ptr
2878 = rs6000_debug_cannot_change_mode_class;
2879 rs6000_preferred_reload_class_ptr
2880 = rs6000_debug_preferred_reload_class;
2881 rs6000_legitimize_reload_address_ptr
2882 = rs6000_debug_legitimize_reload_address;
2883 rs6000_mode_dependent_address_ptr
2884 = rs6000_debug_mode_dependent_address;
2887 if (rs6000_veclibabi_name)
2889 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2890 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2893 error ("unknown vectorization library ABI type (%s) for "
2894 "-mveclibabi= switch", rs6000_veclibabi_name);
2900 if (!rs6000_explicit_options.long_double)
2902 if (main_target_opt != NULL
2903 && (main_target_opt->x_rs6000_long_double_type_size
2904 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2905 error ("target attribute or pragma changes long double size");
2907 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2910 #ifndef POWERPC_LINUX
2911 if (!rs6000_explicit_options.ieee)
2912 rs6000_ieeequad = 1;
2915 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2916 target attribute or pragma which automatically enables both options,
2917 unless the altivec ABI was set. This is set by default for 64-bit, but
2919 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2920 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2922 /* Enable Altivec ABI for AIX -maltivec. */
2923 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2925 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2926 error ("target attribute or pragma changes AltiVec ABI");
2928 rs6000_altivec_abi = 1;
2931 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2932 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2933 be explicitly overridden in either case. */
2936 if (!rs6000_explicit_options.altivec_abi
2937 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2939 if (main_target_opt != NULL &&
2940 !main_target_opt->x_rs6000_altivec_abi)
2941 error ("target attribute or pragma changes AltiVec ABI");
2943 rs6000_altivec_abi = 1;
2946 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2947 if (!rs6000_explicit_options.vrsave)
2948 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2951 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2952 So far, the only darwin64 targets are also MACH-O. */
2954 && DEFAULT_ABI == ABI_DARWIN
2957 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2958 error ("target attribute or pragma changes darwin64 ABI");
2961 rs6000_darwin64_abi = 1;
2962 /* Default to natural alignment, for better performance. */
2963 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2967 /* Place FP constants in the constant pool instead of TOC
2968 if section anchors enabled. */
2969 if (flag_section_anchors)
2970 TARGET_NO_FP_IN_TOC = 1;
2972 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2973 SUBTARGET_OVERRIDE_OPTIONS;
2975 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2976 SUBSUBTARGET_OVERRIDE_OPTIONS;
2978 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2979 SUB3TARGET_OVERRIDE_OPTIONS;
2982 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2983 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2985 /* The e500 and e500mc do not have string instructions, and we set
2986 MASK_STRING above when optimizing for size. */
2987 if ((target_flags & MASK_STRING) != 0)
2988 target_flags = target_flags & ~MASK_STRING;
2990 else if (rs6000_select[1].string != NULL)
2992 /* For the powerpc-eabispe configuration, we set all these by
2993 default, so let's unset them if we manually set another
2994 CPU that is not the E500. */
2995 if (main_target_opt != NULL
2996 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
2997 || (main_target_opt->x_rs6000_spe != rs6000_spe)
2998 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
2999 error ("target attribute or pragma changes SPE ABI");
3002 if (!rs6000_explicit_options.spe_abi)
3004 if (!rs6000_explicit_options.spe)
3006 if (!rs6000_explicit_options.float_gprs)
3007 rs6000_float_gprs = 0;
3009 if (!(target_flags_explicit & MASK_ISEL))
3010 target_flags &= ~MASK_ISEL;
3013 /* Detect invalid option combinations with E500. */
3016 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3017 && rs6000_cpu != PROCESSOR_POWER5
3018 && rs6000_cpu != PROCESSOR_POWER6
3019 && rs6000_cpu != PROCESSOR_POWER7
3020 && rs6000_cpu != PROCESSOR_PPCA2
3021 && rs6000_cpu != PROCESSOR_CELL);
3022 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3023 || rs6000_cpu == PROCESSOR_POWER5
3024 || rs6000_cpu == PROCESSOR_POWER7);
3025 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3026 || rs6000_cpu == PROCESSOR_POWER5
3027 || rs6000_cpu == PROCESSOR_POWER6
3028 || rs6000_cpu == PROCESSOR_POWER7
3029 || rs6000_cpu == PROCESSOR_PPCE500MC
3030 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3032 /* Allow debug switches to override the above settings. These are set to -1
3033 in rs6000.opt to indicate the user hasn't directly set the switch. */
3034 if (TARGET_ALWAYS_HINT >= 0)
3035 rs6000_always_hint = TARGET_ALWAYS_HINT;
3037 if (TARGET_SCHED_GROUPS >= 0)
3038 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3040 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3041 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3043 rs6000_sched_restricted_insns_priority
3044 = (rs6000_sched_groups ? 1 : 0);
3046 /* Handle -msched-costly-dep option. */
3047 rs6000_sched_costly_dep
3048 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3050 if (rs6000_sched_costly_dep_str)
3052 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3053 rs6000_sched_costly_dep = no_dep_costly;
3054 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3055 rs6000_sched_costly_dep = all_deps_costly;
3056 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3057 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3058 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3059 rs6000_sched_costly_dep = store_to_load_dep_costly;
3061 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3062 atoi (rs6000_sched_costly_dep_str));
3065 /* Handle -minsert-sched-nops option. */
3066 rs6000_sched_insert_nops
3067 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3069 if (rs6000_sched_insert_nops_str)
3071 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3072 rs6000_sched_insert_nops = sched_finish_none;
3073 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3074 rs6000_sched_insert_nops = sched_finish_pad_groups;
3075 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3076 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3078 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3079 atoi (rs6000_sched_insert_nops_str));
3084 #ifdef TARGET_REGNAMES
3085 /* If the user desires alternate register names, copy in the
3086 alternate names now. */
3087 if (TARGET_REGNAMES)
3088 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3091 /* Set aix_struct_return last, after the ABI is determined.
3092 If -maix-struct-return or -msvr4-struct-return was explicitly
3093 used, don't override with the ABI default. */
3094 if (!rs6000_explicit_options.aix_struct_ret)
3095 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3098 /* IBM XL compiler defaults to unsigned bitfields. */
3099 if (TARGET_XL_COMPAT)
3100 flag_signed_bitfields = 0;
3103 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3104 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3107 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3109 /* We can only guarantee the availability of DI pseudo-ops when
3110 assembling for 64-bit targets. */
3113 targetm.asm_out.aligned_op.di = NULL;
3114 targetm.asm_out.unaligned_op.di = NULL;
3118 /* Set branch target alignment, if not optimizing for size. */
3121 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3122 aligned 8byte to avoid misprediction by the branch predictor. */
3123 if (rs6000_cpu == PROCESSOR_TITAN
3124 || rs6000_cpu == PROCESSOR_CELL)
3126 if (align_functions <= 0)
3127 align_functions = 8;
3128 if (align_jumps <= 0)
3130 if (align_loops <= 0)
3133 if (rs6000_align_branch_targets)
3135 if (align_functions <= 0)
3136 align_functions = 16;
3137 if (align_jumps <= 0)
3139 if (align_loops <= 0)
3141 can_override_loop_align = 1;
3145 if (align_jumps_max_skip <= 0)
3146 align_jumps_max_skip = 15;
3147 if (align_loops_max_skip <= 0)
3148 align_loops_max_skip = 15;
3151 /* Arrange to save and restore machine status around nested functions. */
3152 init_machine_status = rs6000_init_machine_status;
3154 /* We should always be splitting complex arguments, but we can't break
3155 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3156 if (DEFAULT_ABI != ABI_AIX)
3157 targetm.calls.split_complex_arg = NULL;
3160 /* Initialize rs6000_cost with the appropriate target costs. */
3162 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3166 case PROCESSOR_RIOS1:
3167 rs6000_cost = &rios1_cost;
3170 case PROCESSOR_RIOS2:
3171 rs6000_cost = &rios2_cost;
3174 case PROCESSOR_RS64A:
3175 rs6000_cost = &rs64a_cost;
3178 case PROCESSOR_MPCCORE:
3179 rs6000_cost = &mpccore_cost;
3182 case PROCESSOR_PPC403:
3183 rs6000_cost = &ppc403_cost;
3186 case PROCESSOR_PPC405:
3187 rs6000_cost = &ppc405_cost;
3190 case PROCESSOR_PPC440:
3191 rs6000_cost = &ppc440_cost;
3194 case PROCESSOR_PPC476:
3195 rs6000_cost = &ppc476_cost;
3198 case PROCESSOR_PPC601:
3199 rs6000_cost = &ppc601_cost;
3202 case PROCESSOR_PPC603:
3203 rs6000_cost = &ppc603_cost;
3206 case PROCESSOR_PPC604:
3207 rs6000_cost = &ppc604_cost;
3210 case PROCESSOR_PPC604e:
3211 rs6000_cost = &ppc604e_cost;
3214 case PROCESSOR_PPC620:
3215 rs6000_cost = &ppc620_cost;
3218 case PROCESSOR_PPC630:
3219 rs6000_cost = &ppc630_cost;
3222 case PROCESSOR_CELL:
3223 rs6000_cost = &ppccell_cost;
3226 case PROCESSOR_PPC750:
3227 case PROCESSOR_PPC7400:
3228 rs6000_cost = &ppc750_cost;
3231 case PROCESSOR_PPC7450:
3232 rs6000_cost = &ppc7450_cost;
3235 case PROCESSOR_PPC8540:
3236 rs6000_cost = &ppc8540_cost;
3239 case PROCESSOR_PPCE300C2:
3240 case PROCESSOR_PPCE300C3:
3241 rs6000_cost = &ppce300c2c3_cost;
3244 case PROCESSOR_PPCE500MC:
3245 rs6000_cost = &ppce500mc_cost;
3248 case PROCESSOR_PPCE500MC64:
3249 rs6000_cost = &ppce500mc64_cost;
3252 case PROCESSOR_TITAN:
3253 rs6000_cost = &titan_cost;
3256 case PROCESSOR_POWER4:
3257 case PROCESSOR_POWER5:
3258 rs6000_cost = &power4_cost;
3261 case PROCESSOR_POWER6:
3262 rs6000_cost = &power6_cost;
3265 case PROCESSOR_POWER7:
3266 rs6000_cost = &power7_cost;
3269 case PROCESSOR_PPCA2:
3270 rs6000_cost = &ppca2_cost;
3279 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3280 rs6000_cost->simultaneous_prefetches,
3281 global_options.x_param_values,
3282 global_options_set.x_param_values);
3283 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3284 global_options.x_param_values,
3285 global_options_set.x_param_values);
3286 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3287 rs6000_cost->cache_line_size,
3288 global_options.x_param_values,
3289 global_options_set.x_param_values);
3290 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3291 global_options.x_param_values,
3292 global_options_set.x_param_values);
3294 /* If using typedef char *va_list, signal that
3295 __builtin_va_start (&ap, 0) can be optimized to
3296 ap = __builtin_next_arg (0). */
3297 if (DEFAULT_ABI != ABI_V4)
3298 targetm.expand_builtin_va_start = NULL;
3301 /* Set up single/double float flags.
3302 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3303 then set both flags. */
3304 if (TARGET_HARD_FLOAT && TARGET_FPRS
3305 && rs6000_single_float == 0 && rs6000_double_float == 0)
3306 rs6000_single_float = rs6000_double_float = 1;
3308 /* Reset single and double FP flags if target is E500. */
3311 rs6000_single_float = rs6000_double_float = 0;
3312 if (TARGET_E500_SINGLE)
3313 rs6000_single_float = 1;
3314 if (TARGET_E500_DOUBLE)
3315 rs6000_single_float = rs6000_double_float = 1;
3318 if (main_target_opt)
3320 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3321 error ("target attribute or pragma changes single precision floating "
3323 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3324 error ("target attribute or pragma changes double precision floating "
3328 /* If not explicitly specified via option, decide whether to generate indexed
3329 load/store instructions. */
3330 if (TARGET_AVOID_XFORM == -1)
3331 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3332 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3333 need indexed accesses and the type used is the scalar type of the element
3334 being loaded or stored. */
3335 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3336 && !TARGET_ALTIVEC);
3338 /* Set the -mrecip options. */
3339 if (rs6000_recip_name)
3341 char *p = ASTRDUP (rs6000_recip_name);
3343 unsigned int mask, i;
3346 while ((q = strtok (p, ",")) != NULL)
3357 if (!strcmp (q, "default"))
3358 mask = ((TARGET_RECIP_PRECISION)
3359 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3362 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3363 if (!strcmp (q, recip_options[i].string))
3365 mask = recip_options[i].mask;
3369 if (i == ARRAY_SIZE (recip_options))
3371 error ("unknown option for -mrecip=%s", q);
3379 rs6000_recip_control &= ~mask;
3381 rs6000_recip_control |= mask;
3385 rs6000_init_hard_regno_mode_ok (global_init_p);
3387 /* Save the initial options in case the user does function specific options */
3389 target_option_default_node = target_option_current_node
3390 = build_target_option_node ();
3395 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3396 define the target cpu type. */
3399 rs6000_option_override (void)
3401 (void) rs6000_option_override_internal (true);
3405 /* Implement targetm.vectorize.builtin_mask_for_load. */
3407 rs6000_builtin_mask_for_load (void)
3409 if (TARGET_ALTIVEC || TARGET_VSX)
3410 return altivec_builtin_mask_for_load;
3415 /* Implement LOOP_ALIGN. */
3417 rs6000_loop_align (rtx label)
3422 /* Don't override loop alignment if -falign-loops was specified. */
3423 if (!can_override_loop_align)
3424 return align_loops_log;
3426 bb = BLOCK_FOR_INSN (label);
3427 ninsns = num_loop_insns(bb->loop_father);
3429 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3430 if (ninsns > 4 && ninsns <= 8
3431 && (rs6000_cpu == PROCESSOR_POWER4
3432 || rs6000_cpu == PROCESSOR_POWER5
3433 || rs6000_cpu == PROCESSOR_POWER6
3434 || rs6000_cpu == PROCESSOR_POWER7))
3437 return align_loops_log;
3440 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3442 rs6000_loop_align_max_skip (rtx label)
3444 return (1 << rs6000_loop_align (label)) - 1;
3447 /* Implement targetm.vectorize.builtin_conversion.
3448 Returns a decl of a function that implements conversion of an integer vector
3449 into a floating-point vector, or vice-versa. DEST_TYPE is the
3450 destination type and SRC_TYPE the source type of the conversion.
3451 Return NULL_TREE if it is not available. */
3453 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3455 enum tree_code code = (enum tree_code) tcode;
3459 case FIX_TRUNC_EXPR:
3460 switch (TYPE_MODE (dest_type))
3463 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3466 return TYPE_UNSIGNED (dest_type)
3467 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3468 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3471 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3474 return TYPE_UNSIGNED (dest_type)
3475 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3476 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3483 switch (TYPE_MODE (src_type))
3486 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3489 return TYPE_UNSIGNED (src_type)
3490 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3491 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3494 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3497 return TYPE_UNSIGNED (src_type)
3498 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3499 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3510 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3512 rs6000_builtin_mul_widen_even (tree type)
3514 if (!TARGET_ALTIVEC)
3517 switch (TYPE_MODE (type))
3520 return TYPE_UNSIGNED (type)
3521 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3522 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3525 return TYPE_UNSIGNED (type)
3526 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3527 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3533 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3535 rs6000_builtin_mul_widen_odd (tree type)
3537 if (!TARGET_ALTIVEC)
3540 switch (TYPE_MODE (type))
3543 return TYPE_UNSIGNED (type)
3544 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3545 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3548 return TYPE_UNSIGNED (type)
3549 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3550 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3557 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3558 after applying N number of iterations. This routine does not determine
3559 how may iterations are required to reach desired alignment. */
3562 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3569 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3572 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3582 /* Assuming that all other types are naturally aligned. CHECKME! */
3587 /* Return true if the vector misalignment factor is supported by the
3590 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3597 /* Return if movmisalign pattern is not supported for this mode. */
3598 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3601 if (misalignment == -1)
3603 /* Misalignment factor is unknown at compile time but we know
3604 it's word aligned. */
3605 if (rs6000_vector_alignment_reachable (type, is_packed))
3607 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3609 if (element_size == 64 || element_size == 32)
3616 /* VSX supports word-aligned vector. */
3617 if (misalignment % 4 == 0)
3623 /* Implement targetm.vectorize.builtin_vec_perm. */
3625 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3627 tree inner_type = TREE_TYPE (type);
3628 bool uns_p = TYPE_UNSIGNED (inner_type);
3631 *mask_element_type = unsigned_char_type_node;
3633 switch (TYPE_MODE (type))
3637 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3638 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3643 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3644 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3649 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3650 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3654 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3658 if (!TARGET_ALLOW_DF_PERMUTE)
3661 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3665 if (!TARGET_ALLOW_DF_PERMUTE)
3669 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3670 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3682 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3684 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3685 tree vectype, int misalign)
3689 switch (type_of_cost)
3699 case cond_branch_not_taken:
3703 case cond_branch_taken:
3706 case unaligned_load:
3707 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3709 elements = TYPE_VECTOR_SUBPARTS (vectype);
3711 /* Double word aligned. */
3719 /* Double word aligned. */
3723 /* Unknown misalignment. */
3736 /* Misaligned loads are not supported. */
3741 case unaligned_store:
3742 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3744 elements = TYPE_VECTOR_SUBPARTS (vectype);
3746 /* Double word aligned. */
3754 /* Double word aligned. */
3758 /* Unknown misalignment. */
3771 /* Misaligned stores are not supported. */
3781 /* Implement targetm.vectorize.preferred_simd_mode. */
3783 static enum machine_mode
3784 rs6000_preferred_simd_mode (enum machine_mode mode)
3793 if (TARGET_ALTIVEC || TARGET_VSX)
3817 if (TARGET_PAIRED_FLOAT
3823 /* Implement TARGET_OPTION_INIT_STRUCT. */
3826 rs6000_option_init_struct (struct gcc_options *opts)
3828 if (DEFAULT_ABI == ABI_DARWIN)
3829 /* The Darwin libraries never set errno, so we might as well
3830 avoid calling them when that's the only reason we would. */
3831 opts->x_flag_errno_math = 0;
3833 /* Enable section anchors by default. */
3835 opts->x_flag_section_anchors = 1;
3838 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3841 rs6000_option_default_params (void)
3843 /* Double growth factor to counter reduced min jump length. */
3844 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3847 static enum fpu_type_t
3848 rs6000_parse_fpu_option (const char *option)
3850 if (!strcmp("none", option)) return FPU_NONE;
3851 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3852 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3853 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3854 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3855 error("unknown value %s for -mfpu", option);
3860 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3861 library with vectorized intrinsics. */
3864 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3867 const char *suffix = NULL;
3868 tree fntype, new_fndecl, bdecl = NULL_TREE;
3871 enum machine_mode el_mode, in_mode;
3874 /* Libmass is suitable for unsafe math only as it does not correctly support
3875 parts of IEEE with the required precision such as denormals. Only support
3876 it if we have VSX to use the simd d2 or f4 functions.
3877 XXX: Add variable length support. */
3878 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3881 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3882 n = TYPE_VECTOR_SUBPARTS (type_out);
3883 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3884 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3885 if (el_mode != in_mode
3889 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3891 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3894 case BUILT_IN_ATAN2:
3895 case BUILT_IN_HYPOT:
3901 case BUILT_IN_ACOSH:
3903 case BUILT_IN_ASINH:
3905 case BUILT_IN_ATANH:
3913 case BUILT_IN_EXPM1:
3914 case BUILT_IN_LGAMMA:
3915 case BUILT_IN_LOG10:
3916 case BUILT_IN_LOG1P:
3924 bdecl = implicit_built_in_decls[fn];
3925 suffix = "d2"; /* pow -> powd2 */
3926 if (el_mode != DFmode
3931 case BUILT_IN_ATAN2F:
3932 case BUILT_IN_HYPOTF:
3937 case BUILT_IN_ACOSF:
3938 case BUILT_IN_ACOSHF:
3939 case BUILT_IN_ASINF:
3940 case BUILT_IN_ASINHF:
3941 case BUILT_IN_ATANF:
3942 case BUILT_IN_ATANHF:
3943 case BUILT_IN_CBRTF:
3945 case BUILT_IN_COSHF:
3947 case BUILT_IN_ERFCF:
3948 case BUILT_IN_EXP2F:
3950 case BUILT_IN_EXPM1F:
3951 case BUILT_IN_LGAMMAF:
3952 case BUILT_IN_LOG10F:
3953 case BUILT_IN_LOG1PF:
3954 case BUILT_IN_LOG2F:
3957 case BUILT_IN_SINHF:
3958 case BUILT_IN_SQRTF:
3960 case BUILT_IN_TANHF:
3961 bdecl = implicit_built_in_decls[fn];
3962 suffix = "4"; /* powf -> powf4 */
3963 if (el_mode != SFmode
3975 gcc_assert (suffix != NULL);
3976 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3977 strcpy (name, bname + sizeof ("__builtin_") - 1);
3978 strcat (name, suffix);
3981 fntype = build_function_type_list (type_out, type_in, NULL);
3982 else if (n_args == 2)
3983 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3987 /* Build a function declaration for the vectorized function. */
3988 new_fndecl = build_decl (BUILTINS_LOCATION,
3989 FUNCTION_DECL, get_identifier (name), fntype);
3990 TREE_PUBLIC (new_fndecl) = 1;
3991 DECL_EXTERNAL (new_fndecl) = 1;
3992 DECL_IS_NOVOPS (new_fndecl) = 1;
3993 TREE_READONLY (new_fndecl) = 1;
3998 /* Returns a function decl for a vectorized version of the builtin function
3999 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4000 if it is not available. */
4003 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4006 enum machine_mode in_mode, out_mode;
4009 if (TREE_CODE (type_out) != VECTOR_TYPE
4010 || TREE_CODE (type_in) != VECTOR_TYPE
4011 || !TARGET_VECTORIZE_BUILTINS)
4014 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4015 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4016 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4017 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4019 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4021 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4024 case BUILT_IN_COPYSIGN:
4025 if (VECTOR_UNIT_VSX_P (V2DFmode)
4026 && out_mode == DFmode && out_n == 2
4027 && in_mode == DFmode && in_n == 2)
4028 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4030 case BUILT_IN_COPYSIGNF:
4031 if (out_mode != SFmode || out_n != 4
4032 || in_mode != SFmode || in_n != 4)
4034 if (VECTOR_UNIT_VSX_P (V4SFmode))
4035 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4036 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4037 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4040 if (VECTOR_UNIT_VSX_P (V2DFmode)
4041 && out_mode == DFmode && out_n == 2
4042 && in_mode == DFmode && in_n == 2)
4043 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4045 case BUILT_IN_SQRTF:
4046 if (VECTOR_UNIT_VSX_P (V4SFmode)
4047 && out_mode == SFmode && out_n == 4
4048 && in_mode == SFmode && in_n == 4)
4049 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4052 if (VECTOR_UNIT_VSX_P (V2DFmode)
4053 && out_mode == DFmode && out_n == 2
4054 && in_mode == DFmode && in_n == 2)
4055 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4057 case BUILT_IN_CEILF:
4058 if (out_mode != SFmode || out_n != 4
4059 || in_mode != SFmode || in_n != 4)
4061 if (VECTOR_UNIT_VSX_P (V4SFmode))
4062 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4063 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4064 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4066 case BUILT_IN_FLOOR:
4067 if (VECTOR_UNIT_VSX_P (V2DFmode)
4068 && out_mode == DFmode && out_n == 2
4069 && in_mode == DFmode && in_n == 2)
4070 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4072 case BUILT_IN_FLOORF:
4073 if (out_mode != SFmode || out_n != 4
4074 || in_mode != SFmode || in_n != 4)
4076 if (VECTOR_UNIT_VSX_P (V4SFmode))
4077 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4078 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4079 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4082 if (VECTOR_UNIT_VSX_P (V2DFmode)
4083 && out_mode == DFmode && out_n == 2
4084 && in_mode == DFmode && in_n == 2)
4085 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4088 if (VECTOR_UNIT_VSX_P (V4SFmode)
4089 && out_mode == SFmode && out_n == 4
4090 && in_mode == SFmode && in_n == 4)
4091 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4092 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4093 && out_mode == SFmode && out_n == 4
4094 && in_mode == SFmode && in_n == 4)
4095 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4097 case BUILT_IN_TRUNC:
4098 if (VECTOR_UNIT_VSX_P (V2DFmode)
4099 && out_mode == DFmode && out_n == 2
4100 && in_mode == DFmode && in_n == 2)
4101 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4103 case BUILT_IN_TRUNCF:
4104 if (out_mode != SFmode || out_n != 4
4105 || in_mode != SFmode || in_n != 4)
4107 if (VECTOR_UNIT_VSX_P (V4SFmode))
4108 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4109 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4110 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4112 case BUILT_IN_NEARBYINT:
4113 if (VECTOR_UNIT_VSX_P (V2DFmode)
4114 && flag_unsafe_math_optimizations
4115 && out_mode == DFmode && out_n == 2
4116 && in_mode == DFmode && in_n == 2)
4117 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4119 case BUILT_IN_NEARBYINTF:
4120 if (VECTOR_UNIT_VSX_P (V4SFmode)
4121 && flag_unsafe_math_optimizations
4122 && out_mode == SFmode && out_n == 4
4123 && in_mode == SFmode && in_n == 4)
4124 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4127 if (VECTOR_UNIT_VSX_P (V2DFmode)
4128 && !flag_trapping_math
4129 && out_mode == DFmode && out_n == 2
4130 && in_mode == DFmode && in_n == 2)
4131 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4133 case BUILT_IN_RINTF:
4134 if (VECTOR_UNIT_VSX_P (V4SFmode)
4135 && !flag_trapping_math
4136 && out_mode == SFmode && out_n == 4
4137 && in_mode == SFmode && in_n == 4)
4138 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4145 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4147 enum rs6000_builtins fn
4148 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4151 case RS6000_BUILTIN_RSQRTF:
4152 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4153 && out_mode == SFmode && out_n == 4
4154 && in_mode == SFmode && in_n == 4)
4155 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4157 case RS6000_BUILTIN_RSQRT:
4158 if (VECTOR_UNIT_VSX_P (V2DFmode)
4159 && out_mode == DFmode && out_n == 2
4160 && in_mode == DFmode && in_n == 2)
4161 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4163 case RS6000_BUILTIN_RECIPF:
4164 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4165 && out_mode == SFmode && out_n == 4
4166 && in_mode == SFmode && in_n == 4)
4167 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4169 case RS6000_BUILTIN_RECIP:
4170 if (VECTOR_UNIT_VSX_P (V2DFmode)
4171 && out_mode == DFmode && out_n == 2
4172 && in_mode == DFmode && in_n == 2)
4173 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4180 /* Generate calls to libmass if appropriate. */
4181 if (rs6000_veclib_handler)
4182 return rs6000_veclib_handler (fndecl, type_out, type_in);
4188 /* Implement TARGET_HANDLE_OPTION. */
4191 rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
4192 const struct cl_decoded_option *decoded,
4193 location_t loc ATTRIBUTE_UNUSED)
4195 enum fpu_type_t fpu_type = FPU_NONE;
4197 size_t code = decoded->opt_index;
4198 const char *arg = decoded->arg;
4199 int value = decoded->value;
4201 gcc_assert (opts == &global_options);
4202 gcc_assert (opts_set == &global_options_set);
4207 target_flags &= ~(MASK_POWER | MASK_POWER2
4208 | MASK_MULTIPLE | MASK_STRING);
4209 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4210 | MASK_MULTIPLE | MASK_STRING);
4212 case OPT_mno_powerpc:
4213 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4214 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4215 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4216 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4219 target_flags &= ~MASK_MINIMAL_TOC;
4220 TARGET_NO_FP_IN_TOC = 0;
4221 TARGET_NO_SUM_IN_TOC = 0;
4222 target_flags_explicit |= MASK_MINIMAL_TOC;
4223 #ifdef TARGET_USES_SYSV4_OPT
4224 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4225 just the same as -mminimal-toc. */
4226 target_flags |= MASK_MINIMAL_TOC;
4227 target_flags_explicit |= MASK_MINIMAL_TOC;
4231 #ifdef TARGET_USES_SYSV4_OPT
4233 /* Make -mtoc behave like -mminimal-toc. */
4234 target_flags |= MASK_MINIMAL_TOC;
4235 target_flags_explicit |= MASK_MINIMAL_TOC;
4239 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4241 if (strcmp (arg, "small") == 0)
4242 rs6000_current_cmodel = CMODEL_SMALL;
4243 else if (strcmp (arg, "medium") == 0)
4244 rs6000_current_cmodel = CMODEL_MEDIUM;
4245 else if (strcmp (arg, "large") == 0)
4246 rs6000_current_cmodel = CMODEL_LARGE;
4249 error ("invalid option for -mcmodel: '%s'", arg);
4252 rs6000_explicit_options.cmodel = true;
4255 #ifdef TARGET_USES_AIX64_OPT
4260 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4261 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4262 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4265 #ifdef TARGET_USES_AIX64_OPT
4270 target_flags &= ~MASK_POWERPC64;
4271 target_flags_explicit |= MASK_POWERPC64;
4274 case OPT_minsert_sched_nops_:
4275 rs6000_sched_insert_nops_str = arg;
4278 case OPT_mminimal_toc:
4281 TARGET_NO_FP_IN_TOC = 0;
4282 TARGET_NO_SUM_IN_TOC = 0;
4289 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4290 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4297 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4298 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4302 case OPT_mpowerpc_gpopt:
4303 case OPT_mpowerpc_gfxopt:
4306 target_flags |= MASK_POWERPC;
4307 target_flags_explicit |= MASK_POWERPC;
4311 case OPT_maix_struct_return:
4312 case OPT_msvr4_struct_return:
4313 rs6000_explicit_options.aix_struct_ret = true;
4317 rs6000_explicit_options.vrsave = true;
4318 TARGET_ALTIVEC_VRSAVE = value;
4322 rs6000_explicit_options.spe = true;
4330 while ((q = strtok (p, ",")) != NULL)
4344 if (! strcmp (q, "all"))
4345 mask = MASK_DEBUG_ALL;
4346 else if (! strcmp (q, "stack"))
4347 mask = MASK_DEBUG_STACK;
4348 else if (! strcmp (q, "arg"))
4349 mask = MASK_DEBUG_ARG;
4350 else if (! strcmp (q, "reg"))
4351 mask = MASK_DEBUG_REG;
4352 else if (! strcmp (q, "addr"))
4353 mask = MASK_DEBUG_ADDR;
4354 else if (! strcmp (q, "cost"))
4355 mask = MASK_DEBUG_COST;
4356 else if (! strcmp (q, "target"))
4357 mask = MASK_DEBUG_TARGET;
4359 error ("unknown -mdebug-%s switch", q);
4362 rs6000_debug &= ~mask;
4364 rs6000_debug |= mask;
4368 #ifdef TARGET_USES_SYSV4_OPT
4370 rs6000_abi_name = arg;
4374 rs6000_sdata_name = arg;
4377 case OPT_mtls_size_:
4378 if (strcmp (arg, "16") == 0)
4379 rs6000_tls_size = 16;
4380 else if (strcmp (arg, "32") == 0)
4381 rs6000_tls_size = 32;
4382 else if (strcmp (arg, "64") == 0)
4383 rs6000_tls_size = 64;
4385 error ("bad value %qs for -mtls-size switch", arg);
4388 case OPT_mrelocatable:
4391 target_flags |= MASK_MINIMAL_TOC;
4392 target_flags_explicit |= MASK_MINIMAL_TOC;
4393 TARGET_NO_FP_IN_TOC = 1;
4397 case OPT_mrelocatable_lib:
4400 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4401 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4402 TARGET_NO_FP_IN_TOC = 1;
4406 target_flags &= ~MASK_RELOCATABLE;
4407 target_flags_explicit |= MASK_RELOCATABLE;
4413 if (!strcmp (arg, "altivec"))
4415 rs6000_explicit_options.altivec_abi = true;
4416 rs6000_altivec_abi = 1;
4418 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4421 else if (! strcmp (arg, "no-altivec"))
4423 rs6000_explicit_options.altivec_abi = true;
4424 rs6000_altivec_abi = 0;
4426 else if (! strcmp (arg, "spe"))
4428 rs6000_explicit_options.spe_abi = true;
4430 rs6000_altivec_abi = 0;
4431 if (!TARGET_SPE_ABI)
4432 error ("not configured for ABI: '%s'", arg);
4434 else if (! strcmp (arg, "no-spe"))
4436 rs6000_explicit_options.spe_abi = true;
4440 /* These are here for testing during development only, do not
4441 document in the manual please. */
4442 else if (! strcmp (arg, "d64"))
4444 rs6000_darwin64_abi = 1;
4445 warning (0, "using darwin64 ABI");
4447 else if (! strcmp (arg, "d32"))
4449 rs6000_darwin64_abi = 0;
4450 warning (0, "using old darwin ABI");
4453 else if (! strcmp (arg, "ibmlongdouble"))
4455 rs6000_explicit_options.ieee = true;
4456 rs6000_ieeequad = 0;
4457 warning (0, "using IBM extended precision long double");
4459 else if (! strcmp (arg, "ieeelongdouble"))
4461 rs6000_explicit_options.ieee = true;
4462 rs6000_ieeequad = 1;
4463 warning (0, "using IEEE extended precision long double");
4468 error ("unknown ABI specified: '%s'", arg);
4474 rs6000_select[1].string = arg;
4475 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4476 if (rs6000_cpu_index < 0)
4477 error ("bad value (%s) for -mcpu", arg);
4481 rs6000_select[2].string = arg;
4482 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4483 if (rs6000_tune_index < 0)
4484 error ("bad value (%s) for -mtune", arg);
4487 case OPT_mtraceback_:
4488 if (! strncmp (arg, "full", 4))
4489 rs6000_traceback = traceback_full;
4490 else if (! strncmp (arg, "part", 4))
4491 rs6000_traceback = traceback_part;
4492 else if (! strncmp (arg, "no", 2))
4493 rs6000_traceback = traceback_none;
4495 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4496 "%<partial%> or %<none%>", arg);
4499 case OPT_mfloat_gprs_:
4500 rs6000_explicit_options.float_gprs = true;
4501 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4502 rs6000_float_gprs = 1;
4503 else if (! strcmp (arg, "double"))
4504 rs6000_float_gprs = 2;
4505 else if (! strcmp (arg, "no"))
4506 rs6000_float_gprs = 0;
4509 error ("invalid option for -mfloat-gprs: '%s'", arg);
4514 case OPT_mlong_double_:
4515 rs6000_explicit_options.long_double = true;
4516 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4517 if (value != 64 && value != 128)
4519 error ("unknown switch -mlong-double-%s", arg);
4520 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4524 rs6000_long_double_type_size = value;
4527 case OPT_msched_costly_dep_:
4528 rs6000_sched_costly_dep_str = arg;
4532 rs6000_explicit_options.alignment = true;
4533 if (! strcmp (arg, "power"))
4535 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4536 some C library functions, so warn about it. The flag may be
4537 useful for performance studies from time to time though, so
4538 don't disable it entirely. */
4539 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4540 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4541 " it is incompatible with the installed C and C++ libraries");
4542 rs6000_alignment_flags = MASK_ALIGN_POWER;
4544 else if (! strcmp (arg, "natural"))
4545 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4548 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4553 case OPT_msingle_float:
4554 if (!TARGET_SINGLE_FPU)
4555 warning (0, "-msingle-float option equivalent to -mhard-float");
4556 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4557 rs6000_double_float = 0;
4558 target_flags &= ~MASK_SOFT_FLOAT;
4559 target_flags_explicit |= MASK_SOFT_FLOAT;
4562 case OPT_mdouble_float:
4563 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4564 rs6000_single_float = 1;
4565 target_flags &= ~MASK_SOFT_FLOAT;
4566 target_flags_explicit |= MASK_SOFT_FLOAT;
4569 case OPT_msimple_fpu:
4570 if (!TARGET_SINGLE_FPU)
4571 warning (0, "-msimple-fpu option ignored");
4574 case OPT_mhard_float:
4575 /* -mhard_float implies -msingle-float and -mdouble-float. */
4576 rs6000_single_float = rs6000_double_float = 1;
4579 case OPT_msoft_float:
4580 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4581 rs6000_single_float = rs6000_double_float = 0;
4585 fpu_type = rs6000_parse_fpu_option(arg);
4586 if (fpu_type != FPU_NONE)
4587 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4589 target_flags &= ~MASK_SOFT_FLOAT;
4590 target_flags_explicit |= MASK_SOFT_FLOAT;
4591 rs6000_xilinx_fpu = 1;
4592 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4593 rs6000_single_float = 1;
4594 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4595 rs6000_single_float = rs6000_double_float = 1;
4596 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4597 rs6000_simple_fpu = 1;
4601 /* -mfpu=none is equivalent to -msoft-float */
4602 target_flags |= MASK_SOFT_FLOAT;
4603 target_flags_explicit |= MASK_SOFT_FLOAT;
4604 rs6000_single_float = rs6000_double_float = 0;
4608 rs6000_recip_name = (value) ? "default" : "none";
4612 rs6000_recip_name = arg;
4618 /* Do anything needed at the start of the asm file. */
4621 rs6000_file_start (void)
4625 const char *start = buffer;
4626 struct rs6000_cpu_select *ptr;
4627 const char *default_cpu = TARGET_CPU_DEFAULT;
4628 FILE *file = asm_out_file;
4630 default_file_start ();
4632 #ifdef TARGET_BI_ARCH
4633 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4637 if (flag_verbose_asm)
4639 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4640 rs6000_select[0].string = default_cpu;
4642 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4644 ptr = &rs6000_select[i];
4645 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4647 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4652 if (PPC405_ERRATUM77)
4654 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4658 #ifdef USING_ELFOS_H
4659 switch (rs6000_sdata)
4661 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4662 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4663 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4664 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4667 if (rs6000_sdata && g_switch_value)
4669 fprintf (file, "%s -G %d", start,
4679 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4681 switch_to_section (toc_section);
4682 switch_to_section (text_section);
4687 /* Return nonzero if this function is known to have a null epilogue. */
4690 direct_return (void)
4692 if (reload_completed)
4694 rs6000_stack_t *info = rs6000_stack_info ();
4696 if (info->first_gp_reg_save == 32
4697 && info->first_fp_reg_save == 64
4698 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4699 && ! info->lr_save_p
4700 && ! info->cr_save_p
4701 && info->vrsave_mask == 0
4709 /* Return the number of instructions it takes to form a constant in an
4710 integer register. */
4713 num_insns_constant_wide (HOST_WIDE_INT value)
4715 /* signed constant loadable with {cal|addi} */
4716 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4719 /* constant loadable with {cau|addis} */
4720 else if ((value & 0xffff) == 0
4721 && (value >> 31 == -1 || value >> 31 == 0))
4724 #if HOST_BITS_PER_WIDE_INT == 64
4725 else if (TARGET_POWERPC64)
4727 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4728 HOST_WIDE_INT high = value >> 31;
4730 if (high == 0 || high == -1)
4736 return num_insns_constant_wide (high) + 1;
4738 return num_insns_constant_wide (low) + 1;
4740 return (num_insns_constant_wide (high)
4741 + num_insns_constant_wide (low) + 1);
4750 num_insns_constant (rtx op, enum machine_mode mode)
4752 HOST_WIDE_INT low, high;
4754 switch (GET_CODE (op))
4757 #if HOST_BITS_PER_WIDE_INT == 64
4758 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4759 && mask64_operand (op, mode))
4763 return num_insns_constant_wide (INTVAL (op));
4766 if (mode == SFmode || mode == SDmode)
4771 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4772 if (DECIMAL_FLOAT_MODE_P (mode))
4773 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4775 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4776 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4779 if (mode == VOIDmode || mode == DImode)
4781 high = CONST_DOUBLE_HIGH (op);
4782 low = CONST_DOUBLE_LOW (op);
4789 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4790 if (DECIMAL_FLOAT_MODE_P (mode))
4791 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4793 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4794 high = l[WORDS_BIG_ENDIAN == 0];
4795 low = l[WORDS_BIG_ENDIAN != 0];
4799 return (num_insns_constant_wide (low)
4800 + num_insns_constant_wide (high));
4803 if ((high == 0 && low >= 0)
4804 || (high == -1 && low < 0))
4805 return num_insns_constant_wide (low);
4807 else if (mask64_operand (op, mode))
4811 return num_insns_constant_wide (high) + 1;
4814 return (num_insns_constant_wide (high)
4815 + num_insns_constant_wide (low) + 1);
4823 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4824 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4825 corresponding element of the vector, but for V4SFmode and V2SFmode,
4826 the corresponding "float" is interpreted as an SImode integer. */
4829 const_vector_elt_as_int (rtx op, unsigned int elt)
4833 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4834 gcc_assert (GET_MODE (op) != V2DImode
4835 && GET_MODE (op) != V2DFmode);
4837 tmp = CONST_VECTOR_ELT (op, elt);
4838 if (GET_MODE (op) == V4SFmode
4839 || GET_MODE (op) == V2SFmode)
4840 tmp = gen_lowpart (SImode, tmp);
4841 return INTVAL (tmp);
4844 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4845 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4846 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4847 all items are set to the same value and contain COPIES replicas of the
4848 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4849 operand and the others are set to the value of the operand's msb. */
4852 vspltis_constant (rtx op, unsigned step, unsigned copies)
4854 enum machine_mode mode = GET_MODE (op);
4855 enum machine_mode inner = GET_MODE_INNER (mode);
4863 HOST_WIDE_INT splat_val;
4864 HOST_WIDE_INT msb_val;
4866 if (mode == V2DImode || mode == V2DFmode)
4869 nunits = GET_MODE_NUNITS (mode);
4870 bitsize = GET_MODE_BITSIZE (inner);
4871 mask = GET_MODE_MASK (inner);
4873 val = const_vector_elt_as_int (op, nunits - 1);
4875 msb_val = val > 0 ? 0 : -1;
4877 /* Construct the value to be splatted, if possible. If not, return 0. */
4878 for (i = 2; i <= copies; i *= 2)
4880 HOST_WIDE_INT small_val;
4882 small_val = splat_val >> bitsize;
4884 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4886 splat_val = small_val;
4889 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4890 if (EASY_VECTOR_15 (splat_val))
4893 /* Also check if we can splat, and then add the result to itself. Do so if
4894 the value is positive, of if the splat instruction is using OP's mode;
4895 for splat_val < 0, the splat and the add should use the same mode. */
4896 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4897 && (splat_val >= 0 || (step == 1 && copies == 1)))
4900 /* Also check if are loading up the most significant bit which can be done by
4901 loading up -1 and shifting the value left by -1. */
4902 else if (EASY_VECTOR_MSB (splat_val, inner))
4908 /* Check if VAL is present in every STEP-th element, and the
4909 other elements are filled with its most significant bit. */
4910 for (i = 0; i < nunits - 1; ++i)
4912 HOST_WIDE_INT desired_val;
4913 if (((i + 1) & (step - 1)) == 0)
4916 desired_val = msb_val;
4918 if (desired_val != const_vector_elt_as_int (op, i))
4926 /* Return true if OP is of the given MODE and can be synthesized
4927 with a vspltisb, vspltish or vspltisw. */
4930 easy_altivec_constant (rtx op, enum machine_mode mode)
4932 unsigned step, copies;
4934 if (mode == VOIDmode)
4935 mode = GET_MODE (op);
4936 else if (mode != GET_MODE (op))
4939 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4941 if (mode == V2DFmode)
4942 return zero_constant (op, mode);
4944 if (mode == V2DImode)
4946 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4948 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4949 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4952 if (zero_constant (op, mode))
4955 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4956 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4962 /* Start with a vspltisw. */
4963 step = GET_MODE_NUNITS (mode) / 4;
4966 if (vspltis_constant (op, step, copies))
4969 /* Then try with a vspltish. */
4975 if (vspltis_constant (op, step, copies))
4978 /* And finally a vspltisb. */
4984 if (vspltis_constant (op, step, copies))
4990 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4991 result is OP. Abort if it is not possible. */
4994 gen_easy_altivec_constant (rtx op)
4996 enum machine_mode mode = GET_MODE (op);
4997 int nunits = GET_MODE_NUNITS (mode);
4998 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
4999 unsigned step = nunits / 4;
5000 unsigned copies = 1;
5002 /* Start with a vspltisw. */
5003 if (vspltis_constant (op, step, copies))
5004 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5006 /* Then try with a vspltish. */
5012 if (vspltis_constant (op, step, copies))
5013 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5015 /* And finally a vspltisb. */
5021 if (vspltis_constant (op, step, copies))
5022 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5028 output_vec_const_move (rtx *operands)
5031 enum machine_mode mode;
5036 mode = GET_MODE (dest);
5040 if (zero_constant (vec, mode))
5041 return "xxlxor %x0,%x0,%x0";
5043 if (mode == V2DImode
5044 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5045 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5046 return "vspltisw %0,-1";
5052 if (zero_constant (vec, mode))
5053 return "vxor %0,%0,%0";
5055 splat_vec = gen_easy_altivec_constant (vec);
5056 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5057 operands[1] = XEXP (splat_vec, 0);
5058 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5061 switch (GET_MODE (splat_vec))
5064 return "vspltisw %0,%1";
5067 return "vspltish %0,%1";
5070 return "vspltisb %0,%1";
5077 gcc_assert (TARGET_SPE);
5079 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5080 pattern of V1DI, V4HI, and V2SF.
5082 FIXME: We should probably return # and add post reload
5083 splitters for these, but this way is so easy ;-). */
5084 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5085 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5086 operands[1] = CONST_VECTOR_ELT (vec, 0);
5087 operands[2] = CONST_VECTOR_ELT (vec, 1);
5089 return "li %0,%1\n\tevmergelo %0,%0,%0";
5091 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5094 /* Initialize TARGET of vector PAIRED to VALS. */
5097 paired_expand_vector_init (rtx target, rtx vals)
5099 enum machine_mode mode = GET_MODE (target);
5100 int n_elts = GET_MODE_NUNITS (mode);
5102 rtx x, new_rtx, tmp, constant_op, op1, op2;
5105 for (i = 0; i < n_elts; ++i)
5107 x = XVECEXP (vals, 0, i);
5108 if (!CONSTANT_P (x))
5113 /* Load from constant pool. */
5114 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5120 /* The vector is initialized only with non-constants. */
5121 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5122 XVECEXP (vals, 0, 1));
5124 emit_move_insn (target, new_rtx);
5128 /* One field is non-constant and the other one is a constant. Load the
5129 constant from the constant pool and use ps_merge instruction to
5130 construct the whole vector. */
5131 op1 = XVECEXP (vals, 0, 0);
5132 op2 = XVECEXP (vals, 0, 1);
5134 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5136 tmp = gen_reg_rtx (GET_MODE (constant_op));
5137 emit_move_insn (tmp, constant_op);
5139 if (CONSTANT_P (op1))
5140 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5142 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5144 emit_move_insn (target, new_rtx);
5148 paired_expand_vector_move (rtx operands[])
5150 rtx op0 = operands[0], op1 = operands[1];
5152 emit_move_insn (op0, op1);
5155 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5156 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5157 operands for the relation operation COND. This is a recursive
5161 paired_emit_vector_compare (enum rtx_code rcode,
5162 rtx dest, rtx op0, rtx op1,
5163 rtx cc_op0, rtx cc_op1)
5165 rtx tmp = gen_reg_rtx (V2SFmode);
5168 gcc_assert (TARGET_PAIRED_FLOAT);
5169 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5175 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5179 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5180 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5184 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5187 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5190 tmp1 = gen_reg_rtx (V2SFmode);
5191 max = gen_reg_rtx (V2SFmode);
5192 min = gen_reg_rtx (V2SFmode);
5193 gen_reg_rtx (V2SFmode);
5195 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5196 emit_insn (gen_selv2sf4
5197 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5198 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5199 emit_insn (gen_selv2sf4
5200 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5201 emit_insn (gen_subv2sf3 (tmp1, min, max));
5202 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5205 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5208 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5211 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5214 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5217 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5226 /* Emit vector conditional expression.
5227 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5228 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5231 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5232 rtx cond, rtx cc_op0, rtx cc_op1)
5234 enum rtx_code rcode = GET_CODE (cond);
5236 if (!TARGET_PAIRED_FLOAT)
5239 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5244 /* Initialize vector TARGET to VALS. */
5247 rs6000_expand_vector_init (rtx target, rtx vals)
5249 enum machine_mode mode = GET_MODE (target);
5250 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5251 int n_elts = GET_MODE_NUNITS (mode);
5252 int n_var = 0, one_var = -1;
5253 bool all_same = true, all_const_zero = true;
5257 for (i = 0; i < n_elts; ++i)
5259 x = XVECEXP (vals, 0, i);
5260 if (!CONSTANT_P (x))
5261 ++n_var, one_var = i;
5262 else if (x != CONST0_RTX (inner_mode))
5263 all_const_zero = false;
5265 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5271 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5272 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5273 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5275 /* Zero register. */
5276 emit_insn (gen_rtx_SET (VOIDmode, target,
5277 gen_rtx_XOR (mode, target, target)));
5280 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5282 /* Splat immediate. */
5283 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5288 /* Load from constant pool. */
5289 emit_move_insn (target, const_vec);
5294 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5295 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5299 rtx element = XVECEXP (vals, 0, 0);
5300 if (mode == V2DFmode)
5301 emit_insn (gen_vsx_splat_v2df (target, element));
5303 emit_insn (gen_vsx_splat_v2di (target, element));
5307 if (mode == V2DFmode)
5309 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5310 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5311 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5315 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5316 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5317 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5323 /* With single precision floating point on VSX, know that internally single
5324 precision is actually represented as a double, and either make 2 V2DF
5325 vectors, and convert these vectors to single precision, or do one
5326 conversion, and splat the result to the other elements. */
5327 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5331 rtx freg = gen_reg_rtx (V4SFmode);
5332 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5334 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5335 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5339 rtx dbl_even = gen_reg_rtx (V2DFmode);
5340 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5341 rtx flt_even = gen_reg_rtx (V4SFmode);
5342 rtx flt_odd = gen_reg_rtx (V4SFmode);
5344 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5345 copy_to_reg (XVECEXP (vals, 0, 0)),
5346 copy_to_reg (XVECEXP (vals, 0, 1))));
5347 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5348 copy_to_reg (XVECEXP (vals, 0, 2)),
5349 copy_to_reg (XVECEXP (vals, 0, 3))));
5350 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5351 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5352 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5357 /* Store value to stack temp. Load vector element. Splat. However, splat
5358 of 64-bit items is not supported on Altivec. */
5359 if (all_same && GET_MODE_SIZE (mode) <= 4)
5361 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5362 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5363 XVECEXP (vals, 0, 0));
5364 x = gen_rtx_UNSPEC (VOIDmode,
5365 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5366 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5368 gen_rtx_SET (VOIDmode,
5371 x = gen_rtx_VEC_SELECT (inner_mode, target,
5372 gen_rtx_PARALLEL (VOIDmode,
5373 gen_rtvec (1, const0_rtx)));
5374 emit_insn (gen_rtx_SET (VOIDmode, target,
5375 gen_rtx_VEC_DUPLICATE (mode, x)));
5379 /* One field is non-constant. Load constant then overwrite
5383 rtx copy = copy_rtx (vals);
5385 /* Load constant part of vector, substitute neighboring value for
5387 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5388 rs6000_expand_vector_init (target, copy);
5390 /* Insert variable. */
5391 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5395 /* Construct the vector in memory one field at a time
5396 and load the whole vector. */
5397 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5398 for (i = 0; i < n_elts; i++)
5399 emit_move_insn (adjust_address_nv (mem, inner_mode,
5400 i * GET_MODE_SIZE (inner_mode)),
5401 XVECEXP (vals, 0, i));
5402 emit_move_insn (target, mem);
5405 /* Set field ELT of TARGET to VAL. */
5408 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5410 enum machine_mode mode = GET_MODE (target);
5411 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5412 rtx reg = gen_reg_rtx (mode);
5414 int width = GET_MODE_SIZE (inner_mode);
5417 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5419 rtx (*set_func) (rtx, rtx, rtx, rtx)
5420 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5421 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5425 /* Load single variable value. */
5426 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5427 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5428 x = gen_rtx_UNSPEC (VOIDmode,
5429 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5430 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5432 gen_rtx_SET (VOIDmode,
5436 /* Linear sequence. */
5437 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5438 for (i = 0; i < 16; ++i)
5439 XVECEXP (mask, 0, i) = GEN_INT (i);
5441 /* Set permute mask to insert element into target. */
5442 for (i = 0; i < width; ++i)
5443 XVECEXP (mask, 0, elt*width + i)
5444 = GEN_INT (i + 0x10);
5445 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5446 x = gen_rtx_UNSPEC (mode,
5447 gen_rtvec (3, target, reg,
5448 force_reg (V16QImode, x)),
5450 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5453 /* Extract field ELT from VEC into TARGET. */
5456 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5458 enum machine_mode mode = GET_MODE (vec);
5459 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5462 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5464 rtx (*extract_func) (rtx, rtx, rtx)
5465 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5466 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5470 /* Allocate mode-sized buffer. */
5471 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5473 emit_move_insn (mem, vec);
5475 /* Add offset to field within buffer matching vector element. */
5476 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5478 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5481 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5482 implement ANDing by the mask IN. */
5484 build_mask64_2_operands (rtx in, rtx *out)
5486 #if HOST_BITS_PER_WIDE_INT >= 64
5487 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5490 gcc_assert (GET_CODE (in) == CONST_INT);
5495 /* Assume c initially something like 0x00fff000000fffff. The idea
5496 is to rotate the word so that the middle ^^^^^^ group of zeros
5497 is at the MS end and can be cleared with an rldicl mask. We then
5498 rotate back and clear off the MS ^^ group of zeros with a
5500 c = ~c; /* c == 0xff000ffffff00000 */
5501 lsb = c & -c; /* lsb == 0x0000000000100000 */
5502 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5503 c = ~c; /* c == 0x00fff000000fffff */
5504 c &= -lsb; /* c == 0x00fff00000000000 */
5505 lsb = c & -c; /* lsb == 0x0000100000000000 */
5506 c = ~c; /* c == 0xff000fffffffffff */
5507 c &= -lsb; /* c == 0xff00000000000000 */
5509 while ((lsb >>= 1) != 0)
5510 shift++; /* shift == 44 on exit from loop */
5511 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5512 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5513 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5517 /* Assume c initially something like 0xff000f0000000000. The idea
5518 is to rotate the word so that the ^^^ middle group of zeros
5519 is at the LS end and can be cleared with an rldicr mask. We then
5520 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5522 lsb = c & -c; /* lsb == 0x0000010000000000 */
5523 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5524 c = ~c; /* c == 0x00fff0ffffffffff */
5525 c &= -lsb; /* c == 0x00fff00000000000 */
5526 lsb = c & -c; /* lsb == 0x0000100000000000 */
5527 c = ~c; /* c == 0xff000fffffffffff */
5528 c &= -lsb; /* c == 0xff00000000000000 */
5530 while ((lsb >>= 1) != 0)
5531 shift++; /* shift == 44 on exit from loop */
5532 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5533 m1 >>= shift; /* m1 == 0x0000000000000fff */
5534 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5537 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5538 masks will be all 1's. We are guaranteed more than one transition. */
5539 out[0] = GEN_INT (64 - shift);
5540 out[1] = GEN_INT (m1);
5541 out[2] = GEN_INT (shift);
5542 out[3] = GEN_INT (m2);
5550 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5553 invalid_e500_subreg (rtx op, enum machine_mode mode)
5555 if (TARGET_E500_DOUBLE)
5557 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5558 subreg:TI and reg:TF. Decimal float modes are like integer
5559 modes (only low part of each register used) for this
5561 if (GET_CODE (op) == SUBREG
5562 && (mode == SImode || mode == DImode || mode == TImode
5563 || mode == DDmode || mode == TDmode)
5564 && REG_P (SUBREG_REG (op))
5565 && (GET_MODE (SUBREG_REG (op)) == DFmode
5566 || GET_MODE (SUBREG_REG (op)) == TFmode))
5569 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5571 if (GET_CODE (op) == SUBREG
5572 && (mode == DFmode || mode == TFmode)
5573 && REG_P (SUBREG_REG (op))
5574 && (GET_MODE (SUBREG_REG (op)) == DImode
5575 || GET_MODE (SUBREG_REG (op)) == TImode
5576 || GET_MODE (SUBREG_REG (op)) == DDmode
5577 || GET_MODE (SUBREG_REG (op)) == TDmode))
5582 && GET_CODE (op) == SUBREG
5584 && REG_P (SUBREG_REG (op))
5585 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5591 /* AIX increases natural record alignment to doubleword if the first
5592 field is an FP double while the FP fields remain word aligned. */
5595 rs6000_special_round_type_align (tree type, unsigned int computed,
5596 unsigned int specified)
5598 unsigned int align = MAX (computed, specified);
5599 tree field = TYPE_FIELDS (type);
5601 /* Skip all non field decls */
5602 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5603 field = DECL_CHAIN (field);
5605 if (field != NULL && field != type)
5607 type = TREE_TYPE (field);
5608 while (TREE_CODE (type) == ARRAY_TYPE)
5609 type = TREE_TYPE (type);
5611 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5612 align = MAX (align, 64);
5618 /* Darwin increases record alignment to the natural alignment of
5622 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5623 unsigned int specified)
5625 unsigned int align = MAX (computed, specified);
5627 if (TYPE_PACKED (type))
5630 /* Find the first field, looking down into aggregates. */
5632 tree field = TYPE_FIELDS (type);
5633 /* Skip all non field decls */
5634 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5635 field = DECL_CHAIN (field);
5638 /* A packed field does not contribute any extra alignment. */
5639 if (DECL_PACKED (field))
5641 type = TREE_TYPE (field);
5642 while (TREE_CODE (type) == ARRAY_TYPE)
5643 type = TREE_TYPE (type);
5644 } while (AGGREGATE_TYPE_P (type));
5646 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5647 align = MAX (align, TYPE_ALIGN (type));
5652 /* Return 1 for an operand in small memory on V.4/eabi. */
5655 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5656 enum machine_mode mode ATTRIBUTE_UNUSED)
5661 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5664 if (DEFAULT_ABI != ABI_V4)
5667 /* Vector and float memory instructions have a limited offset on the
5668 SPE, so using a vector or float variable directly as an operand is
5671 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5674 if (GET_CODE (op) == SYMBOL_REF)
5677 else if (GET_CODE (op) != CONST
5678 || GET_CODE (XEXP (op, 0)) != PLUS
5679 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5680 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5685 rtx sum = XEXP (op, 0);
5686 HOST_WIDE_INT summand;
5688 /* We have to be careful here, because it is the referenced address
5689 that must be 32k from _SDA_BASE_, not just the symbol. */
5690 summand = INTVAL (XEXP (sum, 1));
5691 if (summand < 0 || summand > g_switch_value)
5694 sym_ref = XEXP (sum, 0);
5697 return SYMBOL_REF_SMALL_P (sym_ref);
5703 /* Return true if either operand is a general purpose register. */
5706 gpr_or_gpr_p (rtx op0, rtx op1)
5708 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5709 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5713 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5716 reg_offset_addressing_ok_p (enum machine_mode mode)
5726 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5727 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5735 /* Paired vector modes. Only reg+reg addressing is valid. */
5736 if (TARGET_PAIRED_FLOAT)
5748 virtual_stack_registers_memory_p (rtx op)
5752 if (GET_CODE (op) == REG)
5753 regnum = REGNO (op);
5755 else if (GET_CODE (op) == PLUS
5756 && GET_CODE (XEXP (op, 0)) == REG
5757 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5758 regnum = REGNO (XEXP (op, 0));
5763 return (regnum >= FIRST_VIRTUAL_REGISTER
5764 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5767 /* Return true if memory accesses to OP are known to never straddle
5771 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5772 enum machine_mode mode)
5775 unsigned HOST_WIDE_INT dsize, dalign;
5777 if (GET_CODE (op) != SYMBOL_REF)
5780 decl = SYMBOL_REF_DECL (op);
5783 if (GET_MODE_SIZE (mode) == 0)
5786 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5787 replacing memory addresses with an anchor plus offset. We
5788 could find the decl by rummaging around in the block->objects
5789 VEC for the given offset but that seems like too much work. */
5791 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5792 && SYMBOL_REF_ANCHOR_P (op)
5793 && SYMBOL_REF_BLOCK (op) != NULL)
5795 struct object_block *block = SYMBOL_REF_BLOCK (op);
5796 HOST_WIDE_INT lsb, mask;
5798 /* Given the alignment of the block.. */
5799 dalign = block->alignment;
5800 mask = dalign / BITS_PER_UNIT - 1;
5802 /* ..and the combined offset of the anchor and any offset
5803 to this block object.. */
5804 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5805 lsb = offset & -offset;
5807 /* ..find how many bits of the alignment we know for the
5812 return dalign >= GET_MODE_SIZE (mode);
5817 if (TREE_CODE (decl) == FUNCTION_DECL)
5820 if (!DECL_SIZE_UNIT (decl))
5823 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5826 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5830 dalign = DECL_ALIGN_UNIT (decl);
5831 return dalign >= dsize;
5834 type = TREE_TYPE (decl);
5836 if (TREE_CODE (decl) == STRING_CST)
5837 dsize = TREE_STRING_LENGTH (decl);
5838 else if (TYPE_SIZE_UNIT (type)
5839 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5840 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5846 dalign = TYPE_ALIGN (type);
5847 if (CONSTANT_CLASS_P (decl))
5848 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5850 dalign = DATA_ALIGNMENT (decl, dalign);
5851 dalign /= BITS_PER_UNIT;
5852 return dalign >= dsize;
5856 constant_pool_expr_p (rtx op)
5860 split_const (op, &base, &offset);
5861 return (GET_CODE (base) == SYMBOL_REF
5862 && CONSTANT_POOL_ADDRESS_P (base)
5863 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5866 static rtx tocrel_base, tocrel_offset;
5869 toc_relative_expr_p (rtx op)
5871 if (GET_CODE (op) != CONST)
5874 split_const (op, &tocrel_base, &tocrel_offset);
5875 return (GET_CODE (tocrel_base) == UNSPEC
5876 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5879 /* Return true if X is a constant pool address, and also for cmodel=medium
5880 if X is a toc-relative address known to be offsettable within MODE. */
5883 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5887 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5888 && GET_CODE (XEXP (x, 0)) == REG
5889 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5890 || ((TARGET_MINIMAL_TOC
5891 || TARGET_CMODEL != CMODEL_SMALL)
5892 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5893 && toc_relative_expr_p (XEXP (x, 1))
5894 && (TARGET_CMODEL != CMODEL_MEDIUM
5895 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5897 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5898 INTVAL (tocrel_offset), mode)));
5902 legitimate_small_data_p (enum machine_mode mode, rtx x)
5904 return (DEFAULT_ABI == ABI_V4
5905 && !flag_pic && !TARGET_TOC
5906 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5907 && small_data_operand (x, mode));
5910 /* SPE offset addressing is limited to 5-bits worth of double words. */
5911 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5914 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5916 unsigned HOST_WIDE_INT offset, extra;
5918 if (GET_CODE (x) != PLUS)
5920 if (GET_CODE (XEXP (x, 0)) != REG)
5922 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5924 if (!reg_offset_addressing_ok_p (mode))
5925 return virtual_stack_registers_memory_p (x);
5926 if (legitimate_constant_pool_address_p (x, mode, strict))
5928 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5931 offset = INTVAL (XEXP (x, 1));
5939 /* SPE vector modes. */
5940 return SPE_CONST_OFFSET_OK (offset);
5943 if (TARGET_E500_DOUBLE)
5944 return SPE_CONST_OFFSET_OK (offset);
5946 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5948 if (VECTOR_MEM_VSX_P (DFmode))
5953 /* On e500v2, we may have:
5955 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5957 Which gets addressed with evldd instructions. */
5958 if (TARGET_E500_DOUBLE)
5959 return SPE_CONST_OFFSET_OK (offset);
5961 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5963 else if (offset & 3)
5968 if (TARGET_E500_DOUBLE)
5969 return (SPE_CONST_OFFSET_OK (offset)
5970 && SPE_CONST_OFFSET_OK (offset + 8));
5974 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5976 else if (offset & 3)
5987 return (offset < 0x10000) && (offset + extra < 0x10000);
5991 legitimate_indexed_address_p (rtx x, int strict)
5995 if (GET_CODE (x) != PLUS)
6001 /* Recognize the rtl generated by reload which we know will later be
6002 replaced with proper base and index regs. */
6004 && reload_in_progress
6005 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6009 return (REG_P (op0) && REG_P (op1)
6010 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6011 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6012 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6013 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6017 avoiding_indexed_address_p (enum machine_mode mode)
6019 /* Avoid indexed addressing for modes that have non-indexed
6020 load/store instruction forms. */
6021 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6025 legitimate_indirect_address_p (rtx x, int strict)
6027 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6031 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6033 if (!TARGET_MACHO || !flag_pic
6034 || mode != SImode || GET_CODE (x) != MEM)
6038 if (GET_CODE (x) != LO_SUM)
6040 if (GET_CODE (XEXP (x, 0)) != REG)
6042 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6046 return CONSTANT_P (x);
6050 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6052 if (GET_CODE (x) != LO_SUM)
6054 if (GET_CODE (XEXP (x, 0)) != REG)
6056 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6058 /* Restrict addressing for DI because of our SUBREG hackery. */
6059 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6060 || mode == DDmode || mode == TDmode
6065 if (TARGET_ELF || TARGET_MACHO)
6067 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6071 if (GET_MODE_NUNITS (mode) != 1)
6073 if (GET_MODE_BITSIZE (mode) > 64
6074 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6075 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6076 && (mode == DFmode || mode == DDmode))))
6079 return CONSTANT_P (x);
6086 /* Try machine-dependent ways of modifying an illegitimate address
6087 to be legitimate. If we find one, return the new, valid address.
6088 This is used from only one place: `memory_address' in explow.c.
6090 OLDX is the address as it was before break_out_memory_refs was
6091 called. In some cases it is useful to look at this to decide what
6094 It is always safe for this function to do nothing. It exists to
6095 recognize opportunities to optimize the output.
6097 On RS/6000, first check for the sum of a register with a constant
6098 integer that is out of range. If so, generate code to add the
6099 constant with the low-order 16 bits masked to the register and force
6100 this result into another register (this can be done with `cau').
6101 Then generate an address of REG+(CONST&0xffff), allowing for the
6102 possibility of bit 16 being a one.
6104 Then check for the sum of a register and something not constant, try to
6105 load the other things into a register and return the sum. */
6108 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6109 enum machine_mode mode)
6111 unsigned int extra = 0;
6113 if (!reg_offset_addressing_ok_p (mode))
6115 if (virtual_stack_registers_memory_p (x))
6118 /* In theory we should not be seeing addresses of the form reg+0,
6119 but just in case it is generated, optimize it away. */
6120 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6121 return force_reg (Pmode, XEXP (x, 0));
6123 /* Make sure both operands are registers. */
6124 else if (GET_CODE (x) == PLUS)
6125 return gen_rtx_PLUS (Pmode,
6126 force_reg (Pmode, XEXP (x, 0)),
6127 force_reg (Pmode, XEXP (x, 1)));
6129 return force_reg (Pmode, x);
6131 if (GET_CODE (x) == SYMBOL_REF)
6133 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6135 return rs6000_legitimize_tls_address (x, model);
6145 if (!TARGET_POWERPC64)
6153 extra = TARGET_POWERPC64 ? 8 : 12;
6159 if (GET_CODE (x) == PLUS
6160 && GET_CODE (XEXP (x, 0)) == REG
6161 && GET_CODE (XEXP (x, 1)) == CONST_INT
6162 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6164 && !((TARGET_POWERPC64
6165 && (mode == DImode || mode == TImode)
6166 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6167 || SPE_VECTOR_MODE (mode)
6168 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6169 || mode == DImode || mode == DDmode
6170 || mode == TDmode))))
6172 HOST_WIDE_INT high_int, low_int;
6174 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6175 if (low_int >= 0x8000 - extra)
6177 high_int = INTVAL (XEXP (x, 1)) - low_int;
6178 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6179 GEN_INT (high_int)), 0);
6180 return plus_constant (sum, low_int);
6182 else if (GET_CODE (x) == PLUS
6183 && GET_CODE (XEXP (x, 0)) == REG
6184 && GET_CODE (XEXP (x, 1)) != CONST_INT
6185 && GET_MODE_NUNITS (mode) == 1
6186 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6188 || ((mode != DImode && mode != DFmode && mode != DDmode)
6189 || (TARGET_E500_DOUBLE && mode != DDmode)))
6190 && (TARGET_POWERPC64 || mode != DImode)
6191 && !avoiding_indexed_address_p (mode)
6196 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6197 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6199 else if (SPE_VECTOR_MODE (mode)
6200 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6201 || mode == DDmode || mode == TDmode
6202 || mode == DImode)))
6206 /* We accept [reg + reg] and [reg + OFFSET]. */
6208 if (GET_CODE (x) == PLUS)
6210 rtx op1 = XEXP (x, 0);
6211 rtx op2 = XEXP (x, 1);
6214 op1 = force_reg (Pmode, op1);
6216 if (GET_CODE (op2) != REG
6217 && (GET_CODE (op2) != CONST_INT
6218 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6219 || (GET_MODE_SIZE (mode) > 8
6220 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6221 op2 = force_reg (Pmode, op2);
6223 /* We can't always do [reg + reg] for these, because [reg +
6224 reg + offset] is not a legitimate addressing mode. */
6225 y = gen_rtx_PLUS (Pmode, op1, op2);
6227 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6228 return force_reg (Pmode, y);
6233 return force_reg (Pmode, x);
6239 && GET_CODE (x) != CONST_INT
6240 && GET_CODE (x) != CONST_DOUBLE
6242 && GET_MODE_NUNITS (mode) == 1
6243 && (GET_MODE_BITSIZE (mode) <= 32
6244 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6245 && (mode == DFmode || mode == DDmode))))
6247 rtx reg = gen_reg_rtx (Pmode);
6248 emit_insn (gen_elf_high (reg, x));
6249 return gen_rtx_LO_SUM (Pmode, reg, x);
6251 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6254 && ! MACHO_DYNAMIC_NO_PIC_P
6256 && GET_CODE (x) != CONST_INT
6257 && GET_CODE (x) != CONST_DOUBLE
6259 && GET_MODE_NUNITS (mode) == 1
6260 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6261 || (mode != DFmode && mode != DDmode))
6265 rtx reg = gen_reg_rtx (Pmode);
6266 emit_insn (gen_macho_high (reg, x));
6267 return gen_rtx_LO_SUM (Pmode, reg, x);
6270 && GET_CODE (x) == SYMBOL_REF
6271 && constant_pool_expr_p (x)
6272 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6274 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6275 return create_TOC_reference (x, reg);
6281 /* Debug version of rs6000_legitimize_address. */
6283 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6289 ret = rs6000_legitimize_address (x, oldx, mode);
6290 insns = get_insns ();
6296 "\nrs6000_legitimize_address: mode %s, old code %s, "
6297 "new code %s, modified\n",
6298 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6299 GET_RTX_NAME (GET_CODE (ret)));
6301 fprintf (stderr, "Original address:\n");
6304 fprintf (stderr, "oldx:\n");
6307 fprintf (stderr, "New address:\n");
6312 fprintf (stderr, "Insns added:\n");
6313 debug_rtx_list (insns, 20);
6319 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6320 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6331 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6332 We need to emit DTP-relative relocations. */
6335 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6340 fputs ("\t.long\t", file);
6343 fputs (DOUBLE_INT_ASM_OP, file);
6348 output_addr_const (file, x);
6349 fputs ("@dtprel+0x8000", file);
6352 /* In the name of slightly smaller debug output, and to cater to
6353 general assembler lossage, recognize various UNSPEC sequences
6354 and turn them back into a direct symbol reference. */
6357 rs6000_delegitimize_address (rtx orig_x)
6361 orig_x = delegitimize_mem_from_attrs (orig_x);
6366 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6367 && GET_CODE (XEXP (x, 1)) == CONST)
6369 y = XEXP (XEXP (x, 1), 0);
6370 if (GET_CODE (y) == UNSPEC
6371 && XINT (y, 1) == UNSPEC_TOCREL
6372 && ((GET_CODE (XEXP (x, 0)) == REG
6373 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6374 || TARGET_MINIMAL_TOC
6375 || TARGET_CMODEL != CMODEL_SMALL))
6376 || (TARGET_CMODEL != CMODEL_SMALL
6377 && GET_CODE (XEXP (x, 0)) == PLUS
6378 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6379 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6380 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6381 && rtx_equal_p (XEXP (x, 1),
6382 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6384 y = XVECEXP (y, 0, 0);
6385 if (!MEM_P (orig_x))
6388 return replace_equiv_address_nv (orig_x, y);
6393 && GET_CODE (orig_x) == LO_SUM
6394 && GET_CODE (XEXP (x, 1)) == CONST)
6396 y = XEXP (XEXP (x, 1), 0);
6397 if (GET_CODE (y) == UNSPEC
6398 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6399 return XVECEXP (y, 0, 0);
6405 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6407 static GTY(()) rtx rs6000_tls_symbol;
6409 rs6000_tls_get_addr (void)
6411 if (!rs6000_tls_symbol)
6412 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6414 return rs6000_tls_symbol;
6417 /* Construct the SYMBOL_REF for TLS GOT references. */
6419 static GTY(()) rtx rs6000_got_symbol;
6421 rs6000_got_sym (void)
6423 if (!rs6000_got_symbol)
6425 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6426 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6427 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6430 return rs6000_got_symbol;
6433 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6434 this (thread-local) address. */
6437 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6441 dest = gen_reg_rtx (Pmode);
6442 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6448 tlsreg = gen_rtx_REG (Pmode, 13);
6449 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6453 tlsreg = gen_rtx_REG (Pmode, 2);
6454 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6458 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6462 tmp = gen_reg_rtx (Pmode);
6465 tlsreg = gen_rtx_REG (Pmode, 13);
6466 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6470 tlsreg = gen_rtx_REG (Pmode, 2);
6471 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6475 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6477 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6482 rtx r3, got, tga, tmp1, tmp2, call_insn;
6484 /* We currently use relocations like @got@tlsgd for tls, which
6485 means the linker will handle allocation of tls entries, placing
6486 them in the .got section. So use a pointer to the .got section,
6487 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6488 or to secondary GOT sections used by 32-bit -fPIC. */
6490 got = gen_rtx_REG (Pmode, 2);
6494 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6497 rtx gsym = rs6000_got_sym ();
6498 got = gen_reg_rtx (Pmode);
6500 rs6000_emit_move (got, gsym, Pmode);
6505 tmp1 = gen_reg_rtx (Pmode);
6506 tmp2 = gen_reg_rtx (Pmode);
6507 mem = gen_const_mem (Pmode, tmp1);
6508 lab = gen_label_rtx ();
6509 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6510 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6511 emit_move_insn (tmp2, mem);
6512 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6513 set_unique_reg_note (last, REG_EQUAL, gsym);
6518 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6520 r3 = gen_rtx_REG (Pmode, 3);
6521 tga = rs6000_tls_get_addr ();
6522 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6524 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6525 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6526 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6527 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6528 else if (DEFAULT_ABI == ABI_V4)
6529 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6532 call_insn = last_call_insn ();
6533 PATTERN (call_insn) = insn;
6534 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6535 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6536 pic_offset_table_rtx);
6538 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6540 r3 = gen_rtx_REG (Pmode, 3);
6541 tga = rs6000_tls_get_addr ();
6542 tmp1 = gen_reg_rtx (Pmode);
6543 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6545 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6546 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6547 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6548 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6549 else if (DEFAULT_ABI == ABI_V4)
6550 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6553 call_insn = last_call_insn ();
6554 PATTERN (call_insn) = insn;
6555 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6556 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6557 pic_offset_table_rtx);
6559 if (rs6000_tls_size == 16)
6562 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6564 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6566 else if (rs6000_tls_size == 32)
6568 tmp2 = gen_reg_rtx (Pmode);
6570 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6572 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6575 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6577 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6581 tmp2 = gen_reg_rtx (Pmode);
6583 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6585 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6587 insn = gen_rtx_SET (Pmode, dest,
6588 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6594 /* IE, or 64-bit offset LE. */
6595 tmp2 = gen_reg_rtx (Pmode);
6597 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6599 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6602 insn = gen_tls_tls_64 (dest, tmp2, addr);
6604 insn = gen_tls_tls_32 (dest, tmp2, addr);
6612 /* Return 1 if X contains a thread-local symbol. */
6615 rs6000_tls_referenced_p (rtx x)
6617 if (! TARGET_HAVE_TLS)
6620 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6623 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6626 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6628 return rs6000_tls_referenced_p (x);
6631 /* Return 1 if *X is a thread-local symbol. This is the same as
6632 rs6000_tls_symbol_ref except for the type of the unused argument. */
6635 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6637 return RS6000_SYMBOL_REF_TLS_P (*x);
6640 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6641 replace the input X, or the original X if no replacement is called for.
6642 The output parameter *WIN is 1 if the calling macro should goto WIN,
6645 For RS/6000, we wish to handle large displacements off a base
6646 register by splitting the addend across an addiu/addis and the mem insn.
6647 This cuts number of extra insns needed from 3 to 1.
6649 On Darwin, we use this to generate code for floating point constants.
6650 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6651 The Darwin code is inside #if TARGET_MACHO because only then are the
6652 machopic_* functions defined. */
6654 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6655 int opnum, int type,
6656 int ind_levels ATTRIBUTE_UNUSED, int *win)
6658 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6660 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6661 DFmode/DImode MEM. */
6664 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6665 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6666 reg_offset_p = false;
6668 /* We must recognize output that we have already generated ourselves. */
6669 if (GET_CODE (x) == PLUS
6670 && GET_CODE (XEXP (x, 0)) == PLUS
6671 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6672 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6673 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6675 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6676 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6677 opnum, (enum reload_type)type);
6682 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6683 if (GET_CODE (x) == LO_SUM
6684 && GET_CODE (XEXP (x, 0)) == HIGH)
6686 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6687 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6688 opnum, (enum reload_type)type);
6694 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6695 && GET_CODE (x) == LO_SUM
6696 && GET_CODE (XEXP (x, 0)) == PLUS
6697 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6698 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6699 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6700 && machopic_operand_p (XEXP (x, 1)))
6702 /* Result of previous invocation of this function on Darwin
6703 floating point constant. */
6704 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6705 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6706 opnum, (enum reload_type)type);
6712 if (TARGET_CMODEL != CMODEL_SMALL
6713 && GET_CODE (x) == LO_SUM
6714 && GET_CODE (XEXP (x, 0)) == PLUS
6715 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6716 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6717 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6718 && GET_CODE (XEXP (x, 1)) == CONST
6719 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6720 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6721 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6723 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6724 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6725 opnum, (enum reload_type) type);
6730 /* Force ld/std non-word aligned offset into base register by wrapping
6732 if (GET_CODE (x) == PLUS
6733 && GET_CODE (XEXP (x, 0)) == REG
6734 && REGNO (XEXP (x, 0)) < 32
6735 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6736 && GET_CODE (XEXP (x, 1)) == CONST_INT
6738 && (INTVAL (XEXP (x, 1)) & 3) != 0
6739 && VECTOR_MEM_NONE_P (mode)
6740 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6741 && TARGET_POWERPC64)
6743 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6744 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6745 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6746 opnum, (enum reload_type) type);
6751 if (GET_CODE (x) == PLUS
6752 && GET_CODE (XEXP (x, 0)) == REG
6753 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6754 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6755 && GET_CODE (XEXP (x, 1)) == CONST_INT
6757 && !SPE_VECTOR_MODE (mode)
6758 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6759 || mode == DDmode || mode == TDmode
6761 && VECTOR_MEM_NONE_P (mode))
6763 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6764 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6766 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6768 /* Check for 32-bit overflow. */
6769 if (high + low != val)
6775 /* Reload the high part into a base reg; leave the low part
6776 in the mem directly. */
6778 x = gen_rtx_PLUS (GET_MODE (x),
6779 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6783 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6784 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6785 opnum, (enum reload_type)type);
6790 if (GET_CODE (x) == SYMBOL_REF
6792 && VECTOR_MEM_NONE_P (mode)
6793 && !SPE_VECTOR_MODE (mode)
6795 && DEFAULT_ABI == ABI_DARWIN
6796 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6798 && DEFAULT_ABI == ABI_V4
6801 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6802 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6806 && (mode != DImode || TARGET_POWERPC64)
6807 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6808 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6813 rtx offset = machopic_gen_offset (x);
6814 x = gen_rtx_LO_SUM (GET_MODE (x),
6815 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6816 gen_rtx_HIGH (Pmode, offset)), offset);
6820 x = gen_rtx_LO_SUM (GET_MODE (x),
6821 gen_rtx_HIGH (Pmode, x), x);
6823 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6824 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6825 opnum, (enum reload_type)type);
6830 /* Reload an offset address wrapped by an AND that represents the
6831 masking of the lower bits. Strip the outer AND and let reload
6832 convert the offset address into an indirect address. For VSX,
6833 force reload to create the address with an AND in a separate
6834 register, because we can't guarantee an altivec register will
6836 if (VECTOR_MEM_ALTIVEC_P (mode)
6837 && GET_CODE (x) == AND
6838 && GET_CODE (XEXP (x, 0)) == PLUS
6839 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6840 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6841 && GET_CODE (XEXP (x, 1)) == CONST_INT
6842 && INTVAL (XEXP (x, 1)) == -16)
6851 && GET_CODE (x) == SYMBOL_REF
6852 && constant_pool_expr_p (x)
6853 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6855 x = create_TOC_reference (x, NULL_RTX);
6856 if (TARGET_CMODEL != CMODEL_SMALL)
6857 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6858 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6859 opnum, (enum reload_type) type);
6867 /* Debug version of rs6000_legitimize_reload_address. */
6869 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6870 int opnum, int type,
6871 int ind_levels, int *win)
6873 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6876 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6877 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6878 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6882 fprintf (stderr, "Same address returned\n");
6884 fprintf (stderr, "NULL returned\n");
6887 fprintf (stderr, "New address:\n");
6894 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6895 that is a valid memory address for an instruction.
6896 The MODE argument is the machine mode for the MEM expression
6897 that wants to use this address.
6899 On the RS/6000, there are four valid address: a SYMBOL_REF that
6900 refers to a constant pool entry of an address (or the sum of it
6901 plus a constant), a short (16-bit signed) constant plus a register,
6902 the sum of two registers, or a register indirect, possibly with an
6903 auto-increment. For DFmode, DDmode and DImode with a constant plus
6904 register, we must ensure that both words are addressable or PowerPC64
6905 with offset word aligned.
6907 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6908 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6909 because adjacent memory cells are accessed by adding word-sized offsets
6910 during assembly output. */
6912 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6914 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6916 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6917 if (VECTOR_MEM_ALTIVEC_P (mode)
6918 && GET_CODE (x) == AND
6919 && GET_CODE (XEXP (x, 1)) == CONST_INT
6920 && INTVAL (XEXP (x, 1)) == -16)
6923 if (RS6000_SYMBOL_REF_TLS_P (x))
6925 if (legitimate_indirect_address_p (x, reg_ok_strict))
6927 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6928 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6929 && !SPE_VECTOR_MODE (mode)
6932 /* Restrict addressing for DI because of our SUBREG hackery. */
6933 && !(TARGET_E500_DOUBLE
6934 && (mode == DFmode || mode == DDmode || mode == DImode))
6936 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6938 if (virtual_stack_registers_memory_p (x))
6940 if (reg_offset_p && legitimate_small_data_p (mode, x))
6943 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6945 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6948 && GET_CODE (x) == PLUS
6949 && GET_CODE (XEXP (x, 0)) == REG
6950 && (XEXP (x, 0) == virtual_stack_vars_rtx
6951 || XEXP (x, 0) == arg_pointer_rtx)
6952 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6954 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6959 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6961 || (mode != DFmode && mode != DDmode)
6962 || (TARGET_E500_DOUBLE && mode != DDmode))
6963 && (TARGET_POWERPC64 || mode != DImode)
6964 && !avoiding_indexed_address_p (mode)
6965 && legitimate_indexed_address_p (x, reg_ok_strict))
6967 if (GET_CODE (x) == PRE_MODIFY
6971 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6973 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6974 && (TARGET_POWERPC64 || mode != DImode)
6975 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6976 && !SPE_VECTOR_MODE (mode)
6977 /* Restrict addressing for DI because of our SUBREG hackery. */
6978 && !(TARGET_E500_DOUBLE
6979 && (mode == DFmode || mode == DDmode || mode == DImode))
6981 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6982 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6983 || (!avoiding_indexed_address_p (mode)
6984 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6985 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6987 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6992 /* Debug version of rs6000_legitimate_address_p. */
6994 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
6997 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
6999 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7000 "strict = %d, code = %s\n",
7001 ret ? "true" : "false",
7002 GET_MODE_NAME (mode),
7004 GET_RTX_NAME (GET_CODE (x)));
7010 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7013 rs6000_mode_dependent_address_p (const_rtx addr)
7015 return rs6000_mode_dependent_address_ptr (addr);
7018 /* Go to LABEL if ADDR (a legitimate address expression)
7019 has an effect that depends on the machine mode it is used for.
7021 On the RS/6000 this is true of all integral offsets (since AltiVec
7022 and VSX modes don't allow them) or is a pre-increment or decrement.
7024 ??? Except that due to conceptual problems in offsettable_address_p
7025 we can't really report the problems of integral offsets. So leave
7026 this assuming that the adjustable offset must be valid for the
7027 sub-words of a TFmode operand, which is what we had before. */
7030 rs6000_mode_dependent_address (const_rtx addr)
7032 switch (GET_CODE (addr))
7035 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7036 is considered a legitimate address before reload, so there
7037 are no offset restrictions in that case. Note that this
7038 condition is safe in strict mode because any address involving
7039 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7040 been rejected as illegitimate. */
7041 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7042 && XEXP (addr, 0) != arg_pointer_rtx
7043 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7045 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7046 return val + 12 + 0x8000 >= 0x10000;
7051 /* Anything in the constant pool is sufficiently aligned that
7052 all bytes have the same high part address. */
7053 return !legitimate_constant_pool_address_p (addr, QImode, false);
7055 /* Auto-increment cases are now treated generically in recog.c. */
7057 return TARGET_UPDATE;
7059 /* AND is only allowed in Altivec loads. */
7070 /* Debug version of rs6000_mode_dependent_address. */
7072 rs6000_debug_mode_dependent_address (const_rtx addr)
7074 bool ret = rs6000_mode_dependent_address (addr);
7076 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7077 ret ? "true" : "false");
7083 /* Implement FIND_BASE_TERM. */
7086 rs6000_find_base_term (rtx op)
7090 split_const (op, &base, &offset);
7091 if (GET_CODE (base) == UNSPEC)
7092 switch (XINT (base, 1))
7095 case UNSPEC_MACHOPIC_OFFSET:
7096 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7097 for aliasing purposes. */
7098 return XVECEXP (base, 0, 0);
7104 /* More elaborate version of recog's offsettable_memref_p predicate
7105 that works around the ??? note of rs6000_mode_dependent_address.
7106 In particular it accepts
7108 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7110 in 32-bit mode, that the recog predicate rejects. */
7113 rs6000_offsettable_memref_p (rtx op)
7118 /* First mimic offsettable_memref_p. */
7119 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7122 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7123 the latter predicate knows nothing about the mode of the memory
7124 reference and, therefore, assumes that it is the largest supported
7125 mode (TFmode). As a consequence, legitimate offsettable memory
7126 references are rejected. rs6000_legitimate_offset_address_p contains
7127 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7128 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7131 /* Change register usage conditional on target flags. */
7133 rs6000_conditional_register_usage (void)
7137 if (TARGET_DEBUG_TARGET)
7138 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7140 /* Set MQ register fixed (already call_used) if not POWER
7141 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7146 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7148 fixed_regs[13] = call_used_regs[13]
7149 = call_really_used_regs[13] = 1;
7151 /* Conditionally disable FPRs. */
7152 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7153 for (i = 32; i < 64; i++)
7154 fixed_regs[i] = call_used_regs[i]
7155 = call_really_used_regs[i] = 1;
7157 /* The TOC register is not killed across calls in a way that is
7158 visible to the compiler. */
7159 if (DEFAULT_ABI == ABI_AIX)
7160 call_really_used_regs[2] = 0;
7162 if (DEFAULT_ABI == ABI_V4
7163 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7165 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7167 if (DEFAULT_ABI == ABI_V4
7168 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7170 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7171 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7172 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7174 if (DEFAULT_ABI == ABI_DARWIN
7175 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7176 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7177 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7178 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7180 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7181 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7182 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7186 global_regs[SPEFSCR_REGNO] = 1;
7187 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7188 registers in prologues and epilogues. We no longer use r14
7189 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7190 pool for link-compatibility with older versions of GCC. Once
7191 "old" code has died out, we can return r14 to the allocation
7194 = call_used_regs[14]
7195 = call_really_used_regs[14] = 1;
7198 if (!TARGET_ALTIVEC && !TARGET_VSX)
7200 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7201 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7202 call_really_used_regs[VRSAVE_REGNO] = 1;
7205 if (TARGET_ALTIVEC || TARGET_VSX)
7206 global_regs[VSCR_REGNO] = 1;
7208 if (TARGET_ALTIVEC_ABI)
7210 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7211 call_used_regs[i] = call_really_used_regs[i] = 1;
7213 /* AIX reserves VR20:31 in non-extended ABI mode. */
7215 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7216 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7220 /* Try to output insns to set TARGET equal to the constant C if it can
7221 be done in less than N insns. Do all computations in MODE.
7222 Returns the place where the output has been placed if it can be
7223 done and the insns have been emitted. If it would take more than N
7224 insns, zero is returned and no insns and emitted. */
7227 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7228 rtx source, int n ATTRIBUTE_UNUSED)
7230 rtx result, insn, set;
7231 HOST_WIDE_INT c0, c1;
7238 dest = gen_reg_rtx (mode);
7239 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7243 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7245 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7246 GEN_INT (INTVAL (source)
7247 & (~ (HOST_WIDE_INT) 0xffff))));
7248 emit_insn (gen_rtx_SET (VOIDmode, dest,
7249 gen_rtx_IOR (SImode, copy_rtx (result),
7250 GEN_INT (INTVAL (source) & 0xffff))));
7255 switch (GET_CODE (source))
7258 c0 = INTVAL (source);
7263 #if HOST_BITS_PER_WIDE_INT >= 64
7264 c0 = CONST_DOUBLE_LOW (source);
7267 c0 = CONST_DOUBLE_LOW (source);
7268 c1 = CONST_DOUBLE_HIGH (source);
7276 result = rs6000_emit_set_long_const (dest, c0, c1);
7283 insn = get_last_insn ();
7284 set = single_set (insn);
7285 if (! CONSTANT_P (SET_SRC (set)))
7286 set_unique_reg_note (insn, REG_EQUAL, source);
7291 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7292 fall back to a straight forward decomposition. We do this to avoid
7293 exponential run times encountered when looking for longer sequences
7294 with rs6000_emit_set_const. */
7296 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7298 if (!TARGET_POWERPC64)
7300 rtx operand1, operand2;
7302 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7304 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7306 emit_move_insn (operand1, GEN_INT (c1));
7307 emit_move_insn (operand2, GEN_INT (c2));
7311 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7314 ud2 = (c1 & 0xffff0000) >> 16;
7315 #if HOST_BITS_PER_WIDE_INT >= 64
7319 ud4 = (c2 & 0xffff0000) >> 16;
7321 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7322 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7325 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7327 emit_move_insn (dest, GEN_INT (ud1));
7330 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7331 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7334 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7337 emit_move_insn (dest, GEN_INT (ud2 << 16));
7339 emit_move_insn (copy_rtx (dest),
7340 gen_rtx_IOR (DImode, copy_rtx (dest),
7343 else if (ud3 == 0 && ud4 == 0)
7345 gcc_assert (ud2 & 0x8000);
7346 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7349 emit_move_insn (copy_rtx (dest),
7350 gen_rtx_IOR (DImode, copy_rtx (dest),
7352 emit_move_insn (copy_rtx (dest),
7353 gen_rtx_ZERO_EXTEND (DImode,
7354 gen_lowpart (SImode,
7357 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7358 || (ud4 == 0 && ! (ud3 & 0x8000)))
7361 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7364 emit_move_insn (dest, GEN_INT (ud3 << 16));
7367 emit_move_insn (copy_rtx (dest),
7368 gen_rtx_IOR (DImode, copy_rtx (dest),
7370 emit_move_insn (copy_rtx (dest),
7371 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7374 emit_move_insn (copy_rtx (dest),
7375 gen_rtx_IOR (DImode, copy_rtx (dest),
7381 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7384 emit_move_insn (dest, GEN_INT (ud4 << 16));
7387 emit_move_insn (copy_rtx (dest),
7388 gen_rtx_IOR (DImode, copy_rtx (dest),
7391 emit_move_insn (copy_rtx (dest),
7392 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7395 emit_move_insn (copy_rtx (dest),
7396 gen_rtx_IOR (DImode, copy_rtx (dest),
7397 GEN_INT (ud2 << 16)));
7399 emit_move_insn (copy_rtx (dest),
7400 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7406 /* Helper for the following. Get rid of [r+r] memory refs
7407 in cases where it won't work (TImode, TFmode, TDmode). */
7410 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7412 if (reload_in_progress)
7415 if (GET_CODE (operands[0]) == MEM
7416 && GET_CODE (XEXP (operands[0], 0)) != REG
7417 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7418 GET_MODE (operands[0]), false))
7420 = replace_equiv_address (operands[0],
7421 copy_addr_to_reg (XEXP (operands[0], 0)));
7423 if (GET_CODE (operands[1]) == MEM
7424 && GET_CODE (XEXP (operands[1], 0)) != REG
7425 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7426 GET_MODE (operands[1]), false))
7428 = replace_equiv_address (operands[1],
7429 copy_addr_to_reg (XEXP (operands[1], 0)));
7432 /* Emit a move from SOURCE to DEST in mode MODE. */
7434 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7438 operands[1] = source;
7440 if (TARGET_DEBUG_ADDR)
7443 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7444 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7445 GET_MODE_NAME (mode),
7448 can_create_pseudo_p ());
7450 fprintf (stderr, "source:\n");
7454 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7455 if (GET_CODE (operands[1]) == CONST_DOUBLE
7456 && ! FLOAT_MODE_P (mode)
7457 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7459 /* FIXME. This should never happen. */
7460 /* Since it seems that it does, do the safe thing and convert
7462 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7464 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7465 || FLOAT_MODE_P (mode)
7466 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7467 || CONST_DOUBLE_LOW (operands[1]) < 0)
7468 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7469 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7471 /* Check if GCC is setting up a block move that will end up using FP
7472 registers as temporaries. We must make sure this is acceptable. */
7473 if (GET_CODE (operands[0]) == MEM
7474 && GET_CODE (operands[1]) == MEM
7476 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7477 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7478 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7479 ? 32 : MEM_ALIGN (operands[0])))
7480 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7482 : MEM_ALIGN (operands[1]))))
7483 && ! MEM_VOLATILE_P (operands [0])
7484 && ! MEM_VOLATILE_P (operands [1]))
7486 emit_move_insn (adjust_address (operands[0], SImode, 0),
7487 adjust_address (operands[1], SImode, 0));
7488 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7489 adjust_address (copy_rtx (operands[1]), SImode, 4));
7493 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7494 && !gpc_reg_operand (operands[1], mode))
7495 operands[1] = force_reg (mode, operands[1]);
7497 if (mode == SFmode && ! TARGET_POWERPC
7498 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7499 && GET_CODE (operands[0]) == MEM)
7503 if (reload_in_progress || reload_completed)
7504 regnum = true_regnum (operands[1]);
7505 else if (GET_CODE (operands[1]) == REG)
7506 regnum = REGNO (operands[1]);
7510 /* If operands[1] is a register, on POWER it may have
7511 double-precision data in it, so truncate it to single
7513 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7516 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7517 : gen_reg_rtx (mode));
7518 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7519 operands[1] = newreg;
7523 /* Recognize the case where operand[1] is a reference to thread-local
7524 data and load its address to a register. */
7525 if (rs6000_tls_referenced_p (operands[1]))
7527 enum tls_model model;
7528 rtx tmp = operands[1];
7531 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7533 addend = XEXP (XEXP (tmp, 0), 1);
7534 tmp = XEXP (XEXP (tmp, 0), 0);
7537 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7538 model = SYMBOL_REF_TLS_MODEL (tmp);
7539 gcc_assert (model != 0);
7541 tmp = rs6000_legitimize_tls_address (tmp, model);
7544 tmp = gen_rtx_PLUS (mode, tmp, addend);
7545 tmp = force_operand (tmp, operands[0]);
7550 /* Handle the case where reload calls us with an invalid address. */
7551 if (reload_in_progress && mode == Pmode
7552 && (! general_operand (operands[1], mode)
7553 || ! nonimmediate_operand (operands[0], mode)))
7556 /* 128-bit constant floating-point values on Darwin should really be
7557 loaded as two parts. */
7558 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7559 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7561 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7562 know how to get a DFmode SUBREG of a TFmode. */
7563 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7564 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7565 simplify_gen_subreg (imode, operands[1], mode, 0),
7567 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7568 GET_MODE_SIZE (imode)),
7569 simplify_gen_subreg (imode, operands[1], mode,
7570 GET_MODE_SIZE (imode)),
7575 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7576 cfun->machine->sdmode_stack_slot =
7577 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7579 if (reload_in_progress
7581 && MEM_P (operands[0])
7582 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7583 && REG_P (operands[1]))
7585 if (FP_REGNO_P (REGNO (operands[1])))
7587 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7588 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7589 emit_insn (gen_movsd_store (mem, operands[1]));
7591 else if (INT_REGNO_P (REGNO (operands[1])))
7593 rtx mem = adjust_address_nv (operands[0], mode, 4);
7594 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7595 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7601 if (reload_in_progress
7603 && REG_P (operands[0])
7604 && MEM_P (operands[1])
7605 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7607 if (FP_REGNO_P (REGNO (operands[0])))
7609 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7610 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7611 emit_insn (gen_movsd_load (operands[0], mem));
7613 else if (INT_REGNO_P (REGNO (operands[0])))
7615 rtx mem = adjust_address_nv (operands[1], mode, 4);
7616 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7617 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7624 /* FIXME: In the long term, this switch statement should go away
7625 and be replaced by a sequence of tests based on things like
7631 if (CONSTANT_P (operands[1])
7632 && GET_CODE (operands[1]) != CONST_INT)
7633 operands[1] = force_const_mem (mode, operands[1]);
7638 rs6000_eliminate_indexed_memrefs (operands);
7645 if (CONSTANT_P (operands[1])
7646 && ! easy_fp_constant (operands[1], mode))
7647 operands[1] = force_const_mem (mode, operands[1]);
7660 if (CONSTANT_P (operands[1])
7661 && !easy_vector_constant (operands[1], mode))
7662 operands[1] = force_const_mem (mode, operands[1]);
7667 /* Use default pattern for address of ELF small data */
7670 && DEFAULT_ABI == ABI_V4
7671 && (GET_CODE (operands[1]) == SYMBOL_REF
7672 || GET_CODE (operands[1]) == CONST)
7673 && small_data_operand (operands[1], mode))
7675 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7679 if (DEFAULT_ABI == ABI_V4
7680 && mode == Pmode && mode == SImode
7681 && flag_pic == 1 && got_operand (operands[1], mode))
7683 emit_insn (gen_movsi_got (operands[0], operands[1]));
7687 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7691 && CONSTANT_P (operands[1])
7692 && GET_CODE (operands[1]) != HIGH
7693 && GET_CODE (operands[1]) != CONST_INT)
7695 rtx target = (!can_create_pseudo_p ()
7697 : gen_reg_rtx (mode));
7699 /* If this is a function address on -mcall-aixdesc,
7700 convert it to the address of the descriptor. */
7701 if (DEFAULT_ABI == ABI_AIX
7702 && GET_CODE (operands[1]) == SYMBOL_REF
7703 && XSTR (operands[1], 0)[0] == '.')
7705 const char *name = XSTR (operands[1], 0);
7707 while (*name == '.')
7709 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7710 CONSTANT_POOL_ADDRESS_P (new_ref)
7711 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7712 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7713 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7714 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7715 operands[1] = new_ref;
7718 if (DEFAULT_ABI == ABI_DARWIN)
7721 if (MACHO_DYNAMIC_NO_PIC_P)
7723 /* Take care of any required data indirection. */
7724 operands[1] = rs6000_machopic_legitimize_pic_address (
7725 operands[1], mode, operands[0]);
7726 if (operands[0] != operands[1])
7727 emit_insn (gen_rtx_SET (VOIDmode,
7728 operands[0], operands[1]));
7732 emit_insn (gen_macho_high (target, operands[1]));
7733 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7737 emit_insn (gen_elf_high (target, operands[1]));
7738 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7742 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7743 and we have put it in the TOC, we just need to make a TOC-relative
7746 && GET_CODE (operands[1]) == SYMBOL_REF
7747 && constant_pool_expr_p (operands[1])
7748 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7749 get_pool_mode (operands[1])))
7750 || (TARGET_CMODEL == CMODEL_MEDIUM
7751 && GET_CODE (operands[1]) == SYMBOL_REF
7752 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7753 && SYMBOL_REF_LOCAL_P (operands[1])))
7756 if (TARGET_CMODEL != CMODEL_SMALL)
7758 if (can_create_pseudo_p ())
7759 reg = gen_reg_rtx (Pmode);
7763 operands[1] = create_TOC_reference (operands[1], reg);
7765 else if (mode == Pmode
7766 && CONSTANT_P (operands[1])
7767 && ((GET_CODE (operands[1]) != CONST_INT
7768 && ! easy_fp_constant (operands[1], mode))
7769 || (GET_CODE (operands[1]) == CONST_INT
7770 && (num_insns_constant (operands[1], mode)
7771 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7772 || (GET_CODE (operands[0]) == REG
7773 && FP_REGNO_P (REGNO (operands[0]))))
7774 && GET_CODE (operands[1]) != HIGH
7775 && ! legitimate_constant_pool_address_p (operands[1], mode,
7777 && ! toc_relative_expr_p (operands[1])
7778 && (TARGET_CMODEL == CMODEL_SMALL
7779 || can_create_pseudo_p ()
7780 || (REG_P (operands[0])
7781 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7785 /* Darwin uses a special PIC legitimizer. */
7786 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7789 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7791 if (operands[0] != operands[1])
7792 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7797 /* If we are to limit the number of things we put in the TOC and
7798 this is a symbol plus a constant we can add in one insn,
7799 just put the symbol in the TOC and add the constant. Don't do
7800 this if reload is in progress. */
7801 if (GET_CODE (operands[1]) == CONST
7802 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7803 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7804 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7805 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7806 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7807 && ! side_effects_p (operands[0]))
7810 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7811 rtx other = XEXP (XEXP (operands[1], 0), 1);
7813 sym = force_reg (mode, sym);
7814 emit_insn (gen_add3_insn (operands[0], sym, other));
7818 operands[1] = force_const_mem (mode, operands[1]);
7821 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7822 && constant_pool_expr_p (XEXP (operands[1], 0))
7823 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7824 get_pool_constant (XEXP (operands[1], 0)),
7825 get_pool_mode (XEXP (operands[1], 0))))
7829 if (TARGET_CMODEL != CMODEL_SMALL)
7831 if (can_create_pseudo_p ())
7832 reg = gen_reg_rtx (Pmode);
7836 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7837 operands[1] = gen_const_mem (mode, tocref);
7838 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7844 rs6000_eliminate_indexed_memrefs (operands);
7848 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7850 gen_rtx_SET (VOIDmode,
7851 operands[0], operands[1]),
7852 gen_rtx_CLOBBER (VOIDmode,
7853 gen_rtx_SCRATCH (SImode)))));
7859 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7862 /* Above, we may have called force_const_mem which may have returned
7863 an invalid address. If we can, fix this up; otherwise, reload will
7864 have to deal with it. */
7865 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7866 operands[1] = validize_mem (operands[1]);
7869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7872 /* Nonzero if we can use a floating-point register to pass this arg. */
7873 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7874 (SCALAR_FLOAT_MODE_P (MODE) \
7875 && (CUM)->fregno <= FP_ARG_MAX_REG \
7876 && TARGET_HARD_FLOAT && TARGET_FPRS)
7878 /* Nonzero if we can use an AltiVec register to pass this arg. */
7879 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7880 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7881 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7882 && TARGET_ALTIVEC_ABI \
7885 /* Return a nonzero value to say to return the function value in
7886 memory, just as large structures are always returned. TYPE will be
7887 the data type of the value, and FNTYPE will be the type of the
7888 function doing the returning, or @code{NULL} for libcalls.
7890 The AIX ABI for the RS/6000 specifies that all structures are
7891 returned in memory. The Darwin ABI does the same.
7893 For the Darwin 64 Bit ABI, a function result can be returned in
7894 registers or in memory, depending on the size of the return data
7895 type. If it is returned in registers, the value occupies the same
7896 registers as it would if it were the first and only function
7897 argument. Otherwise, the function places its result in memory at
7898 the location pointed to by GPR3.
7900 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7901 but a draft put them in memory, and GCC used to implement the draft
7902 instead of the final standard. Therefore, aix_struct_return
7903 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7904 compatibility can change DRAFT_V4_STRUCT_RET to override the
7905 default, and -m switches get the final word. See
7906 rs6000_option_override_internal for more details.
7908 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7909 long double support is enabled. These values are returned in memory.
7911 int_size_in_bytes returns -1 for variable size objects, which go in
7912 memory always. The cast to unsigned makes -1 > 8. */
7915 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7917 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7919 && rs6000_darwin64_abi
7920 && TREE_CODE (type) == RECORD_TYPE
7921 && int_size_in_bytes (type) > 0)
7923 CUMULATIVE_ARGS valcum;
7927 valcum.fregno = FP_ARG_MIN_REG;
7928 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7929 /* Do a trial code generation as if this were going to be passed
7930 as an argument; if any part goes in memory, we return NULL. */
7931 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7934 /* Otherwise fall through to more conventional ABI rules. */
7937 if (AGGREGATE_TYPE_P (type)
7938 && (aix_struct_return
7939 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7942 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7943 modes only exist for GCC vector types if -maltivec. */
7944 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7945 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7948 /* Return synthetic vectors in memory. */
7949 if (TREE_CODE (type) == VECTOR_TYPE
7950 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7952 static bool warned_for_return_big_vectors = false;
7953 if (!warned_for_return_big_vectors)
7955 warning (0, "GCC vector returned by reference: "
7956 "non-standard ABI extension with no compatibility guarantee");
7957 warned_for_return_big_vectors = true;
7962 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7968 #ifdef HAVE_AS_GNU_ATTRIBUTE
7969 /* Return TRUE if a call to function FNDECL may be one that
7970 potentially affects the function calling ABI of the object file. */
7973 call_ABI_of_interest (tree fndecl)
7975 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7977 struct cgraph_node *c_node;
7979 /* Libcalls are always interesting. */
7980 if (fndecl == NULL_TREE)
7983 /* Any call to an external function is interesting. */
7984 if (DECL_EXTERNAL (fndecl))
7987 /* Interesting functions that we are emitting in this object file. */
7988 c_node = cgraph_get_node (fndecl);
7989 return !cgraph_only_called_directly_p (c_node);
7995 /* Initialize a variable CUM of type CUMULATIVE_ARGS
7996 for a call to a function whose data type is FNTYPE.
7997 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
7999 For incoming args we set the number of arguments in the prototype large
8000 so we never return a PARALLEL. */
8003 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
8004 rtx libname ATTRIBUTE_UNUSED, int incoming,
8005 int libcall, int n_named_args,
8006 tree fndecl ATTRIBUTE_UNUSED,
8007 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8009 static CUMULATIVE_ARGS zero_cumulative;
8011 *cum = zero_cumulative;
8013 cum->fregno = FP_ARG_MIN_REG;
8014 cum->vregno = ALTIVEC_ARG_MIN_REG;
8015 cum->prototype = (fntype && prototype_p (fntype));
8016 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8017 ? CALL_LIBCALL : CALL_NORMAL);
8018 cum->sysv_gregno = GP_ARG_MIN_REG;
8019 cum->stdarg = stdarg_p (fntype);
8021 cum->nargs_prototype = 0;
8022 if (incoming || cum->prototype)
8023 cum->nargs_prototype = n_named_args;
8025 /* Check for a longcall attribute. */
8026 if ((!fntype && rs6000_default_long_calls)
8028 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8029 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8030 cum->call_cookie |= CALL_LONG;
8032 if (TARGET_DEBUG_ARG)
8034 fprintf (stderr, "\ninit_cumulative_args:");
8037 tree ret_type = TREE_TYPE (fntype);
8038 fprintf (stderr, " ret code = %s,",
8039 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8042 if (cum->call_cookie & CALL_LONG)
8043 fprintf (stderr, " longcall,");
8045 fprintf (stderr, " proto = %d, nargs = %d\n",
8046 cum->prototype, cum->nargs_prototype);
8049 #ifdef HAVE_AS_GNU_ATTRIBUTE
8050 if (DEFAULT_ABI == ABI_V4)
8052 cum->escapes = call_ABI_of_interest (fndecl);
8059 return_type = TREE_TYPE (fntype);
8060 return_mode = TYPE_MODE (return_type);
8063 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8065 if (return_type != NULL)
8067 if (TREE_CODE (return_type) == RECORD_TYPE
8068 && TYPE_TRANSPARENT_AGGR (return_type))
8070 return_type = TREE_TYPE (first_field (return_type));
8071 return_mode = TYPE_MODE (return_type);
8073 if (AGGREGATE_TYPE_P (return_type)
8074 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8076 rs6000_returns_struct = true;
8078 if (SCALAR_FLOAT_MODE_P (return_mode))
8079 rs6000_passes_float = true;
8080 else if (ALTIVEC_VECTOR_MODE (return_mode)
8081 || VSX_VECTOR_MODE (return_mode)
8082 || SPE_VECTOR_MODE (return_mode))
8083 rs6000_passes_vector = true;
8090 && TARGET_ALTIVEC_ABI
8091 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8093 error ("cannot return value in vector register because"
8094 " altivec instructions are disabled, use -maltivec"
8099 /* Return true if TYPE must be passed on the stack and not in registers. */
8102 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8104 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8105 return must_pass_in_stack_var_size (mode, type);
8107 return must_pass_in_stack_var_size_or_pad (mode, type);
8110 /* If defined, a C expression which determines whether, and in which
8111 direction, to pad out an argument with extra space. The value
8112 should be of type `enum direction': either `upward' to pad above
8113 the argument, `downward' to pad below, or `none' to inhibit
8116 For the AIX ABI structs are always stored left shifted in their
8120 function_arg_padding (enum machine_mode mode, const_tree type)
8122 #ifndef AGGREGATE_PADDING_FIXED
8123 #define AGGREGATE_PADDING_FIXED 0
8125 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8126 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8129 if (!AGGREGATE_PADDING_FIXED)
8131 /* GCC used to pass structures of the same size as integer types as
8132 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8133 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8134 passed padded downward, except that -mstrict-align further
8135 muddied the water in that multi-component structures of 2 and 4
8136 bytes in size were passed padded upward.
8138 The following arranges for best compatibility with previous
8139 versions of gcc, but removes the -mstrict-align dependency. */
8140 if (BYTES_BIG_ENDIAN)
8142 HOST_WIDE_INT size = 0;
8144 if (mode == BLKmode)
8146 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8147 size = int_size_in_bytes (type);
8150 size = GET_MODE_SIZE (mode);
8152 if (size == 1 || size == 2 || size == 4)
8158 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8160 if (type != 0 && AGGREGATE_TYPE_P (type))
8164 /* Fall back to the default. */
8165 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8168 /* If defined, a C expression that gives the alignment boundary, in bits,
8169 of an argument with the specified mode and type. If it is not defined,
8170 PARM_BOUNDARY is used for all arguments.
8172 V.4 wants long longs and doubles to be double word aligned. Just
8173 testing the mode size is a boneheaded way to do this as it means
8174 that other types such as complex int are also double word aligned.
8175 However, we're stuck with this because changing the ABI might break
8176 existing library interfaces.
8178 Doubleword align SPE vectors.
8179 Quadword align Altivec vectors.
8180 Quadword align large synthetic vector types. */
8183 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8185 if (DEFAULT_ABI == ABI_V4
8186 && (GET_MODE_SIZE (mode) == 8
8187 || (TARGET_HARD_FLOAT
8189 && (mode == TFmode || mode == TDmode))))
8191 else if (SPE_VECTOR_MODE (mode)
8192 || (type && TREE_CODE (type) == VECTOR_TYPE
8193 && int_size_in_bytes (type) >= 8
8194 && int_size_in_bytes (type) < 16))
8196 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8197 || (type && TREE_CODE (type) == VECTOR_TYPE
8198 && int_size_in_bytes (type) >= 16))
8200 else if (TARGET_MACHO
8201 && rs6000_darwin64_abi
8203 && type && TYPE_ALIGN (type) > 64)
8206 return PARM_BOUNDARY;
8209 /* For a function parm of MODE and TYPE, return the starting word in
8210 the parameter area. NWORDS of the parameter area are already used. */
8213 rs6000_parm_start (enum machine_mode mode, const_tree type,
8214 unsigned int nwords)
8217 unsigned int parm_offset;
8219 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8220 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8221 return nwords + (-(parm_offset + nwords) & align);
8224 /* Compute the size (in words) of a function argument. */
8226 static unsigned long
8227 rs6000_arg_size (enum machine_mode mode, const_tree type)
8231 if (mode != BLKmode)
8232 size = GET_MODE_SIZE (mode);
8234 size = int_size_in_bytes (type);
8237 return (size + 3) >> 2;
8239 return (size + 7) >> 3;
8242 /* Use this to flush pending int fields. */
8245 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8246 HOST_WIDE_INT bitpos, int final)
8248 unsigned int startbit, endbit;
8249 int intregs, intoffset;
8250 enum machine_mode mode;
8252 /* Handle the situations where a float is taking up the first half
8253 of the GPR, and the other half is empty (typically due to
8254 alignment restrictions). We can detect this by a 8-byte-aligned
8255 int field, or by seeing that this is the final flush for this
8256 argument. Count the word and continue on. */
8257 if (cum->floats_in_gpr == 1
8258 && (cum->intoffset % 64 == 0
8259 || (cum->intoffset == -1 && final)))
8262 cum->floats_in_gpr = 0;
8265 if (cum->intoffset == -1)
8268 intoffset = cum->intoffset;
8269 cum->intoffset = -1;
8270 cum->floats_in_gpr = 0;
8272 if (intoffset % BITS_PER_WORD != 0)
8274 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8276 if (mode == BLKmode)
8278 /* We couldn't find an appropriate mode, which happens,
8279 e.g., in packed structs when there are 3 bytes to load.
8280 Back intoffset back to the beginning of the word in this
8282 intoffset = intoffset & -BITS_PER_WORD;
8286 startbit = intoffset & -BITS_PER_WORD;
8287 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8288 intregs = (endbit - startbit) / BITS_PER_WORD;
8289 cum->words += intregs;
8290 /* words should be unsigned. */
8291 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8293 int pad = (endbit/BITS_PER_WORD) - cum->words;
8298 /* The darwin64 ABI calls for us to recurse down through structs,
8299 looking for elements passed in registers. Unfortunately, we have
8300 to track int register count here also because of misalignments
8301 in powerpc alignment mode. */
8304 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8306 HOST_WIDE_INT startbitpos)
8310 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8311 if (TREE_CODE (f) == FIELD_DECL)
8313 HOST_WIDE_INT bitpos = startbitpos;
8314 tree ftype = TREE_TYPE (f);
8315 enum machine_mode mode;
8316 if (ftype == error_mark_node)
8318 mode = TYPE_MODE (ftype);
8320 if (DECL_SIZE (f) != 0
8321 && host_integerp (bit_position (f), 1))
8322 bitpos += int_bit_position (f);
8324 /* ??? FIXME: else assume zero offset. */
8326 if (TREE_CODE (ftype) == RECORD_TYPE)
8327 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8328 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8330 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8331 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8332 cum->fregno += n_fpregs;
8333 /* Single-precision floats present a special problem for
8334 us, because they are smaller than an 8-byte GPR, and so
8335 the structure-packing rules combined with the standard
8336 varargs behavior mean that we want to pack float/float
8337 and float/int combinations into a single register's
8338 space. This is complicated by the arg advance flushing,
8339 which works on arbitrarily large groups of int-type
8343 if (cum->floats_in_gpr == 1)
8345 /* Two floats in a word; count the word and reset
8348 cum->floats_in_gpr = 0;
8350 else if (bitpos % 64 == 0)
8352 /* A float at the beginning of an 8-byte word;
8353 count it and put off adjusting cum->words until
8354 we see if a arg advance flush is going to do it
8356 cum->floats_in_gpr++;
8360 /* The float is at the end of a word, preceded
8361 by integer fields, so the arg advance flush
8362 just above has already set cum->words and
8363 everything is taken care of. */
8367 cum->words += n_fpregs;
8369 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8371 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8375 else if (cum->intoffset == -1)
8376 cum->intoffset = bitpos;
8380 /* Check for an item that needs to be considered specially under the darwin 64
8381 bit ABI. These are record types where the mode is BLK or the structure is
8384 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8386 return rs6000_darwin64_abi
8387 && ((mode == BLKmode
8388 && TREE_CODE (type) == RECORD_TYPE
8389 && int_size_in_bytes (type) > 0)
8390 || (type && TREE_CODE (type) == RECORD_TYPE
8391 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8394 /* Update the data in CUM to advance over an argument
8395 of mode MODE and data type TYPE.
8396 (TYPE is null for libcalls where that information may not be available.)
8398 Note that for args passed by reference, function_arg will be called
8399 with MODE and TYPE set to that of the pointer to the arg, not the arg
8403 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8404 const_tree type, bool named, int depth)
8406 /* Only tick off an argument if we're not recursing. */
8408 cum->nargs_prototype--;
8410 #ifdef HAVE_AS_GNU_ATTRIBUTE
8411 if (DEFAULT_ABI == ABI_V4
8414 if (SCALAR_FLOAT_MODE_P (mode))
8415 rs6000_passes_float = true;
8416 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8417 rs6000_passes_vector = true;
8418 else if (SPE_VECTOR_MODE (mode)
8420 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8421 rs6000_passes_vector = true;
8425 if (TARGET_ALTIVEC_ABI
8426 && (ALTIVEC_VECTOR_MODE (mode)
8427 || VSX_VECTOR_MODE (mode)
8428 || (type && TREE_CODE (type) == VECTOR_TYPE
8429 && int_size_in_bytes (type) == 16)))
8433 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8436 if (!TARGET_ALTIVEC)
8437 error ("cannot pass argument in vector register because"
8438 " altivec instructions are disabled, use -maltivec"
8441 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8442 even if it is going to be passed in a vector register.
8443 Darwin does the same for variable-argument functions. */
8444 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8445 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8455 /* Vector parameters must be 16-byte aligned. This places
8456 them at 2 mod 4 in terms of words in 32-bit mode, since
8457 the parameter save area starts at offset 24 from the
8458 stack. In 64-bit mode, they just have to start on an
8459 even word, since the parameter save area is 16-byte
8460 aligned. Space for GPRs is reserved even if the argument
8461 will be passed in memory. */
8463 align = (2 - cum->words) & 3;
8465 align = cum->words & 1;
8466 cum->words += align + rs6000_arg_size (mode, type);
8468 if (TARGET_DEBUG_ARG)
8470 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8472 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8473 cum->nargs_prototype, cum->prototype,
8474 GET_MODE_NAME (mode));
8478 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8480 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8483 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8485 int size = int_size_in_bytes (type);
8486 /* Variable sized types have size == -1 and are
8487 treated as if consisting entirely of ints.
8488 Pad to 16 byte boundary if needed. */
8489 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8490 && (cum->words % 2) != 0)
8492 /* For varargs, we can just go up by the size of the struct. */
8494 cum->words += (size + 7) / 8;
8497 /* It is tempting to say int register count just goes up by
8498 sizeof(type)/8, but this is wrong in a case such as
8499 { int; double; int; } [powerpc alignment]. We have to
8500 grovel through the fields for these too. */
8502 cum->floats_in_gpr = 0;
8503 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8504 rs6000_darwin64_record_arg_advance_flush (cum,
8505 size * BITS_PER_UNIT, 1);
8507 if (TARGET_DEBUG_ARG)
8509 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8510 cum->words, TYPE_ALIGN (type), size);
8512 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8513 cum->nargs_prototype, cum->prototype,
8514 GET_MODE_NAME (mode));
8517 else if (DEFAULT_ABI == ABI_V4)
8519 if (TARGET_HARD_FLOAT && TARGET_FPRS
8520 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8521 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8522 || (mode == TFmode && !TARGET_IEEEQUAD)
8523 || mode == SDmode || mode == DDmode || mode == TDmode))
8525 /* _Decimal128 must use an even/odd register pair. This assumes
8526 that the register number is odd when fregno is odd. */
8527 if (mode == TDmode && (cum->fregno % 2) == 1)
8530 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8531 <= FP_ARG_V4_MAX_REG)
8532 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8535 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8536 if (mode == DFmode || mode == TFmode
8537 || mode == DDmode || mode == TDmode)
8538 cum->words += cum->words & 1;
8539 cum->words += rs6000_arg_size (mode, type);
8544 int n_words = rs6000_arg_size (mode, type);
8545 int gregno = cum->sysv_gregno;
8547 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8548 (r7,r8) or (r9,r10). As does any other 2 word item such
8549 as complex int due to a historical mistake. */
8551 gregno += (1 - gregno) & 1;
8553 /* Multi-reg args are not split between registers and stack. */
8554 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8556 /* Long long and SPE vectors are aligned on the stack.
8557 So are other 2 word items such as complex int due to
8558 a historical mistake. */
8560 cum->words += cum->words & 1;
8561 cum->words += n_words;
8564 /* Note: continuing to accumulate gregno past when we've started
8565 spilling to the stack indicates the fact that we've started
8566 spilling to the stack to expand_builtin_saveregs. */
8567 cum->sysv_gregno = gregno + n_words;
8570 if (TARGET_DEBUG_ARG)
8572 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8573 cum->words, cum->fregno);
8574 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8575 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8576 fprintf (stderr, "mode = %4s, named = %d\n",
8577 GET_MODE_NAME (mode), named);
8582 int n_words = rs6000_arg_size (mode, type);
8583 int start_words = cum->words;
8584 int align_words = rs6000_parm_start (mode, type, start_words);
8586 cum->words = align_words + n_words;
8588 if (SCALAR_FLOAT_MODE_P (mode)
8589 && TARGET_HARD_FLOAT && TARGET_FPRS)
8591 /* _Decimal128 must be passed in an even/odd float register pair.
8592 This assumes that the register number is odd when fregno is
8594 if (mode == TDmode && (cum->fregno % 2) == 1)
8596 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8599 if (TARGET_DEBUG_ARG)
8601 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8602 cum->words, cum->fregno);
8603 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8604 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8605 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8606 named, align_words - start_words, depth);
8612 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8613 const_tree type, bool named)
8615 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8619 spe_build_register_parallel (enum machine_mode mode, int gregno)
8626 r1 = gen_rtx_REG (DImode, gregno);
8627 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8628 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8632 r1 = gen_rtx_REG (DImode, gregno);
8633 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8634 r3 = gen_rtx_REG (DImode, gregno + 2);
8635 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8636 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8639 r1 = gen_rtx_REG (DImode, gregno);
8640 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8641 r3 = gen_rtx_REG (DImode, gregno + 2);
8642 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8643 r5 = gen_rtx_REG (DImode, gregno + 4);
8644 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8645 r7 = gen_rtx_REG (DImode, gregno + 6);
8646 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8647 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8654 /* Determine where to put a SIMD argument on the SPE. */
8656 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8659 int gregno = cum->sysv_gregno;
8661 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8662 are passed and returned in a pair of GPRs for ABI compatibility. */
8663 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8664 || mode == DCmode || mode == TCmode))
8666 int n_words = rs6000_arg_size (mode, type);
8668 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8670 gregno += (1 - gregno) & 1;
8672 /* Multi-reg args are not split between registers and stack. */
8673 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8676 return spe_build_register_parallel (mode, gregno);
8680 int n_words = rs6000_arg_size (mode, type);
8682 /* SPE vectors are put in odd registers. */
8683 if (n_words == 2 && (gregno & 1) == 0)
8686 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8689 enum machine_mode m = SImode;
8691 r1 = gen_rtx_REG (m, gregno);
8692 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8693 r2 = gen_rtx_REG (m, gregno + 1);
8694 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8695 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8702 if (gregno <= GP_ARG_MAX_REG)
8703 return gen_rtx_REG (mode, gregno);
8709 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8710 structure between cum->intoffset and bitpos to integer registers. */
8713 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8714 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8716 enum machine_mode mode;
8718 unsigned int startbit, endbit;
8719 int this_regno, intregs, intoffset;
8722 if (cum->intoffset == -1)
8725 intoffset = cum->intoffset;
8726 cum->intoffset = -1;
8728 /* If this is the trailing part of a word, try to only load that
8729 much into the register. Otherwise load the whole register. Note
8730 that in the latter case we may pick up unwanted bits. It's not a
8731 problem at the moment but may wish to revisit. */
8733 if (intoffset % BITS_PER_WORD != 0)
8735 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8737 if (mode == BLKmode)
8739 /* We couldn't find an appropriate mode, which happens,
8740 e.g., in packed structs when there are 3 bytes to load.
8741 Back intoffset back to the beginning of the word in this
8743 intoffset = intoffset & -BITS_PER_WORD;
8750 startbit = intoffset & -BITS_PER_WORD;
8751 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8752 intregs = (endbit - startbit) / BITS_PER_WORD;
8753 this_regno = cum->words + intoffset / BITS_PER_WORD;
8755 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8758 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8762 intoffset /= BITS_PER_UNIT;
8765 regno = GP_ARG_MIN_REG + this_regno;
8766 reg = gen_rtx_REG (mode, regno);
8768 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8771 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8775 while (intregs > 0);
8778 /* Recursive workhorse for the following. */
8781 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8782 HOST_WIDE_INT startbitpos, rtx rvec[],
8787 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8788 if (TREE_CODE (f) == FIELD_DECL)
8790 HOST_WIDE_INT bitpos = startbitpos;
8791 tree ftype = TREE_TYPE (f);
8792 enum machine_mode mode;
8793 if (ftype == error_mark_node)
8795 mode = TYPE_MODE (ftype);
8797 if (DECL_SIZE (f) != 0
8798 && host_integerp (bit_position (f), 1))
8799 bitpos += int_bit_position (f);
8801 /* ??? FIXME: else assume zero offset. */
8803 if (TREE_CODE (ftype) == RECORD_TYPE)
8804 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8805 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8807 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8811 case SCmode: mode = SFmode; break;
8812 case DCmode: mode = DFmode; break;
8813 case TCmode: mode = TFmode; break;
8817 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8818 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8820 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8821 && (mode == TFmode || mode == TDmode));
8822 /* Long double or _Decimal128 split over regs and memory. */
8823 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8827 = gen_rtx_EXPR_LIST (VOIDmode,
8828 gen_rtx_REG (mode, cum->fregno++),
8829 GEN_INT (bitpos / BITS_PER_UNIT));
8830 if (mode == TFmode || mode == TDmode)
8833 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8835 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8837 = gen_rtx_EXPR_LIST (VOIDmode,
8838 gen_rtx_REG (mode, cum->vregno++),
8839 GEN_INT (bitpos / BITS_PER_UNIT));
8841 else if (cum->intoffset == -1)
8842 cum->intoffset = bitpos;
8846 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8847 the register(s) to be used for each field and subfield of a struct
8848 being passed by value, along with the offset of where the
8849 register's value may be found in the block. FP fields go in FP
8850 register, vector fields go in vector registers, and everything
8851 else goes in int registers, packed as in memory.
8853 This code is also used for function return values. RETVAL indicates
8854 whether this is the case.
8856 Much of this is taken from the SPARC V9 port, which has a similar
8857 calling convention. */
8860 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8861 bool named, bool retval)
8863 rtx rvec[FIRST_PSEUDO_REGISTER];
8864 int k = 1, kbase = 1;
8865 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8866 /* This is a copy; modifications are not visible to our caller. */
8867 CUMULATIVE_ARGS copy_cum = *orig_cum;
8868 CUMULATIVE_ARGS *cum = ©_cum;
8870 /* Pad to 16 byte boundary if needed. */
8871 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8872 && (cum->words % 2) != 0)
8879 /* Put entries into rvec[] for individual FP and vector fields, and
8880 for the chunks of memory that go in int regs. Note we start at
8881 element 1; 0 is reserved for an indication of using memory, and
8882 may or may not be filled in below. */
8883 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8884 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8886 /* If any part of the struct went on the stack put all of it there.
8887 This hack is because the generic code for
8888 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8889 parts of the struct are not at the beginning. */
8893 return NULL_RTX; /* doesn't go in registers at all */
8895 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8897 if (k > 1 || cum->use_stack)
8898 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8903 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8906 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8911 rtx rvec[GP_ARG_NUM_REG + 1];
8913 if (align_words >= GP_ARG_NUM_REG)
8916 n_units = rs6000_arg_size (mode, type);
8918 /* Optimize the simple case where the arg fits in one gpr, except in
8919 the case of BLKmode due to assign_parms assuming that registers are
8920 BITS_PER_WORD wide. */
8922 || (n_units == 1 && mode != BLKmode))
8923 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8926 if (align_words + n_units > GP_ARG_NUM_REG)
8927 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8928 using a magic NULL_RTX component.
8929 This is not strictly correct. Only some of the arg belongs in
8930 memory, not all of it. However, the normal scheme using
8931 function_arg_partial_nregs can result in unusual subregs, eg.
8932 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8933 store the whole arg to memory is often more efficient than code
8934 to store pieces, and we know that space is available in the right
8935 place for the whole arg. */
8936 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8941 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8942 rtx off = GEN_INT (i++ * 4);
8943 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8945 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8947 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8950 /* Determine where to put an argument to a function.
8951 Value is zero to push the argument on the stack,
8952 or a hard register in which to store the argument.
8954 MODE is the argument's machine mode.
8955 TYPE is the data type of the argument (as a tree).
8956 This is null for libcalls where that information may
8958 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8959 the preceding args and about the function being called. It is
8960 not modified in this routine.
8961 NAMED is nonzero if this argument is a named parameter
8962 (otherwise it is an extra parameter matching an ellipsis).
8964 On RS/6000 the first eight words of non-FP are normally in registers
8965 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8966 Under V.4, the first 8 FP args are in registers.
8968 If this is floating-point and no prototype is specified, we use
8969 both an FP and integer register (or possibly FP reg and stack). Library
8970 functions (when CALL_LIBCALL is set) always have the proper types for args,
8971 so we can pass the FP value just in one register. emit_library_function
8972 doesn't support PARALLEL anyway.
8974 Note that for args passed by reference, function_arg will be called
8975 with MODE and TYPE set to that of the pointer to the arg, not the arg
8979 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8980 const_tree type, bool named)
8982 enum rs6000_abi abi = DEFAULT_ABI;
8984 /* Return a marker to indicate whether CR1 needs to set or clear the
8985 bit that V.4 uses to say fp args were passed in registers.
8986 Assume that we don't need the marker for software floating point,
8987 or compiler generated library calls. */
8988 if (mode == VOIDmode)
8991 && (cum->call_cookie & CALL_LIBCALL) == 0
8993 || (cum->nargs_prototype < 0
8994 && (cum->prototype || TARGET_NO_PROTOTYPE))))
8996 /* For the SPE, we need to crxor CR6 always. */
8998 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
8999 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
9000 return GEN_INT (cum->call_cookie
9001 | ((cum->fregno == FP_ARG_MIN_REG)
9002 ? CALL_V4_SET_FP_ARGS
9003 : CALL_V4_CLEAR_FP_ARGS));
9006 return GEN_INT (cum->call_cookie);
9009 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9011 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9012 if (rslt != NULL_RTX)
9014 /* Else fall through to usual handling. */
9017 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9018 if (TARGET_64BIT && ! cum->prototype)
9020 /* Vector parameters get passed in vector register
9021 and also in GPRs or memory, in absence of prototype. */
9024 align_words = (cum->words + 1) & ~1;
9026 if (align_words >= GP_ARG_NUM_REG)
9032 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9034 return gen_rtx_PARALLEL (mode,
9036 gen_rtx_EXPR_LIST (VOIDmode,
9038 gen_rtx_EXPR_LIST (VOIDmode,
9039 gen_rtx_REG (mode, cum->vregno),
9043 return gen_rtx_REG (mode, cum->vregno);
9044 else if (TARGET_ALTIVEC_ABI
9045 && (ALTIVEC_VECTOR_MODE (mode)
9046 || VSX_VECTOR_MODE (mode)
9047 || (type && TREE_CODE (type) == VECTOR_TYPE
9048 && int_size_in_bytes (type) == 16)))
9050 if (named || abi == ABI_V4)
9054 /* Vector parameters to varargs functions under AIX or Darwin
9055 get passed in memory and possibly also in GPRs. */
9056 int align, align_words, n_words;
9057 enum machine_mode part_mode;
9059 /* Vector parameters must be 16-byte aligned. This places them at
9060 2 mod 4 in terms of words in 32-bit mode, since the parameter
9061 save area starts at offset 24 from the stack. In 64-bit mode,
9062 they just have to start on an even word, since the parameter
9063 save area is 16-byte aligned. */
9065 align = (2 - cum->words) & 3;
9067 align = cum->words & 1;
9068 align_words = cum->words + align;
9070 /* Out of registers? Memory, then. */
9071 if (align_words >= GP_ARG_NUM_REG)
9074 if (TARGET_32BIT && TARGET_POWERPC64)
9075 return rs6000_mixed_function_arg (mode, type, align_words);
9077 /* The vector value goes in GPRs. Only the part of the
9078 value in GPRs is reported here. */
9080 n_words = rs6000_arg_size (mode, type);
9081 if (align_words + n_words > GP_ARG_NUM_REG)
9082 /* Fortunately, there are only two possibilities, the value
9083 is either wholly in GPRs or half in GPRs and half not. */
9086 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9089 else if (TARGET_SPE_ABI && TARGET_SPE
9090 && (SPE_VECTOR_MODE (mode)
9091 || (TARGET_E500_DOUBLE && (mode == DFmode
9094 || mode == TCmode))))
9095 return rs6000_spe_function_arg (cum, mode, type);
9097 else if (abi == ABI_V4)
9099 if (TARGET_HARD_FLOAT && TARGET_FPRS
9100 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9101 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9102 || (mode == TFmode && !TARGET_IEEEQUAD)
9103 || mode == SDmode || mode == DDmode || mode == TDmode))
9105 /* _Decimal128 must use an even/odd register pair. This assumes
9106 that the register number is odd when fregno is odd. */
9107 if (mode == TDmode && (cum->fregno % 2) == 1)
9110 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9111 <= FP_ARG_V4_MAX_REG)
9112 return gen_rtx_REG (mode, cum->fregno);
9118 int n_words = rs6000_arg_size (mode, type);
9119 int gregno = cum->sysv_gregno;
9121 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9122 (r7,r8) or (r9,r10). As does any other 2 word item such
9123 as complex int due to a historical mistake. */
9125 gregno += (1 - gregno) & 1;
9127 /* Multi-reg args are not split between registers and stack. */
9128 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9131 if (TARGET_32BIT && TARGET_POWERPC64)
9132 return rs6000_mixed_function_arg (mode, type,
9133 gregno - GP_ARG_MIN_REG);
9134 return gen_rtx_REG (mode, gregno);
9139 int align_words = rs6000_parm_start (mode, type, cum->words);
9141 /* _Decimal128 must be passed in an even/odd float register pair.
9142 This assumes that the register number is odd when fregno is odd. */
9143 if (mode == TDmode && (cum->fregno % 2) == 1)
9146 if (USE_FP_FOR_ARG_P (cum, mode, type))
9148 rtx rvec[GP_ARG_NUM_REG + 1];
9152 enum machine_mode fmode = mode;
9153 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9155 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9157 /* Currently, we only ever need one reg here because complex
9158 doubles are split. */
9159 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9160 && (fmode == TFmode || fmode == TDmode));
9162 /* Long double or _Decimal128 split over regs and memory. */
9163 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9166 /* Do we also need to pass this arg in the parameter save
9169 && (cum->nargs_prototype <= 0
9170 || (DEFAULT_ABI == ABI_AIX
9172 && align_words >= GP_ARG_NUM_REG)));
9174 if (!needs_psave && mode == fmode)
9175 return gen_rtx_REG (fmode, cum->fregno);
9180 /* Describe the part that goes in gprs or the stack.
9181 This piece must come first, before the fprs. */
9182 if (align_words < GP_ARG_NUM_REG)
9184 unsigned long n_words = rs6000_arg_size (mode, type);
9186 if (align_words + n_words > GP_ARG_NUM_REG
9187 || (TARGET_32BIT && TARGET_POWERPC64))
9189 /* If this is partially on the stack, then we only
9190 include the portion actually in registers here. */
9191 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9194 if (align_words + n_words > GP_ARG_NUM_REG)
9195 /* Not all of the arg fits in gprs. Say that it
9196 goes in memory too, using a magic NULL_RTX
9197 component. Also see comment in
9198 rs6000_mixed_function_arg for why the normal
9199 function_arg_partial_nregs scheme doesn't work
9201 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9205 r = gen_rtx_REG (rmode,
9206 GP_ARG_MIN_REG + align_words);
9207 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9208 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9210 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9214 /* The whole arg fits in gprs. */
9215 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9216 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9220 /* It's entirely in memory. */
9221 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9224 /* Describe where this piece goes in the fprs. */
9225 r = gen_rtx_REG (fmode, cum->fregno);
9226 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9228 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9230 else if (align_words < GP_ARG_NUM_REG)
9232 if (TARGET_32BIT && TARGET_POWERPC64)
9233 return rs6000_mixed_function_arg (mode, type, align_words);
9235 if (mode == BLKmode)
9238 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9245 /* For an arg passed partly in registers and partly in memory, this is
9246 the number of bytes passed in registers. For args passed entirely in
9247 registers or entirely in memory, zero. When an arg is described by a
9248 PARALLEL, perhaps using more than one register type, this function
9249 returns the number of bytes used by the first element of the PARALLEL. */
9252 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9253 tree type, bool named)
9258 if (DEFAULT_ABI == ABI_V4)
9261 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9262 && cum->nargs_prototype >= 0)
9265 /* In this complicated case we just disable the partial_nregs code. */
9266 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9269 align_words = rs6000_parm_start (mode, type, cum->words);
9271 if (USE_FP_FOR_ARG_P (cum, mode, type))
9273 /* If we are passing this arg in the fixed parameter save area
9274 (gprs or memory) as well as fprs, then this function should
9275 return the number of partial bytes passed in the parameter
9276 save area rather than partial bytes passed in fprs. */
9278 && (cum->nargs_prototype <= 0
9279 || (DEFAULT_ABI == ABI_AIX
9281 && align_words >= GP_ARG_NUM_REG)))
9283 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9284 > FP_ARG_MAX_REG + 1)
9285 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9286 else if (cum->nargs_prototype >= 0)
9290 if (align_words < GP_ARG_NUM_REG
9291 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9292 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9294 if (ret != 0 && TARGET_DEBUG_ARG)
9295 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9300 /* A C expression that indicates when an argument must be passed by
9301 reference. If nonzero for an argument, a copy of that argument is
9302 made in memory and a pointer to the argument is passed instead of
9303 the argument itself. The pointer is passed in whatever way is
9304 appropriate for passing a pointer to that type.
9306 Under V.4, aggregates and long double are passed by reference.
9308 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9309 reference unless the AltiVec vector extension ABI is in force.
9311 As an extension to all ABIs, variable sized types are passed by
9315 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9316 enum machine_mode mode, const_tree type,
9317 bool named ATTRIBUTE_UNUSED)
9319 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9321 if (TARGET_DEBUG_ARG)
9322 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9329 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9331 if (TARGET_DEBUG_ARG)
9332 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9336 if (int_size_in_bytes (type) < 0)
9338 if (TARGET_DEBUG_ARG)
9339 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9343 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9344 modes only exist for GCC vector types if -maltivec. */
9345 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9347 if (TARGET_DEBUG_ARG)
9348 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9352 /* Pass synthetic vectors in memory. */
9353 if (TREE_CODE (type) == VECTOR_TYPE
9354 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9356 static bool warned_for_pass_big_vectors = false;
9357 if (TARGET_DEBUG_ARG)
9358 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9359 if (!warned_for_pass_big_vectors)
9361 warning (0, "GCC vector passed by reference: "
9362 "non-standard ABI extension with no compatibility guarantee");
9363 warned_for_pass_big_vectors = true;
9372 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9375 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9380 for (i = 0; i < nregs; i++)
9382 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9383 if (reload_completed)
9385 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9388 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9389 i * GET_MODE_SIZE (reg_mode));
9392 tem = replace_equiv_address (tem, XEXP (tem, 0));
9396 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9400 /* Perform any needed actions needed for a function that is receiving a
9401 variable number of arguments.
9405 MODE and TYPE are the mode and type of the current parameter.
9407 PRETEND_SIZE is a variable that should be set to the amount of stack
9408 that must be pushed by the prolog to pretend that our caller pushed
9411 Normally, this macro will push all remaining incoming registers on the
9412 stack and set PRETEND_SIZE to the length of the registers pushed. */
9415 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9416 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9419 CUMULATIVE_ARGS next_cum;
9420 int reg_size = TARGET_32BIT ? 4 : 8;
9421 rtx save_area = NULL_RTX, mem;
9422 int first_reg_offset;
9425 /* Skip the last named argument. */
9427 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9429 if (DEFAULT_ABI == ABI_V4)
9431 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9435 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9436 HOST_WIDE_INT offset = 0;
9438 /* Try to optimize the size of the varargs save area.
9439 The ABI requires that ap.reg_save_area is doubleword
9440 aligned, but we don't need to allocate space for all
9441 the bytes, only those to which we actually will save
9443 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9444 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9445 if (TARGET_HARD_FLOAT && TARGET_FPRS
9446 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9447 && cfun->va_list_fpr_size)
9450 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9451 * UNITS_PER_FP_WORD;
9452 if (cfun->va_list_fpr_size
9453 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9454 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9456 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9457 * UNITS_PER_FP_WORD;
9461 offset = -((first_reg_offset * reg_size) & ~7);
9462 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9464 gpr_reg_num = cfun->va_list_gpr_size;
9465 if (reg_size == 4 && (first_reg_offset & 1))
9468 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9471 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9473 - (int) (GP_ARG_NUM_REG * reg_size);
9475 if (gpr_size + fpr_size)
9478 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9479 gcc_assert (GET_CODE (reg_save_area) == MEM);
9480 reg_save_area = XEXP (reg_save_area, 0);
9481 if (GET_CODE (reg_save_area) == PLUS)
9483 gcc_assert (XEXP (reg_save_area, 0)
9484 == virtual_stack_vars_rtx);
9485 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9486 offset += INTVAL (XEXP (reg_save_area, 1));
9489 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9492 cfun->machine->varargs_save_offset = offset;
9493 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9498 first_reg_offset = next_cum.words;
9499 save_area = virtual_incoming_args_rtx;
9501 if (targetm.calls.must_pass_in_stack (mode, type))
9502 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9505 set = get_varargs_alias_set ();
9506 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9507 && cfun->va_list_gpr_size)
9509 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9511 if (va_list_gpr_counter_field)
9513 /* V4 va_list_gpr_size counts number of registers needed. */
9514 if (nregs > cfun->va_list_gpr_size)
9515 nregs = cfun->va_list_gpr_size;
9519 /* char * va_list instead counts number of bytes needed. */
9520 if (nregs > cfun->va_list_gpr_size / reg_size)
9521 nregs = cfun->va_list_gpr_size / reg_size;
9524 mem = gen_rtx_MEM (BLKmode,
9525 plus_constant (save_area,
9526 first_reg_offset * reg_size));
9527 MEM_NOTRAP_P (mem) = 1;
9528 set_mem_alias_set (mem, set);
9529 set_mem_align (mem, BITS_PER_WORD);
9531 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9535 /* Save FP registers if needed. */
9536 if (DEFAULT_ABI == ABI_V4
9537 && TARGET_HARD_FLOAT && TARGET_FPRS
9539 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9540 && cfun->va_list_fpr_size)
9542 int fregno = next_cum.fregno, nregs;
9543 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9544 rtx lab = gen_label_rtx ();
9545 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9546 * UNITS_PER_FP_WORD);
9549 (gen_rtx_SET (VOIDmode,
9551 gen_rtx_IF_THEN_ELSE (VOIDmode,
9552 gen_rtx_NE (VOIDmode, cr1,
9554 gen_rtx_LABEL_REF (VOIDmode, lab),
9558 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9559 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9561 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9563 plus_constant (save_area, off));
9564 MEM_NOTRAP_P (mem) = 1;
9565 set_mem_alias_set (mem, set);
9566 set_mem_align (mem, GET_MODE_ALIGNMENT (
9567 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9568 ? DFmode : SFmode));
9569 emit_move_insn (mem, gen_rtx_REG (
9570 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9571 ? DFmode : SFmode, fregno));
9578 /* Create the va_list data type. */
9581 rs6000_build_builtin_va_list (void)
9583 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9585 /* For AIX, prefer 'char *' because that's what the system
9586 header files like. */
9587 if (DEFAULT_ABI != ABI_V4)
9588 return build_pointer_type (char_type_node);
9590 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9591 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9592 get_identifier ("__va_list_tag"), record);
9594 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9595 unsigned_char_type_node);
9596 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9597 unsigned_char_type_node);
9598 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9600 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9601 get_identifier ("reserved"), short_unsigned_type_node);
9602 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9603 get_identifier ("overflow_arg_area"),
9605 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9606 get_identifier ("reg_save_area"),
9609 va_list_gpr_counter_field = f_gpr;
9610 va_list_fpr_counter_field = f_fpr;
9612 DECL_FIELD_CONTEXT (f_gpr) = record;
9613 DECL_FIELD_CONTEXT (f_fpr) = record;
9614 DECL_FIELD_CONTEXT (f_res) = record;
9615 DECL_FIELD_CONTEXT (f_ovf) = record;
9616 DECL_FIELD_CONTEXT (f_sav) = record;
9618 TYPE_STUB_DECL (record) = type_decl;
9619 TYPE_NAME (record) = type_decl;
9620 TYPE_FIELDS (record) = f_gpr;
9621 DECL_CHAIN (f_gpr) = f_fpr;
9622 DECL_CHAIN (f_fpr) = f_res;
9623 DECL_CHAIN (f_res) = f_ovf;
9624 DECL_CHAIN (f_ovf) = f_sav;
9626 layout_type (record);
9628 /* The correct type is an array type of one element. */
9629 return build_array_type (record, build_index_type (size_zero_node));
9632 /* Implement va_start. */
9635 rs6000_va_start (tree valist, rtx nextarg)
9637 HOST_WIDE_INT words, n_gpr, n_fpr;
9638 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9639 tree gpr, fpr, ovf, sav, t;
9641 /* Only SVR4 needs something special. */
9642 if (DEFAULT_ABI != ABI_V4)
9644 std_expand_builtin_va_start (valist, nextarg);
9648 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9649 f_fpr = DECL_CHAIN (f_gpr);
9650 f_res = DECL_CHAIN (f_fpr);
9651 f_ovf = DECL_CHAIN (f_res);
9652 f_sav = DECL_CHAIN (f_ovf);
9654 valist = build_simple_mem_ref (valist);
9655 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9656 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9658 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9660 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9663 /* Count number of gp and fp argument registers used. */
9664 words = crtl->args.info.words;
9665 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9667 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9670 if (TARGET_DEBUG_ARG)
9671 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9672 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9673 words, n_gpr, n_fpr);
9675 if (cfun->va_list_gpr_size)
9677 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9678 build_int_cst (NULL_TREE, n_gpr));
9679 TREE_SIDE_EFFECTS (t) = 1;
9680 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9683 if (cfun->va_list_fpr_size)
9685 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9686 build_int_cst (NULL_TREE, n_fpr));
9687 TREE_SIDE_EFFECTS (t) = 1;
9688 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9690 #ifdef HAVE_AS_GNU_ATTRIBUTE
9691 if (call_ABI_of_interest (cfun->decl))
9692 rs6000_passes_float = true;
9696 /* Find the overflow area. */
9697 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9699 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9700 size_int (words * UNITS_PER_WORD));
9701 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9702 TREE_SIDE_EFFECTS (t) = 1;
9703 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9705 /* If there were no va_arg invocations, don't set up the register
9707 if (!cfun->va_list_gpr_size
9708 && !cfun->va_list_fpr_size
9709 && n_gpr < GP_ARG_NUM_REG
9710 && n_fpr < FP_ARG_V4_MAX_REG)
9713 /* Find the register save area. */
9714 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9715 if (cfun->machine->varargs_save_offset)
9716 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9717 size_int (cfun->machine->varargs_save_offset));
9718 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9719 TREE_SIDE_EFFECTS (t) = 1;
9720 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9723 /* Implement va_arg. */
9726 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9729 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9730 tree gpr, fpr, ovf, sav, reg, t, u;
9731 int size, rsize, n_reg, sav_ofs, sav_scale;
9732 tree lab_false, lab_over, addr;
9734 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9738 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9740 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9741 return build_va_arg_indirect_ref (t);
9744 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9745 earlier version of gcc, with the property that it always applied alignment
9746 adjustments to the va-args (even for zero-sized types). The cheapest way
9747 to deal with this is to replicate the effect of the part of
9748 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9750 We don't need to check for pass-by-reference because of the test above.
9751 We can return a simplifed answer, since we know there's no offset to add. */
9754 && rs6000_darwin64_abi
9755 && integer_zerop (TYPE_SIZE (type)))
9757 unsigned HOST_WIDE_INT align, boundary;
9758 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9759 align = PARM_BOUNDARY / BITS_PER_UNIT;
9760 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9761 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9762 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9763 boundary /= BITS_PER_UNIT;
9764 if (boundary > align)
9767 /* This updates arg ptr by the amount that would be necessary
9768 to align the zero-sized (but not zero-alignment) item. */
9769 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9770 fold_build2 (POINTER_PLUS_EXPR,
9772 valist_tmp, size_int (boundary - 1)));
9773 gimplify_and_add (t, pre_p);
9775 t = fold_convert (sizetype, valist_tmp);
9776 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9777 fold_convert (TREE_TYPE (valist),
9778 fold_build2 (BIT_AND_EXPR, sizetype, t,
9779 size_int (-boundary))));
9780 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9781 gimplify_and_add (t, pre_p);
9783 /* Since it is zero-sized there's no increment for the item itself. */
9784 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9785 return build_va_arg_indirect_ref (valist_tmp);
9788 if (DEFAULT_ABI != ABI_V4)
9790 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9792 tree elem_type = TREE_TYPE (type);
9793 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9794 int elem_size = GET_MODE_SIZE (elem_mode);
9796 if (elem_size < UNITS_PER_WORD)
9798 tree real_part, imag_part;
9799 gimple_seq post = NULL;
9801 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9803 /* Copy the value into a temporary, lest the formal temporary
9804 be reused out from under us. */
9805 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9806 gimple_seq_add_seq (pre_p, post);
9808 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9811 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9815 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9818 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9819 f_fpr = DECL_CHAIN (f_gpr);
9820 f_res = DECL_CHAIN (f_fpr);
9821 f_ovf = DECL_CHAIN (f_res);
9822 f_sav = DECL_CHAIN (f_ovf);
9824 valist = build_va_arg_indirect_ref (valist);
9825 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9826 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9828 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9830 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9833 size = int_size_in_bytes (type);
9834 rsize = (size + 3) / 4;
9837 if (TARGET_HARD_FLOAT && TARGET_FPRS
9838 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9839 || (TARGET_DOUBLE_FLOAT
9840 && (TYPE_MODE (type) == DFmode
9841 || TYPE_MODE (type) == TFmode
9842 || TYPE_MODE (type) == SDmode
9843 || TYPE_MODE (type) == DDmode
9844 || TYPE_MODE (type) == TDmode))))
9846 /* FP args go in FP registers, if present. */
9848 n_reg = (size + 7) / 8;
9849 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9850 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9851 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9856 /* Otherwise into GP registers. */
9865 /* Pull the value out of the saved registers.... */
9868 addr = create_tmp_var (ptr_type_node, "addr");
9870 /* AltiVec vectors never go in registers when -mabi=altivec. */
9871 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9875 lab_false = create_artificial_label (input_location);
9876 lab_over = create_artificial_label (input_location);
9878 /* Long long and SPE vectors are aligned in the registers.
9879 As are any other 2 gpr item such as complex int due to a
9880 historical mistake. */
9882 if (n_reg == 2 && reg == gpr)
9885 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9886 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9887 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9888 unshare_expr (reg), u);
9890 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9891 reg number is 0 for f1, so we want to make it odd. */
9892 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9894 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9895 build_int_cst (TREE_TYPE (reg), 1));
9896 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9899 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9900 t = build2 (GE_EXPR, boolean_type_node, u, t);
9901 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9902 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9903 gimplify_and_add (t, pre_p);
9907 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9909 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9910 build_int_cst (TREE_TYPE (reg), n_reg));
9911 u = fold_convert (sizetype, u);
9912 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9913 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9915 /* _Decimal32 varargs are located in the second word of the 64-bit
9916 FP register for 32-bit binaries. */
9917 if (!TARGET_POWERPC64
9918 && TARGET_HARD_FLOAT && TARGET_FPRS
9919 && TYPE_MODE (type) == SDmode)
9920 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9922 gimplify_assign (addr, t, pre_p);
9924 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9926 stmt = gimple_build_label (lab_false);
9927 gimple_seq_add_stmt (pre_p, stmt);
9929 if ((n_reg == 2 && !regalign) || n_reg > 2)
9931 /* Ensure that we don't find any more args in regs.
9932 Alignment has taken care of for special cases. */
9933 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9937 /* ... otherwise out of the overflow area. */
9939 /* Care for on-stack alignment if needed. */
9943 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9944 t = fold_convert (sizetype, t);
9945 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9947 t = fold_convert (TREE_TYPE (ovf), t);
9949 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9951 gimplify_assign (unshare_expr (addr), t, pre_p);
9953 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9954 gimplify_assign (unshare_expr (ovf), t, pre_p);
9958 stmt = gimple_build_label (lab_over);
9959 gimple_seq_add_stmt (pre_p, stmt);
9962 if (STRICT_ALIGNMENT
9963 && (TYPE_ALIGN (type)
9964 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9966 /* The value (of type complex double, for example) may not be
9967 aligned in memory in the saved registers, so copy via a
9968 temporary. (This is the same code as used for SPARC.) */
9969 tree tmp = create_tmp_var (type, "va_arg_tmp");
9970 tree dest_addr = build_fold_addr_expr (tmp);
9972 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9973 3, dest_addr, addr, size_int (rsize * 4));
9975 gimplify_and_add (copy, pre_p);
9979 addr = fold_convert (ptrtype, addr);
9980 return build_va_arg_indirect_ref (addr);
9986 def_builtin (int mask, const char *name, tree type, int code)
9988 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9991 if (rs6000_builtin_decls[code])
9992 fatal_error ("internal error: builtin function to %s already processed",
9995 rs6000_builtin_decls[code] = t =
9996 add_builtin_function (name, type, code, BUILT_IN_MD,
9999 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
10000 switch (builtin_classify[code])
10003 gcc_unreachable ();
10005 /* assume builtin can do anything. */
10006 case RS6000_BTC_MISC:
10009 /* const function, function only depends on the inputs. */
10010 case RS6000_BTC_CONST:
10011 TREE_READONLY (t) = 1;
10012 TREE_NOTHROW (t) = 1;
10015 /* pure function, function can read global memory. */
10016 case RS6000_BTC_PURE:
10017 DECL_PURE_P (t) = 1;
10018 TREE_NOTHROW (t) = 1;
10021 /* Function is a math function. If rounding mode is on, then treat
10022 the function as not reading global memory, but it can have
10023 arbitrary side effects. If it is off, then assume the function is
10024 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10025 attribute in builtin-attribute.def that is used for the math
10027 case RS6000_BTC_FP_PURE:
10028 TREE_NOTHROW (t) = 1;
10029 if (flag_rounding_math)
10031 DECL_PURE_P (t) = 1;
10032 DECL_IS_NOVOPS (t) = 1;
10035 TREE_READONLY (t) = 1;
10041 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10043 static const struct builtin_description bdesc_3arg[] =
10045 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10046 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10047 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10048 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10049 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10050 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10051 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10052 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10053 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10054 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10055 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10056 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10057 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10058 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10059 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10060 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10061 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10062 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10063 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10064 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10065 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10066 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10067 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10068 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10069 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10070 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10071 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10072 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10073 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10074 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10075 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10076 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10077 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10078 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10079 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10081 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10082 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10083 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10084 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10097 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10098 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10099 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10100 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10102 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10103 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10104 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10105 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10107 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10108 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10110 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10111 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10112 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10113 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10114 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10115 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10116 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10117 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10118 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10119 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10121 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10122 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10123 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10124 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10125 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10126 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10127 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10128 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10129 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10130 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10132 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10133 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10134 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10135 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10136 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10137 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10138 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10139 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10140 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10142 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10143 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10144 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10145 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10146 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10147 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10148 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10150 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10151 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10152 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10153 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10154 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10155 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10156 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10157 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10158 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10161 /* DST operations: void foo (void *, const int, const char). */
10163 static const struct builtin_description bdesc_dst[] =
10165 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10166 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10167 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10168 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10170 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10171 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10176 /* Simple binary operations: VECc = foo (VECa, VECb). */
10178 static struct builtin_description bdesc_2arg[] =
10180 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10181 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10182 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10183 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10184 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10185 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10186 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10187 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10188 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10189 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10190 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10191 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10192 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10193 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10194 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10195 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10196 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10197 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10198 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10199 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10200 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10201 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10202 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10203 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10204 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10205 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10206 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10207 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10208 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10209 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10210 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10211 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10212 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10213 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10214 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10215 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10216 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10217 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10218 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10219 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10220 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10221 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10222 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10223 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10224 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10225 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10226 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10227 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10228 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10229 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10230 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10231 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10232 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10233 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10234 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10235 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10236 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10237 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10238 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10239 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10240 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10241 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10242 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10243 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10244 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10245 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10246 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10247 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10248 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10249 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10250 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10251 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10252 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10253 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10254 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10255 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10256 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10257 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10258 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10259 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10260 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10261 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10262 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10263 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10264 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10265 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10266 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10267 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10268 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10269 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10270 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10271 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10272 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10273 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10274 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10275 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10276 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10277 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10278 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10279 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10280 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10281 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10282 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10283 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10284 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10285 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10286 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10287 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10288 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10289 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10290 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10291 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10292 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10293 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10294 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10295 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10296 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10298 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10299 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10300 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10301 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10302 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10303 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10304 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10305 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10306 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10307 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10308 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10309 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10311 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10312 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10313 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10314 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10315 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10316 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10317 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10318 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10319 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10320 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10321 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10322 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10324 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10325 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10326 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10327 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10328 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10329 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10331 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10332 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10333 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10334 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10335 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10336 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10337 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10338 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10339 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10340 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10341 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10342 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10344 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10345 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10346 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10347 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10348 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10349 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10357 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10358 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10361 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10362 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10384 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10385 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10388 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10389 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10400 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10401 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10404 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10405 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10418 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10419 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10422 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10423 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10453 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10454 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10457 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10458 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10472 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10474 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10475 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10477 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10478 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10479 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10480 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10481 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10482 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10483 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10484 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10485 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10486 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10488 /* Place holder, leave as first spe builtin. */
10489 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10490 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10491 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10492 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10493 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10494 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10495 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10496 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10497 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10498 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10499 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10500 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10501 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10502 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10503 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10504 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10505 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10506 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10507 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10508 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10509 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10510 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10511 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10512 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10513 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10514 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10515 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10516 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10517 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10518 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10519 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10520 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10521 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10522 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10523 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10524 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10525 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10526 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10527 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10528 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10529 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10530 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10531 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10532 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10533 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10534 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10535 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10536 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10537 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10538 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10539 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10540 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10541 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10542 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10543 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10544 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10545 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10546 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10547 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10548 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10549 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10550 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10551 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10552 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10553 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10554 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10555 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10556 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10557 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10558 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10559 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10560 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10561 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10562 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10563 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10564 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10565 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10566 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10567 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10568 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10569 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10570 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10571 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10572 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10573 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10574 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10575 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10576 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10577 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10578 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10579 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10580 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10581 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10582 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10583 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10584 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10585 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10586 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10587 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10588 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10589 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10590 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10591 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10592 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10593 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10594 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10595 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10596 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10597 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10599 /* SPE binary operations expecting a 5-bit unsigned literal. */
10600 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10602 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10603 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10604 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10605 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10606 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10607 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10608 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10609 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10610 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10611 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10612 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10613 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10614 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10615 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10616 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10617 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10618 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10619 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10620 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10621 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10622 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10623 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10624 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10625 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10626 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10627 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10629 /* Place-holder. Leave as last binary SPE builtin. */
10630 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10633 /* AltiVec predicates. */
10635 struct builtin_description_predicates
10637 const unsigned int mask;
10638 const enum insn_code icode;
10639 const char *const name;
10640 const enum rs6000_builtins code;
10643 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10645 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10646 ALTIVEC_BUILTIN_VCMPBFP_P },
10647 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10648 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10649 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10650 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10651 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10652 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10653 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10654 ALTIVEC_BUILTIN_VCMPEQUW_P },
10655 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10656 ALTIVEC_BUILTIN_VCMPGTSW_P },
10657 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10658 ALTIVEC_BUILTIN_VCMPGTUW_P },
10659 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10660 ALTIVEC_BUILTIN_VCMPEQUH_P },
10661 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10662 ALTIVEC_BUILTIN_VCMPGTSH_P },
10663 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10664 ALTIVEC_BUILTIN_VCMPGTUH_P },
10665 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10666 ALTIVEC_BUILTIN_VCMPEQUB_P },
10667 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10668 ALTIVEC_BUILTIN_VCMPGTSB_P },
10669 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10670 ALTIVEC_BUILTIN_VCMPGTUB_P },
10672 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10673 VSX_BUILTIN_XVCMPEQSP_P },
10674 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10675 VSX_BUILTIN_XVCMPGESP_P },
10676 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10677 VSX_BUILTIN_XVCMPGTSP_P },
10678 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10679 VSX_BUILTIN_XVCMPEQDP_P },
10680 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10681 VSX_BUILTIN_XVCMPGEDP_P },
10682 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10683 VSX_BUILTIN_XVCMPGTDP_P },
10685 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10686 ALTIVEC_BUILTIN_VCMPEQ_P },
10687 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10688 ALTIVEC_BUILTIN_VCMPGT_P },
10689 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10690 ALTIVEC_BUILTIN_VCMPGE_P }
10693 /* SPE predicates. */
10694 static struct builtin_description bdesc_spe_predicates[] =
10696 /* Place-holder. Leave as first. */
10697 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10698 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10699 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10700 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10701 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10702 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10703 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10704 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10705 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10706 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10707 /* Place-holder. Leave as last. */
10708 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10711 /* SPE evsel predicates. */
10712 static struct builtin_description bdesc_spe_evsel[] =
10714 /* Place-holder. Leave as first. */
10715 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10716 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10717 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10718 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10719 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10720 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10721 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10722 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10723 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10724 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10725 /* Place-holder. Leave as last. */
10726 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10729 /* PAIRED predicates. */
10730 static const struct builtin_description bdesc_paired_preds[] =
10732 /* Place-holder. Leave as first. */
10733 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10734 /* Place-holder. Leave as last. */
10735 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10738 /* ABS* operations. */
10740 static const struct builtin_description bdesc_abs[] =
10742 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10743 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10744 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10745 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10746 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10747 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10748 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10749 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10750 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10751 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10752 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10755 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10758 static struct builtin_description bdesc_1arg[] =
10760 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10761 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10762 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10763 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10764 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10765 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10766 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10767 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10768 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10769 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10770 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10771 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10772 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10773 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10774 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10775 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10776 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10777 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10779 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10780 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10781 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10782 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10783 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10784 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10785 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10787 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10788 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10789 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10790 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10791 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10792 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10793 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10795 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10796 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10797 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10798 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10799 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10800 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10802 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10803 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10804 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10805 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10806 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10807 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10809 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10810 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10811 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10812 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10814 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10815 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10816 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10817 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10818 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10819 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10820 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10821 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10822 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10824 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10825 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10826 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10827 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10828 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10829 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10830 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10831 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10832 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10834 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10835 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10836 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10837 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10838 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10861 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10862 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10863 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10865 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10866 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10867 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10868 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10870 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10871 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10872 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10873 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10874 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10875 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10876 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10877 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10878 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10879 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10880 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10881 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10882 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10883 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10884 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10885 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10886 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10887 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10888 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10889 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10890 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10891 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10892 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10893 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10894 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10895 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10896 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10897 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10898 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10899 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10901 /* Place-holder. Leave as last unary SPE builtin. */
10902 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10904 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10905 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10906 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10907 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10908 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10912 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10915 tree arg0 = CALL_EXPR_ARG (exp, 0);
10916 rtx op0 = expand_normal (arg0);
10917 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10918 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10920 if (icode == CODE_FOR_nothing)
10921 /* Builtin not supported on this processor. */
10924 /* If we got invalid arguments bail out before generating bad rtl. */
10925 if (arg0 == error_mark_node)
10928 if (icode == CODE_FOR_altivec_vspltisb
10929 || icode == CODE_FOR_altivec_vspltish
10930 || icode == CODE_FOR_altivec_vspltisw
10931 || icode == CODE_FOR_spe_evsplatfi
10932 || icode == CODE_FOR_spe_evsplati)
10934 /* Only allow 5-bit *signed* literals. */
10935 if (GET_CODE (op0) != CONST_INT
10936 || INTVAL (op0) > 15
10937 || INTVAL (op0) < -16)
10939 error ("argument 1 must be a 5-bit signed literal");
10945 || GET_MODE (target) != tmode
10946 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10947 target = gen_reg_rtx (tmode);
10949 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10950 op0 = copy_to_mode_reg (mode0, op0);
10952 pat = GEN_FCN (icode) (target, op0);
10961 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10963 rtx pat, scratch1, scratch2;
10964 tree arg0 = CALL_EXPR_ARG (exp, 0);
10965 rtx op0 = expand_normal (arg0);
10966 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10967 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10969 /* If we have invalid arguments, bail out before generating bad rtl. */
10970 if (arg0 == error_mark_node)
10974 || GET_MODE (target) != tmode
10975 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10976 target = gen_reg_rtx (tmode);
10978 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10979 op0 = copy_to_mode_reg (mode0, op0);
10981 scratch1 = gen_reg_rtx (mode0);
10982 scratch2 = gen_reg_rtx (mode0);
10984 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10993 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
10996 tree arg0 = CALL_EXPR_ARG (exp, 0);
10997 tree arg1 = CALL_EXPR_ARG (exp, 1);
10998 rtx op0 = expand_normal (arg0);
10999 rtx op1 = expand_normal (arg1);
11000 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11001 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11002 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11004 if (icode == CODE_FOR_nothing)
11005 /* Builtin not supported on this processor. */
11008 /* If we got invalid arguments bail out before generating bad rtl. */
11009 if (arg0 == error_mark_node || arg1 == error_mark_node)
11012 if (icode == CODE_FOR_altivec_vcfux
11013 || icode == CODE_FOR_altivec_vcfsx
11014 || icode == CODE_FOR_altivec_vctsxs
11015 || icode == CODE_FOR_altivec_vctuxs
11016 || icode == CODE_FOR_altivec_vspltb
11017 || icode == CODE_FOR_altivec_vsplth
11018 || icode == CODE_FOR_altivec_vspltw
11019 || icode == CODE_FOR_spe_evaddiw
11020 || icode == CODE_FOR_spe_evldd
11021 || icode == CODE_FOR_spe_evldh
11022 || icode == CODE_FOR_spe_evldw
11023 || icode == CODE_FOR_spe_evlhhesplat
11024 || icode == CODE_FOR_spe_evlhhossplat
11025 || icode == CODE_FOR_spe_evlhhousplat
11026 || icode == CODE_FOR_spe_evlwhe
11027 || icode == CODE_FOR_spe_evlwhos
11028 || icode == CODE_FOR_spe_evlwhou
11029 || icode == CODE_FOR_spe_evlwhsplat
11030 || icode == CODE_FOR_spe_evlwwsplat
11031 || icode == CODE_FOR_spe_evrlwi
11032 || icode == CODE_FOR_spe_evslwi
11033 || icode == CODE_FOR_spe_evsrwis
11034 || icode == CODE_FOR_spe_evsubifw
11035 || icode == CODE_FOR_spe_evsrwiu)
11037 /* Only allow 5-bit unsigned literals. */
11039 if (TREE_CODE (arg1) != INTEGER_CST
11040 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11042 error ("argument 2 must be a 5-bit unsigned literal");
11048 || GET_MODE (target) != tmode
11049 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11050 target = gen_reg_rtx (tmode);
11052 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11053 op0 = copy_to_mode_reg (mode0, op0);
11054 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11055 op1 = copy_to_mode_reg (mode1, op1);
11057 pat = GEN_FCN (icode) (target, op0, op1);
11066 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11069 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11070 tree arg0 = CALL_EXPR_ARG (exp, 1);
11071 tree arg1 = CALL_EXPR_ARG (exp, 2);
11072 rtx op0 = expand_normal (arg0);
11073 rtx op1 = expand_normal (arg1);
11074 enum machine_mode tmode = SImode;
11075 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11076 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11079 if (TREE_CODE (cr6_form) != INTEGER_CST)
11081 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11085 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11087 gcc_assert (mode0 == mode1);
11089 /* If we have invalid arguments, bail out before generating bad rtl. */
11090 if (arg0 == error_mark_node || arg1 == error_mark_node)
11094 || GET_MODE (target) != tmode
11095 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11096 target = gen_reg_rtx (tmode);
11098 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11099 op0 = copy_to_mode_reg (mode0, op0);
11100 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11101 op1 = copy_to_mode_reg (mode1, op1);
11103 scratch = gen_reg_rtx (mode0);
11105 pat = GEN_FCN (icode) (scratch, op0, op1);
11110 /* The vec_any* and vec_all* predicates use the same opcodes for two
11111 different operations, but the bits in CR6 will be different
11112 depending on what information we want. So we have to play tricks
11113 with CR6 to get the right bits out.
11115 If you think this is disgusting, look at the specs for the
11116 AltiVec predicates. */
11118 switch (cr6_form_int)
11121 emit_insn (gen_cr6_test_for_zero (target));
11124 emit_insn (gen_cr6_test_for_zero_reverse (target));
11127 emit_insn (gen_cr6_test_for_lt (target));
11130 emit_insn (gen_cr6_test_for_lt_reverse (target));
11133 error ("argument 1 of __builtin_altivec_predicate is out of range");
11141 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11144 tree arg0 = CALL_EXPR_ARG (exp, 0);
11145 tree arg1 = CALL_EXPR_ARG (exp, 1);
11146 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11147 enum machine_mode mode0 = Pmode;
11148 enum machine_mode mode1 = Pmode;
11149 rtx op0 = expand_normal (arg0);
11150 rtx op1 = expand_normal (arg1);
11152 if (icode == CODE_FOR_nothing)
11153 /* Builtin not supported on this processor. */
11156 /* If we got invalid arguments bail out before generating bad rtl. */
11157 if (arg0 == error_mark_node || arg1 == error_mark_node)
11161 || GET_MODE (target) != tmode
11162 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11163 target = gen_reg_rtx (tmode);
11165 op1 = copy_to_mode_reg (mode1, op1);
11167 if (op0 == const0_rtx)
11169 addr = gen_rtx_MEM (tmode, op1);
11173 op0 = copy_to_mode_reg (mode0, op0);
11174 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11177 pat = GEN_FCN (icode) (target, addr);
11187 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11190 tree arg0 = CALL_EXPR_ARG (exp, 0);
11191 tree arg1 = CALL_EXPR_ARG (exp, 1);
11192 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11193 enum machine_mode mode0 = Pmode;
11194 enum machine_mode mode1 = Pmode;
11195 rtx op0 = expand_normal (arg0);
11196 rtx op1 = expand_normal (arg1);
11198 if (icode == CODE_FOR_nothing)
11199 /* Builtin not supported on this processor. */
11202 /* If we got invalid arguments bail out before generating bad rtl. */
11203 if (arg0 == error_mark_node || arg1 == error_mark_node)
11207 || GET_MODE (target) != tmode
11208 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11209 target = gen_reg_rtx (tmode);
11211 op1 = copy_to_mode_reg (mode1, op1);
11213 if (op0 == const0_rtx)
11215 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11219 op0 = copy_to_mode_reg (mode0, op0);
11220 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11223 pat = GEN_FCN (icode) (target, addr);
11233 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11235 tree arg0 = CALL_EXPR_ARG (exp, 0);
11236 tree arg1 = CALL_EXPR_ARG (exp, 1);
11237 tree arg2 = CALL_EXPR_ARG (exp, 2);
11238 rtx op0 = expand_normal (arg0);
11239 rtx op1 = expand_normal (arg1);
11240 rtx op2 = expand_normal (arg2);
11242 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11243 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11244 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11246 /* Invalid arguments. Bail before doing anything stoopid! */
11247 if (arg0 == error_mark_node
11248 || arg1 == error_mark_node
11249 || arg2 == error_mark_node)
11252 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11253 op0 = copy_to_mode_reg (mode2, op0);
11254 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11255 op1 = copy_to_mode_reg (mode0, op1);
11256 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11257 op2 = copy_to_mode_reg (mode1, op2);
11259 pat = GEN_FCN (icode) (op1, op2, op0);
11266 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11268 tree arg0 = CALL_EXPR_ARG (exp, 0);
11269 tree arg1 = CALL_EXPR_ARG (exp, 1);
11270 tree arg2 = CALL_EXPR_ARG (exp, 2);
11271 rtx op0 = expand_normal (arg0);
11272 rtx op1 = expand_normal (arg1);
11273 rtx op2 = expand_normal (arg2);
11275 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11276 enum machine_mode mode1 = Pmode;
11277 enum machine_mode mode2 = Pmode;
11279 /* Invalid arguments. Bail before doing anything stoopid! */
11280 if (arg0 == error_mark_node
11281 || arg1 == error_mark_node
11282 || arg2 == error_mark_node)
11285 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11286 op0 = copy_to_mode_reg (tmode, op0);
11288 op2 = copy_to_mode_reg (mode2, op2);
11290 if (op1 == const0_rtx)
11292 addr = gen_rtx_MEM (tmode, op2);
11296 op1 = copy_to_mode_reg (mode1, op1);
11297 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11300 pat = GEN_FCN (icode) (addr, op0);
11307 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11309 tree arg0 = CALL_EXPR_ARG (exp, 0);
11310 tree arg1 = CALL_EXPR_ARG (exp, 1);
11311 tree arg2 = CALL_EXPR_ARG (exp, 2);
11312 rtx op0 = expand_normal (arg0);
11313 rtx op1 = expand_normal (arg1);
11314 rtx op2 = expand_normal (arg2);
11316 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11317 enum machine_mode smode = insn_data[icode].operand[1].mode;
11318 enum machine_mode mode1 = Pmode;
11319 enum machine_mode mode2 = Pmode;
11321 /* Invalid arguments. Bail before doing anything stoopid! */
11322 if (arg0 == error_mark_node
11323 || arg1 == error_mark_node
11324 || arg2 == error_mark_node)
11327 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11328 op0 = copy_to_mode_reg (smode, op0);
11330 op2 = copy_to_mode_reg (mode2, op2);
11332 if (op1 == const0_rtx)
11334 addr = gen_rtx_MEM (tmode, op2);
11338 op1 = copy_to_mode_reg (mode1, op1);
11339 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11342 pat = GEN_FCN (icode) (addr, op0);
11349 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11352 tree arg0 = CALL_EXPR_ARG (exp, 0);
11353 tree arg1 = CALL_EXPR_ARG (exp, 1);
11354 tree arg2 = CALL_EXPR_ARG (exp, 2);
11355 rtx op0 = expand_normal (arg0);
11356 rtx op1 = expand_normal (arg1);
11357 rtx op2 = expand_normal (arg2);
11358 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11359 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11360 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11361 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11363 if (icode == CODE_FOR_nothing)
11364 /* Builtin not supported on this processor. */
11367 /* If we got invalid arguments bail out before generating bad rtl. */
11368 if (arg0 == error_mark_node
11369 || arg1 == error_mark_node
11370 || arg2 == error_mark_node)
11373 /* Check and prepare argument depending on the instruction code.
11375 Note that a switch statement instead of the sequence of tests
11376 would be incorrect as many of the CODE_FOR values could be
11377 CODE_FOR_nothing and that would yield multiple alternatives
11378 with identical values. We'd never reach here at runtime in
11380 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11381 || icode == CODE_FOR_altivec_vsldoi_v4si
11382 || icode == CODE_FOR_altivec_vsldoi_v8hi
11383 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11385 /* Only allow 4-bit unsigned literals. */
11387 if (TREE_CODE (arg2) != INTEGER_CST
11388 || TREE_INT_CST_LOW (arg2) & ~0xf)
11390 error ("argument 3 must be a 4-bit unsigned literal");
11394 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11395 || icode == CODE_FOR_vsx_xxpermdi_v2di
11396 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11397 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11398 || icode == CODE_FOR_vsx_xxsldwi_v4si
11399 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11400 || icode == CODE_FOR_vsx_xxsldwi_v2di
11401 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11403 /* Only allow 2-bit unsigned literals. */
11405 if (TREE_CODE (arg2) != INTEGER_CST
11406 || TREE_INT_CST_LOW (arg2) & ~0x3)
11408 error ("argument 3 must be a 2-bit unsigned literal");
11412 else if (icode == CODE_FOR_vsx_set_v2df
11413 || icode == CODE_FOR_vsx_set_v2di)
11415 /* Only allow 1-bit unsigned literals. */
11417 if (TREE_CODE (arg2) != INTEGER_CST
11418 || TREE_INT_CST_LOW (arg2) & ~0x1)
11420 error ("argument 3 must be a 1-bit unsigned literal");
11426 || GET_MODE (target) != tmode
11427 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11428 target = gen_reg_rtx (tmode);
11430 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11431 op0 = copy_to_mode_reg (mode0, op0);
11432 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11433 op1 = copy_to_mode_reg (mode1, op1);
11434 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11435 op2 = copy_to_mode_reg (mode2, op2);
11437 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11438 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11440 pat = GEN_FCN (icode) (target, op0, op1, op2);
11448 /* Expand the lvx builtins. */
11450 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11452 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11453 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11455 enum machine_mode tmode, mode0;
11457 enum insn_code icode;
11461 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11462 icode = CODE_FOR_vector_altivec_load_v16qi;
11464 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11465 icode = CODE_FOR_vector_altivec_load_v8hi;
11467 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11468 icode = CODE_FOR_vector_altivec_load_v4si;
11470 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11471 icode = CODE_FOR_vector_altivec_load_v4sf;
11473 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11474 icode = CODE_FOR_vector_altivec_load_v2df;
11476 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11477 icode = CODE_FOR_vector_altivec_load_v2di;
11480 *expandedp = false;
11486 arg0 = CALL_EXPR_ARG (exp, 0);
11487 op0 = expand_normal (arg0);
11488 tmode = insn_data[icode].operand[0].mode;
11489 mode0 = insn_data[icode].operand[1].mode;
11492 || GET_MODE (target) != tmode
11493 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11494 target = gen_reg_rtx (tmode);
11496 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11497 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11499 pat = GEN_FCN (icode) (target, op0);
11506 /* Expand the stvx builtins. */
11508 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11511 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11512 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11514 enum machine_mode mode0, mode1;
11516 enum insn_code icode;
11520 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11521 icode = CODE_FOR_vector_altivec_store_v16qi;
11523 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11524 icode = CODE_FOR_vector_altivec_store_v8hi;
11526 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11527 icode = CODE_FOR_vector_altivec_store_v4si;
11529 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11530 icode = CODE_FOR_vector_altivec_store_v4sf;
11532 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11533 icode = CODE_FOR_vector_altivec_store_v2df;
11535 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11536 icode = CODE_FOR_vector_altivec_store_v2di;
11539 *expandedp = false;
11543 arg0 = CALL_EXPR_ARG (exp, 0);
11544 arg1 = CALL_EXPR_ARG (exp, 1);
11545 op0 = expand_normal (arg0);
11546 op1 = expand_normal (arg1);
11547 mode0 = insn_data[icode].operand[0].mode;
11548 mode1 = insn_data[icode].operand[1].mode;
11550 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11551 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11552 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11553 op1 = copy_to_mode_reg (mode1, op1);
11555 pat = GEN_FCN (icode) (op0, op1);
11563 /* Expand the dst builtins. */
11565 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11568 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11569 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11570 tree arg0, arg1, arg2;
11571 enum machine_mode mode0, mode1;
11572 rtx pat, op0, op1, op2;
11573 const struct builtin_description *d;
11576 *expandedp = false;
11578 /* Handle DST variants. */
11580 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11581 if (d->code == fcode)
11583 arg0 = CALL_EXPR_ARG (exp, 0);
11584 arg1 = CALL_EXPR_ARG (exp, 1);
11585 arg2 = CALL_EXPR_ARG (exp, 2);
11586 op0 = expand_normal (arg0);
11587 op1 = expand_normal (arg1);
11588 op2 = expand_normal (arg2);
11589 mode0 = insn_data[d->icode].operand[0].mode;
11590 mode1 = insn_data[d->icode].operand[1].mode;
11592 /* Invalid arguments, bail out before generating bad rtl. */
11593 if (arg0 == error_mark_node
11594 || arg1 == error_mark_node
11595 || arg2 == error_mark_node)
11600 if (TREE_CODE (arg2) != INTEGER_CST
11601 || TREE_INT_CST_LOW (arg2) & ~0x3)
11603 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11607 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11608 op0 = copy_to_mode_reg (Pmode, op0);
11609 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11610 op1 = copy_to_mode_reg (mode1, op1);
11612 pat = GEN_FCN (d->icode) (op0, op1, op2);
11622 /* Expand vec_init builtin. */
11624 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11626 enum machine_mode tmode = TYPE_MODE (type);
11627 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11628 int i, n_elt = GET_MODE_NUNITS (tmode);
11629 rtvec v = rtvec_alloc (n_elt);
11631 gcc_assert (VECTOR_MODE_P (tmode));
11632 gcc_assert (n_elt == call_expr_nargs (exp));
11634 for (i = 0; i < n_elt; ++i)
11636 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11637 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11640 if (!target || !register_operand (target, tmode))
11641 target = gen_reg_rtx (tmode);
11643 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11647 /* Return the integer constant in ARG. Constrain it to be in the range
11648 of the subparts of VEC_TYPE; issue an error if not. */
11651 get_element_number (tree vec_type, tree arg)
11653 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11655 if (!host_integerp (arg, 1)
11656 || (elt = tree_low_cst (arg, 1), elt > max))
11658 error ("selector must be an integer constant in the range 0..%wi", max);
11665 /* Expand vec_set builtin. */
11667 altivec_expand_vec_set_builtin (tree exp)
11669 enum machine_mode tmode, mode1;
11670 tree arg0, arg1, arg2;
11674 arg0 = CALL_EXPR_ARG (exp, 0);
11675 arg1 = CALL_EXPR_ARG (exp, 1);
11676 arg2 = CALL_EXPR_ARG (exp, 2);
11678 tmode = TYPE_MODE (TREE_TYPE (arg0));
11679 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11680 gcc_assert (VECTOR_MODE_P (tmode));
11682 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11683 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11684 elt = get_element_number (TREE_TYPE (arg0), arg2);
11686 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11687 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11689 op0 = force_reg (tmode, op0);
11690 op1 = force_reg (mode1, op1);
11692 rs6000_expand_vector_set (op0, op1, elt);
11697 /* Expand vec_ext builtin. */
11699 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11701 enum machine_mode tmode, mode0;
11706 arg0 = CALL_EXPR_ARG (exp, 0);
11707 arg1 = CALL_EXPR_ARG (exp, 1);
11709 op0 = expand_normal (arg0);
11710 elt = get_element_number (TREE_TYPE (arg0), arg1);
11712 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11713 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11714 gcc_assert (VECTOR_MODE_P (mode0));
11716 op0 = force_reg (mode0, op0);
11718 if (optimize || !target || !register_operand (target, tmode))
11719 target = gen_reg_rtx (tmode);
11721 rs6000_expand_vector_extract (target, op0, elt);
11726 /* Expand the builtin in EXP and store the result in TARGET. Store
11727 true in *EXPANDEDP if we found a builtin to expand. */
11729 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11731 const struct builtin_description *d;
11732 const struct builtin_description_predicates *dp;
11734 enum insn_code icode;
11735 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11738 enum machine_mode tmode, mode0;
11739 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11741 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11742 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11743 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11744 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11747 error ("unresolved overload for Altivec builtin %qF", fndecl);
11751 target = altivec_expand_ld_builtin (exp, target, expandedp);
11755 target = altivec_expand_st_builtin (exp, target, expandedp);
11759 target = altivec_expand_dst_builtin (exp, target, expandedp);
11767 case ALTIVEC_BUILTIN_STVX:
11768 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11769 case ALTIVEC_BUILTIN_STVEBX:
11770 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11771 case ALTIVEC_BUILTIN_STVEHX:
11772 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11773 case ALTIVEC_BUILTIN_STVEWX:
11774 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11775 case ALTIVEC_BUILTIN_STVXL:
11776 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11778 case ALTIVEC_BUILTIN_STVLX:
11779 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11780 case ALTIVEC_BUILTIN_STVLXL:
11781 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11782 case ALTIVEC_BUILTIN_STVRX:
11783 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11784 case ALTIVEC_BUILTIN_STVRXL:
11785 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11787 case VSX_BUILTIN_STXVD2X_V2DF:
11788 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11789 case VSX_BUILTIN_STXVD2X_V2DI:
11790 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11791 case VSX_BUILTIN_STXVW4X_V4SF:
11792 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11793 case VSX_BUILTIN_STXVW4X_V4SI:
11794 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11795 case VSX_BUILTIN_STXVW4X_V8HI:
11796 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11797 case VSX_BUILTIN_STXVW4X_V16QI:
11798 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11800 case ALTIVEC_BUILTIN_MFVSCR:
11801 icode = CODE_FOR_altivec_mfvscr;
11802 tmode = insn_data[icode].operand[0].mode;
11805 || GET_MODE (target) != tmode
11806 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11807 target = gen_reg_rtx (tmode);
11809 pat = GEN_FCN (icode) (target);
11815 case ALTIVEC_BUILTIN_MTVSCR:
11816 icode = CODE_FOR_altivec_mtvscr;
11817 arg0 = CALL_EXPR_ARG (exp, 0);
11818 op0 = expand_normal (arg0);
11819 mode0 = insn_data[icode].operand[0].mode;
11821 /* If we got invalid arguments bail out before generating bad rtl. */
11822 if (arg0 == error_mark_node)
11825 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11826 op0 = copy_to_mode_reg (mode0, op0);
11828 pat = GEN_FCN (icode) (op0);
11833 case ALTIVEC_BUILTIN_DSSALL:
11834 emit_insn (gen_altivec_dssall ());
11837 case ALTIVEC_BUILTIN_DSS:
11838 icode = CODE_FOR_altivec_dss;
11839 arg0 = CALL_EXPR_ARG (exp, 0);
11841 op0 = expand_normal (arg0);
11842 mode0 = insn_data[icode].operand[0].mode;
11844 /* If we got invalid arguments bail out before generating bad rtl. */
11845 if (arg0 == error_mark_node)
11848 if (TREE_CODE (arg0) != INTEGER_CST
11849 || TREE_INT_CST_LOW (arg0) & ~0x3)
11851 error ("argument to dss must be a 2-bit unsigned literal");
11855 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11856 op0 = copy_to_mode_reg (mode0, op0);
11858 emit_insn (gen_altivec_dss (op0));
11861 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11862 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11863 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11864 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11865 case VSX_BUILTIN_VEC_INIT_V2DF:
11866 case VSX_BUILTIN_VEC_INIT_V2DI:
11867 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11869 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11870 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11871 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11872 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11873 case VSX_BUILTIN_VEC_SET_V2DF:
11874 case VSX_BUILTIN_VEC_SET_V2DI:
11875 return altivec_expand_vec_set_builtin (exp);
11877 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11878 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11879 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11880 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11881 case VSX_BUILTIN_VEC_EXT_V2DF:
11882 case VSX_BUILTIN_VEC_EXT_V2DI:
11883 return altivec_expand_vec_ext_builtin (exp, target);
11887 /* Fall through. */
11890 /* Expand abs* operations. */
11892 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11893 if (d->code == fcode)
11894 return altivec_expand_abs_builtin (d->icode, exp, target);
11896 /* Expand the AltiVec predicates. */
11897 dp = bdesc_altivec_preds;
11898 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11899 if (dp->code == fcode)
11900 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11902 /* LV* are funky. We initialized them differently. */
11905 case ALTIVEC_BUILTIN_LVSL:
11906 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11907 exp, target, false);
11908 case ALTIVEC_BUILTIN_LVSR:
11909 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11910 exp, target, false);
11911 case ALTIVEC_BUILTIN_LVEBX:
11912 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11913 exp, target, false);
11914 case ALTIVEC_BUILTIN_LVEHX:
11915 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11916 exp, target, false);
11917 case ALTIVEC_BUILTIN_LVEWX:
11918 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11919 exp, target, false);
11920 case ALTIVEC_BUILTIN_LVXL:
11921 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11922 exp, target, false);
11923 case ALTIVEC_BUILTIN_LVX:
11924 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11925 exp, target, false);
11926 case ALTIVEC_BUILTIN_LVLX:
11927 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11928 exp, target, true);
11929 case ALTIVEC_BUILTIN_LVLXL:
11930 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11931 exp, target, true);
11932 case ALTIVEC_BUILTIN_LVRX:
11933 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11934 exp, target, true);
11935 case ALTIVEC_BUILTIN_LVRXL:
11936 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11937 exp, target, true);
11938 case VSX_BUILTIN_LXVD2X_V2DF:
11939 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11940 exp, target, false);
11941 case VSX_BUILTIN_LXVD2X_V2DI:
11942 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11943 exp, target, false);
11944 case VSX_BUILTIN_LXVW4X_V4SF:
11945 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11946 exp, target, false);
11947 case VSX_BUILTIN_LXVW4X_V4SI:
11948 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11949 exp, target, false);
11950 case VSX_BUILTIN_LXVW4X_V8HI:
11951 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11952 exp, target, false);
11953 case VSX_BUILTIN_LXVW4X_V16QI:
11954 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11955 exp, target, false);
11959 /* Fall through. */
11962 *expandedp = false;
11966 /* Expand the builtin in EXP and store the result in TARGET. Store
11967 true in *EXPANDEDP if we found a builtin to expand. */
11969 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11971 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11972 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11973 const struct builtin_description *d;
11980 case PAIRED_BUILTIN_STX:
11981 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11982 case PAIRED_BUILTIN_LX:
11983 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11986 /* Fall through. */
11989 /* Expand the paired predicates. */
11990 d = bdesc_paired_preds;
11991 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11992 if (d->code == fcode)
11993 return paired_expand_predicate_builtin (d->icode, exp, target);
11995 *expandedp = false;
11999 /* Binops that need to be initialized manually, but can be expanded
12000 automagically by rs6000_expand_binop_builtin. */
12001 static struct builtin_description bdesc_2arg_spe[] =
12003 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
12004 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
12005 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
12006 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
12007 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
12008 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12009 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12010 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12011 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12012 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12013 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12014 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12015 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12016 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12017 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12018 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12019 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12020 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12021 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12022 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12023 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12024 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12027 /* Expand the builtin in EXP and store the result in TARGET. Store
12028 true in *EXPANDEDP if we found a builtin to expand.
12030 This expands the SPE builtins that are not simple unary and binary
12033 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12035 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12037 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12038 enum insn_code icode;
12039 enum machine_mode tmode, mode0;
12041 struct builtin_description *d;
12046 /* Syntax check for a 5-bit unsigned immediate. */
12049 case SPE_BUILTIN_EVSTDD:
12050 case SPE_BUILTIN_EVSTDH:
12051 case SPE_BUILTIN_EVSTDW:
12052 case SPE_BUILTIN_EVSTWHE:
12053 case SPE_BUILTIN_EVSTWHO:
12054 case SPE_BUILTIN_EVSTWWE:
12055 case SPE_BUILTIN_EVSTWWO:
12056 arg1 = CALL_EXPR_ARG (exp, 2);
12057 if (TREE_CODE (arg1) != INTEGER_CST
12058 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12060 error ("argument 2 must be a 5-bit unsigned literal");
12068 /* The evsplat*i instructions are not quite generic. */
12071 case SPE_BUILTIN_EVSPLATFI:
12072 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12074 case SPE_BUILTIN_EVSPLATI:
12075 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12081 d = (struct builtin_description *) bdesc_2arg_spe;
12082 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12083 if (d->code == fcode)
12084 return rs6000_expand_binop_builtin (d->icode, exp, target);
12086 d = (struct builtin_description *) bdesc_spe_predicates;
12087 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12088 if (d->code == fcode)
12089 return spe_expand_predicate_builtin (d->icode, exp, target);
12091 d = (struct builtin_description *) bdesc_spe_evsel;
12092 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12093 if (d->code == fcode)
12094 return spe_expand_evsel_builtin (d->icode, exp, target);
12098 case SPE_BUILTIN_EVSTDDX:
12099 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12100 case SPE_BUILTIN_EVSTDHX:
12101 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12102 case SPE_BUILTIN_EVSTDWX:
12103 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12104 case SPE_BUILTIN_EVSTWHEX:
12105 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12106 case SPE_BUILTIN_EVSTWHOX:
12107 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12108 case SPE_BUILTIN_EVSTWWEX:
12109 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12110 case SPE_BUILTIN_EVSTWWOX:
12111 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12112 case SPE_BUILTIN_EVSTDD:
12113 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12114 case SPE_BUILTIN_EVSTDH:
12115 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12116 case SPE_BUILTIN_EVSTDW:
12117 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12118 case SPE_BUILTIN_EVSTWHE:
12119 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12120 case SPE_BUILTIN_EVSTWHO:
12121 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12122 case SPE_BUILTIN_EVSTWWE:
12123 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12124 case SPE_BUILTIN_EVSTWWO:
12125 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12126 case SPE_BUILTIN_MFSPEFSCR:
12127 icode = CODE_FOR_spe_mfspefscr;
12128 tmode = insn_data[icode].operand[0].mode;
12131 || GET_MODE (target) != tmode
12132 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12133 target = gen_reg_rtx (tmode);
12135 pat = GEN_FCN (icode) (target);
12140 case SPE_BUILTIN_MTSPEFSCR:
12141 icode = CODE_FOR_spe_mtspefscr;
12142 arg0 = CALL_EXPR_ARG (exp, 0);
12143 op0 = expand_normal (arg0);
12144 mode0 = insn_data[icode].operand[0].mode;
12146 if (arg0 == error_mark_node)
12149 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12150 op0 = copy_to_mode_reg (mode0, op0);
12152 pat = GEN_FCN (icode) (op0);
12160 *expandedp = false;
12165 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12167 rtx pat, scratch, tmp;
12168 tree form = CALL_EXPR_ARG (exp, 0);
12169 tree arg0 = CALL_EXPR_ARG (exp, 1);
12170 tree arg1 = CALL_EXPR_ARG (exp, 2);
12171 rtx op0 = expand_normal (arg0);
12172 rtx op1 = expand_normal (arg1);
12173 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12174 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12176 enum rtx_code code;
12178 if (TREE_CODE (form) != INTEGER_CST)
12180 error ("argument 1 of __builtin_paired_predicate must be a constant");
12184 form_int = TREE_INT_CST_LOW (form);
12186 gcc_assert (mode0 == mode1);
12188 if (arg0 == error_mark_node || arg1 == error_mark_node)
12192 || GET_MODE (target) != SImode
12193 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12194 target = gen_reg_rtx (SImode);
12195 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12196 op0 = copy_to_mode_reg (mode0, op0);
12197 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12198 op1 = copy_to_mode_reg (mode1, op1);
12200 scratch = gen_reg_rtx (CCFPmode);
12202 pat = GEN_FCN (icode) (scratch, op0, op1);
12224 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12227 error ("argument 1 of __builtin_paired_predicate is out of range");
12231 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12232 emit_move_insn (target, tmp);
12237 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12239 rtx pat, scratch, tmp;
12240 tree form = CALL_EXPR_ARG (exp, 0);
12241 tree arg0 = CALL_EXPR_ARG (exp, 1);
12242 tree arg1 = CALL_EXPR_ARG (exp, 2);
12243 rtx op0 = expand_normal (arg0);
12244 rtx op1 = expand_normal (arg1);
12245 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12246 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12248 enum rtx_code code;
12250 if (TREE_CODE (form) != INTEGER_CST)
12252 error ("argument 1 of __builtin_spe_predicate must be a constant");
12256 form_int = TREE_INT_CST_LOW (form);
12258 gcc_assert (mode0 == mode1);
12260 if (arg0 == error_mark_node || arg1 == error_mark_node)
12264 || GET_MODE (target) != SImode
12265 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12266 target = gen_reg_rtx (SImode);
12268 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12269 op0 = copy_to_mode_reg (mode0, op0);
12270 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12271 op1 = copy_to_mode_reg (mode1, op1);
12273 scratch = gen_reg_rtx (CCmode);
12275 pat = GEN_FCN (icode) (scratch, op0, op1);
12280 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12281 _lower_. We use one compare, but look in different bits of the
12282 CR for each variant.
12284 There are 2 elements in each SPE simd type (upper/lower). The CR
12285 bits are set as follows:
12287 BIT0 | BIT 1 | BIT 2 | BIT 3
12288 U | L | (U | L) | (U & L)
12290 So, for an "all" relationship, BIT 3 would be set.
12291 For an "any" relationship, BIT 2 would be set. Etc.
12293 Following traditional nomenclature, these bits map to:
12295 BIT0 | BIT 1 | BIT 2 | BIT 3
12298 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12303 /* All variant. OV bit. */
12305 /* We need to get to the OV bit, which is the ORDERED bit. We
12306 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12307 that's ugly and will make validate_condition_mode die.
12308 So let's just use another pattern. */
12309 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12311 /* Any variant. EQ bit. */
12315 /* Upper variant. LT bit. */
12319 /* Lower variant. GT bit. */
12324 error ("argument 1 of __builtin_spe_predicate is out of range");
12328 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12329 emit_move_insn (target, tmp);
12334 /* The evsel builtins look like this:
12336 e = __builtin_spe_evsel_OP (a, b, c, d);
12338 and work like this:
12340 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12341 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12345 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12348 tree arg0 = CALL_EXPR_ARG (exp, 0);
12349 tree arg1 = CALL_EXPR_ARG (exp, 1);
12350 tree arg2 = CALL_EXPR_ARG (exp, 2);
12351 tree arg3 = CALL_EXPR_ARG (exp, 3);
12352 rtx op0 = expand_normal (arg0);
12353 rtx op1 = expand_normal (arg1);
12354 rtx op2 = expand_normal (arg2);
12355 rtx op3 = expand_normal (arg3);
12356 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12357 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12359 gcc_assert (mode0 == mode1);
12361 if (arg0 == error_mark_node || arg1 == error_mark_node
12362 || arg2 == error_mark_node || arg3 == error_mark_node)
12366 || GET_MODE (target) != mode0
12367 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12368 target = gen_reg_rtx (mode0);
12370 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12371 op0 = copy_to_mode_reg (mode0, op0);
12372 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12373 op1 = copy_to_mode_reg (mode0, op1);
12374 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12375 op2 = copy_to_mode_reg (mode0, op2);
12376 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12377 op3 = copy_to_mode_reg (mode0, op3);
12379 /* Generate the compare. */
12380 scratch = gen_reg_rtx (CCmode);
12381 pat = GEN_FCN (icode) (scratch, op0, op1);
12386 if (mode0 == V2SImode)
12387 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12389 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12394 /* Expand an expression EXP that calls a built-in function,
12395 with result going to TARGET if that's convenient
12396 (and in mode MODE if that's convenient).
12397 SUBTARGET may be used as the target for computing one of EXP's operands.
12398 IGNORE is nonzero if the value is to be ignored. */
12401 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12402 enum machine_mode mode ATTRIBUTE_UNUSED,
12403 int ignore ATTRIBUTE_UNUSED)
12405 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12406 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12407 const struct builtin_description *d;
12414 case RS6000_BUILTIN_RECIP:
12415 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12417 case RS6000_BUILTIN_RECIPF:
12418 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12420 case RS6000_BUILTIN_RSQRTF:
12421 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12423 case RS6000_BUILTIN_RSQRT:
12424 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12426 case RS6000_BUILTIN_BSWAP_HI:
12427 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12429 case POWER7_BUILTIN_BPERMD:
12430 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12431 ? CODE_FOR_bpermd_di
12432 : CODE_FOR_bpermd_si), exp, target);
12434 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12435 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12437 int icode = (int) CODE_FOR_altivec_lvsr;
12438 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12439 enum machine_mode mode = insn_data[icode].operand[1].mode;
12443 gcc_assert (TARGET_ALTIVEC);
12445 arg = CALL_EXPR_ARG (exp, 0);
12446 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12447 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12448 addr = memory_address (mode, op);
12449 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12453 /* For the load case need to negate the address. */
12454 op = gen_reg_rtx (GET_MODE (addr));
12455 emit_insn (gen_rtx_SET (VOIDmode, op,
12456 gen_rtx_NEG (GET_MODE (addr), addr)));
12458 op = gen_rtx_MEM (mode, op);
12461 || GET_MODE (target) != tmode
12462 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12463 target = gen_reg_rtx (tmode);
12465 /*pat = gen_altivec_lvsr (target, op);*/
12466 pat = GEN_FCN (icode) (target, op);
12474 case ALTIVEC_BUILTIN_VCFUX:
12475 case ALTIVEC_BUILTIN_VCFSX:
12476 case ALTIVEC_BUILTIN_VCTUXS:
12477 case ALTIVEC_BUILTIN_VCTSXS:
12478 /* FIXME: There's got to be a nicer way to handle this case than
12479 constructing a new CALL_EXPR. */
12480 if (call_expr_nargs (exp) == 1)
12482 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12483 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12491 if (TARGET_ALTIVEC)
12493 ret = altivec_expand_builtin (exp, target, &success);
12500 ret = spe_expand_builtin (exp, target, &success);
12505 if (TARGET_PAIRED_FLOAT)
12507 ret = paired_expand_builtin (exp, target, &success);
12513 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12515 /* Handle simple unary operations. */
12516 d = (struct builtin_description *) bdesc_1arg;
12517 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12518 if (d->code == fcode)
12519 return rs6000_expand_unop_builtin (d->icode, exp, target);
12521 /* Handle simple binary operations. */
12522 d = (struct builtin_description *) bdesc_2arg;
12523 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12524 if (d->code == fcode)
12525 return rs6000_expand_binop_builtin (d->icode, exp, target);
12527 /* Handle simple ternary operations. */
12529 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12530 if (d->code == fcode)
12531 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12533 gcc_unreachable ();
12537 rs6000_init_builtins (void)
12542 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12543 V2SF_type_node = build_vector_type (float_type_node, 2);
12544 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12545 V2DF_type_node = build_vector_type (double_type_node, 2);
12546 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12547 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12548 V4SF_type_node = build_vector_type (float_type_node, 4);
12549 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12550 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12552 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12553 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12554 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12555 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12557 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12558 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12559 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12560 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12562 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12563 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12564 'vector unsigned short'. */
12566 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12567 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12568 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12569 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12570 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12572 long_integer_type_internal_node = long_integer_type_node;
12573 long_unsigned_type_internal_node = long_unsigned_type_node;
12574 long_long_integer_type_internal_node = long_long_integer_type_node;
12575 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12576 intQI_type_internal_node = intQI_type_node;
12577 uintQI_type_internal_node = unsigned_intQI_type_node;
12578 intHI_type_internal_node = intHI_type_node;
12579 uintHI_type_internal_node = unsigned_intHI_type_node;
12580 intSI_type_internal_node = intSI_type_node;
12581 uintSI_type_internal_node = unsigned_intSI_type_node;
12582 intDI_type_internal_node = intDI_type_node;
12583 uintDI_type_internal_node = unsigned_intDI_type_node;
12584 float_type_internal_node = float_type_node;
12585 double_type_internal_node = double_type_node;
12586 void_type_internal_node = void_type_node;
12588 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12590 builtin_mode_to_type[QImode][0] = integer_type_node;
12591 builtin_mode_to_type[HImode][0] = integer_type_node;
12592 builtin_mode_to_type[SImode][0] = intSI_type_node;
12593 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12594 builtin_mode_to_type[DImode][0] = intDI_type_node;
12595 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12596 builtin_mode_to_type[SFmode][0] = float_type_node;
12597 builtin_mode_to_type[DFmode][0] = double_type_node;
12598 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12599 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12600 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12601 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12602 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12603 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12604 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12605 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12606 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12607 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12608 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12609 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12610 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12612 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12613 get_identifier ("__bool char"),
12614 bool_char_type_node);
12615 TYPE_NAME (bool_char_type_node) = tdecl;
12616 (*lang_hooks.decls.pushdecl) (tdecl);
12617 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12618 get_identifier ("__bool short"),
12619 bool_short_type_node);
12620 TYPE_NAME (bool_short_type_node) = tdecl;
12621 (*lang_hooks.decls.pushdecl) (tdecl);
12622 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12623 get_identifier ("__bool int"),
12624 bool_int_type_node);
12625 TYPE_NAME (bool_int_type_node) = tdecl;
12626 (*lang_hooks.decls.pushdecl) (tdecl);
12627 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12629 TYPE_NAME (pixel_type_node) = tdecl;
12630 (*lang_hooks.decls.pushdecl) (tdecl);
12632 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12633 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12634 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12635 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12636 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12638 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12639 get_identifier ("__vector unsigned char"),
12640 unsigned_V16QI_type_node);
12641 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12642 (*lang_hooks.decls.pushdecl) (tdecl);
12643 tdecl = build_decl (BUILTINS_LOCATION,
12644 TYPE_DECL, get_identifier ("__vector signed char"),
12646 TYPE_NAME (V16QI_type_node) = tdecl;
12647 (*lang_hooks.decls.pushdecl) (tdecl);
12648 tdecl = build_decl (BUILTINS_LOCATION,
12649 TYPE_DECL, get_identifier ("__vector __bool char"),
12650 bool_V16QI_type_node);
12651 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12652 (*lang_hooks.decls.pushdecl) (tdecl);
12654 tdecl = build_decl (BUILTINS_LOCATION,
12655 TYPE_DECL, get_identifier ("__vector unsigned short"),
12656 unsigned_V8HI_type_node);
12657 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12658 (*lang_hooks.decls.pushdecl) (tdecl);
12659 tdecl = build_decl (BUILTINS_LOCATION,
12660 TYPE_DECL, get_identifier ("__vector signed short"),
12662 TYPE_NAME (V8HI_type_node) = tdecl;
12663 (*lang_hooks.decls.pushdecl) (tdecl);
12664 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12665 get_identifier ("__vector __bool short"),
12666 bool_V8HI_type_node);
12667 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12668 (*lang_hooks.decls.pushdecl) (tdecl);
12670 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12671 get_identifier ("__vector unsigned int"),
12672 unsigned_V4SI_type_node);
12673 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12674 (*lang_hooks.decls.pushdecl) (tdecl);
12675 tdecl = build_decl (BUILTINS_LOCATION,
12676 TYPE_DECL, get_identifier ("__vector signed int"),
12678 TYPE_NAME (V4SI_type_node) = tdecl;
12679 (*lang_hooks.decls.pushdecl) (tdecl);
12680 tdecl = build_decl (BUILTINS_LOCATION,
12681 TYPE_DECL, get_identifier ("__vector __bool int"),
12682 bool_V4SI_type_node);
12683 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12684 (*lang_hooks.decls.pushdecl) (tdecl);
12686 tdecl = build_decl (BUILTINS_LOCATION,
12687 TYPE_DECL, get_identifier ("__vector float"),
12689 TYPE_NAME (V4SF_type_node) = tdecl;
12690 (*lang_hooks.decls.pushdecl) (tdecl);
12691 tdecl = build_decl (BUILTINS_LOCATION,
12692 TYPE_DECL, get_identifier ("__vector __pixel"),
12693 pixel_V8HI_type_node);
12694 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12695 (*lang_hooks.decls.pushdecl) (tdecl);
12699 tdecl = build_decl (BUILTINS_LOCATION,
12700 TYPE_DECL, get_identifier ("__vector double"),
12702 TYPE_NAME (V2DF_type_node) = tdecl;
12703 (*lang_hooks.decls.pushdecl) (tdecl);
12705 tdecl = build_decl (BUILTINS_LOCATION,
12706 TYPE_DECL, get_identifier ("__vector long"),
12708 TYPE_NAME (V2DI_type_node) = tdecl;
12709 (*lang_hooks.decls.pushdecl) (tdecl);
12711 tdecl = build_decl (BUILTINS_LOCATION,
12712 TYPE_DECL, get_identifier ("__vector unsigned long"),
12713 unsigned_V2DI_type_node);
12714 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12715 (*lang_hooks.decls.pushdecl) (tdecl);
12717 tdecl = build_decl (BUILTINS_LOCATION,
12718 TYPE_DECL, get_identifier ("__vector __bool long"),
12719 bool_V2DI_type_node);
12720 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12721 (*lang_hooks.decls.pushdecl) (tdecl);
12724 if (TARGET_PAIRED_FLOAT)
12725 paired_init_builtins ();
12727 spe_init_builtins ();
12728 if (TARGET_ALTIVEC)
12729 altivec_init_builtins ();
12730 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12731 rs6000_common_init_builtins ();
12734 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12735 RS6000_BUILTIN_RECIP,
12736 "__builtin_recipdiv");
12737 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12738 RS6000_BUILTIN_RECIP);
12742 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12743 RS6000_BUILTIN_RECIPF,
12744 "__builtin_recipdivf");
12745 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12746 RS6000_BUILTIN_RECIPF);
12748 if (TARGET_FRSQRTE)
12750 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12751 RS6000_BUILTIN_RSQRT,
12752 "__builtin_rsqrt");
12753 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12754 RS6000_BUILTIN_RSQRT);
12756 if (TARGET_FRSQRTES)
12758 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12759 RS6000_BUILTIN_RSQRTF,
12760 "__builtin_rsqrtf");
12761 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12762 RS6000_BUILTIN_RSQRTF);
12764 if (TARGET_POPCNTD)
12766 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12767 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12768 POWER7_BUILTIN_BPERMD,
12769 "__builtin_bpermd");
12770 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12771 POWER7_BUILTIN_BPERMD);
12773 if (TARGET_POWERPC)
12775 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12776 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12777 unsigned_intHI_type_node,
12779 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12780 RS6000_BUILTIN_BSWAP_HI);
12784 /* AIX libm provides clog as __clog. */
12785 if (built_in_decls [BUILT_IN_CLOG])
12786 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12789 #ifdef SUBTARGET_INIT_BUILTINS
12790 SUBTARGET_INIT_BUILTINS;
12794 /* Returns the rs6000 builtin decl for CODE. */
12797 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12799 if (code >= RS6000_BUILTIN_COUNT)
12800 return error_mark_node;
12802 return rs6000_builtin_decls[code];
12805 /* Search through a set of builtins and enable the mask bits.
12806 DESC is an array of builtins.
12807 SIZE is the total number of builtins.
12808 START is the builtin enum at which to start.
12809 END is the builtin enum at which to end. */
12811 enable_mask_for_builtins (struct builtin_description *desc, int size,
12812 enum rs6000_builtins start,
12813 enum rs6000_builtins end)
12817 for (i = 0; i < size; ++i)
12818 if (desc[i].code == start)
12824 for (; i < size; ++i)
12826 /* Flip all the bits on. */
12827 desc[i].mask = target_flags;
12828 if (desc[i].code == end)
12834 spe_init_builtins (void)
12836 tree endlink = void_list_node;
12837 tree puint_type_node = build_pointer_type (unsigned_type_node);
12838 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12839 struct builtin_description *d;
12842 tree v2si_ftype_4_v2si
12843 = build_function_type
12844 (opaque_V2SI_type_node,
12845 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12846 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12847 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12848 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12851 tree v2sf_ftype_4_v2sf
12852 = build_function_type
12853 (opaque_V2SF_type_node,
12854 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12855 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12856 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12857 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12860 tree int_ftype_int_v2si_v2si
12861 = build_function_type
12862 (integer_type_node,
12863 tree_cons (NULL_TREE, integer_type_node,
12864 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12865 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12868 tree int_ftype_int_v2sf_v2sf
12869 = build_function_type
12870 (integer_type_node,
12871 tree_cons (NULL_TREE, integer_type_node,
12872 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12873 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12876 tree void_ftype_v2si_puint_int
12877 = build_function_type (void_type_node,
12878 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12879 tree_cons (NULL_TREE, puint_type_node,
12880 tree_cons (NULL_TREE,
12884 tree void_ftype_v2si_puint_char
12885 = build_function_type (void_type_node,
12886 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12887 tree_cons (NULL_TREE, puint_type_node,
12888 tree_cons (NULL_TREE,
12892 tree void_ftype_v2si_pv2si_int
12893 = build_function_type (void_type_node,
12894 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12895 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12896 tree_cons (NULL_TREE,
12900 tree void_ftype_v2si_pv2si_char
12901 = build_function_type (void_type_node,
12902 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12903 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12904 tree_cons (NULL_TREE,
12908 tree void_ftype_int
12909 = build_function_type (void_type_node,
12910 tree_cons (NULL_TREE, integer_type_node, endlink));
12912 tree int_ftype_void
12913 = build_function_type (integer_type_node, endlink);
12915 tree v2si_ftype_pv2si_int
12916 = build_function_type (opaque_V2SI_type_node,
12917 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12918 tree_cons (NULL_TREE, integer_type_node,
12921 tree v2si_ftype_puint_int
12922 = build_function_type (opaque_V2SI_type_node,
12923 tree_cons (NULL_TREE, puint_type_node,
12924 tree_cons (NULL_TREE, integer_type_node,
12927 tree v2si_ftype_pushort_int
12928 = build_function_type (opaque_V2SI_type_node,
12929 tree_cons (NULL_TREE, pushort_type_node,
12930 tree_cons (NULL_TREE, integer_type_node,
12933 tree v2si_ftype_signed_char
12934 = build_function_type (opaque_V2SI_type_node,
12935 tree_cons (NULL_TREE, signed_char_type_node,
12938 /* The initialization of the simple binary and unary builtins is
12939 done in rs6000_common_init_builtins, but we have to enable the
12940 mask bits here manually because we have run out of `target_flags'
12941 bits. We really need to redesign this mask business. */
12943 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12944 ARRAY_SIZE (bdesc_2arg),
12945 SPE_BUILTIN_EVADDW,
12946 SPE_BUILTIN_EVXOR);
12947 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12948 ARRAY_SIZE (bdesc_1arg),
12950 SPE_BUILTIN_EVSUBFUSIAAW);
12951 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12952 ARRAY_SIZE (bdesc_spe_predicates),
12953 SPE_BUILTIN_EVCMPEQ,
12954 SPE_BUILTIN_EVFSTSTLT);
12955 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12956 ARRAY_SIZE (bdesc_spe_evsel),
12957 SPE_BUILTIN_EVSEL_CMPGTS,
12958 SPE_BUILTIN_EVSEL_FSTSTEQ);
12960 (*lang_hooks.decls.pushdecl)
12961 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12962 get_identifier ("__ev64_opaque__"),
12963 opaque_V2SI_type_node));
12965 /* Initialize irregular SPE builtins. */
12967 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12968 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12969 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12970 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12971 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12972 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12973 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12974 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12975 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12976 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12977 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12978 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12979 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12980 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12981 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12982 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12983 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12984 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12987 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12988 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12989 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12990 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12991 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12992 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12993 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12994 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12995 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
12996 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
12997 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
12998 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
12999 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
13000 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
13001 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
13002 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
13003 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
13004 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
13005 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
13006 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
13007 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
13008 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13011 d = (struct builtin_description *) bdesc_spe_predicates;
13012 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13016 switch (insn_data[d->icode].operand[1].mode)
13019 type = int_ftype_int_v2si_v2si;
13022 type = int_ftype_int_v2sf_v2sf;
13025 gcc_unreachable ();
13028 def_builtin (d->mask, d->name, type, d->code);
13031 /* Evsel predicates. */
13032 d = (struct builtin_description *) bdesc_spe_evsel;
13033 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13037 switch (insn_data[d->icode].operand[1].mode)
13040 type = v2si_ftype_4_v2si;
13043 type = v2sf_ftype_4_v2sf;
13046 gcc_unreachable ();
13049 def_builtin (d->mask, d->name, type, d->code);
13054 paired_init_builtins (void)
13056 const struct builtin_description *d;
13058 tree endlink = void_list_node;
13060 tree int_ftype_int_v2sf_v2sf
13061 = build_function_type
13062 (integer_type_node,
13063 tree_cons (NULL_TREE, integer_type_node,
13064 tree_cons (NULL_TREE, V2SF_type_node,
13065 tree_cons (NULL_TREE, V2SF_type_node,
13067 tree pcfloat_type_node =
13068 build_pointer_type (build_qualified_type
13069 (float_type_node, TYPE_QUAL_CONST));
13071 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13072 long_integer_type_node,
13075 tree void_ftype_v2sf_long_pcfloat =
13076 build_function_type_list (void_type_node,
13078 long_integer_type_node,
13083 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13084 PAIRED_BUILTIN_LX);
13087 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13088 PAIRED_BUILTIN_STX);
13091 d = bdesc_paired_preds;
13092 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13096 switch (insn_data[d->icode].operand[1].mode)
13099 type = int_ftype_int_v2sf_v2sf;
13102 gcc_unreachable ();
13105 def_builtin (d->mask, d->name, type, d->code);
13110 altivec_init_builtins (void)
13112 const struct builtin_description *d;
13113 const struct builtin_description_predicates *dp;
13117 tree pvoid_type_node = build_pointer_type (void_type_node);
13119 tree pcvoid_type_node
13120 = build_pointer_type (build_qualified_type (void_type_node,
13123 tree int_ftype_opaque
13124 = build_function_type_list (integer_type_node,
13125 opaque_V4SI_type_node, NULL_TREE);
13126 tree opaque_ftype_opaque
13127 = build_function_type (integer_type_node,
13129 tree opaque_ftype_opaque_int
13130 = build_function_type_list (opaque_V4SI_type_node,
13131 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13132 tree opaque_ftype_opaque_opaque_int
13133 = build_function_type_list (opaque_V4SI_type_node,
13134 opaque_V4SI_type_node, opaque_V4SI_type_node,
13135 integer_type_node, NULL_TREE);
13136 tree int_ftype_int_opaque_opaque
13137 = build_function_type_list (integer_type_node,
13138 integer_type_node, opaque_V4SI_type_node,
13139 opaque_V4SI_type_node, NULL_TREE);
13140 tree int_ftype_int_v4si_v4si
13141 = build_function_type_list (integer_type_node,
13142 integer_type_node, V4SI_type_node,
13143 V4SI_type_node, NULL_TREE);
13144 tree void_ftype_v4si
13145 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13146 tree v8hi_ftype_void
13147 = build_function_type (V8HI_type_node, void_list_node);
13148 tree void_ftype_void
13149 = build_function_type (void_type_node, void_list_node);
13150 tree void_ftype_int
13151 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13153 tree opaque_ftype_long_pcvoid
13154 = build_function_type_list (opaque_V4SI_type_node,
13155 long_integer_type_node, pcvoid_type_node,
13157 tree v16qi_ftype_long_pcvoid
13158 = build_function_type_list (V16QI_type_node,
13159 long_integer_type_node, pcvoid_type_node,
13161 tree v8hi_ftype_long_pcvoid
13162 = build_function_type_list (V8HI_type_node,
13163 long_integer_type_node, pcvoid_type_node,
13165 tree v4si_ftype_long_pcvoid
13166 = build_function_type_list (V4SI_type_node,
13167 long_integer_type_node, pcvoid_type_node,
13169 tree v4sf_ftype_long_pcvoid
13170 = build_function_type_list (V4SF_type_node,
13171 long_integer_type_node, pcvoid_type_node,
13173 tree v2df_ftype_long_pcvoid
13174 = build_function_type_list (V2DF_type_node,
13175 long_integer_type_node, pcvoid_type_node,
13177 tree v2di_ftype_long_pcvoid
13178 = build_function_type_list (V2DI_type_node,
13179 long_integer_type_node, pcvoid_type_node,
13182 tree void_ftype_opaque_long_pvoid
13183 = build_function_type_list (void_type_node,
13184 opaque_V4SI_type_node, long_integer_type_node,
13185 pvoid_type_node, NULL_TREE);
13186 tree void_ftype_v4si_long_pvoid
13187 = build_function_type_list (void_type_node,
13188 V4SI_type_node, long_integer_type_node,
13189 pvoid_type_node, NULL_TREE);
13190 tree void_ftype_v16qi_long_pvoid
13191 = build_function_type_list (void_type_node,
13192 V16QI_type_node, long_integer_type_node,
13193 pvoid_type_node, NULL_TREE);
13194 tree void_ftype_v8hi_long_pvoid
13195 = build_function_type_list (void_type_node,
13196 V8HI_type_node, long_integer_type_node,
13197 pvoid_type_node, NULL_TREE);
13198 tree void_ftype_v4sf_long_pvoid
13199 = build_function_type_list (void_type_node,
13200 V4SF_type_node, long_integer_type_node,
13201 pvoid_type_node, NULL_TREE);
13202 tree void_ftype_v2df_long_pvoid
13203 = build_function_type_list (void_type_node,
13204 V2DF_type_node, long_integer_type_node,
13205 pvoid_type_node, NULL_TREE);
13206 tree void_ftype_v2di_long_pvoid
13207 = build_function_type_list (void_type_node,
13208 V2DI_type_node, long_integer_type_node,
13209 pvoid_type_node, NULL_TREE);
13210 tree int_ftype_int_v8hi_v8hi
13211 = build_function_type_list (integer_type_node,
13212 integer_type_node, V8HI_type_node,
13213 V8HI_type_node, NULL_TREE);
13214 tree int_ftype_int_v16qi_v16qi
13215 = build_function_type_list (integer_type_node,
13216 integer_type_node, V16QI_type_node,
13217 V16QI_type_node, NULL_TREE);
13218 tree int_ftype_int_v4sf_v4sf
13219 = build_function_type_list (integer_type_node,
13220 integer_type_node, V4SF_type_node,
13221 V4SF_type_node, NULL_TREE);
13222 tree int_ftype_int_v2df_v2df
13223 = build_function_type_list (integer_type_node,
13224 integer_type_node, V2DF_type_node,
13225 V2DF_type_node, NULL_TREE);
13226 tree v4si_ftype_v4si
13227 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13228 tree v8hi_ftype_v8hi
13229 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13230 tree v16qi_ftype_v16qi
13231 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13232 tree v4sf_ftype_v4sf
13233 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13234 tree v2df_ftype_v2df
13235 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13236 tree void_ftype_pcvoid_int_int
13237 = build_function_type_list (void_type_node,
13238 pcvoid_type_node, integer_type_node,
13239 integer_type_node, NULL_TREE);
13241 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13242 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13243 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13244 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13245 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13246 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13247 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13248 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13249 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13250 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13251 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13252 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13253 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13254 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13255 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13256 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13257 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13258 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13259 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13260 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13261 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13262 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13263 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13264 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13265 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13266 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13267 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13268 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13269 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13270 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13272 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13273 VSX_BUILTIN_LXVD2X_V2DF);
13274 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13275 VSX_BUILTIN_LXVD2X_V2DI);
13276 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13277 VSX_BUILTIN_LXVW4X_V4SF);
13278 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13279 VSX_BUILTIN_LXVW4X_V4SI);
13280 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13281 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13282 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13283 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13284 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13285 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13286 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13287 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13288 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13289 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13290 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13291 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13292 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13293 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13294 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13295 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13296 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13297 VSX_BUILTIN_VEC_LD);
13298 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13299 VSX_BUILTIN_VEC_ST);
13301 if (rs6000_cpu == PROCESSOR_CELL)
13303 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13304 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13305 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13306 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13308 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13309 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13310 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13311 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13313 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13314 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13315 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13316 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13318 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13319 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13320 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13321 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13323 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13324 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13325 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13327 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13328 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13329 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13330 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13331 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13332 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13333 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13334 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13335 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13336 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13337 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13338 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13340 /* Add the DST variants. */
13342 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13343 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13345 /* Initialize the predicates. */
13346 dp = bdesc_altivec_preds;
13347 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13349 enum machine_mode mode1;
13351 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13352 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13353 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13354 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13359 mode1 = insn_data[dp->icode].operand[1].mode;
13364 type = int_ftype_int_opaque_opaque;
13367 type = int_ftype_int_v4si_v4si;
13370 type = int_ftype_int_v8hi_v8hi;
13373 type = int_ftype_int_v16qi_v16qi;
13376 type = int_ftype_int_v4sf_v4sf;
13379 type = int_ftype_int_v2df_v2df;
13382 gcc_unreachable ();
13385 def_builtin (dp->mask, dp->name, type, dp->code);
13388 /* Initialize the abs* operators. */
13390 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13392 enum machine_mode mode0;
13395 mode0 = insn_data[d->icode].operand[0].mode;
13400 type = v4si_ftype_v4si;
13403 type = v8hi_ftype_v8hi;
13406 type = v16qi_ftype_v16qi;
13409 type = v4sf_ftype_v4sf;
13412 type = v2df_ftype_v2df;
13415 gcc_unreachable ();
13418 def_builtin (d->mask, d->name, type, d->code);
13421 if (TARGET_ALTIVEC)
13425 /* Initialize target builtin that implements
13426 targetm.vectorize.builtin_mask_for_load. */
13428 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13429 v16qi_ftype_long_pcvoid,
13430 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13431 BUILT_IN_MD, NULL, NULL_TREE);
13432 TREE_READONLY (decl) = 1;
13433 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13434 altivec_builtin_mask_for_load = decl;
13437 /* Access to the vec_init patterns. */
13438 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13439 integer_type_node, integer_type_node,
13440 integer_type_node, NULL_TREE);
13441 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13442 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13444 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13445 short_integer_type_node,
13446 short_integer_type_node,
13447 short_integer_type_node,
13448 short_integer_type_node,
13449 short_integer_type_node,
13450 short_integer_type_node,
13451 short_integer_type_node, NULL_TREE);
13452 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13453 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13455 ftype = build_function_type_list (V16QI_type_node, char_type_node,
13456 char_type_node, char_type_node,
13457 char_type_node, char_type_node,
13458 char_type_node, char_type_node,
13459 char_type_node, char_type_node,
13460 char_type_node, char_type_node,
13461 char_type_node, char_type_node,
13462 char_type_node, char_type_node,
13463 char_type_node, NULL_TREE);
13464 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13465 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13467 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13468 float_type_node, float_type_node,
13469 float_type_node, NULL_TREE);
13470 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13471 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13475 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13476 double_type_node, NULL_TREE);
13477 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13478 VSX_BUILTIN_VEC_INIT_V2DF);
13480 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13481 intDI_type_node, NULL_TREE);
13482 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13483 VSX_BUILTIN_VEC_INIT_V2DI);
13486 /* Access to the vec_set patterns. */
13487 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13489 integer_type_node, NULL_TREE);
13490 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13491 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13493 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13495 integer_type_node, NULL_TREE);
13496 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13497 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13499 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13501 integer_type_node, NULL_TREE);
13502 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13503 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13505 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13507 integer_type_node, NULL_TREE);
13508 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13509 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13513 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13515 integer_type_node, NULL_TREE);
13516 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13517 VSX_BUILTIN_VEC_SET_V2DF);
13519 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13521 integer_type_node, NULL_TREE);
13522 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13523 VSX_BUILTIN_VEC_SET_V2DI);
13526 /* Access to the vec_extract patterns. */
13527 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13528 integer_type_node, NULL_TREE);
13529 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13530 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13532 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13533 integer_type_node, NULL_TREE);
13534 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13535 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13537 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13538 integer_type_node, NULL_TREE);
13539 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13540 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13542 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13543 integer_type_node, NULL_TREE);
13544 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13545 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13549 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13550 integer_type_node, NULL_TREE);
13551 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13552 VSX_BUILTIN_VEC_EXT_V2DF);
13554 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13555 integer_type_node, NULL_TREE);
13556 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13557 VSX_BUILTIN_VEC_EXT_V2DI);
13561 /* Hash function for builtin functions with up to 3 arguments and a return
13564 builtin_hash_function (const void *hash_entry)
13568 const struct builtin_hash_struct *bh =
13569 (const struct builtin_hash_struct *) hash_entry;
13571 for (i = 0; i < 4; i++)
13573 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13574 ret = (ret * 2) + bh->uns_p[i];
13580 /* Compare builtin hash entries H1 and H2 for equivalence. */
13582 builtin_hash_eq (const void *h1, const void *h2)
13584 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13585 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13587 return ((p1->mode[0] == p2->mode[0])
13588 && (p1->mode[1] == p2->mode[1])
13589 && (p1->mode[2] == p2->mode[2])
13590 && (p1->mode[3] == p2->mode[3])
13591 && (p1->uns_p[0] == p2->uns_p[0])
13592 && (p1->uns_p[1] == p2->uns_p[1])
13593 && (p1->uns_p[2] == p2->uns_p[2])
13594 && (p1->uns_p[3] == p2->uns_p[3]));
13597 /* Map types for builtin functions with an explicit return type and up to 3
13598 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13599 of the argument. */
13601 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13602 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13603 enum rs6000_builtins builtin, const char *name)
13605 struct builtin_hash_struct h;
13606 struct builtin_hash_struct *h2;
13610 tree ret_type = NULL_TREE;
13611 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13614 /* Create builtin_hash_table. */
13615 if (builtin_hash_table == NULL)
13616 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13617 builtin_hash_eq, NULL);
13619 h.type = NULL_TREE;
13620 h.mode[0] = mode_ret;
13621 h.mode[1] = mode_arg0;
13622 h.mode[2] = mode_arg1;
13623 h.mode[3] = mode_arg2;
13629 /* If the builtin is a type that produces unsigned results or takes unsigned
13630 arguments, and it is returned as a decl for the vectorizer (such as
13631 widening multiplies, permute), make sure the arguments and return value
13632 are type correct. */
13635 /* unsigned 2 argument functions. */
13636 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13637 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13638 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13639 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13645 /* unsigned 3 argument functions. */
13646 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13647 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13648 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13649 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13650 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13651 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13652 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13653 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13654 case VSX_BUILTIN_VPERM_16QI_UNS:
13655 case VSX_BUILTIN_VPERM_8HI_UNS:
13656 case VSX_BUILTIN_VPERM_4SI_UNS:
13657 case VSX_BUILTIN_VPERM_2DI_UNS:
13658 case VSX_BUILTIN_XXSEL_16QI_UNS:
13659 case VSX_BUILTIN_XXSEL_8HI_UNS:
13660 case VSX_BUILTIN_XXSEL_4SI_UNS:
13661 case VSX_BUILTIN_XXSEL_2DI_UNS:
13668 /* signed permute functions with unsigned char mask. */
13669 case ALTIVEC_BUILTIN_VPERM_16QI:
13670 case ALTIVEC_BUILTIN_VPERM_8HI:
13671 case ALTIVEC_BUILTIN_VPERM_4SI:
13672 case ALTIVEC_BUILTIN_VPERM_4SF:
13673 case ALTIVEC_BUILTIN_VPERM_2DI:
13674 case ALTIVEC_BUILTIN_VPERM_2DF:
13675 case VSX_BUILTIN_VPERM_16QI:
13676 case VSX_BUILTIN_VPERM_8HI:
13677 case VSX_BUILTIN_VPERM_4SI:
13678 case VSX_BUILTIN_VPERM_4SF:
13679 case VSX_BUILTIN_VPERM_2DI:
13680 case VSX_BUILTIN_VPERM_2DF:
13684 /* unsigned args, signed return. */
13685 case VSX_BUILTIN_XVCVUXDDP_UNS:
13686 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13690 /* signed args, unsigned return. */
13691 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13692 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13700 /* Figure out how many args are present. */
13701 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13705 fatal_error ("internal error: builtin function %s had no type", name);
13707 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13708 if (!ret_type && h.uns_p[0])
13709 ret_type = builtin_mode_to_type[h.mode[0]][0];
13712 fatal_error ("internal error: builtin function %s had an unexpected "
13713 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13715 for (i = 0; i < num_args; i++)
13717 int m = (int) h.mode[i+1];
13718 int uns_p = h.uns_p[i+1];
13720 arg_type[i] = builtin_mode_to_type[m][uns_p];
13721 if (!arg_type[i] && uns_p)
13722 arg_type[i] = builtin_mode_to_type[m][0];
13725 fatal_error ("internal error: builtin function %s, argument %d "
13726 "had unexpected argument type %s", name, i,
13727 GET_MODE_NAME (m));
13730 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13731 if (*found == NULL)
13733 h2 = ggc_alloc_builtin_hash_struct ();
13735 *found = (void *)h2;
13736 args = void_list_node;
13738 for (i = num_args - 1; i >= 0; i--)
13739 args = tree_cons (NULL_TREE, arg_type[i], args);
13741 h2->type = build_function_type (ret_type, args);
13744 return ((struct builtin_hash_struct *)(*found))->type;
13748 rs6000_common_init_builtins (void)
13750 const struct builtin_description *d;
13753 tree opaque_ftype_opaque = NULL_TREE;
13754 tree opaque_ftype_opaque_opaque = NULL_TREE;
13755 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13756 tree v2si_ftype_qi = NULL_TREE;
13757 tree v2si_ftype_v2si_qi = NULL_TREE;
13758 tree v2si_ftype_int_qi = NULL_TREE;
13760 if (!TARGET_PAIRED_FLOAT)
13762 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13763 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13766 /* Add the ternary operators. */
13768 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13771 int mask = d->mask;
13773 if ((mask != 0 && (mask & target_flags) == 0)
13774 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13777 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13778 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13779 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13780 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13782 if (! (type = opaque_ftype_opaque_opaque_opaque))
13783 type = opaque_ftype_opaque_opaque_opaque
13784 = build_function_type_list (opaque_V4SI_type_node,
13785 opaque_V4SI_type_node,
13786 opaque_V4SI_type_node,
13787 opaque_V4SI_type_node,
13792 enum insn_code icode = d->icode;
13793 if (d->name == 0 || icode == CODE_FOR_nothing)
13796 type = builtin_function_type (insn_data[icode].operand[0].mode,
13797 insn_data[icode].operand[1].mode,
13798 insn_data[icode].operand[2].mode,
13799 insn_data[icode].operand[3].mode,
13803 def_builtin (d->mask, d->name, type, d->code);
13806 /* Add the binary operators. */
13808 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13810 enum machine_mode mode0, mode1, mode2;
13812 int mask = d->mask;
13814 if ((mask != 0 && (mask & target_flags) == 0)
13815 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13818 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13819 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13820 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13821 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13823 if (! (type = opaque_ftype_opaque_opaque))
13824 type = opaque_ftype_opaque_opaque
13825 = build_function_type_list (opaque_V4SI_type_node,
13826 opaque_V4SI_type_node,
13827 opaque_V4SI_type_node,
13832 enum insn_code icode = d->icode;
13833 if (d->name == 0 || icode == CODE_FOR_nothing)
13836 mode0 = insn_data[icode].operand[0].mode;
13837 mode1 = insn_data[icode].operand[1].mode;
13838 mode2 = insn_data[icode].operand[2].mode;
13840 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13842 if (! (type = v2si_ftype_v2si_qi))
13843 type = v2si_ftype_v2si_qi
13844 = build_function_type_list (opaque_V2SI_type_node,
13845 opaque_V2SI_type_node,
13850 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13851 && mode2 == QImode)
13853 if (! (type = v2si_ftype_int_qi))
13854 type = v2si_ftype_int_qi
13855 = build_function_type_list (opaque_V2SI_type_node,
13862 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13866 def_builtin (d->mask, d->name, type, d->code);
13869 /* Add the simple unary operators. */
13870 d = (struct builtin_description *) bdesc_1arg;
13871 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13873 enum machine_mode mode0, mode1;
13875 int mask = d->mask;
13877 if ((mask != 0 && (mask & target_flags) == 0)
13878 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13881 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13882 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13883 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13884 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13886 if (! (type = opaque_ftype_opaque))
13887 type = opaque_ftype_opaque
13888 = build_function_type_list (opaque_V4SI_type_node,
13889 opaque_V4SI_type_node,
13894 enum insn_code icode = d->icode;
13895 if (d->name == 0 || icode == CODE_FOR_nothing)
13898 mode0 = insn_data[icode].operand[0].mode;
13899 mode1 = insn_data[icode].operand[1].mode;
13901 if (mode0 == V2SImode && mode1 == QImode)
13903 if (! (type = v2si_ftype_qi))
13904 type = v2si_ftype_qi
13905 = build_function_type_list (opaque_V2SI_type_node,
13911 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13915 def_builtin (d->mask, d->name, type, d->code);
13920 rs6000_init_libfuncs (void)
13922 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13923 && !TARGET_POWER2 && !TARGET_POWERPC)
13925 /* AIX library routines for float->int conversion. */
13926 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13927 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13928 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13929 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13932 if (!TARGET_IEEEQUAD)
13933 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13934 if (!TARGET_XL_COMPAT)
13936 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13937 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13938 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13939 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13941 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13943 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13944 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13945 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13946 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13947 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13948 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13949 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13951 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13952 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13953 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13954 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13955 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13956 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13957 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13958 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13961 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13962 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13966 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13967 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13968 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13969 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13973 /* 32-bit SVR4 quad floating point routines. */
13975 set_optab_libfunc (add_optab, TFmode, "_q_add");
13976 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13977 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13978 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13979 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13980 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13981 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13983 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13984 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13985 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13986 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13987 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13988 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13990 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13991 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13992 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13993 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13994 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13995 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
13996 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
13997 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
14002 /* Expand a block clear operation, and return 1 if successful. Return 0
14003 if we should let the compiler generate normal code.
14005 operands[0] is the destination
14006 operands[1] is the length
14007 operands[3] is the alignment */
14010 expand_block_clear (rtx operands[])
14012 rtx orig_dest = operands[0];
14013 rtx bytes_rtx = operands[1];
14014 rtx align_rtx = operands[3];
14015 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14016 HOST_WIDE_INT align;
14017 HOST_WIDE_INT bytes;
14022 /* If this is not a fixed size move, just call memcpy */
14026 /* This must be a fixed size alignment */
14027 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14028 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14030 /* Anything to clear? */
14031 bytes = INTVAL (bytes_rtx);
14035 /* Use the builtin memset after a point, to avoid huge code bloat.
14036 When optimize_size, avoid any significant code bloat; calling
14037 memset is about 4 instructions, so allow for one instruction to
14038 load zero and three to do clearing. */
14039 if (TARGET_ALTIVEC && align >= 128)
14041 else if (TARGET_POWERPC64 && align >= 32)
14043 else if (TARGET_SPE && align >= 64)
14048 if (optimize_size && bytes > 3 * clear_step)
14050 if (! optimize_size && bytes > 8 * clear_step)
14053 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14055 enum machine_mode mode = BLKmode;
14058 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14063 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14068 else if (bytes >= 8 && TARGET_POWERPC64
14069 /* 64-bit loads and stores require word-aligned
14071 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14076 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14077 { /* move 4 bytes */
14081 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14082 { /* move 2 bytes */
14086 else /* move 1 byte at a time */
14092 dest = adjust_address (orig_dest, mode, offset);
14094 emit_move_insn (dest, CONST0_RTX (mode));
14101 /* Expand a block move operation, and return 1 if successful. Return 0
14102 if we should let the compiler generate normal code.
14104 operands[0] is the destination
14105 operands[1] is the source
14106 operands[2] is the length
14107 operands[3] is the alignment */
14109 #define MAX_MOVE_REG 4
14112 expand_block_move (rtx operands[])
14114 rtx orig_dest = operands[0];
14115 rtx orig_src = operands[1];
14116 rtx bytes_rtx = operands[2];
14117 rtx align_rtx = operands[3];
14118 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14123 rtx stores[MAX_MOVE_REG];
14126 /* If this is not a fixed size move, just call memcpy */
14130 /* This must be a fixed size alignment */
14131 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14132 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14134 /* Anything to move? */
14135 bytes = INTVAL (bytes_rtx);
14139 if (bytes > rs6000_block_move_inline_limit)
14142 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14145 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14146 rtx (*mov) (rtx, rtx);
14148 enum machine_mode mode = BLKmode;
14151 /* Altivec first, since it will be faster than a string move
14152 when it applies, and usually not significantly larger. */
14153 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14157 gen_func.mov = gen_movv4si;
14159 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14163 gen_func.mov = gen_movv2si;
14165 else if (TARGET_STRING
14166 && bytes > 24 /* move up to 32 bytes at a time */
14172 && ! fixed_regs[10]
14173 && ! fixed_regs[11]
14174 && ! fixed_regs[12])
14176 move_bytes = (bytes > 32) ? 32 : bytes;
14177 gen_func.movmemsi = gen_movmemsi_8reg;
14179 else if (TARGET_STRING
14180 && bytes > 16 /* move up to 24 bytes at a time */
14186 && ! fixed_regs[10])
14188 move_bytes = (bytes > 24) ? 24 : bytes;
14189 gen_func.movmemsi = gen_movmemsi_6reg;
14191 else if (TARGET_STRING
14192 && bytes > 8 /* move up to 16 bytes at a time */
14196 && ! fixed_regs[8])
14198 move_bytes = (bytes > 16) ? 16 : bytes;
14199 gen_func.movmemsi = gen_movmemsi_4reg;
14201 else if (bytes >= 8 && TARGET_POWERPC64
14202 /* 64-bit loads and stores require word-aligned
14204 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14208 gen_func.mov = gen_movdi;
14210 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14211 { /* move up to 8 bytes at a time */
14212 move_bytes = (bytes > 8) ? 8 : bytes;
14213 gen_func.movmemsi = gen_movmemsi_2reg;
14215 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14216 { /* move 4 bytes */
14219 gen_func.mov = gen_movsi;
14221 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14222 { /* move 2 bytes */
14225 gen_func.mov = gen_movhi;
14227 else if (TARGET_STRING && bytes > 1)
14228 { /* move up to 4 bytes at a time */
14229 move_bytes = (bytes > 4) ? 4 : bytes;
14230 gen_func.movmemsi = gen_movmemsi_1reg;
14232 else /* move 1 byte at a time */
14236 gen_func.mov = gen_movqi;
14239 src = adjust_address (orig_src, mode, offset);
14240 dest = adjust_address (orig_dest, mode, offset);
14242 if (mode != BLKmode)
14244 rtx tmp_reg = gen_reg_rtx (mode);
14246 emit_insn ((*gen_func.mov) (tmp_reg, src));
14247 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14250 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14253 for (i = 0; i < num_reg; i++)
14254 emit_insn (stores[i]);
14258 if (mode == BLKmode)
14260 /* Move the address into scratch registers. The movmemsi
14261 patterns require zero offset. */
14262 if (!REG_P (XEXP (src, 0)))
14264 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14265 src = replace_equiv_address (src, src_reg);
14267 set_mem_size (src, GEN_INT (move_bytes));
14269 if (!REG_P (XEXP (dest, 0)))
14271 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14272 dest = replace_equiv_address (dest, dest_reg);
14274 set_mem_size (dest, GEN_INT (move_bytes));
14276 emit_insn ((*gen_func.movmemsi) (dest, src,
14277 GEN_INT (move_bytes & 31),
14286 /* Return a string to perform a load_multiple operation.
14287 operands[0] is the vector.
14288 operands[1] is the source address.
14289 operands[2] is the first destination register. */
14292 rs6000_output_load_multiple (rtx operands[3])
14294 /* We have to handle the case where the pseudo used to contain the address
14295 is assigned to one of the output registers. */
14297 int words = XVECLEN (operands[0], 0);
14300 if (XVECLEN (operands[0], 0) == 1)
14301 return "{l|lwz} %2,0(%1)";
14303 for (i = 0; i < words; i++)
14304 if (refers_to_regno_p (REGNO (operands[2]) + i,
14305 REGNO (operands[2]) + i + 1, operands[1], 0))
14309 xop[0] = GEN_INT (4 * (words-1));
14310 xop[1] = operands[1];
14311 xop[2] = operands[2];
14312 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14317 xop[0] = GEN_INT (4 * (words-1));
14318 xop[1] = operands[1];
14319 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14320 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);
14325 for (j = 0; j < words; j++)
14328 xop[0] = GEN_INT (j * 4);
14329 xop[1] = operands[1];
14330 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14331 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14333 xop[0] = GEN_INT (i * 4);
14334 xop[1] = operands[1];
14335 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14340 return "{lsi|lswi} %2,%1,%N0";
14344 /* A validation routine: say whether CODE, a condition code, and MODE
14345 match. The other alternatives either don't make sense or should
14346 never be generated. */
14349 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14351 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14352 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14353 && GET_MODE_CLASS (mode) == MODE_CC);
14355 /* These don't make sense. */
14356 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14357 || mode != CCUNSmode);
14359 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14360 || mode == CCUNSmode);
14362 gcc_assert (mode == CCFPmode
14363 || (code != ORDERED && code != UNORDERED
14364 && code != UNEQ && code != LTGT
14365 && code != UNGT && code != UNLT
14366 && code != UNGE && code != UNLE));
14368 /* These should never be generated except for
14369 flag_finite_math_only. */
14370 gcc_assert (mode != CCFPmode
14371 || flag_finite_math_only
14372 || (code != LE && code != GE
14373 && code != UNEQ && code != LTGT
14374 && code != UNGT && code != UNLT));
14376 /* These are invalid; the information is not there. */
14377 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14381 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14382 mask required to convert the result of a rotate insn into a shift
14383 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14386 includes_lshift_p (rtx shiftop, rtx andop)
14388 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14390 shift_mask <<= INTVAL (shiftop);
14392 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14395 /* Similar, but for right shift. */
14398 includes_rshift_p (rtx shiftop, rtx andop)
14400 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14402 shift_mask >>= INTVAL (shiftop);
14404 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14407 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14408 to perform a left shift. It must have exactly SHIFTOP least
14409 significant 0's, then one or more 1's, then zero or more 0's. */
14412 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14414 if (GET_CODE (andop) == CONST_INT)
14416 HOST_WIDE_INT c, lsb, shift_mask;
14418 c = INTVAL (andop);
14419 if (c == 0 || c == ~0)
14423 shift_mask <<= INTVAL (shiftop);
14425 /* Find the least significant one bit. */
14428 /* It must coincide with the LSB of the shift mask. */
14429 if (-lsb != shift_mask)
14432 /* Invert to look for the next transition (if any). */
14435 /* Remove the low group of ones (originally low group of zeros). */
14438 /* Again find the lsb, and check we have all 1's above. */
14442 else if (GET_CODE (andop) == CONST_DOUBLE
14443 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14445 HOST_WIDE_INT low, high, lsb;
14446 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14448 low = CONST_DOUBLE_LOW (andop);
14449 if (HOST_BITS_PER_WIDE_INT < 64)
14450 high = CONST_DOUBLE_HIGH (andop);
14452 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14453 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14456 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14458 shift_mask_high = ~0;
14459 if (INTVAL (shiftop) > 32)
14460 shift_mask_high <<= INTVAL (shiftop) - 32;
14462 lsb = high & -high;
14464 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14470 lsb = high & -high;
14471 return high == -lsb;
14474 shift_mask_low = ~0;
14475 shift_mask_low <<= INTVAL (shiftop);
14479 if (-lsb != shift_mask_low)
14482 if (HOST_BITS_PER_WIDE_INT < 64)
14487 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14489 lsb = high & -high;
14490 return high == -lsb;
14494 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14500 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14501 to perform a left shift. It must have SHIFTOP or more least
14502 significant 0's, with the remainder of the word 1's. */
14505 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14507 if (GET_CODE (andop) == CONST_INT)
14509 HOST_WIDE_INT c, lsb, shift_mask;
14512 shift_mask <<= INTVAL (shiftop);
14513 c = INTVAL (andop);
14515 /* Find the least significant one bit. */
14518 /* It must be covered by the shift mask.
14519 This test also rejects c == 0. */
14520 if ((lsb & shift_mask) == 0)
14523 /* Check we have all 1's above the transition, and reject all 1's. */
14524 return c == -lsb && lsb != 1;
14526 else if (GET_CODE (andop) == CONST_DOUBLE
14527 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14529 HOST_WIDE_INT low, lsb, shift_mask_low;
14531 low = CONST_DOUBLE_LOW (andop);
14533 if (HOST_BITS_PER_WIDE_INT < 64)
14535 HOST_WIDE_INT high, shift_mask_high;
14537 high = CONST_DOUBLE_HIGH (andop);
14541 shift_mask_high = ~0;
14542 if (INTVAL (shiftop) > 32)
14543 shift_mask_high <<= INTVAL (shiftop) - 32;
14545 lsb = high & -high;
14547 if ((lsb & shift_mask_high) == 0)
14550 return high == -lsb;
14556 shift_mask_low = ~0;
14557 shift_mask_low <<= INTVAL (shiftop);
14561 if ((lsb & shift_mask_low) == 0)
14564 return low == -lsb && lsb != 1;
14570 /* Return 1 if operands will generate a valid arguments to rlwimi
14571 instruction for insert with right shift in 64-bit mode. The mask may
14572 not start on the first bit or stop on the last bit because wrap-around
14573 effects of instruction do not correspond to semantics of RTL insn. */
14576 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14578 if (INTVAL (startop) > 32
14579 && INTVAL (startop) < 64
14580 && INTVAL (sizeop) > 1
14581 && INTVAL (sizeop) + INTVAL (startop) < 64
14582 && INTVAL (shiftop) > 0
14583 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14584 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14590 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14591 for lfq and stfq insns iff the registers are hard registers. */
14594 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14596 /* We might have been passed a SUBREG. */
14597 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14600 /* We might have been passed non floating point registers. */
14601 if (!FP_REGNO_P (REGNO (reg1))
14602 || !FP_REGNO_P (REGNO (reg2)))
14605 return (REGNO (reg1) == REGNO (reg2) - 1);
14608 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14609 addr1 and addr2 must be in consecutive memory locations
14610 (addr2 == addr1 + 8). */
14613 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14616 unsigned int reg1, reg2;
14617 int offset1, offset2;
14619 /* The mems cannot be volatile. */
14620 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14623 addr1 = XEXP (mem1, 0);
14624 addr2 = XEXP (mem2, 0);
14626 /* Extract an offset (if used) from the first addr. */
14627 if (GET_CODE (addr1) == PLUS)
14629 /* If not a REG, return zero. */
14630 if (GET_CODE (XEXP (addr1, 0)) != REG)
14634 reg1 = REGNO (XEXP (addr1, 0));
14635 /* The offset must be constant! */
14636 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14638 offset1 = INTVAL (XEXP (addr1, 1));
14641 else if (GET_CODE (addr1) != REG)
14645 reg1 = REGNO (addr1);
14646 /* This was a simple (mem (reg)) expression. Offset is 0. */
14650 /* And now for the second addr. */
14651 if (GET_CODE (addr2) == PLUS)
14653 /* If not a REG, return zero. */
14654 if (GET_CODE (XEXP (addr2, 0)) != REG)
14658 reg2 = REGNO (XEXP (addr2, 0));
14659 /* The offset must be constant. */
14660 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14662 offset2 = INTVAL (XEXP (addr2, 1));
14665 else if (GET_CODE (addr2) != REG)
14669 reg2 = REGNO (addr2);
14670 /* This was a simple (mem (reg)) expression. Offset is 0. */
14674 /* Both of these must have the same base register. */
14678 /* The offset for the second addr must be 8 more than the first addr. */
14679 if (offset2 != offset1 + 8)
14682 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14689 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14691 static bool eliminated = false;
14694 if (mode != SDmode)
14695 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14698 rtx mem = cfun->machine->sdmode_stack_slot;
14699 gcc_assert (mem != NULL_RTX);
14703 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14704 cfun->machine->sdmode_stack_slot = mem;
14710 if (TARGET_DEBUG_ADDR)
14712 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14713 GET_MODE_NAME (mode));
14715 fprintf (stderr, "\tNULL_RTX\n");
14724 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14726 /* Don't walk into types. */
14727 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14729 *walk_subtrees = 0;
14733 switch (TREE_CODE (*tp))
14742 case VIEW_CONVERT_EXPR:
14743 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14753 enum reload_reg_type {
14755 VECTOR_REGISTER_TYPE,
14756 OTHER_REGISTER_TYPE
14759 static enum reload_reg_type
14760 rs6000_reload_register_type (enum reg_class rclass)
14766 return GPR_REGISTER_TYPE;
14771 return VECTOR_REGISTER_TYPE;
14774 return OTHER_REGISTER_TYPE;
14778 /* Inform reload about cases where moving X with a mode MODE to a register in
14779 RCLASS requires an extra scratch or immediate register. Return the class
14780 needed for the immediate register.
14782 For VSX and Altivec, we may need a register to convert sp+offset into
14785 For misaligned 64-bit gpr loads and stores we need a register to
14786 convert an offset address to indirect. */
14789 rs6000_secondary_reload (bool in_p,
14791 reg_class_t rclass_i,
14792 enum machine_mode mode,
14793 secondary_reload_info *sri)
14795 enum reg_class rclass = (enum reg_class) rclass_i;
14796 reg_class_t ret = ALL_REGS;
14797 enum insn_code icode;
14798 bool default_p = false;
14800 sri->icode = CODE_FOR_nothing;
14802 /* Convert vector loads and stores into gprs to use an additional base
14804 icode = rs6000_vector_reload[mode][in_p != false];
14805 if (icode != CODE_FOR_nothing)
14808 sri->icode = CODE_FOR_nothing;
14809 sri->extra_cost = 0;
14811 if (GET_CODE (x) == MEM)
14813 rtx addr = XEXP (x, 0);
14815 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14816 an extra register in that case, but it would need an extra
14817 register if the addressing is reg+reg or (reg+reg)&(-16). */
14818 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14820 if (!legitimate_indirect_address_p (addr, false)
14821 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14823 sri->icode = icode;
14824 /* account for splitting the loads, and converting the
14825 address from reg+reg to reg. */
14826 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14827 + ((GET_CODE (addr) == AND) ? 1 : 0));
14830 /* Loads to and stores from vector registers can only do reg+reg
14831 addressing. Altivec registers can also do (reg+reg)&(-16). */
14832 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14833 || rclass == FLOAT_REGS || rclass == NO_REGS)
14835 if (!VECTOR_MEM_ALTIVEC_P (mode)
14836 && GET_CODE (addr) == AND
14837 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14838 && INTVAL (XEXP (addr, 1)) == -16
14839 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14840 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14842 sri->icode = icode;
14843 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14846 else if (!legitimate_indirect_address_p (addr, false)
14847 && (rclass == NO_REGS
14848 || !legitimate_indexed_address_p (addr, false)))
14850 sri->icode = icode;
14851 sri->extra_cost = 1;
14854 icode = CODE_FOR_nothing;
14856 /* Any other loads, including to pseudo registers which haven't been
14857 assigned to a register yet, default to require a scratch
14861 sri->icode = icode;
14862 sri->extra_cost = 2;
14865 else if (REG_P (x))
14867 int regno = true_regnum (x);
14869 icode = CODE_FOR_nothing;
14870 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14874 enum reg_class xclass = REGNO_REG_CLASS (regno);
14875 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14876 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14878 /* If memory is needed, use default_secondary_reload to create the
14880 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14889 else if (TARGET_POWERPC64
14890 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14892 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14894 rtx addr = XEXP (x, 0);
14896 if (GET_CODE (addr) == PRE_MODIFY)
14897 addr = XEXP (addr, 1);
14898 else if (GET_CODE (addr) == LO_SUM
14899 && GET_CODE (XEXP (addr, 0)) == REG
14900 && GET_CODE (XEXP (addr, 1)) == CONST)
14901 addr = XEXP (XEXP (addr, 1), 0);
14903 if (GET_CODE (addr) == PLUS
14904 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14905 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14908 sri->icode = CODE_FOR_reload_di_load;
14910 sri->icode = CODE_FOR_reload_di_store;
14911 sri->extra_cost = 2;
14921 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14923 gcc_assert (ret != ALL_REGS);
14925 if (TARGET_DEBUG_ADDR)
14928 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14930 reg_class_names[ret],
14931 in_p ? "true" : "false",
14932 reg_class_names[rclass],
14933 GET_MODE_NAME (mode));
14936 fprintf (stderr, ", default secondary reload");
14938 if (sri->icode != CODE_FOR_nothing)
14939 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14940 insn_data[sri->icode].name, sri->extra_cost);
14942 fprintf (stderr, "\n");
14950 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14951 to SP+reg addressing. */
14954 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14956 int regno = true_regnum (reg);
14957 enum machine_mode mode = GET_MODE (reg);
14958 enum reg_class rclass;
14960 rtx and_op2 = NULL_RTX;
14963 rtx scratch_or_premodify = scratch;
14967 if (TARGET_DEBUG_ADDR)
14969 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14970 store_p ? "store" : "load");
14971 fprintf (stderr, "reg:\n");
14973 fprintf (stderr, "mem:\n");
14975 fprintf (stderr, "scratch:\n");
14976 debug_rtx (scratch);
14979 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14980 gcc_assert (GET_CODE (mem) == MEM);
14981 rclass = REGNO_REG_CLASS (regno);
14982 addr = XEXP (mem, 0);
14986 /* GPRs can handle reg + small constant, all other addresses need to use
14987 the scratch register. */
14990 if (GET_CODE (addr) == AND)
14992 and_op2 = XEXP (addr, 1);
14993 addr = XEXP (addr, 0);
14996 if (GET_CODE (addr) == PRE_MODIFY)
14998 scratch_or_premodify = XEXP (addr, 0);
14999 gcc_assert (REG_P (scratch_or_premodify));
15000 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15001 addr = XEXP (addr, 1);
15004 if (GET_CODE (addr) == PLUS
15005 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
15006 || and_op2 != NULL_RTX))
15008 addr_op1 = XEXP (addr, 0);
15009 addr_op2 = XEXP (addr, 1);
15010 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15012 if (!REG_P (addr_op2)
15013 && (GET_CODE (addr_op2) != CONST_INT
15014 || !satisfies_constraint_I (addr_op2)))
15016 if (TARGET_DEBUG_ADDR)
15019 "\nMove plus addr to register %s, mode = %s: ",
15020 rs6000_reg_names[REGNO (scratch)],
15021 GET_MODE_NAME (mode));
15022 debug_rtx (addr_op2);
15024 rs6000_emit_move (scratch, addr_op2, Pmode);
15025 addr_op2 = scratch;
15028 emit_insn (gen_rtx_SET (VOIDmode,
15029 scratch_or_premodify,
15030 gen_rtx_PLUS (Pmode,
15034 addr = scratch_or_premodify;
15035 scratch_or_premodify = scratch;
15037 else if (!legitimate_indirect_address_p (addr, false)
15038 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15040 if (TARGET_DEBUG_ADDR)
15042 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15043 rs6000_reg_names[REGNO (scratch_or_premodify)],
15044 GET_MODE_NAME (mode));
15047 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15048 addr = scratch_or_premodify;
15049 scratch_or_premodify = scratch;
15053 /* Float/Altivec registers can only handle reg+reg addressing. Move
15054 other addresses into a scratch register. */
15059 /* With float regs, we need to handle the AND ourselves, since we can't
15060 use the Altivec instruction with an implicit AND -16. Allow scalar
15061 loads to float registers to use reg+offset even if VSX. */
15062 if (GET_CODE (addr) == AND
15063 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15064 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15065 || INTVAL (XEXP (addr, 1)) != -16
15066 || !VECTOR_MEM_ALTIVEC_P (mode)))
15068 and_op2 = XEXP (addr, 1);
15069 addr = XEXP (addr, 0);
15072 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15073 as the address later. */
15074 if (GET_CODE (addr) == PRE_MODIFY
15075 && (!VECTOR_MEM_VSX_P (mode)
15076 || and_op2 != NULL_RTX
15077 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15079 scratch_or_premodify = XEXP (addr, 0);
15080 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15082 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15083 addr = XEXP (addr, 1);
15086 if (legitimate_indirect_address_p (addr, false) /* reg */
15087 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15088 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15089 || (GET_CODE (addr) == AND /* Altivec memory */
15090 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15091 && INTVAL (XEXP (addr, 1)) == -16
15092 && VECTOR_MEM_ALTIVEC_P (mode))
15093 || (rclass == FLOAT_REGS /* legacy float mem */
15094 && GET_MODE_SIZE (mode) == 8
15095 && and_op2 == NULL_RTX
15096 && scratch_or_premodify == scratch
15097 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15100 else if (GET_CODE (addr) == PLUS)
15102 addr_op1 = XEXP (addr, 0);
15103 addr_op2 = XEXP (addr, 1);
15104 gcc_assert (REG_P (addr_op1));
15106 if (TARGET_DEBUG_ADDR)
15108 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15109 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15110 debug_rtx (addr_op2);
15112 rs6000_emit_move (scratch, addr_op2, Pmode);
15113 emit_insn (gen_rtx_SET (VOIDmode,
15114 scratch_or_premodify,
15115 gen_rtx_PLUS (Pmode,
15118 addr = scratch_or_premodify;
15119 scratch_or_premodify = scratch;
15122 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15123 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15125 if (TARGET_DEBUG_ADDR)
15127 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15128 rs6000_reg_names[REGNO (scratch_or_premodify)],
15129 GET_MODE_NAME (mode));
15133 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15134 addr = scratch_or_premodify;
15135 scratch_or_premodify = scratch;
15139 gcc_unreachable ();
15144 gcc_unreachable ();
15147 /* If the original address involved a pre-modify that we couldn't use the VSX
15148 memory instruction with update, and we haven't taken care of already,
15149 store the address in the pre-modify register and use that as the
15151 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15153 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15154 addr = scratch_or_premodify;
15157 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15158 memory instruction, recreate the AND now, including the clobber which is
15159 generated by the general ANDSI3/ANDDI3 patterns for the
15160 andi. instruction. */
15161 if (and_op2 != NULL_RTX)
15163 if (! legitimate_indirect_address_p (addr, false))
15165 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15169 if (TARGET_DEBUG_ADDR)
15171 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15172 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15173 debug_rtx (and_op2);
15176 and_rtx = gen_rtx_SET (VOIDmode,
15178 gen_rtx_AND (Pmode,
15182 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15183 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15184 gen_rtvec (2, and_rtx, cc_clobber)));
15188 /* Adjust the address if it changed. */
15189 if (addr != XEXP (mem, 0))
15191 mem = change_address (mem, mode, addr);
15192 if (TARGET_DEBUG_ADDR)
15193 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15196 /* Now create the move. */
15198 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15200 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15205 /* Convert reloads involving 64-bit gprs and misaligned offset
15206 addressing to use indirect addressing. */
15209 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
15211 int regno = true_regnum (reg);
15212 enum reg_class rclass;
15214 rtx scratch_or_premodify = scratch;
15216 if (TARGET_DEBUG_ADDR)
15218 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
15219 store_p ? "store" : "load");
15220 fprintf (stderr, "reg:\n");
15222 fprintf (stderr, "mem:\n");
15224 fprintf (stderr, "scratch:\n");
15225 debug_rtx (scratch);
15228 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
15229 gcc_assert (GET_CODE (mem) == MEM);
15230 rclass = REGNO_REG_CLASS (regno);
15231 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
15232 addr = XEXP (mem, 0);
15234 if (GET_CODE (addr) == PRE_MODIFY)
15236 scratch_or_premodify = XEXP (addr, 0);
15237 gcc_assert (REG_P (scratch_or_premodify));
15238 addr = XEXP (addr, 1);
15240 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
15242 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15244 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
15246 /* Now create the move. */
15248 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15250 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15255 /* Allocate a 64-bit stack slot to be used for copying SDmode
15256 values through if this function has any SDmode references. */
15259 rs6000_alloc_sdmode_stack_slot (void)
15263 gimple_stmt_iterator gsi;
15265 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15268 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15270 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15273 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15274 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15280 /* Check for any SDmode parameters of the function. */
15281 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15283 if (TREE_TYPE (t) == error_mark_node)
15286 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15287 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15289 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15290 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15298 rs6000_instantiate_decls (void)
15300 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15301 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15304 /* Given an rtx X being reloaded into a reg required to be
15305 in class CLASS, return the class of reg to actually use.
15306 In general this is just CLASS; but on some machines
15307 in some cases it is preferable to use a more restrictive class.
15309 On the RS/6000, we have to return NO_REGS when we want to reload a
15310 floating-point CONST_DOUBLE to force it to be copied to memory.
15312 We also don't want to reload integer values into floating-point
15313 registers if we can at all help it. In fact, this can
15314 cause reload to die, if it tries to generate a reload of CTR
15315 into a FP register and discovers it doesn't have the memory location
15318 ??? Would it be a good idea to have reload do the converse, that is
15319 try to reload floating modes into FP registers if possible?
15322 static enum reg_class
15323 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15325 enum machine_mode mode = GET_MODE (x);
15327 if (VECTOR_UNIT_VSX_P (mode)
15328 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15331 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15332 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15333 && easy_vector_constant (x, mode))
15334 return ALTIVEC_REGS;
15336 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15339 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15340 return GENERAL_REGS;
15342 /* For VSX, prefer the traditional registers for 64-bit values because we can
15343 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15344 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15345 prefer Altivec loads.. */
15346 if (rclass == VSX_REGS)
15348 if (GET_MODE_SIZE (mode) <= 8)
15351 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15352 return ALTIVEC_REGS;
15360 /* Debug version of rs6000_preferred_reload_class. */
15361 static enum reg_class
15362 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15364 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15367 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15369 reg_class_names[ret], reg_class_names[rclass],
15370 GET_MODE_NAME (GET_MODE (x)));
15376 /* If we are copying between FP or AltiVec registers and anything else, we need
15377 a memory location. The exception is when we are targeting ppc64 and the
15378 move to/from fpr to gpr instructions are available. Also, under VSX, you
15379 can copy vector registers from the FP register set to the Altivec register
15380 set and vice versa. */
15383 rs6000_secondary_memory_needed (enum reg_class class1,
15384 enum reg_class class2,
15385 enum machine_mode mode)
15387 if (class1 == class2)
15390 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15391 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15392 between these classes. But we need memory for other things that can go in
15393 FLOAT_REGS like SFmode. */
15395 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15396 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15397 || class1 == FLOAT_REGS))
15398 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15399 && class2 != FLOAT_REGS);
15401 if (class1 == VSX_REGS || class2 == VSX_REGS)
15404 if (class1 == FLOAT_REGS
15405 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15406 || ((mode != DFmode)
15407 && (mode != DDmode)
15408 && (mode != DImode))))
15411 if (class2 == FLOAT_REGS
15412 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15413 || ((mode != DFmode)
15414 && (mode != DDmode)
15415 && (mode != DImode))))
15418 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15424 /* Debug version of rs6000_secondary_memory_needed. */
15426 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15427 enum reg_class class2,
15428 enum machine_mode mode)
15430 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15433 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15434 "class2 = %s, mode = %s\n",
15435 ret ? "true" : "false", reg_class_names[class1],
15436 reg_class_names[class2], GET_MODE_NAME (mode));
15441 /* Return the register class of a scratch register needed to copy IN into
15442 or out of a register in RCLASS in MODE. If it can be done directly,
15443 NO_REGS is returned. */
15445 static enum reg_class
15446 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15451 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15453 && MACHOPIC_INDIRECT
15457 /* We cannot copy a symbolic operand directly into anything
15458 other than BASE_REGS for TARGET_ELF. So indicate that a
15459 register from BASE_REGS is needed as an intermediate
15462 On Darwin, pic addresses require a load from memory, which
15463 needs a base register. */
15464 if (rclass != BASE_REGS
15465 && (GET_CODE (in) == SYMBOL_REF
15466 || GET_CODE (in) == HIGH
15467 || GET_CODE (in) == LABEL_REF
15468 || GET_CODE (in) == CONST))
15472 if (GET_CODE (in) == REG)
15474 regno = REGNO (in);
15475 if (regno >= FIRST_PSEUDO_REGISTER)
15477 regno = true_regnum (in);
15478 if (regno >= FIRST_PSEUDO_REGISTER)
15482 else if (GET_CODE (in) == SUBREG)
15484 regno = true_regnum (in);
15485 if (regno >= FIRST_PSEUDO_REGISTER)
15491 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15493 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15494 || (regno >= 0 && INT_REGNO_P (regno)))
15497 /* Constants, memory, and FP registers can go into FP registers. */
15498 if ((regno == -1 || FP_REGNO_P (regno))
15499 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15500 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15502 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15505 && (regno == -1 || VSX_REGNO_P (regno))
15506 && VSX_REG_CLASS_P (rclass))
15509 /* Memory, and AltiVec registers can go into AltiVec registers. */
15510 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15511 && rclass == ALTIVEC_REGS)
15514 /* We can copy among the CR registers. */
15515 if ((rclass == CR_REGS || rclass == CR0_REGS)
15516 && regno >= 0 && CR_REGNO_P (regno))
15519 /* Otherwise, we need GENERAL_REGS. */
15520 return GENERAL_REGS;
15523 /* Debug version of rs6000_secondary_reload_class. */
15524 static enum reg_class
15525 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15526 enum machine_mode mode, rtx in)
15528 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15530 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15531 "mode = %s, input rtx:\n",
15532 reg_class_names[ret], reg_class_names[rclass],
15533 GET_MODE_NAME (mode));
15539 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15542 rs6000_cannot_change_mode_class (enum machine_mode from,
15543 enum machine_mode to,
15544 enum reg_class rclass)
15546 unsigned from_size = GET_MODE_SIZE (from);
15547 unsigned to_size = GET_MODE_SIZE (to);
15549 if (from_size != to_size)
15551 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15552 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15553 && reg_classes_intersect_p (xclass, rclass));
15556 if (TARGET_E500_DOUBLE
15557 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15558 || (((to) == TFmode) + ((from) == TFmode)) == 1
15559 || (((to) == DDmode) + ((from) == DDmode)) == 1
15560 || (((to) == TDmode) + ((from) == TDmode)) == 1
15561 || (((to) == DImode) + ((from) == DImode)) == 1))
15564 /* Since the VSX register set includes traditional floating point registers
15565 and altivec registers, just check for the size being different instead of
15566 trying to check whether the modes are vector modes. Otherwise it won't
15567 allow say DF and DI to change classes. */
15568 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15569 return (from_size != 8 && from_size != 16);
15571 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15572 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15575 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15576 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15582 /* Debug version of rs6000_cannot_change_mode_class. */
15584 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15585 enum machine_mode to,
15586 enum reg_class rclass)
15588 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15591 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15592 "to = %s, rclass = %s\n",
15593 ret ? "true" : "false",
15594 GET_MODE_NAME (from), GET_MODE_NAME (to),
15595 reg_class_names[rclass]);
15600 /* Given a comparison operation, return the bit number in CCR to test. We
15601 know this is a valid comparison.
15603 SCC_P is 1 if this is for an scc. That means that %D will have been
15604 used instead of %C, so the bits will be in different places.
15606 Return -1 if OP isn't a valid comparison for some reason. */
15609 ccr_bit (rtx op, int scc_p)
15611 enum rtx_code code = GET_CODE (op);
15612 enum machine_mode cc_mode;
15617 if (!COMPARISON_P (op))
15620 reg = XEXP (op, 0);
15622 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15624 cc_mode = GET_MODE (reg);
15625 cc_regnum = REGNO (reg);
15626 base_bit = 4 * (cc_regnum - CR0_REGNO);
15628 validate_condition_mode (code, cc_mode);
15630 /* When generating a sCOND operation, only positive conditions are
15633 || code == EQ || code == GT || code == LT || code == UNORDERED
15634 || code == GTU || code == LTU);
15639 return scc_p ? base_bit + 3 : base_bit + 2;
15641 return base_bit + 2;
15642 case GT: case GTU: case UNLE:
15643 return base_bit + 1;
15644 case LT: case LTU: case UNGE:
15646 case ORDERED: case UNORDERED:
15647 return base_bit + 3;
15650 /* If scc, we will have done a cror to put the bit in the
15651 unordered position. So test that bit. For integer, this is ! LT
15652 unless this is an scc insn. */
15653 return scc_p ? base_bit + 3 : base_bit;
15656 return scc_p ? base_bit + 3 : base_bit + 1;
15659 gcc_unreachable ();
15663 /* Return the GOT register. */
15666 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15668 /* The second flow pass currently (June 1999) can't update
15669 regs_ever_live without disturbing other parts of the compiler, so
15670 update it here to make the prolog/epilogue code happy. */
15671 if (!can_create_pseudo_p ()
15672 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15673 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15675 crtl->uses_pic_offset_table = 1;
15677 return pic_offset_table_rtx;
15680 static rs6000_stack_t stack_info;
15682 /* Function to init struct machine_function.
15683 This will be called, via a pointer variable,
15684 from push_function_context. */
15686 static struct machine_function *
15687 rs6000_init_machine_status (void)
15689 stack_info.reload_completed = 0;
15690 return ggc_alloc_cleared_machine_function ();
15693 /* These macros test for integers and extract the low-order bits. */
15695 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15696 && GET_MODE (X) == VOIDmode)
15698 #define INT_LOWPART(X) \
15699 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15702 extract_MB (rtx op)
15705 unsigned long val = INT_LOWPART (op);
15707 /* If the high bit is zero, the value is the first 1 bit we find
15709 if ((val & 0x80000000) == 0)
15711 gcc_assert (val & 0xffffffff);
15714 while (((val <<= 1) & 0x80000000) == 0)
15719 /* If the high bit is set and the low bit is not, or the mask is all
15720 1's, the value is zero. */
15721 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15724 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15727 while (((val >>= 1) & 1) != 0)
15734 extract_ME (rtx op)
15737 unsigned long val = INT_LOWPART (op);
15739 /* If the low bit is zero, the value is the first 1 bit we find from
15741 if ((val & 1) == 0)
15743 gcc_assert (val & 0xffffffff);
15746 while (((val >>= 1) & 1) == 0)
15752 /* If the low bit is set and the high bit is not, or the mask is all
15753 1's, the value is 31. */
15754 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15757 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15760 while (((val <<= 1) & 0x80000000) != 0)
15766 /* Locate some local-dynamic symbol still in use by this function
15767 so that we can print its name in some tls_ld pattern. */
15769 static const char *
15770 rs6000_get_some_local_dynamic_name (void)
15774 if (cfun->machine->some_ld_name)
15775 return cfun->machine->some_ld_name;
15777 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15779 && for_each_rtx (&PATTERN (insn),
15780 rs6000_get_some_local_dynamic_name_1, 0))
15781 return cfun->machine->some_ld_name;
15783 gcc_unreachable ();
15786 /* Helper function for rs6000_get_some_local_dynamic_name. */
15789 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15793 if (GET_CODE (x) == SYMBOL_REF)
15795 const char *str = XSTR (x, 0);
15796 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15798 cfun->machine->some_ld_name = str;
15806 /* Write out a function code label. */
15809 rs6000_output_function_entry (FILE *file, const char *fname)
15811 if (fname[0] != '.')
15813 switch (DEFAULT_ABI)
15816 gcc_unreachable ();
15822 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15831 RS6000_OUTPUT_BASENAME (file, fname);
15834 /* Print an operand. Recognize special options, documented below. */
15837 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15838 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15840 #define SMALL_DATA_RELOC "sda21"
15841 #define SMALL_DATA_REG 0
15845 print_operand (FILE *file, rtx x, int code)
15849 unsigned HOST_WIDE_INT uval;
15854 /* Write out an instruction after the call which may be replaced
15855 with glue code by the loader. This depends on the AIX version. */
15856 asm_fprintf (file, RS6000_CALL_GLUE);
15859 /* %a is output_address. */
15862 /* If X is a constant integer whose low-order 5 bits are zero,
15863 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15864 in the AIX assembler where "sri" with a zero shift count
15865 writes a trash instruction. */
15866 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15873 /* If constant, low-order 16 bits of constant, unsigned.
15874 Otherwise, write normally. */
15876 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15878 print_operand (file, x, 0);
15882 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15883 for 64-bit mask direction. */
15884 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15887 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15891 /* X is a CR register. Print the number of the GT bit of the CR. */
15892 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15893 output_operand_lossage ("invalid %%c value");
15895 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15899 /* Like 'J' but get to the GT bit only. */
15900 gcc_assert (GET_CODE (x) == REG);
15902 /* Bit 1 is GT bit. */
15903 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15905 /* Add one for shift count in rlinm for scc. */
15906 fprintf (file, "%d", i + 1);
15910 /* X is a CR register. Print the number of the EQ bit of the CR */
15911 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15912 output_operand_lossage ("invalid %%E value");
15914 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15918 /* X is a CR register. Print the shift count needed to move it
15919 to the high-order four bits. */
15920 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15921 output_operand_lossage ("invalid %%f value");
15923 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15927 /* Similar, but print the count for the rotate in the opposite
15929 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15930 output_operand_lossage ("invalid %%F value");
15932 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15936 /* X is a constant integer. If it is negative, print "m",
15937 otherwise print "z". This is to make an aze or ame insn. */
15938 if (GET_CODE (x) != CONST_INT)
15939 output_operand_lossage ("invalid %%G value");
15940 else if (INTVAL (x) >= 0)
15947 /* If constant, output low-order five bits. Otherwise, write
15950 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15952 print_operand (file, x, 0);
15956 /* If constant, output low-order six bits. Otherwise, write
15959 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15961 print_operand (file, x, 0);
15965 /* Print `i' if this is a constant, else nothing. */
15971 /* Write the bit number in CCR for jump. */
15972 i = ccr_bit (x, 0);
15974 output_operand_lossage ("invalid %%j code");
15976 fprintf (file, "%d", i);
15980 /* Similar, but add one for shift count in rlinm for scc and pass
15981 scc flag to `ccr_bit'. */
15982 i = ccr_bit (x, 1);
15984 output_operand_lossage ("invalid %%J code");
15986 /* If we want bit 31, write a shift count of zero, not 32. */
15987 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15991 /* X must be a constant. Write the 1's complement of the
15994 output_operand_lossage ("invalid %%k value");
15996 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
16000 /* X must be a symbolic constant on ELF. Write an
16001 expression suitable for an 'addi' that adds in the low 16
16002 bits of the MEM. */
16003 if (GET_CODE (x) == CONST)
16005 if (GET_CODE (XEXP (x, 0)) != PLUS
16006 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
16007 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
16008 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
16009 output_operand_lossage ("invalid %%K value");
16011 print_operand_address (file, x);
16012 fputs ("@l", file);
16015 /* %l is output_asm_label. */
16018 /* Write second word of DImode or DFmode reference. Works on register
16019 or non-indexed memory only. */
16020 if (GET_CODE (x) == REG)
16021 fputs (reg_names[REGNO (x) + 1], file);
16022 else if (GET_CODE (x) == MEM)
16024 /* Handle possible auto-increment. Since it is pre-increment and
16025 we have already done it, we can just use an offset of word. */
16026 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16027 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16028 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16030 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16031 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16034 output_address (XEXP (adjust_address_nv (x, SImode,
16038 if (small_data_operand (x, GET_MODE (x)))
16039 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16040 reg_names[SMALL_DATA_REG]);
16045 /* MB value for a mask operand. */
16046 if (! mask_operand (x, SImode))
16047 output_operand_lossage ("invalid %%m value");
16049 fprintf (file, "%d", extract_MB (x));
16053 /* ME value for a mask operand. */
16054 if (! mask_operand (x, SImode))
16055 output_operand_lossage ("invalid %%M value");
16057 fprintf (file, "%d", extract_ME (x));
16060 /* %n outputs the negative of its operand. */
16063 /* Write the number of elements in the vector times 4. */
16064 if (GET_CODE (x) != PARALLEL)
16065 output_operand_lossage ("invalid %%N value");
16067 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16071 /* Similar, but subtract 1 first. */
16072 if (GET_CODE (x) != PARALLEL)
16073 output_operand_lossage ("invalid %%O value");
16075 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16079 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16081 || INT_LOWPART (x) < 0
16082 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16083 output_operand_lossage ("invalid %%p value");
16085 fprintf (file, "%d", i);
16089 /* The operand must be an indirect memory reference. The result
16090 is the register name. */
16091 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16092 || REGNO (XEXP (x, 0)) >= 32)
16093 output_operand_lossage ("invalid %%P value");
16095 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16099 /* This outputs the logical code corresponding to a boolean
16100 expression. The expression may have one or both operands
16101 negated (if one, only the first one). For condition register
16102 logical operations, it will also treat the negated
16103 CR codes as NOTs, but not handle NOTs of them. */
16105 const char *const *t = 0;
16107 enum rtx_code code = GET_CODE (x);
16108 static const char * const tbl[3][3] = {
16109 { "and", "andc", "nor" },
16110 { "or", "orc", "nand" },
16111 { "xor", "eqv", "xor" } };
16115 else if (code == IOR)
16117 else if (code == XOR)
16120 output_operand_lossage ("invalid %%q value");
16122 if (GET_CODE (XEXP (x, 0)) != NOT)
16126 if (GET_CODE (XEXP (x, 1)) == NOT)
16144 /* X is a CR register. Print the mask for `mtcrf'. */
16145 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16146 output_operand_lossage ("invalid %%R value");
16148 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16152 /* Low 5 bits of 32 - value */
16154 output_operand_lossage ("invalid %%s value");
16156 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16160 /* PowerPC64 mask position. All 0's is excluded.
16161 CONST_INT 32-bit mask is considered sign-extended so any
16162 transition must occur within the CONST_INT, not on the boundary. */
16163 if (! mask64_operand (x, DImode))
16164 output_operand_lossage ("invalid %%S value");
16166 uval = INT_LOWPART (x);
16168 if (uval & 1) /* Clear Left */
16170 #if HOST_BITS_PER_WIDE_INT > 64
16171 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16175 else /* Clear Right */
16178 #if HOST_BITS_PER_WIDE_INT > 64
16179 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16185 gcc_assert (i >= 0);
16186 fprintf (file, "%d", i);
16190 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16191 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16193 /* Bit 3 is OV bit. */
16194 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16196 /* If we want bit 31, write a shift count of zero, not 32. */
16197 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16201 /* Print the symbolic name of a branch target register. */
16202 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16203 && REGNO (x) != CTR_REGNO))
16204 output_operand_lossage ("invalid %%T value");
16205 else if (REGNO (x) == LR_REGNO)
16206 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16208 fputs ("ctr", file);
16212 /* High-order 16 bits of constant for use in unsigned operand. */
16214 output_operand_lossage ("invalid %%u value");
16216 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16217 (INT_LOWPART (x) >> 16) & 0xffff);
16221 /* High-order 16 bits of constant for use in signed operand. */
16223 output_operand_lossage ("invalid %%v value");
16225 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16226 (INT_LOWPART (x) >> 16) & 0xffff);
16230 /* Print `u' if this has an auto-increment or auto-decrement. */
16231 if (GET_CODE (x) == MEM
16232 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16233 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16234 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16239 /* Print the trap code for this operand. */
16240 switch (GET_CODE (x))
16243 fputs ("eq", file); /* 4 */
16246 fputs ("ne", file); /* 24 */
16249 fputs ("lt", file); /* 16 */
16252 fputs ("le", file); /* 20 */
16255 fputs ("gt", file); /* 8 */
16258 fputs ("ge", file); /* 12 */
16261 fputs ("llt", file); /* 2 */
16264 fputs ("lle", file); /* 6 */
16267 fputs ("lgt", file); /* 1 */
16270 fputs ("lge", file); /* 5 */
16273 gcc_unreachable ();
16278 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16281 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16282 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16284 print_operand (file, x, 0);
16288 /* MB value for a PowerPC64 rldic operand. */
16289 val = (GET_CODE (x) == CONST_INT
16290 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16295 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16296 if ((val <<= 1) < 0)
16299 #if HOST_BITS_PER_WIDE_INT == 32
16300 if (GET_CODE (x) == CONST_INT && i >= 0)
16301 i += 32; /* zero-extend high-part was all 0's */
16302 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16304 val = CONST_DOUBLE_LOW (x);
16310 for ( ; i < 64; i++)
16311 if ((val <<= 1) < 0)
16316 fprintf (file, "%d", i + 1);
16320 /* X is a FPR or Altivec register used in a VSX context. */
16321 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16322 output_operand_lossage ("invalid %%x value");
16325 int reg = REGNO (x);
16326 int vsx_reg = (FP_REGNO_P (reg)
16328 : reg - FIRST_ALTIVEC_REGNO + 32);
16330 #ifdef TARGET_REGNAMES
16331 if (TARGET_REGNAMES)
16332 fprintf (file, "%%vs%d", vsx_reg);
16335 fprintf (file, "%d", vsx_reg);
16340 if (GET_CODE (x) == MEM
16341 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16342 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16343 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16348 /* Like 'L', for third word of TImode */
16349 if (GET_CODE (x) == REG)
16350 fputs (reg_names[REGNO (x) + 2], file);
16351 else if (GET_CODE (x) == MEM)
16353 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16354 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16355 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16356 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16357 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16359 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16360 if (small_data_operand (x, GET_MODE (x)))
16361 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16362 reg_names[SMALL_DATA_REG]);
16367 /* X is a SYMBOL_REF. Write out the name preceded by a
16368 period and without any trailing data in brackets. Used for function
16369 names. If we are configured for System V (or the embedded ABI) on
16370 the PowerPC, do not emit the period, since those systems do not use
16371 TOCs and the like. */
16372 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16374 /* Mark the decl as referenced so that cgraph will output the
16376 if (SYMBOL_REF_DECL (x))
16377 mark_decl_referenced (SYMBOL_REF_DECL (x));
16379 /* For macho, check to see if we need a stub. */
16382 const char *name = XSTR (x, 0);
16384 if (darwin_emit_branch_islands
16385 && MACHOPIC_INDIRECT
16386 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16387 name = machopic_indirection_name (x, /*stub_p=*/true);
16389 assemble_name (file, name);
16391 else if (!DOT_SYMBOLS)
16392 assemble_name (file, XSTR (x, 0));
16394 rs6000_output_function_entry (file, XSTR (x, 0));
16398 /* Like 'L', for last word of TImode. */
16399 if (GET_CODE (x) == REG)
16400 fputs (reg_names[REGNO (x) + 3], file);
16401 else if (GET_CODE (x) == MEM)
16403 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16404 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16405 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16406 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16407 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16409 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16410 if (small_data_operand (x, GET_MODE (x)))
16411 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16412 reg_names[SMALL_DATA_REG]);
16416 /* Print AltiVec or SPE memory operand. */
16421 gcc_assert (GET_CODE (x) == MEM);
16425 /* Ugly hack because %y is overloaded. */
16426 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16427 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16428 || GET_MODE (x) == TFmode
16429 || GET_MODE (x) == TImode))
16431 /* Handle [reg]. */
16432 if (GET_CODE (tmp) == REG)
16434 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16437 /* Handle [reg+UIMM]. */
16438 else if (GET_CODE (tmp) == PLUS &&
16439 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16443 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16445 x = INTVAL (XEXP (tmp, 1));
16446 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16450 /* Fall through. Must be [reg+reg]. */
16452 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16453 && GET_CODE (tmp) == AND
16454 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16455 && INTVAL (XEXP (tmp, 1)) == -16)
16456 tmp = XEXP (tmp, 0);
16457 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16458 && GET_CODE (tmp) == PRE_MODIFY)
16459 tmp = XEXP (tmp, 1);
16460 if (GET_CODE (tmp) == REG)
16461 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16464 if (!GET_CODE (tmp) == PLUS
16465 || !REG_P (XEXP (tmp, 0))
16466 || !REG_P (XEXP (tmp, 1)))
16468 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16472 if (REGNO (XEXP (tmp, 0)) == 0)
16473 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16474 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16476 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16477 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16483 if (GET_CODE (x) == REG)
16484 fprintf (file, "%s", reg_names[REGNO (x)]);
16485 else if (GET_CODE (x) == MEM)
16487 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16488 know the width from the mode. */
16489 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16490 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16491 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16492 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16493 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16494 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16495 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16496 output_address (XEXP (XEXP (x, 0), 1));
16498 output_address (XEXP (x, 0));
16502 if (toc_relative_expr_p (x))
16503 /* This hack along with a corresponding hack in
16504 rs6000_output_addr_const_extra arranges to output addends
16505 where the assembler expects to find them. eg.
16506 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16507 without this hack would be output as "x@toc+4". We
16509 output_addr_const (file, tocrel_base);
16511 output_addr_const (file, x);
16516 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16520 output_operand_lossage ("invalid %%xn code");
16524 /* Print the address of an operand. */
16527 print_operand_address (FILE *file, rtx x)
16529 if (GET_CODE (x) == REG)
16530 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16531 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16532 || GET_CODE (x) == LABEL_REF)
16534 output_addr_const (file, x);
16535 if (small_data_operand (x, GET_MODE (x)))
16536 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16537 reg_names[SMALL_DATA_REG]);
16539 gcc_assert (!TARGET_TOC);
16541 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16543 gcc_assert (REG_P (XEXP (x, 0)));
16544 if (REGNO (XEXP (x, 0)) == 0)
16545 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16546 reg_names[ REGNO (XEXP (x, 0)) ]);
16548 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16549 reg_names[ REGNO (XEXP (x, 1)) ]);
16551 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16552 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16553 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16555 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16556 && CONSTANT_P (XEXP (x, 1)))
16558 fprintf (file, "lo16(");
16559 output_addr_const (file, XEXP (x, 1));
16560 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16563 else if (legitimate_constant_pool_address_p (x, QImode, true))
16565 /* This hack along with a corresponding hack in
16566 rs6000_output_addr_const_extra arranges to output addends
16567 where the assembler expects to find them. eg.
16569 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16570 without this hack would be output as "x@toc+8@l(9)". We
16571 want "x+8@toc@l(9)". */
16572 output_addr_const (file, tocrel_base);
16573 if (GET_CODE (x) == LO_SUM)
16574 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16576 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16579 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16580 && CONSTANT_P (XEXP (x, 1)))
16582 output_addr_const (file, XEXP (x, 1));
16583 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16587 gcc_unreachable ();
16590 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16593 rs6000_output_addr_const_extra (FILE *file, rtx x)
16595 if (GET_CODE (x) == UNSPEC)
16596 switch (XINT (x, 1))
16598 case UNSPEC_TOCREL:
16599 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16600 output_addr_const (file, XVECEXP (x, 0, 0));
16601 if (x == tocrel_base && tocrel_offset != const0_rtx)
16603 if (INTVAL (tocrel_offset) >= 0)
16604 fprintf (file, "+");
16605 output_addr_const (file, tocrel_offset);
16607 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16610 assemble_name (file, toc_label_name);
16612 else if (TARGET_ELF)
16613 fputs ("@toc", file);
16617 case UNSPEC_MACHOPIC_OFFSET:
16618 output_addr_const (file, XVECEXP (x, 0, 0));
16620 machopic_output_function_base_name (file);
16627 /* Target hook for assembling integer objects. The PowerPC version has
16628 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16629 is defined. It also needs to handle DI-mode objects on 64-bit
16633 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16635 #ifdef RELOCATABLE_NEEDS_FIXUP
16636 /* Special handling for SI values. */
16637 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16639 static int recurse = 0;
16641 /* For -mrelocatable, we mark all addresses that need to be fixed up
16642 in the .fixup section. */
16643 if (TARGET_RELOCATABLE
16644 && in_section != toc_section
16645 && in_section != text_section
16646 && !unlikely_text_section_p (in_section)
16648 && GET_CODE (x) != CONST_INT
16649 && GET_CODE (x) != CONST_DOUBLE
16655 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16657 ASM_OUTPUT_LABEL (asm_out_file, buf);
16658 fprintf (asm_out_file, "\t.long\t(");
16659 output_addr_const (asm_out_file, x);
16660 fprintf (asm_out_file, ")@fixup\n");
16661 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16662 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16663 fprintf (asm_out_file, "\t.long\t");
16664 assemble_name (asm_out_file, buf);
16665 fprintf (asm_out_file, "\n\t.previous\n");
16669 /* Remove initial .'s to turn a -mcall-aixdesc function
16670 address into the address of the descriptor, not the function
16672 else if (GET_CODE (x) == SYMBOL_REF
16673 && XSTR (x, 0)[0] == '.'
16674 && DEFAULT_ABI == ABI_AIX)
16676 const char *name = XSTR (x, 0);
16677 while (*name == '.')
16680 fprintf (asm_out_file, "\t.long\t%s\n", name);
16684 #endif /* RELOCATABLE_NEEDS_FIXUP */
16685 return default_assemble_integer (x, size, aligned_p);
16688 #ifdef HAVE_GAS_HIDDEN
16689 /* Emit an assembler directive to set symbol visibility for DECL to
16690 VISIBILITY_TYPE. */
16693 rs6000_assemble_visibility (tree decl, int vis)
16695 /* Functions need to have their entry point symbol visibility set as
16696 well as their descriptor symbol visibility. */
16697 if (DEFAULT_ABI == ABI_AIX
16699 && TREE_CODE (decl) == FUNCTION_DECL)
16701 static const char * const visibility_types[] = {
16702 NULL, "internal", "hidden", "protected"
16705 const char *name, *type;
16707 name = ((* targetm.strip_name_encoding)
16708 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16709 type = visibility_types[vis];
16711 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16712 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16715 default_assemble_visibility (decl, vis);
16720 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16722 /* Reversal of FP compares takes care -- an ordered compare
16723 becomes an unordered compare and vice versa. */
16724 if (mode == CCFPmode
16725 && (!flag_finite_math_only
16726 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16727 || code == UNEQ || code == LTGT))
16728 return reverse_condition_maybe_unordered (code);
16730 return reverse_condition (code);
16733 /* Generate a compare for CODE. Return a brand-new rtx that
16734 represents the result of the compare. */
16737 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16739 enum machine_mode comp_mode;
16740 rtx compare_result;
16741 enum rtx_code code = GET_CODE (cmp);
16742 rtx op0 = XEXP (cmp, 0);
16743 rtx op1 = XEXP (cmp, 1);
16745 if (FLOAT_MODE_P (mode))
16746 comp_mode = CCFPmode;
16747 else if (code == GTU || code == LTU
16748 || code == GEU || code == LEU)
16749 comp_mode = CCUNSmode;
16750 else if ((code == EQ || code == NE)
16751 && GET_CODE (op0) == SUBREG
16752 && GET_CODE (op1) == SUBREG
16753 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16754 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16755 /* These are unsigned values, perhaps there will be a later
16756 ordering compare that can be shared with this one.
16757 Unfortunately we cannot detect the signedness of the operands
16758 for non-subregs. */
16759 comp_mode = CCUNSmode;
16761 comp_mode = CCmode;
16763 /* First, the compare. */
16764 compare_result = gen_reg_rtx (comp_mode);
16766 /* E500 FP compare instructions on the GPRs. Yuck! */
16767 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16768 && FLOAT_MODE_P (mode))
16770 rtx cmp, or_result, compare_result2;
16771 enum machine_mode op_mode = GET_MODE (op0);
16773 if (op_mode == VOIDmode)
16774 op_mode = GET_MODE (op1);
16776 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16777 This explains the following mess. */
16781 case EQ: case UNEQ: case NE: case LTGT:
16785 cmp = (flag_finite_math_only && !flag_trapping_math)
16786 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16787 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16791 cmp = (flag_finite_math_only && !flag_trapping_math)
16792 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16793 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16797 cmp = (flag_finite_math_only && !flag_trapping_math)
16798 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16799 : gen_cmptfeq_gpr (compare_result, op0, op1);
16803 gcc_unreachable ();
16807 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16811 cmp = (flag_finite_math_only && !flag_trapping_math)
16812 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16813 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16817 cmp = (flag_finite_math_only && !flag_trapping_math)
16818 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16819 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16823 cmp = (flag_finite_math_only && !flag_trapping_math)
16824 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16825 : gen_cmptfgt_gpr (compare_result, op0, op1);
16829 gcc_unreachable ();
16833 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16837 cmp = (flag_finite_math_only && !flag_trapping_math)
16838 ? gen_tstsflt_gpr (compare_result, op0, op1)
16839 : gen_cmpsflt_gpr (compare_result, op0, op1);
16843 cmp = (flag_finite_math_only && !flag_trapping_math)
16844 ? gen_tstdflt_gpr (compare_result, op0, op1)
16845 : gen_cmpdflt_gpr (compare_result, op0, op1);
16849 cmp = (flag_finite_math_only && !flag_trapping_math)
16850 ? gen_tsttflt_gpr (compare_result, op0, op1)
16851 : gen_cmptflt_gpr (compare_result, op0, op1);
16855 gcc_unreachable ();
16859 gcc_unreachable ();
16862 /* Synthesize LE and GE from LT/GT || EQ. */
16863 if (code == LE || code == GE || code == LEU || code == GEU)
16869 case LE: code = LT; break;
16870 case GE: code = GT; break;
16871 case LEU: code = LT; break;
16872 case GEU: code = GT; break;
16873 default: gcc_unreachable ();
16876 compare_result2 = gen_reg_rtx (CCFPmode);
16882 cmp = (flag_finite_math_only && !flag_trapping_math)
16883 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16884 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16888 cmp = (flag_finite_math_only && !flag_trapping_math)
16889 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16890 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16894 cmp = (flag_finite_math_only && !flag_trapping_math)
16895 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16896 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16900 gcc_unreachable ();
16904 /* OR them together. */
16905 or_result = gen_reg_rtx (CCFPmode);
16906 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16908 compare_result = or_result;
16913 if (code == NE || code == LTGT)
16923 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16924 CLOBBERs to match cmptf_internal2 pattern. */
16925 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16926 && GET_MODE (op0) == TFmode
16927 && !TARGET_IEEEQUAD
16928 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16929 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16931 gen_rtx_SET (VOIDmode,
16933 gen_rtx_COMPARE (comp_mode, op0, op1)),
16934 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16935 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16936 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16937 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16938 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16939 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16940 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16941 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16942 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16943 else if (GET_CODE (op1) == UNSPEC
16944 && XINT (op1, 1) == UNSPEC_SP_TEST)
16946 rtx op1b = XVECEXP (op1, 0, 0);
16947 comp_mode = CCEQmode;
16948 compare_result = gen_reg_rtx (CCEQmode);
16950 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16952 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16955 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16956 gen_rtx_COMPARE (comp_mode, op0, op1)));
16959 /* Some kinds of FP comparisons need an OR operation;
16960 under flag_finite_math_only we don't bother. */
16961 if (FLOAT_MODE_P (mode)
16962 && !flag_finite_math_only
16963 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16964 && (code == LE || code == GE
16965 || code == UNEQ || code == LTGT
16966 || code == UNGT || code == UNLT))
16968 enum rtx_code or1, or2;
16969 rtx or1_rtx, or2_rtx, compare2_rtx;
16970 rtx or_result = gen_reg_rtx (CCEQmode);
16974 case LE: or1 = LT; or2 = EQ; break;
16975 case GE: or1 = GT; or2 = EQ; break;
16976 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16977 case LTGT: or1 = LT; or2 = GT; break;
16978 case UNGT: or1 = UNORDERED; or2 = GT; break;
16979 case UNLT: or1 = UNORDERED; or2 = LT; break;
16980 default: gcc_unreachable ();
16982 validate_condition_mode (or1, comp_mode);
16983 validate_condition_mode (or2, comp_mode);
16984 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16985 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16986 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16987 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16989 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16991 compare_result = or_result;
16995 validate_condition_mode (code, GET_MODE (compare_result));
16997 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
17001 /* Emit the RTL for an sISEL pattern. */
17004 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
17006 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
17010 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
17013 enum machine_mode op_mode;
17014 enum rtx_code cond_code;
17015 rtx result = operands[0];
17017 if (TARGET_ISEL && (mode == SImode || mode == DImode))
17019 rs6000_emit_sISEL (mode, operands);
17023 condition_rtx = rs6000_generate_compare (operands[1], mode);
17024 cond_code = GET_CODE (condition_rtx);
17026 if (FLOAT_MODE_P (mode)
17027 && !TARGET_FPRS && TARGET_HARD_FLOAT)
17031 PUT_MODE (condition_rtx, SImode);
17032 t = XEXP (condition_rtx, 0);
17034 gcc_assert (cond_code == NE || cond_code == EQ);
17036 if (cond_code == NE)
17037 emit_insn (gen_e500_flip_gt_bit (t, t));
17039 emit_insn (gen_move_from_CR_gt_bit (result, t));
17043 if (cond_code == NE
17044 || cond_code == GE || cond_code == LE
17045 || cond_code == GEU || cond_code == LEU
17046 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17048 rtx not_result = gen_reg_rtx (CCEQmode);
17049 rtx not_op, rev_cond_rtx;
17050 enum machine_mode cc_mode;
17052 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17054 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17055 SImode, XEXP (condition_rtx, 0), const0_rtx);
17056 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17057 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17058 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17061 op_mode = GET_MODE (XEXP (operands[1], 0));
17062 if (op_mode == VOIDmode)
17063 op_mode = GET_MODE (XEXP (operands[1], 1));
17065 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17067 PUT_MODE (condition_rtx, DImode);
17068 convert_move (result, condition_rtx, 0);
17072 PUT_MODE (condition_rtx, SImode);
17073 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17077 /* Emit a branch of kind CODE to location LOC. */
17080 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17082 rtx condition_rtx, loc_ref;
17084 condition_rtx = rs6000_generate_compare (operands[0], mode);
17085 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17086 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17087 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17088 loc_ref, pc_rtx)));
17091 /* Return the string to output a conditional branch to LABEL, which is
17092 the operand number of the label, or -1 if the branch is really a
17093 conditional return.
17095 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17096 condition code register and its mode specifies what kind of
17097 comparison we made.
17099 REVERSED is nonzero if we should reverse the sense of the comparison.
17101 INSN is the insn. */
17104 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17106 static char string[64];
17107 enum rtx_code code = GET_CODE (op);
17108 rtx cc_reg = XEXP (op, 0);
17109 enum machine_mode mode = GET_MODE (cc_reg);
17110 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17111 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17112 int really_reversed = reversed ^ need_longbranch;
17118 validate_condition_mode (code, mode);
17120 /* Work out which way this really branches. We could use
17121 reverse_condition_maybe_unordered here always but this
17122 makes the resulting assembler clearer. */
17123 if (really_reversed)
17125 /* Reversal of FP compares takes care -- an ordered compare
17126 becomes an unordered compare and vice versa. */
17127 if (mode == CCFPmode)
17128 code = reverse_condition_maybe_unordered (code);
17130 code = reverse_condition (code);
17133 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17135 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17140 /* Opposite of GT. */
17149 gcc_unreachable ();
17155 /* Not all of these are actually distinct opcodes, but
17156 we distinguish them for clarity of the resulting assembler. */
17157 case NE: case LTGT:
17158 ccode = "ne"; break;
17159 case EQ: case UNEQ:
17160 ccode = "eq"; break;
17162 ccode = "ge"; break;
17163 case GT: case GTU: case UNGT:
17164 ccode = "gt"; break;
17166 ccode = "le"; break;
17167 case LT: case LTU: case UNLT:
17168 ccode = "lt"; break;
17169 case UNORDERED: ccode = "un"; break;
17170 case ORDERED: ccode = "nu"; break;
17171 case UNGE: ccode = "nl"; break;
17172 case UNLE: ccode = "ng"; break;
17174 gcc_unreachable ();
17177 /* Maybe we have a guess as to how likely the branch is.
17178 The old mnemonics don't have a way to specify this information. */
17180 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17181 if (note != NULL_RTX)
17183 /* PROB is the difference from 50%. */
17184 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17186 /* Only hint for highly probable/improbable branches on newer
17187 cpus as static prediction overrides processor dynamic
17188 prediction. For older cpus we may as well always hint, but
17189 assume not taken for branches that are very close to 50% as a
17190 mispredicted taken branch is more expensive than a
17191 mispredicted not-taken branch. */
17192 if (rs6000_always_hint
17193 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17194 && br_prob_note_reliable_p (note)))
17196 if (abs (prob) > REG_BR_PROB_BASE / 20
17197 && ((prob > 0) ^ need_longbranch))
17205 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17207 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17209 /* We need to escape any '%' characters in the reg_names string.
17210 Assume they'd only be the first character.... */
17211 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17213 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17217 /* If the branch distance was too far, we may have to use an
17218 unconditional branch to go the distance. */
17219 if (need_longbranch)
17220 s += sprintf (s, ",$+8\n\tb %s", label);
17222 s += sprintf (s, ",%s", label);
17228 /* Return the string to flip the GT bit on a CR. */
17230 output_e500_flip_gt_bit (rtx dst, rtx src)
17232 static char string[64];
17235 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17236 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17239 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17240 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17242 sprintf (string, "crnot %d,%d", a, b);
17246 /* Return insn for VSX or Altivec comparisons. */
17249 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17252 enum machine_mode mode = GET_MODE (op0);
17260 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17266 mask = gen_reg_rtx (mode);
17267 emit_insn (gen_rtx_SET (VOIDmode,
17269 gen_rtx_fmt_ee (code, mode, op0, op1)));
17276 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17277 DMODE is expected destination mode. This is a recursive function. */
17280 rs6000_emit_vector_compare (enum rtx_code rcode,
17282 enum machine_mode dmode)
17285 bool swap_operands = false;
17286 bool try_again = false;
17288 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17289 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17291 /* See if the comparison works as is. */
17292 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17300 swap_operands = true;
17305 swap_operands = true;
17313 /* Invert condition and try again.
17314 e.g., A != B becomes ~(A==B). */
17316 enum rtx_code rev_code;
17317 enum insn_code nor_code;
17320 rev_code = reverse_condition_maybe_unordered (rcode);
17321 if (rev_code == UNKNOWN)
17324 nor_code = optab_handler (one_cmpl_optab, dmode);
17325 if (nor_code == CODE_FOR_nothing)
17328 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17332 mask = gen_reg_rtx (dmode);
17333 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17341 /* Try GT/GTU/LT/LTU OR EQ */
17344 enum insn_code ior_code;
17345 enum rtx_code new_code;
17366 gcc_unreachable ();
17369 ior_code = optab_handler (ior_optab, dmode);
17370 if (ior_code == CODE_FOR_nothing)
17373 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17377 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17381 mask = gen_reg_rtx (dmode);
17382 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17400 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17405 /* You only get two chances. */
17409 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17410 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17411 operands for the relation operation COND. */
17414 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17415 rtx cond, rtx cc_op0, rtx cc_op1)
17417 enum machine_mode dest_mode = GET_MODE (dest);
17418 enum rtx_code rcode = GET_CODE (cond);
17419 enum machine_mode cc_mode = CCmode;
17423 bool invert_move = false;
17425 if (VECTOR_UNIT_NONE_P (dest_mode))
17430 /* Swap operands if we can, and fall back to doing the operation as
17431 specified, and doing a NOR to invert the test. */
17437 /* Invert condition and try again.
17438 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17439 invert_move = true;
17440 rcode = reverse_condition_maybe_unordered (rcode);
17441 if (rcode == UNKNOWN)
17445 /* Mark unsigned tests with CCUNSmode. */
17450 cc_mode = CCUNSmode;
17457 /* Get the vector mask for the given relational operations. */
17458 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17466 op_true = op_false;
17470 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17471 emit_insn (gen_rtx_SET (VOIDmode,
17473 gen_rtx_IF_THEN_ELSE (dest_mode,
17480 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17481 operands of the last comparison is nonzero/true, FALSE_COND if it
17482 is zero/false. Return 0 if the hardware has no such operation. */
17485 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17487 enum rtx_code code = GET_CODE (op);
17488 rtx op0 = XEXP (op, 0);
17489 rtx op1 = XEXP (op, 1);
17490 REAL_VALUE_TYPE c1;
17491 enum machine_mode compare_mode = GET_MODE (op0);
17492 enum machine_mode result_mode = GET_MODE (dest);
17494 bool is_against_zero;
17496 /* These modes should always match. */
17497 if (GET_MODE (op1) != compare_mode
17498 /* In the isel case however, we can use a compare immediate, so
17499 op1 may be a small constant. */
17500 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17502 if (GET_MODE (true_cond) != result_mode)
17504 if (GET_MODE (false_cond) != result_mode)
17507 /* First, work out if the hardware can do this at all, or
17508 if it's too slow.... */
17509 if (!FLOAT_MODE_P (compare_mode))
17512 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17515 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17516 && SCALAR_FLOAT_MODE_P (compare_mode))
17519 is_against_zero = op1 == CONST0_RTX (compare_mode);
17521 /* A floating-point subtract might overflow, underflow, or produce
17522 an inexact result, thus changing the floating-point flags, so it
17523 can't be generated if we care about that. It's safe if one side
17524 of the construct is zero, since then no subtract will be
17526 if (SCALAR_FLOAT_MODE_P (compare_mode)
17527 && flag_trapping_math && ! is_against_zero)
17530 /* Eliminate half of the comparisons by switching operands, this
17531 makes the remaining code simpler. */
17532 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17533 || code == LTGT || code == LT || code == UNLE)
17535 code = reverse_condition_maybe_unordered (code);
17537 true_cond = false_cond;
17541 /* UNEQ and LTGT take four instructions for a comparison with zero,
17542 it'll probably be faster to use a branch here too. */
17543 if (code == UNEQ && HONOR_NANS (compare_mode))
17546 if (GET_CODE (op1) == CONST_DOUBLE)
17547 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17549 /* We're going to try to implement comparisons by performing
17550 a subtract, then comparing against zero. Unfortunately,
17551 Inf - Inf is NaN which is not zero, and so if we don't
17552 know that the operand is finite and the comparison
17553 would treat EQ different to UNORDERED, we can't do it. */
17554 if (HONOR_INFINITIES (compare_mode)
17555 && code != GT && code != UNGE
17556 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17557 /* Constructs of the form (a OP b ? a : b) are safe. */
17558 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17559 || (! rtx_equal_p (op0, true_cond)
17560 && ! rtx_equal_p (op1, true_cond))))
17563 /* At this point we know we can use fsel. */
17565 /* Reduce the comparison to a comparison against zero. */
17566 if (! is_against_zero)
17568 temp = gen_reg_rtx (compare_mode);
17569 emit_insn (gen_rtx_SET (VOIDmode, temp,
17570 gen_rtx_MINUS (compare_mode, op0, op1)));
17572 op1 = CONST0_RTX (compare_mode);
17575 /* If we don't care about NaNs we can reduce some of the comparisons
17576 down to faster ones. */
17577 if (! HONOR_NANS (compare_mode))
17583 true_cond = false_cond;
17596 /* Now, reduce everything down to a GE. */
17603 temp = gen_reg_rtx (compare_mode);
17604 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17609 temp = gen_reg_rtx (compare_mode);
17610 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17615 temp = gen_reg_rtx (compare_mode);
17616 emit_insn (gen_rtx_SET (VOIDmode, temp,
17617 gen_rtx_NEG (compare_mode,
17618 gen_rtx_ABS (compare_mode, op0))));
17623 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17624 temp = gen_reg_rtx (result_mode);
17625 emit_insn (gen_rtx_SET (VOIDmode, temp,
17626 gen_rtx_IF_THEN_ELSE (result_mode,
17627 gen_rtx_GE (VOIDmode,
17629 true_cond, false_cond)));
17630 false_cond = true_cond;
17633 temp = gen_reg_rtx (compare_mode);
17634 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17639 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17640 temp = gen_reg_rtx (result_mode);
17641 emit_insn (gen_rtx_SET (VOIDmode, temp,
17642 gen_rtx_IF_THEN_ELSE (result_mode,
17643 gen_rtx_GE (VOIDmode,
17645 true_cond, false_cond)));
17646 true_cond = false_cond;
17649 temp = gen_reg_rtx (compare_mode);
17650 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17655 gcc_unreachable ();
17658 emit_insn (gen_rtx_SET (VOIDmode, dest,
17659 gen_rtx_IF_THEN_ELSE (result_mode,
17660 gen_rtx_GE (VOIDmode,
17662 true_cond, false_cond)));
17666 /* Same as above, but for ints (isel). */
17669 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17671 rtx condition_rtx, cr;
17672 enum machine_mode mode = GET_MODE (dest);
17673 enum rtx_code cond_code;
17674 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17677 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17680 /* We still have to do the compare, because isel doesn't do a
17681 compare, it just looks at the CRx bits set by a previous compare
17683 condition_rtx = rs6000_generate_compare (op, mode);
17684 cond_code = GET_CODE (condition_rtx);
17685 cr = XEXP (condition_rtx, 0);
17686 signedp = GET_MODE (cr) == CCmode;
17688 isel_func = (mode == SImode
17689 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17690 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17694 case LT: case GT: case LTU: case GTU: case EQ:
17695 /* isel handles these directly. */
17699 /* We need to swap the sense of the comparison. */
17702 true_cond = false_cond;
17704 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17709 false_cond = force_reg (mode, false_cond);
17710 if (true_cond != const0_rtx)
17711 true_cond = force_reg (mode, true_cond);
17713 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17719 output_isel (rtx *operands)
17721 enum rtx_code code;
17723 code = GET_CODE (operands[1]);
17725 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17727 gcc_assert (GET_CODE (operands[2]) == REG
17728 && GET_CODE (operands[3]) == REG);
17729 PUT_CODE (operands[1], reverse_condition (code));
17730 return "isel %0,%3,%2,%j1";
17733 return "isel %0,%2,%3,%j1";
17737 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17739 enum machine_mode mode = GET_MODE (op0);
17743 /* VSX/altivec have direct min/max insns. */
17744 if ((code == SMAX || code == SMIN)
17745 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17746 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17748 emit_insn (gen_rtx_SET (VOIDmode,
17750 gen_rtx_fmt_ee (code, mode, op0, op1)));
17754 if (code == SMAX || code == SMIN)
17759 if (code == SMAX || code == UMAX)
17760 target = emit_conditional_move (dest, c, op0, op1, mode,
17761 op0, op1, mode, 0);
17763 target = emit_conditional_move (dest, c, op0, op1, mode,
17764 op1, op0, mode, 0);
17765 gcc_assert (target);
17766 if (target != dest)
17767 emit_move_insn (dest, target);
17770 /* Emit instructions to perform a load-reserved/store-conditional operation.
17771 The operation performed is an atomic
17772 (set M (CODE:MODE M OP))
17773 If not NULL, BEFORE is atomically set to M before the operation, and
17774 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17775 If SYNC_P then a memory barrier is emitted before the operation.
17776 Either OP or M may be wrapped in a NOT operation. */
17779 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17780 rtx m, rtx op, rtx before_param, rtx after_param,
17783 enum machine_mode used_mode;
17784 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17787 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17788 rtx shift = NULL_RTX;
17791 emit_insn (gen_lwsync ());
17795 /* If this is smaller than SImode, we'll have to use SImode with
17797 if (mode == QImode || mode == HImode)
17801 if (MEM_ALIGN (used_m) >= 32)
17804 if (BYTES_BIG_ENDIAN)
17805 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17807 shift = GEN_INT (ishift);
17808 used_m = change_address (used_m, SImode, 0);
17812 rtx addrSI, aligned_addr;
17813 int shift_mask = mode == QImode ? 0x18 : 0x10;
17815 addrSI = gen_lowpart_common (SImode,
17816 force_reg (Pmode, XEXP (used_m, 0)));
17817 addrSI = force_reg (SImode, addrSI);
17818 shift = gen_reg_rtx (SImode);
17820 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17821 GEN_INT (shift_mask)));
17822 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17824 aligned_addr = expand_binop (Pmode, and_optab,
17826 GEN_INT (-4), NULL_RTX,
17827 1, OPTAB_LIB_WIDEN);
17828 used_m = change_address (used_m, SImode, aligned_addr);
17829 set_mem_align (used_m, 32);
17831 /* It's safe to keep the old alias set of USED_M, because
17832 the operation is atomic and only affects the original
17836 if (GET_CODE (op) == NOT)
17838 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17839 oldop = gen_rtx_NOT (SImode, oldop);
17842 oldop = lowpart_subreg (SImode, op, mode);
17848 newop = expand_binop (SImode, and_optab,
17849 oldop, GEN_INT (imask), NULL_RTX,
17850 1, OPTAB_LIB_WIDEN);
17851 emit_insn (gen_ashlsi3 (newop, newop, shift));
17854 case NOT: /* NAND */
17855 newop = expand_binop (SImode, ior_optab,
17856 oldop, GEN_INT (~imask), NULL_RTX,
17857 1, OPTAB_LIB_WIDEN);
17858 emit_insn (gen_rotlsi3 (newop, newop, shift));
17862 newop = expand_binop (SImode, ior_optab,
17863 oldop, GEN_INT (~imask), NULL_RTX,
17864 1, OPTAB_LIB_WIDEN);
17865 emit_insn (gen_rotlsi3 (newop, newop, shift));
17873 newop = expand_binop (SImode, and_optab,
17874 oldop, GEN_INT (imask), NULL_RTX,
17875 1, OPTAB_LIB_WIDEN);
17876 emit_insn (gen_ashlsi3 (newop, newop, shift));
17878 mask = gen_reg_rtx (SImode);
17879 emit_move_insn (mask, GEN_INT (imask));
17880 emit_insn (gen_ashlsi3 (mask, mask, shift));
17883 newop = gen_rtx_PLUS (SImode, m, newop);
17885 newop = gen_rtx_MINUS (SImode, m, newop);
17886 newop = gen_rtx_AND (SImode, newop, mask);
17887 newop = gen_rtx_IOR (SImode, newop,
17888 gen_rtx_AND (SImode,
17889 gen_rtx_NOT (SImode, mask),
17895 gcc_unreachable ();
17899 used_mode = SImode;
17900 before = gen_reg_rtx (used_mode);
17901 after = gen_reg_rtx (used_mode);
17906 before = before_param;
17907 after = after_param;
17909 if (before == NULL_RTX)
17910 before = gen_reg_rtx (used_mode);
17911 if (after == NULL_RTX)
17912 after = gen_reg_rtx (used_mode);
17915 if ((code == PLUS || code == MINUS)
17916 && used_mode != mode)
17917 the_op = op; /* Computed above. */
17918 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17919 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17920 else if (code == NOT)
17921 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17922 gen_rtx_NOT (used_mode, m),
17923 gen_rtx_NOT (used_mode, op));
17925 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17927 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17928 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17929 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17930 gen_rtx_UNSPEC (used_mode,
17931 gen_rtvec (1, the_op),
17933 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17935 if ((code == PLUS || code == MINUS) && used_mode != mode)
17936 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17937 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17939 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17940 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17942 /* Shift and mask the return values properly. */
17943 if (used_mode != mode && before_param)
17945 emit_insn (gen_lshrsi3 (before, before, shift));
17946 convert_move (before_param, before, 1);
17949 if (used_mode != mode && after_param)
17951 emit_insn (gen_lshrsi3 (after, after, shift));
17952 convert_move (after_param, after, 1);
17955 /* The previous sequence will end with a branch that's dependent on
17956 the conditional store, so placing an isync will ensure that no
17957 other instructions (especially, no load or store instructions)
17958 can start before the atomic operation completes. */
17960 emit_insn (gen_isync ());
17963 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17964 COND is true. Mark the jump as unlikely to be taken. */
17967 emit_unlikely_jump (rtx cond, rtx label)
17969 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17972 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17973 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17974 add_reg_note (x, REG_BR_PROB, very_unlikely);
17977 /* A subroutine of the atomic operation splitters. Emit a load-locked
17978 instruction in MODE. */
17981 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17983 rtx (*fn) (rtx, rtx) = NULL;
17984 if (mode == SImode)
17985 fn = gen_load_locked_si;
17986 else if (mode == DImode)
17987 fn = gen_load_locked_di;
17988 emit_insn (fn (reg, mem));
17991 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17992 instruction in MODE. */
17995 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
17997 rtx (*fn) (rtx, rtx, rtx) = NULL;
17998 if (mode == SImode)
17999 fn = gen_store_conditional_si;
18000 else if (mode == DImode)
18001 fn = gen_store_conditional_di;
18003 /* Emit sync before stwcx. to address PPC405 Erratum. */
18004 if (PPC405_ERRATUM77)
18005 emit_insn (gen_memory_barrier ());
18007 emit_insn (fn (res, mem, val));
18010 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
18011 to perform. MEM is the memory on which to operate. VAL is the second
18012 operand of the binary operator. BEFORE and AFTER are optional locations to
18013 return the value of MEM either before of after the operation. SCRATCH is
18014 a scratch register. */
18017 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
18018 rtx before, rtx after, rtx scratch)
18020 enum machine_mode mode = GET_MODE (mem);
18021 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18023 emit_insn (gen_lwsync ());
18025 label = gen_label_rtx ();
18026 emit_label (label);
18027 label = gen_rtx_LABEL_REF (VOIDmode, label);
18029 if (before == NULL_RTX)
18031 emit_load_locked (mode, before, mem);
18034 x = gen_rtx_IOR (mode,
18035 gen_rtx_NOT (mode, before),
18036 gen_rtx_NOT (mode, val));
18037 else if (code == AND)
18038 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
18040 x = gen_rtx_fmt_ee (code, mode, before, val);
18042 if (after != NULL_RTX)
18043 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18044 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18046 emit_store_conditional (mode, cond, mem, scratch);
18048 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18049 emit_unlikely_jump (x, label);
18051 emit_insn (gen_isync ());
18054 /* Expand an atomic compare and swap operation. MEM is the memory on which
18055 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18056 value to be stored. SCRATCH is a scratch GPR. */
18059 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18062 enum machine_mode mode = GET_MODE (mem);
18063 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18065 emit_insn (gen_lwsync ());
18067 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18068 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18069 emit_label (XEXP (label1, 0));
18071 emit_load_locked (mode, retval, mem);
18073 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18074 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18076 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18077 emit_unlikely_jump (x, label2);
18079 emit_move_insn (scratch, newval);
18080 emit_store_conditional (mode, cond, mem, scratch);
18082 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18083 emit_unlikely_jump (x, label1);
18085 emit_insn (gen_isync ());
18086 emit_label (XEXP (label2, 0));
18089 /* Expand an atomic test and set operation. MEM is the memory on which
18090 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18093 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18095 enum machine_mode mode = GET_MODE (mem);
18096 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18098 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18099 emit_label (XEXP (label, 0));
18101 emit_load_locked (mode, retval, mem);
18102 emit_move_insn (scratch, val);
18103 emit_store_conditional (mode, cond, mem, scratch);
18105 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18106 emit_unlikely_jump (x, label);
18108 emit_insn (gen_isync ());
18112 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18114 enum machine_mode mode = GET_MODE (mem);
18115 rtx addrSI, align, wdst, shift, mask;
18116 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18117 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18119 /* Shift amount for subword relative to aligned word. */
18120 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18121 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18122 shift = gen_reg_rtx (SImode);
18123 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18124 GEN_INT (shift_mask)));
18125 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18127 /* Shift and mask old value into position within word. */
18128 oldval = convert_modes (SImode, mode, oldval, 1);
18129 oldval = expand_binop (SImode, and_optab,
18130 oldval, GEN_INT (imask), NULL_RTX,
18131 1, OPTAB_LIB_WIDEN);
18132 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18134 /* Shift and mask new value into position within word. */
18135 newval = convert_modes (SImode, mode, newval, 1);
18136 newval = expand_binop (SImode, and_optab,
18137 newval, GEN_INT (imask), NULL_RTX,
18138 1, OPTAB_LIB_WIDEN);
18139 emit_insn (gen_ashlsi3 (newval, newval, shift));
18141 /* Mask for insertion. */
18142 mask = gen_reg_rtx (SImode);
18143 emit_move_insn (mask, GEN_INT (imask));
18144 emit_insn (gen_ashlsi3 (mask, mask, shift));
18146 /* Address of aligned word containing subword. */
18147 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18148 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18149 mem = change_address (mem, SImode, align);
18150 set_mem_align (mem, 32);
18151 MEM_VOLATILE_P (mem) = 1;
18153 wdst = gen_reg_rtx (SImode);
18154 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18155 oldval, newval, mem));
18157 /* Shift the result back. */
18158 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18160 emit_move_insn (dst, gen_lowpart (mode, wdst));
18164 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18165 rtx oldval, rtx newval, rtx mem,
18168 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18170 emit_insn (gen_lwsync ());
18171 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18172 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18173 emit_label (XEXP (label1, 0));
18175 emit_load_locked (SImode, scratch, mem);
18177 /* Mask subword within loaded value for comparison with oldval.
18178 Use UNSPEC_AND to avoid clobber.*/
18179 emit_insn (gen_rtx_SET (SImode, dest,
18180 gen_rtx_UNSPEC (SImode,
18181 gen_rtvec (2, scratch, mask),
18184 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18185 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18187 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18188 emit_unlikely_jump (x, label2);
18190 /* Clear subword within loaded value for insertion of new value. */
18191 emit_insn (gen_rtx_SET (SImode, scratch,
18192 gen_rtx_AND (SImode,
18193 gen_rtx_NOT (SImode, mask), scratch)));
18194 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18195 emit_store_conditional (SImode, cond, mem, scratch);
18197 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18198 emit_unlikely_jump (x, label1);
18200 emit_insn (gen_isync ());
18201 emit_label (XEXP (label2, 0));
18205 /* Emit instructions to move SRC to DST. Called by splitters for
18206 multi-register moves. It will emit at most one instruction for
18207 each register that is accessed; that is, it won't emit li/lis pairs
18208 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18212 rs6000_split_multireg_move (rtx dst, rtx src)
18214 /* The register number of the first register being moved. */
18216 /* The mode that is to be moved. */
18217 enum machine_mode mode;
18218 /* The mode that the move is being done in, and its size. */
18219 enum machine_mode reg_mode;
18221 /* The number of registers that will be moved. */
18224 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18225 mode = GET_MODE (dst);
18226 nregs = hard_regno_nregs[reg][mode];
18227 if (FP_REGNO_P (reg))
18228 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18229 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18230 else if (ALTIVEC_REGNO_P (reg))
18231 reg_mode = V16QImode;
18232 else if (TARGET_E500_DOUBLE && mode == TFmode)
18235 reg_mode = word_mode;
18236 reg_mode_size = GET_MODE_SIZE (reg_mode);
18238 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18240 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18242 /* Move register range backwards, if we might have destructive
18245 for (i = nregs - 1; i >= 0; i--)
18246 emit_insn (gen_rtx_SET (VOIDmode,
18247 simplify_gen_subreg (reg_mode, dst, mode,
18248 i * reg_mode_size),
18249 simplify_gen_subreg (reg_mode, src, mode,
18250 i * reg_mode_size)));
18256 bool used_update = false;
18257 rtx restore_basereg = NULL_RTX;
18259 if (MEM_P (src) && INT_REGNO_P (reg))
18263 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18264 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18267 breg = XEXP (XEXP (src, 0), 0);
18268 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18269 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18270 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18271 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18272 src = replace_equiv_address (src, breg);
18274 else if (! rs6000_offsettable_memref_p (src))
18276 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18278 rtx basereg = XEXP (XEXP (src, 0), 0);
18281 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18282 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18283 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18284 used_update = true;
18287 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18288 XEXP (XEXP (src, 0), 1)));
18289 src = replace_equiv_address (src, basereg);
18293 rtx basereg = gen_rtx_REG (Pmode, reg);
18294 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18295 src = replace_equiv_address (src, basereg);
18299 breg = XEXP (src, 0);
18300 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18301 breg = XEXP (breg, 0);
18303 /* If the base register we are using to address memory is
18304 also a destination reg, then change that register last. */
18306 && REGNO (breg) >= REGNO (dst)
18307 && REGNO (breg) < REGNO (dst) + nregs)
18308 j = REGNO (breg) - REGNO (dst);
18310 else if (MEM_P (dst) && INT_REGNO_P (reg))
18314 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18315 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18318 breg = XEXP (XEXP (dst, 0), 0);
18319 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18320 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18321 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18323 /* We have to update the breg before doing the store.
18324 Use store with update, if available. */
18328 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18329 emit_insn (TARGET_32BIT
18330 ? (TARGET_POWERPC64
18331 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18332 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18333 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18334 used_update = true;
18337 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18338 dst = replace_equiv_address (dst, breg);
18340 else if (!rs6000_offsettable_memref_p (dst)
18341 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18343 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18345 rtx basereg = XEXP (XEXP (dst, 0), 0);
18348 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18349 emit_insn (gen_rtx_SET (VOIDmode,
18350 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18351 used_update = true;
18354 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18355 XEXP (XEXP (dst, 0), 1)));
18356 dst = replace_equiv_address (dst, basereg);
18360 rtx basereg = XEXP (XEXP (dst, 0), 0);
18361 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18362 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18364 && REG_P (offsetreg)
18365 && REGNO (basereg) != REGNO (offsetreg));
18366 if (REGNO (basereg) == 0)
18368 rtx tmp = offsetreg;
18369 offsetreg = basereg;
18372 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18373 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18374 dst = replace_equiv_address (dst, basereg);
18377 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18378 gcc_assert (rs6000_offsettable_memref_p (dst));
18381 for (i = 0; i < nregs; i++)
18383 /* Calculate index to next subword. */
18388 /* If compiler already emitted move of first word by
18389 store with update, no need to do anything. */
18390 if (j == 0 && used_update)
18393 emit_insn (gen_rtx_SET (VOIDmode,
18394 simplify_gen_subreg (reg_mode, dst, mode,
18395 j * reg_mode_size),
18396 simplify_gen_subreg (reg_mode, src, mode,
18397 j * reg_mode_size)));
18399 if (restore_basereg != NULL_RTX)
18400 emit_insn (restore_basereg);
18405 /* This page contains routines that are used to determine what the
18406 function prologue and epilogue code will do and write them out. */
18408 /* Return the first fixed-point register that is required to be
18409 saved. 32 if none. */
18412 first_reg_to_save (void)
18416 /* Find lowest numbered live register. */
18417 for (first_reg = 13; first_reg <= 31; first_reg++)
18418 if (df_regs_ever_live_p (first_reg)
18419 && (! call_used_regs[first_reg]
18420 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18421 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18422 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18423 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18428 && crtl->uses_pic_offset_table
18429 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18430 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18436 /* Similar, for FP regs. */
18439 first_fp_reg_to_save (void)
18443 /* Find lowest numbered live register. */
18444 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18445 if (df_regs_ever_live_p (first_reg))
18451 /* Similar, for AltiVec regs. */
18454 first_altivec_reg_to_save (void)
18458 /* Stack frame remains as is unless we are in AltiVec ABI. */
18459 if (! TARGET_ALTIVEC_ABI)
18460 return LAST_ALTIVEC_REGNO + 1;
18462 /* On Darwin, the unwind routines are compiled without
18463 TARGET_ALTIVEC, and use save_world to save/restore the
18464 altivec registers when necessary. */
18465 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18466 && ! TARGET_ALTIVEC)
18467 return FIRST_ALTIVEC_REGNO + 20;
18469 /* Find lowest numbered live register. */
18470 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18471 if (df_regs_ever_live_p (i))
18477 /* Return a 32-bit mask of the AltiVec registers we need to set in
18478 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18479 the 32-bit word is 0. */
18481 static unsigned int
18482 compute_vrsave_mask (void)
18484 unsigned int i, mask = 0;
18486 /* On Darwin, the unwind routines are compiled without
18487 TARGET_ALTIVEC, and use save_world to save/restore the
18488 call-saved altivec registers when necessary. */
18489 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18490 && ! TARGET_ALTIVEC)
18493 /* First, find out if we use _any_ altivec registers. */
18494 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18495 if (df_regs_ever_live_p (i))
18496 mask |= ALTIVEC_REG_BIT (i);
18501 /* Next, remove the argument registers from the set. These must
18502 be in the VRSAVE mask set by the caller, so we don't need to add
18503 them in again. More importantly, the mask we compute here is
18504 used to generate CLOBBERs in the set_vrsave insn, and we do not
18505 wish the argument registers to die. */
18506 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18507 mask &= ~ALTIVEC_REG_BIT (i);
18509 /* Similarly, remove the return value from the set. */
18512 diddle_return_value (is_altivec_return_reg, &yes);
18514 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18520 /* For a very restricted set of circumstances, we can cut down the
18521 size of prologues/epilogues by calling our own save/restore-the-world
18525 compute_save_world_info (rs6000_stack_t *info_ptr)
18527 info_ptr->world_save_p = 1;
18528 info_ptr->world_save_p
18529 = (WORLD_SAVE_P (info_ptr)
18530 && DEFAULT_ABI == ABI_DARWIN
18531 && ! (cfun->calls_setjmp && flag_exceptions)
18532 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18533 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18534 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18535 && info_ptr->cr_save_p);
18537 /* This will not work in conjunction with sibcalls. Make sure there
18538 are none. (This check is expensive, but seldom executed.) */
18539 if (WORLD_SAVE_P (info_ptr))
18542 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18543 if ( GET_CODE (insn) == CALL_INSN
18544 && SIBLING_CALL_P (insn))
18546 info_ptr->world_save_p = 0;
18551 if (WORLD_SAVE_P (info_ptr))
18553 /* Even if we're not touching VRsave, make sure there's room on the
18554 stack for it, if it looks like we're calling SAVE_WORLD, which
18555 will attempt to save it. */
18556 info_ptr->vrsave_size = 4;
18558 /* If we are going to save the world, we need to save the link register too. */
18559 info_ptr->lr_save_p = 1;
18561 /* "Save" the VRsave register too if we're saving the world. */
18562 if (info_ptr->vrsave_mask == 0)
18563 info_ptr->vrsave_mask = compute_vrsave_mask ();
18565 /* Because the Darwin register save/restore routines only handle
18566 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18568 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18569 && (info_ptr->first_altivec_reg_save
18570 >= FIRST_SAVED_ALTIVEC_REGNO));
18577 is_altivec_return_reg (rtx reg, void *xyes)
18579 bool *yes = (bool *) xyes;
18580 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18585 /* Determine the strategy for savings/restoring registers. */
18588 SAVRES_MULTIPLE = 0x1,
18589 SAVE_INLINE_FPRS = 0x2,
18590 SAVE_INLINE_GPRS = 0x4,
18591 REST_INLINE_FPRS = 0x8,
18592 REST_INLINE_GPRS = 0x10,
18593 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18594 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18595 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18599 rs6000_savres_strategy (rs6000_stack_t *info,
18600 bool using_static_chain_p)
18604 if (TARGET_MULTIPLE
18605 && !TARGET_POWERPC64
18606 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18607 && info->first_gp_reg_save < 31
18608 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18609 strategy |= SAVRES_MULTIPLE;
18611 if (crtl->calls_eh_return
18612 || cfun->machine->ra_need_lr
18613 || info->total_size > 32767)
18614 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18615 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18617 if (info->first_fp_reg_save == 64
18618 || FP_SAVE_INLINE (info->first_fp_reg_save)
18619 /* The out-of-line FP routines use double-precision stores;
18620 we can't use those routines if we don't have such stores. */
18621 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18622 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18623 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18625 if (info->first_gp_reg_save == 32
18626 || GP_SAVE_INLINE (info->first_gp_reg_save)
18627 || !((strategy & SAVRES_MULTIPLE)
18628 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18629 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18631 /* Don't bother to try to save things out-of-line if r11 is occupied
18632 by the static chain. It would require too much fiddling and the
18633 static chain is rarely used anyway. */
18634 if (using_static_chain_p)
18635 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18637 /* If we are going to use store multiple, then don't even bother
18638 with the out-of-line routines, since the store-multiple
18639 instruction will always be smaller. */
18640 if ((strategy & SAVRES_MULTIPLE))
18641 strategy |= SAVE_INLINE_GPRS;
18643 /* The situation is more complicated with load multiple. We'd
18644 prefer to use the out-of-line routines for restores, since the
18645 "exit" out-of-line routines can handle the restore of LR and the
18646 frame teardown. However if doesn't make sense to use the
18647 out-of-line routine if that is the only reason we'd need to save
18648 LR, and we can't use the "exit" out-of-line gpr restore if we
18649 have saved some fprs; In those cases it is advantageous to use
18650 load multiple when available. */
18651 if ((strategy & SAVRES_MULTIPLE)
18652 && (!info->lr_save_p
18653 || info->first_fp_reg_save != 64))
18654 strategy |= REST_INLINE_GPRS;
18656 /* We can only use load multiple or the out-of-line routines to
18657 restore if we've used store multiple or out-of-line routines
18658 in the prologue, i.e. if we've saved all the registers from
18659 first_gp_reg_save. Otherwise, we risk loading garbage. */
18660 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18661 strategy |= REST_INLINE_GPRS;
18663 /* Saving CR interferes with the exit routines used on the SPE, so
18666 && info->spe_64bit_regs_used
18667 && info->cr_save_p)
18668 strategy |= REST_INLINE_GPRS;
18670 #ifdef POWERPC_LINUX
18673 if (!(strategy & SAVE_INLINE_FPRS))
18674 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18675 else if (!(strategy & SAVE_INLINE_GPRS)
18676 && info->first_fp_reg_save == 64)
18677 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18680 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18681 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18686 /* Calculate the stack information for the current function. This is
18687 complicated by having two separate calling sequences, the AIX calling
18688 sequence and the V.4 calling sequence.
18690 AIX (and Darwin/Mac OS X) stack frames look like:
18692 SP----> +---------------------------------------+
18693 | back chain to caller | 0 0
18694 +---------------------------------------+
18695 | saved CR | 4 8 (8-11)
18696 +---------------------------------------+
18698 +---------------------------------------+
18699 | reserved for compilers | 12 24
18700 +---------------------------------------+
18701 | reserved for binders | 16 32
18702 +---------------------------------------+
18703 | saved TOC pointer | 20 40
18704 +---------------------------------------+
18705 | Parameter save area (P) | 24 48
18706 +---------------------------------------+
18707 | Alloca space (A) | 24+P etc.
18708 +---------------------------------------+
18709 | Local variable space (L) | 24+P+A
18710 +---------------------------------------+
18711 | Float/int conversion temporary (X) | 24+P+A+L
18712 +---------------------------------------+
18713 | Save area for AltiVec registers (W) | 24+P+A+L+X
18714 +---------------------------------------+
18715 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18716 +---------------------------------------+
18717 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18718 +---------------------------------------+
18719 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18720 +---------------------------------------+
18721 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18722 +---------------------------------------+
18723 old SP->| back chain to caller's caller |
18724 +---------------------------------------+
18726 The required alignment for AIX configurations is two words (i.e., 8
18730 V.4 stack frames look like:
18732 SP----> +---------------------------------------+
18733 | back chain to caller | 0
18734 +---------------------------------------+
18735 | caller's saved LR | 4
18736 +---------------------------------------+
18737 | Parameter save area (P) | 8
18738 +---------------------------------------+
18739 | Alloca space (A) | 8+P
18740 +---------------------------------------+
18741 | Varargs save area (V) | 8+P+A
18742 +---------------------------------------+
18743 | Local variable space (L) | 8+P+A+V
18744 +---------------------------------------+
18745 | Float/int conversion temporary (X) | 8+P+A+V+L
18746 +---------------------------------------+
18747 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18748 +---------------------------------------+
18749 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18750 +---------------------------------------+
18751 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18752 +---------------------------------------+
18753 | SPE: area for 64-bit GP registers |
18754 +---------------------------------------+
18755 | SPE alignment padding |
18756 +---------------------------------------+
18757 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18758 +---------------------------------------+
18759 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18760 +---------------------------------------+
18761 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18762 +---------------------------------------+
18763 old SP->| back chain to caller's caller |
18764 +---------------------------------------+
18766 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18767 given. (But note below and in sysv4.h that we require only 8 and
18768 may round up the size of our stack frame anyways. The historical
18769 reason is early versions of powerpc-linux which didn't properly
18770 align the stack at program startup. A happy side-effect is that
18771 -mno-eabi libraries can be used with -meabi programs.)
18773 The EABI configuration defaults to the V.4 layout. However,
18774 the stack alignment requirements may differ. If -mno-eabi is not
18775 given, the required stack alignment is 8 bytes; if -mno-eabi is
18776 given, the required alignment is 16 bytes. (But see V.4 comment
18779 #ifndef ABI_STACK_BOUNDARY
18780 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18783 static rs6000_stack_t *
18784 rs6000_stack_info (void)
18786 rs6000_stack_t *info_ptr = &stack_info;
18787 int reg_size = TARGET_32BIT ? 4 : 8;
18791 HOST_WIDE_INT non_fixed_size;
18792 bool using_static_chain_p;
18794 if (reload_completed && info_ptr->reload_completed)
18797 memset (info_ptr, 0, sizeof (*info_ptr));
18798 info_ptr->reload_completed = reload_completed;
18802 /* Cache value so we don't rescan instruction chain over and over. */
18803 if (cfun->machine->insn_chain_scanned_p == 0)
18804 cfun->machine->insn_chain_scanned_p
18805 = spe_func_has_64bit_regs_p () + 1;
18806 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18809 /* Select which calling sequence. */
18810 info_ptr->abi = DEFAULT_ABI;
18812 /* Calculate which registers need to be saved & save area size. */
18813 info_ptr->first_gp_reg_save = first_reg_to_save ();
18814 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18815 even if it currently looks like we won't. Reload may need it to
18816 get at a constant; if so, it will have already created a constant
18817 pool entry for it. */
18818 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18819 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18820 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18821 && crtl->uses_const_pool
18822 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18823 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18825 first_gp = info_ptr->first_gp_reg_save;
18827 info_ptr->gp_size = reg_size * (32 - first_gp);
18829 /* For the SPE, we have an additional upper 32-bits on each GPR.
18830 Ideally we should save the entire 64-bits only when the upper
18831 half is used in SIMD instructions. Since we only record
18832 registers live (not the size they are used in), this proves
18833 difficult because we'd have to traverse the instruction chain at
18834 the right time, taking reload into account. This is a real pain,
18835 so we opt to save the GPRs in 64-bits always if but one register
18836 gets used in 64-bits. Otherwise, all the registers in the frame
18837 get saved in 32-bits.
18839 So... since when we save all GPRs (except the SP) in 64-bits, the
18840 traditional GP save area will be empty. */
18841 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18842 info_ptr->gp_size = 0;
18844 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18845 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18847 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18848 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18849 - info_ptr->first_altivec_reg_save);
18851 /* Does this function call anything? */
18852 info_ptr->calls_p = (! current_function_is_leaf
18853 || cfun->machine->ra_needs_full_frame);
18855 /* Determine if we need to save the condition code registers. */
18856 if (df_regs_ever_live_p (CR2_REGNO)
18857 || df_regs_ever_live_p (CR3_REGNO)
18858 || df_regs_ever_live_p (CR4_REGNO))
18860 info_ptr->cr_save_p = 1;
18861 if (DEFAULT_ABI == ABI_V4)
18862 info_ptr->cr_size = reg_size;
18865 /* If the current function calls __builtin_eh_return, then we need
18866 to allocate stack space for registers that will hold data for
18867 the exception handler. */
18868 if (crtl->calls_eh_return)
18871 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18874 /* SPE saves EH registers in 64-bits. */
18875 ehrd_size = i * (TARGET_SPE_ABI
18876 && info_ptr->spe_64bit_regs_used != 0
18877 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18882 /* Determine various sizes. */
18883 info_ptr->reg_size = reg_size;
18884 info_ptr->fixed_size = RS6000_SAVE_AREA;
18885 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18886 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18887 TARGET_ALTIVEC ? 16 : 8);
18888 if (FRAME_GROWS_DOWNWARD)
18889 info_ptr->vars_size
18890 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18891 + info_ptr->parm_size,
18892 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18893 - (info_ptr->fixed_size + info_ptr->vars_size
18894 + info_ptr->parm_size);
18896 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18897 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18899 info_ptr->spe_gp_size = 0;
18901 if (TARGET_ALTIVEC_ABI)
18902 info_ptr->vrsave_mask = compute_vrsave_mask ();
18904 info_ptr->vrsave_mask = 0;
18906 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18907 info_ptr->vrsave_size = 4;
18909 info_ptr->vrsave_size = 0;
18911 compute_save_world_info (info_ptr);
18913 /* Calculate the offsets. */
18914 switch (DEFAULT_ABI)
18918 gcc_unreachable ();
18922 info_ptr->fp_save_offset = - info_ptr->fp_size;
18923 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18925 if (TARGET_ALTIVEC_ABI)
18927 info_ptr->vrsave_save_offset
18928 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18930 /* Align stack so vector save area is on a quadword boundary.
18931 The padding goes above the vectors. */
18932 if (info_ptr->altivec_size != 0)
18933 info_ptr->altivec_padding_size
18934 = info_ptr->vrsave_save_offset & 0xF;
18936 info_ptr->altivec_padding_size = 0;
18938 info_ptr->altivec_save_offset
18939 = info_ptr->vrsave_save_offset
18940 - info_ptr->altivec_padding_size
18941 - info_ptr->altivec_size;
18942 gcc_assert (info_ptr->altivec_size == 0
18943 || info_ptr->altivec_save_offset % 16 == 0);
18945 /* Adjust for AltiVec case. */
18946 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18949 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18950 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18951 info_ptr->lr_save_offset = 2*reg_size;
18955 info_ptr->fp_save_offset = - info_ptr->fp_size;
18956 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18957 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18959 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18961 /* Align stack so SPE GPR save area is aligned on a
18962 double-word boundary. */
18963 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18964 info_ptr->spe_padding_size
18965 = 8 - (-info_ptr->cr_save_offset % 8);
18967 info_ptr->spe_padding_size = 0;
18969 info_ptr->spe_gp_save_offset
18970 = info_ptr->cr_save_offset
18971 - info_ptr->spe_padding_size
18972 - info_ptr->spe_gp_size;
18974 /* Adjust for SPE case. */
18975 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18977 else if (TARGET_ALTIVEC_ABI)
18979 info_ptr->vrsave_save_offset
18980 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18982 /* Align stack so vector save area is on a quadword boundary. */
18983 if (info_ptr->altivec_size != 0)
18984 info_ptr->altivec_padding_size
18985 = 16 - (-info_ptr->vrsave_save_offset % 16);
18987 info_ptr->altivec_padding_size = 0;
18989 info_ptr->altivec_save_offset
18990 = info_ptr->vrsave_save_offset
18991 - info_ptr->altivec_padding_size
18992 - info_ptr->altivec_size;
18994 /* Adjust for AltiVec case. */
18995 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
18998 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
18999 info_ptr->ehrd_offset -= ehrd_size;
19000 info_ptr->lr_save_offset = reg_size;
19004 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
19005 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
19006 + info_ptr->gp_size
19007 + info_ptr->altivec_size
19008 + info_ptr->altivec_padding_size
19009 + info_ptr->spe_gp_size
19010 + info_ptr->spe_padding_size
19012 + info_ptr->cr_size
19013 + info_ptr->vrsave_size,
19016 non_fixed_size = (info_ptr->vars_size
19017 + info_ptr->parm_size
19018 + info_ptr->save_size);
19020 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
19021 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
19023 /* Determine if we need to save the link register. */
19024 if (info_ptr->calls_p
19025 || (DEFAULT_ABI == ABI_AIX
19027 && !TARGET_PROFILE_KERNEL)
19028 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
19029 #ifdef TARGET_RELOCATABLE
19030 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
19032 || rs6000_ra_ever_killed ())
19033 info_ptr->lr_save_p = 1;
19035 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19036 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19037 && call_used_regs[STATIC_CHAIN_REGNUM]);
19038 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19039 using_static_chain_p);
19041 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19042 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19043 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19044 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19045 info_ptr->lr_save_p = 1;
19047 if (info_ptr->lr_save_p)
19048 df_set_regs_ever_live (LR_REGNO, true);
19050 /* Determine if we need to allocate any stack frame:
19052 For AIX we need to push the stack if a frame pointer is needed
19053 (because the stack might be dynamically adjusted), if we are
19054 debugging, if we make calls, or if the sum of fp_save, gp_save,
19055 and local variables are more than the space needed to save all
19056 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19057 + 18*8 = 288 (GPR13 reserved).
19059 For V.4 we don't have the stack cushion that AIX uses, but assume
19060 that the debugger can handle stackless frames. */
19062 if (info_ptr->calls_p)
19063 info_ptr->push_p = 1;
19065 else if (DEFAULT_ABI == ABI_V4)
19066 info_ptr->push_p = non_fixed_size != 0;
19068 else if (frame_pointer_needed)
19069 info_ptr->push_p = 1;
19071 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19072 info_ptr->push_p = 1;
19075 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19077 /* Zero offsets if we're not saving those registers. */
19078 if (info_ptr->fp_size == 0)
19079 info_ptr->fp_save_offset = 0;
19081 if (info_ptr->gp_size == 0)
19082 info_ptr->gp_save_offset = 0;
19084 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19085 info_ptr->altivec_save_offset = 0;
19087 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19088 info_ptr->vrsave_save_offset = 0;
19090 if (! TARGET_SPE_ABI
19091 || info_ptr->spe_64bit_regs_used == 0
19092 || info_ptr->spe_gp_size == 0)
19093 info_ptr->spe_gp_save_offset = 0;
19095 if (! info_ptr->lr_save_p)
19096 info_ptr->lr_save_offset = 0;
19098 if (! info_ptr->cr_save_p)
19099 info_ptr->cr_save_offset = 0;
19104 /* Return true if the current function uses any GPRs in 64-bit SIMD
19108 spe_func_has_64bit_regs_p (void)
19112 /* Functions that save and restore all the call-saved registers will
19113 need to save/restore the registers in 64-bits. */
19114 if (crtl->calls_eh_return
19115 || cfun->calls_setjmp
19116 || crtl->has_nonlocal_goto)
19119 insns = get_insns ();
19121 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19127 /* FIXME: This should be implemented with attributes...
19129 (set_attr "spe64" "true")....then,
19130 if (get_spe64(insn)) return true;
19132 It's the only reliable way to do the stuff below. */
19134 i = PATTERN (insn);
19135 if (GET_CODE (i) == SET)
19137 enum machine_mode mode = GET_MODE (SET_SRC (i));
19139 if (SPE_VECTOR_MODE (mode))
19141 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19151 debug_stack_info (rs6000_stack_t *info)
19153 const char *abi_string;
19156 info = rs6000_stack_info ();
19158 fprintf (stderr, "\nStack information for function %s:\n",
19159 ((current_function_decl && DECL_NAME (current_function_decl))
19160 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19165 default: abi_string = "Unknown"; break;
19166 case ABI_NONE: abi_string = "NONE"; break;
19167 case ABI_AIX: abi_string = "AIX"; break;
19168 case ABI_DARWIN: abi_string = "Darwin"; break;
19169 case ABI_V4: abi_string = "V.4"; break;
19172 fprintf (stderr, "\tABI = %5s\n", abi_string);
19174 if (TARGET_ALTIVEC_ABI)
19175 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19177 if (TARGET_SPE_ABI)
19178 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19180 if (info->first_gp_reg_save != 32)
19181 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19183 if (info->first_fp_reg_save != 64)
19184 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19186 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19187 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19188 info->first_altivec_reg_save);
19190 if (info->lr_save_p)
19191 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19193 if (info->cr_save_p)
19194 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19196 if (info->vrsave_mask)
19197 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19200 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19203 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19205 if (info->gp_save_offset)
19206 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19208 if (info->fp_save_offset)
19209 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19211 if (info->altivec_save_offset)
19212 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19213 info->altivec_save_offset);
19215 if (info->spe_gp_save_offset)
19216 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19217 info->spe_gp_save_offset);
19219 if (info->vrsave_save_offset)
19220 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19221 info->vrsave_save_offset);
19223 if (info->lr_save_offset)
19224 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19226 if (info->cr_save_offset)
19227 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19229 if (info->varargs_save_offset)
19230 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19232 if (info->total_size)
19233 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19236 if (info->vars_size)
19237 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19240 if (info->parm_size)
19241 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19243 if (info->fixed_size)
19244 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19247 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19249 if (info->spe_gp_size)
19250 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19253 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19255 if (info->altivec_size)
19256 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19258 if (info->vrsave_size)
19259 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19261 if (info->altivec_padding_size)
19262 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19263 info->altivec_padding_size);
19265 if (info->spe_padding_size)
19266 fprintf (stderr, "\tspe_padding_size = %5d\n",
19267 info->spe_padding_size);
19270 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19272 if (info->save_size)
19273 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19275 if (info->reg_size != 4)
19276 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19278 fprintf (stderr, "\n");
19282 rs6000_return_addr (int count, rtx frame)
19284 /* Currently we don't optimize very well between prolog and body
19285 code and for PIC code the code can be actually quite bad, so
19286 don't try to be too clever here. */
19287 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19289 cfun->machine->ra_needs_full_frame = 1;
19296 plus_constant (copy_to_reg
19297 (gen_rtx_MEM (Pmode,
19298 memory_address (Pmode, frame))),
19299 RETURN_ADDRESS_OFFSET)));
19302 cfun->machine->ra_need_lr = 1;
19303 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19306 /* Say whether a function is a candidate for sibcall handling or not.
19307 We do not allow indirect calls to be optimized into sibling calls.
19308 Also, we can't do it if there are any vector parameters; there's
19309 nowhere to put the VRsave code so it works; note that functions with
19310 vector parameters are required to have a prototype, so the argument
19311 type info must be available here. (The tail recursion case can work
19312 with vector parameters, but there's no way to distinguish here.) */
19314 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19319 if (TARGET_ALTIVEC_VRSAVE)
19321 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19322 type; type = TREE_CHAIN (type))
19324 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19328 if (DEFAULT_ABI == ABI_DARWIN
19329 || ((*targetm.binds_local_p) (decl)
19330 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19332 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19334 if (!lookup_attribute ("longcall", attr_list)
19335 || lookup_attribute ("shortcall", attr_list))
19342 /* NULL if INSN insn is valid within a low-overhead loop.
19343 Otherwise return why doloop cannot be applied.
19344 PowerPC uses the COUNT register for branch on table instructions. */
19346 static const char *
19347 rs6000_invalid_within_doloop (const_rtx insn)
19350 return "Function call in the loop.";
19353 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19354 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19355 return "Computed branch in the loop.";
19361 rs6000_ra_ever_killed (void)
19367 if (cfun->is_thunk)
19370 if (cfun->machine->lr_save_state)
19371 return cfun->machine->lr_save_state - 1;
19373 /* regs_ever_live has LR marked as used if any sibcalls are present,
19374 but this should not force saving and restoring in the
19375 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19376 clobbers LR, so that is inappropriate. */
19378 /* Also, the prologue can generate a store into LR that
19379 doesn't really count, like this:
19382 bcl to set PIC register
19386 When we're called from the epilogue, we need to avoid counting
19387 this as a store. */
19389 push_topmost_sequence ();
19390 top = get_insns ();
19391 pop_topmost_sequence ();
19392 reg = gen_rtx_REG (Pmode, LR_REGNO);
19394 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19400 if (!SIBLING_CALL_P (insn))
19403 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19405 else if (set_of (reg, insn) != NULL_RTX
19406 && !prologue_epilogue_contains (insn))
19413 /* Emit instructions needed to load the TOC register.
19414 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19415 a constant pool; or for SVR4 -fpic. */
19418 rs6000_emit_load_toc_table (int fromprolog)
19421 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19423 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19426 rtx lab, tmp1, tmp2, got;
19428 lab = gen_label_rtx ();
19429 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19430 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19432 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19434 got = rs6000_got_sym ();
19435 tmp1 = tmp2 = dest;
19438 tmp1 = gen_reg_rtx (Pmode);
19439 tmp2 = gen_reg_rtx (Pmode);
19441 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19442 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19443 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19444 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19446 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19448 emit_insn (gen_load_toc_v4_pic_si ());
19449 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19451 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19454 rtx temp0 = (fromprolog
19455 ? gen_rtx_REG (Pmode, 0)
19456 : gen_reg_rtx (Pmode));
19462 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19463 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19465 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19466 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19468 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19469 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19470 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19476 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19477 lab = gen_label_rtx ();
19478 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19479 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19480 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19482 emit_insn (gen_addsi3 (dest, temp0, dest));
19484 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19486 /* This is for AIX code running in non-PIC ELF32. */
19489 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19490 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19492 emit_insn (gen_elf_high (dest, realsym));
19493 emit_insn (gen_elf_low (dest, dest, realsym));
19497 gcc_assert (DEFAULT_ABI == ABI_AIX);
19500 emit_insn (gen_load_toc_aix_si (dest));
19502 emit_insn (gen_load_toc_aix_di (dest));
19506 /* Emit instructions to restore the link register after determining where
19507 its value has been stored. */
19510 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19512 rs6000_stack_t *info = rs6000_stack_info ();
19515 operands[0] = source;
19516 operands[1] = scratch;
19518 if (info->lr_save_p)
19520 rtx frame_rtx = stack_pointer_rtx;
19521 HOST_WIDE_INT sp_offset = 0;
19524 if (frame_pointer_needed
19525 || cfun->calls_alloca
19526 || info->total_size > 32767)
19528 tmp = gen_frame_mem (Pmode, frame_rtx);
19529 emit_move_insn (operands[1], tmp);
19530 frame_rtx = operands[1];
19532 else if (info->push_p)
19533 sp_offset = info->total_size;
19535 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19536 tmp = gen_frame_mem (Pmode, tmp);
19537 emit_move_insn (tmp, operands[0]);
19540 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19542 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19543 state of lr_save_p so any change from here on would be a bug. In
19544 particular, stop rs6000_ra_ever_killed from considering the SET
19545 of lr we may have added just above. */
19546 cfun->machine->lr_save_state = info->lr_save_p + 1;
19549 static GTY(()) alias_set_type set = -1;
19552 get_TOC_alias_set (void)
19555 set = new_alias_set ();
19559 /* This returns nonzero if the current function uses the TOC. This is
19560 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19561 is generated by the ABI_V4 load_toc_* patterns. */
19568 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19571 rtx pat = PATTERN (insn);
19574 if (GET_CODE (pat) == PARALLEL)
19575 for (i = 0; i < XVECLEN (pat, 0); i++)
19577 rtx sub = XVECEXP (pat, 0, i);
19578 if (GET_CODE (sub) == USE)
19580 sub = XEXP (sub, 0);
19581 if (GET_CODE (sub) == UNSPEC
19582 && XINT (sub, 1) == UNSPEC_TOC)
19592 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19594 rtx tocrel, tocreg;
19596 if (TARGET_DEBUG_ADDR)
19598 if (GET_CODE (symbol) == SYMBOL_REF)
19599 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19603 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19604 GET_RTX_NAME (GET_CODE (symbol)));
19605 debug_rtx (symbol);
19609 if (!can_create_pseudo_p ())
19610 df_set_regs_ever_live (TOC_REGISTER, true);
19612 tocrel = gen_rtx_CONST (Pmode,
19613 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19615 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19616 if (TARGET_CMODEL != CMODEL_SMALL)
19618 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19619 if (largetoc_reg != NULL)
19621 emit_move_insn (largetoc_reg, hi);
19624 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19627 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19630 /* Issue assembly directives that create a reference to the given DWARF
19631 FRAME_TABLE_LABEL from the current function section. */
19633 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19635 fprintf (asm_out_file, "\t.ref %s\n",
19636 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19639 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19640 and the change to the stack pointer. */
19643 rs6000_emit_stack_tie (void)
19645 rtx mem = gen_frame_mem (BLKmode,
19646 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19648 emit_insn (gen_stack_tie (mem));
19651 /* Emit the correct code for allocating stack space, as insns.
19652 If COPY_REG, make sure a copy of the old frame is left there.
19653 The generated code may use hard register 0 as a temporary. */
19656 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19659 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19660 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19661 rtx todec = gen_int_mode (-size, Pmode);
19664 if (INTVAL (todec) != -size)
19666 warning (0, "stack frame too large");
19667 emit_insn (gen_trap ());
19671 if (crtl->limit_stack)
19673 if (REG_P (stack_limit_rtx)
19674 && REGNO (stack_limit_rtx) > 1
19675 && REGNO (stack_limit_rtx) <= 31)
19677 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19678 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19681 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19683 && DEFAULT_ABI == ABI_V4)
19685 rtx toload = gen_rtx_CONST (VOIDmode,
19686 gen_rtx_PLUS (Pmode,
19690 emit_insn (gen_elf_high (tmp_reg, toload));
19691 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19692 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19696 warning (0, "stack limit expression is not supported");
19700 emit_move_insn (copy_reg, stack_reg);
19704 /* Need a note here so that try_split doesn't get confused. */
19705 if (get_last_insn () == NULL_RTX)
19706 emit_note (NOTE_INSN_DELETED);
19707 insn = emit_move_insn (tmp_reg, todec);
19708 try_split (PATTERN (insn), insn, 0);
19712 insn = emit_insn (TARGET_32BIT
19713 ? gen_movsi_update_stack (stack_reg, stack_reg,
19715 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19716 todec, stack_reg));
19717 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19718 it now and set the alias set/attributes. The above gen_*_update
19719 calls will generate a PARALLEL with the MEM set being the first
19721 par = PATTERN (insn);
19722 gcc_assert (GET_CODE (par) == PARALLEL);
19723 set = XVECEXP (par, 0, 0);
19724 gcc_assert (GET_CODE (set) == SET);
19725 mem = SET_DEST (set);
19726 gcc_assert (MEM_P (mem));
19727 MEM_NOTRAP_P (mem) = 1;
19728 set_mem_alias_set (mem, get_frame_alias_set ());
19730 RTX_FRAME_RELATED_P (insn) = 1;
19731 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19732 gen_rtx_SET (VOIDmode, stack_reg,
19733 gen_rtx_PLUS (Pmode, stack_reg,
19734 GEN_INT (-size))));
19737 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19739 #if PROBE_INTERVAL > 32768
19740 #error Cannot use indexed addressing mode for stack probing
19743 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19744 inclusive. These are offsets from the current stack pointer. */
19747 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19749 /* See if we have a constant small number of probes to generate. If so,
19750 that's the easy case. */
19751 if (first + size <= 32768)
19755 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19756 it exceeds SIZE. If only one probe is needed, this will not
19757 generate any code. Then probe at FIRST + SIZE. */
19758 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19759 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19761 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19764 /* Otherwise, do the same as above, but in a loop. Note that we must be
19765 extra careful with variables wrapping around because we might be at
19766 the very top (or the very bottom) of the address space and we have
19767 to be able to handle this case properly; in particular, we use an
19768 equality test for the loop condition. */
19771 HOST_WIDE_INT rounded_size;
19772 rtx r12 = gen_rtx_REG (Pmode, 12);
19773 rtx r0 = gen_rtx_REG (Pmode, 0);
19775 /* Sanity check for the addressing mode we're going to use. */
19776 gcc_assert (first <= 32768);
19778 /* Step 1: round SIZE to the previous multiple of the interval. */
19780 rounded_size = size & -PROBE_INTERVAL;
19783 /* Step 2: compute initial and final value of the loop counter. */
19785 /* TEST_ADDR = SP + FIRST. */
19786 emit_insn (gen_rtx_SET (VOIDmode, r12,
19787 plus_constant (stack_pointer_rtx, -first)));
19789 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19790 if (rounded_size > 32768)
19792 emit_move_insn (r0, GEN_INT (-rounded_size));
19793 emit_insn (gen_rtx_SET (VOIDmode, r0,
19794 gen_rtx_PLUS (Pmode, r12, r0)));
19797 emit_insn (gen_rtx_SET (VOIDmode, r0,
19798 plus_constant (r12, -rounded_size)));
19801 /* Step 3: the loop
19803 while (TEST_ADDR != LAST_ADDR)
19805 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19809 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19810 until it is equal to ROUNDED_SIZE. */
19813 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19815 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19818 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19819 that SIZE is equal to ROUNDED_SIZE. */
19821 if (size != rounded_size)
19822 emit_stack_probe (plus_constant (r12, rounded_size - size));
19826 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19827 absolute addresses. */
19830 output_probe_stack_range (rtx reg1, rtx reg2)
19832 static int labelno = 0;
19833 char loop_lab[32], end_lab[32];
19836 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19837 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19839 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19841 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19845 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19847 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19849 fputs ("\tbeq 0,", asm_out_file);
19850 assemble_name_raw (asm_out_file, end_lab);
19851 fputc ('\n', asm_out_file);
19853 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19854 xops[1] = GEN_INT (-PROBE_INTERVAL);
19855 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19857 /* Probe at TEST_ADDR and branch. */
19858 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19859 fprintf (asm_out_file, "\tb ");
19860 assemble_name_raw (asm_out_file, loop_lab);
19861 fputc ('\n', asm_out_file);
19863 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19868 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19869 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19870 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19871 deduce these equivalences by itself so it wasn't necessary to hold
19872 its hand so much. */
19875 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19876 rtx reg2, rtx rreg)
19880 /* copy_rtx will not make unique copies of registers, so we need to
19881 ensure we don't have unwanted sharing here. */
19883 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19886 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19888 real = copy_rtx (PATTERN (insn));
19890 if (reg2 != NULL_RTX)
19891 real = replace_rtx (real, reg2, rreg);
19893 real = replace_rtx (real, reg,
19894 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19895 STACK_POINTER_REGNUM),
19898 /* We expect that 'real' is either a SET or a PARALLEL containing
19899 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19900 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19902 if (GET_CODE (real) == SET)
19906 temp = simplify_rtx (SET_SRC (set));
19908 SET_SRC (set) = temp;
19909 temp = simplify_rtx (SET_DEST (set));
19911 SET_DEST (set) = temp;
19912 if (GET_CODE (SET_DEST (set)) == MEM)
19914 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19916 XEXP (SET_DEST (set), 0) = temp;
19923 gcc_assert (GET_CODE (real) == PARALLEL);
19924 for (i = 0; i < XVECLEN (real, 0); i++)
19925 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19927 rtx set = XVECEXP (real, 0, i);
19929 temp = simplify_rtx (SET_SRC (set));
19931 SET_SRC (set) = temp;
19932 temp = simplify_rtx (SET_DEST (set));
19934 SET_DEST (set) = temp;
19935 if (GET_CODE (SET_DEST (set)) == MEM)
19937 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19939 XEXP (SET_DEST (set), 0) = temp;
19941 RTX_FRAME_RELATED_P (set) = 1;
19945 RTX_FRAME_RELATED_P (insn) = 1;
19946 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19949 /* Returns an insn that has a vrsave set operation with the
19950 appropriate CLOBBERs. */
19953 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19956 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19957 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19960 = gen_rtx_SET (VOIDmode,
19962 gen_rtx_UNSPEC_VOLATILE (SImode,
19963 gen_rtvec (2, reg, vrsave),
19964 UNSPECV_SET_VRSAVE));
19968 /* We need to clobber the registers in the mask so the scheduler
19969 does not move sets to VRSAVE before sets of AltiVec registers.
19971 However, if the function receives nonlocal gotos, reload will set
19972 all call saved registers live. We will end up with:
19974 (set (reg 999) (mem))
19975 (parallel [ (set (reg vrsave) (unspec blah))
19976 (clobber (reg 999))])
19978 The clobber will cause the store into reg 999 to be dead, and
19979 flow will attempt to delete an epilogue insn. In this case, we
19980 need an unspec use/set of the register. */
19982 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19983 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19985 if (!epiloguep || call_used_regs [i])
19986 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19987 gen_rtx_REG (V4SImode, i));
19990 rtx reg = gen_rtx_REG (V4SImode, i);
19993 = gen_rtx_SET (VOIDmode,
19995 gen_rtx_UNSPEC (V4SImode,
19996 gen_rtvec (1, reg), 27));
20000 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
20002 for (i = 0; i < nclobs; ++i)
20003 XVECEXP (insn, 0, i) = clobs[i];
20008 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
20009 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
20012 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
20013 unsigned int regno, int offset, HOST_WIDE_INT total_size)
20015 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
20016 rtx replacea, replaceb;
20018 int_rtx = GEN_INT (offset);
20020 /* Some cases that need register indexed addressing. */
20021 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
20022 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
20023 || (TARGET_E500_DOUBLE && mode == DFmode)
20025 && SPE_VECTOR_MODE (mode)
20026 && !SPE_CONST_OFFSET_OK (offset)))
20028 /* Whomever calls us must make sure r11 is available in the
20029 flow path of instructions in the prologue. */
20030 offset_rtx = gen_rtx_REG (Pmode, 11);
20031 emit_move_insn (offset_rtx, int_rtx);
20033 replacea = offset_rtx;
20034 replaceb = int_rtx;
20038 offset_rtx = int_rtx;
20039 replacea = NULL_RTX;
20040 replaceb = NULL_RTX;
20043 reg = gen_rtx_REG (mode, regno);
20044 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20045 mem = gen_frame_mem (mode, addr);
20047 insn = emit_move_insn (mem, reg);
20049 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20052 /* Emit an offset memory reference suitable for a frame store, while
20053 converting to a valid addressing mode. */
20056 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20058 rtx int_rtx, offset_rtx;
20060 int_rtx = GEN_INT (offset);
20062 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20063 || (TARGET_E500_DOUBLE && mode == DFmode))
20065 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20066 emit_move_insn (offset_rtx, int_rtx);
20069 offset_rtx = int_rtx;
20071 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20074 /* Look for user-defined global regs. We should not save and restore these,
20075 and cannot use stmw/lmw if there are any in its range. */
20078 no_global_regs_above (int first, bool gpr)
20081 int last = gpr ? 32 : 64;
20082 for (i = first; i < last; i++)
20083 if (global_regs[i])
20088 #ifndef TARGET_FIX_AND_CONTINUE
20089 #define TARGET_FIX_AND_CONTINUE 0
20092 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20093 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20094 #define LAST_SAVRES_REGISTER 31
20095 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20097 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20099 /* Temporary holding space for an out-of-line register save/restore
20101 static char savres_routine_name[30];
20103 /* Return the name for an out-of-line register save/restore routine.
20104 We are saving/restoring GPRs if GPR is true. */
20107 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20108 bool savep, bool gpr, bool lr)
20110 const char *prefix = "";
20111 const char *suffix = "";
20113 /* Different targets are supposed to define
20114 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20115 routine name could be defined with:
20117 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20119 This is a nice idea in practice, but in reality, things are
20120 complicated in several ways:
20122 - ELF targets have save/restore routines for GPRs.
20124 - SPE targets use different prefixes for 32/64-bit registers, and
20125 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20127 - PPC64 ELF targets have routines for save/restore of GPRs that
20128 differ in what they do with the link register, so having a set
20129 prefix doesn't work. (We only use one of the save routines at
20130 the moment, though.)
20132 - PPC32 elf targets have "exit" versions of the restore routines
20133 that restore the link register and can save some extra space.
20134 These require an extra suffix. (There are also "tail" versions
20135 of the restore routines and "GOT" versions of the save routines,
20136 but we don't generate those at present. Same problems apply,
20139 We deal with all this by synthesizing our own prefix/suffix and
20140 using that for the simple sprintf call shown above. */
20143 /* No floating point saves on the SPE. */
20147 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20149 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20154 else if (DEFAULT_ABI == ABI_V4)
20160 prefix = savep ? "_savegpr_" : "_restgpr_";
20162 prefix = savep ? "_savefpr_" : "_restfpr_";
20167 else if (DEFAULT_ABI == ABI_AIX)
20169 #ifndef POWERPC_LINUX
20170 /* No out-of-line save/restore routines for GPRs on AIX. */
20171 gcc_assert (!TARGET_AIX || !gpr);
20177 ? (lr ? "_savegpr0_" : "_savegpr1_")
20178 : (lr ? "_restgpr0_" : "_restgpr1_"));
20179 #ifdef POWERPC_LINUX
20181 prefix = (savep ? "_savefpr_" : "_restfpr_");
20185 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20186 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20189 else if (DEFAULT_ABI == ABI_DARWIN)
20190 sorry ("out-of-line save/restore routines not supported on Darwin");
20192 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20194 return savres_routine_name;
20197 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20198 We are saving/restoring GPRs if GPR is true. */
20201 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20204 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20206 int select = ((savep ? 1 : 0) << 2
20208 /* On the SPE, we never have any FPRs, but we do have
20209 32/64-bit versions of the routines. */
20210 ? (info->spe_64bit_regs_used ? 1 : 0)
20211 : (gpr ? 1 : 0)) << 1)
20214 /* Don't generate bogus routine names. */
20215 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20216 && regno <= LAST_SAVRES_REGISTER);
20218 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20224 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20226 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20227 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20228 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20234 /* Emit a sequence of insns, including a stack tie if needed, for
20235 resetting the stack pointer. If SAVRES is true, then don't reset the
20236 stack pointer, but move the base of the frame into r11 for use by
20237 out-of-line register restore routines. */
20240 rs6000_emit_stack_reset (rs6000_stack_t *info,
20241 rtx sp_reg_rtx, rtx frame_reg_rtx,
20242 int sp_offset, bool savres)
20244 /* This blockage is needed so that sched doesn't decide to move
20245 the sp change before the register restores. */
20246 if (frame_reg_rtx != sp_reg_rtx
20248 && info->spe_64bit_regs_used != 0
20249 && info->first_gp_reg_save != 32))
20250 rs6000_emit_stack_tie ();
20252 if (frame_reg_rtx != sp_reg_rtx)
20254 if (sp_offset != 0)
20256 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20257 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20258 GEN_INT (sp_offset)));
20261 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20263 else if (sp_offset != 0)
20265 /* If we are restoring registers out-of-line, we will be using the
20266 "exit" variants of the restore routines, which will reset the
20267 stack for us. But we do need to point r11 into the right place
20268 for those routines. */
20269 rtx dest_reg = (savres
20270 ? gen_rtx_REG (Pmode, 11)
20273 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20274 GEN_INT (sp_offset)));
20281 /* Construct a parallel rtx describing the effect of a call to an
20282 out-of-line register save/restore routine. */
20285 rs6000_make_savres_rtx (rs6000_stack_t *info,
20286 rtx frame_reg_rtx, int save_area_offset,
20287 enum machine_mode reg_mode,
20288 bool savep, bool gpr, bool lr)
20291 int offset, start_reg, end_reg, n_regs;
20292 int reg_size = GET_MODE_SIZE (reg_mode);
20298 ? info->first_gp_reg_save
20299 : info->first_fp_reg_save);
20300 end_reg = gpr ? 32 : 64;
20301 n_regs = end_reg - start_reg;
20302 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20305 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20307 RTVEC_ELT (p, offset++)
20308 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20310 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20311 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20312 RTVEC_ELT (p, offset++)
20313 = gen_rtx_USE (VOIDmode,
20314 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20318 for (i = 0; i < end_reg - start_reg; i++)
20320 rtx addr, reg, mem;
20321 reg = gen_rtx_REG (reg_mode, start_reg + i);
20322 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20323 GEN_INT (save_area_offset + reg_size*i));
20324 mem = gen_frame_mem (reg_mode, addr);
20326 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20328 savep ? reg : mem);
20333 rtx addr, reg, mem;
20334 reg = gen_rtx_REG (Pmode, 0);
20335 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20336 GEN_INT (info->lr_save_offset));
20337 mem = gen_frame_mem (Pmode, addr);
20338 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20341 return gen_rtx_PARALLEL (VOIDmode, p);
20344 /* Determine whether the gp REG is really used. */
20347 rs6000_reg_live_or_pic_offset_p (int reg)
20349 /* If the function calls eh_return, claim used all the registers that would
20350 be checked for liveness otherwise. This is required for the PIC offset
20351 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20352 register allocation purposes in this case. */
20354 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20355 && (!call_used_regs[reg]
20356 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20357 && !TARGET_SINGLE_PIC_BASE
20358 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20359 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20360 && !TARGET_SINGLE_PIC_BASE
20361 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20362 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20365 /* Emit function prologue as insns. */
20368 rs6000_emit_prologue (void)
20370 rs6000_stack_t *info = rs6000_stack_info ();
20371 enum machine_mode reg_mode = Pmode;
20372 int reg_size = TARGET_32BIT ? 4 : 8;
20373 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20374 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20375 rtx frame_reg_rtx = sp_reg_rtx;
20376 rtx cr_save_rtx = NULL_RTX;
20379 int saving_FPRs_inline;
20380 int saving_GPRs_inline;
20381 int using_store_multiple;
20382 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20383 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20384 && call_used_regs[STATIC_CHAIN_REGNUM]);
20385 HOST_WIDE_INT sp_offset = 0;
20387 if (flag_stack_usage)
20388 current_function_static_stack_size = info->total_size;
20390 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20391 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20393 if (TARGET_FIX_AND_CONTINUE)
20395 /* gdb on darwin arranges to forward a function from the old
20396 address by modifying the first 5 instructions of the function
20397 to branch to the overriding function. This is necessary to
20398 permit function pointers that point to the old function to
20399 actually forward to the new function. */
20400 emit_insn (gen_nop ());
20401 emit_insn (gen_nop ());
20402 emit_insn (gen_nop ());
20403 emit_insn (gen_nop ());
20404 emit_insn (gen_nop ());
20407 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20409 reg_mode = V2SImode;
20413 strategy = info->savres_strategy;
20414 using_store_multiple = strategy & SAVRES_MULTIPLE;
20415 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20416 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20418 /* For V.4, update stack before we do any saving and set back pointer. */
20419 if (! WORLD_SAVE_P (info)
20421 && (DEFAULT_ABI == ABI_V4
20422 || crtl->calls_eh_return))
20424 bool need_r11 = (TARGET_SPE
20425 ? (!saving_GPRs_inline
20426 && info->spe_64bit_regs_used == 0)
20427 : (!saving_FPRs_inline || !saving_GPRs_inline));
20428 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20430 if (info->total_size < 32767)
20431 sp_offset = info->total_size;
20433 frame_reg_rtx = copy_reg;
20434 else if (info->cr_save_p
20436 || info->first_fp_reg_save < 64
20437 || info->first_gp_reg_save < 32
20438 || info->altivec_size != 0
20439 || info->vrsave_mask != 0
20440 || crtl->calls_eh_return)
20442 copy_reg = frame_ptr_rtx;
20443 frame_reg_rtx = copy_reg;
20447 /* The prologue won't be saving any regs so there is no need
20448 to set up a frame register to access any frame save area.
20449 We also won't be using sp_offset anywhere below, but set
20450 the correct value anyway to protect against future
20451 changes to this function. */
20452 sp_offset = info->total_size;
20454 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20455 if (frame_reg_rtx != sp_reg_rtx)
20456 rs6000_emit_stack_tie ();
20459 /* Handle world saves specially here. */
20460 if (WORLD_SAVE_P (info))
20467 /* save_world expects lr in r0. */
20468 reg0 = gen_rtx_REG (Pmode, 0);
20469 if (info->lr_save_p)
20471 insn = emit_move_insn (reg0,
20472 gen_rtx_REG (Pmode, LR_REGNO));
20473 RTX_FRAME_RELATED_P (insn) = 1;
20476 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20477 assumptions about the offsets of various bits of the stack
20479 gcc_assert (info->gp_save_offset == -220
20480 && info->fp_save_offset == -144
20481 && info->lr_save_offset == 8
20482 && info->cr_save_offset == 4
20485 && (!crtl->calls_eh_return
20486 || info->ehrd_offset == -432)
20487 && info->vrsave_save_offset == -224
20488 && info->altivec_save_offset == -416);
20490 treg = gen_rtx_REG (SImode, 11);
20491 emit_move_insn (treg, GEN_INT (-info->total_size));
20493 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20494 in R11. It also clobbers R12, so beware! */
20496 /* Preserve CR2 for save_world prologues */
20498 sz += 32 - info->first_gp_reg_save;
20499 sz += 64 - info->first_fp_reg_save;
20500 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20501 p = rtvec_alloc (sz);
20503 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20504 gen_rtx_REG (SImode,
20506 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20507 gen_rtx_SYMBOL_REF (Pmode,
20509 /* We do floats first so that the instruction pattern matches
20511 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20513 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20514 ? DFmode : SFmode),
20515 info->first_fp_reg_save + i);
20516 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20517 GEN_INT (info->fp_save_offset
20518 + sp_offset + 8 * i));
20519 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20520 ? DFmode : SFmode), addr);
20522 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20524 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20526 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20527 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20528 GEN_INT (info->altivec_save_offset
20529 + sp_offset + 16 * i));
20530 rtx mem = gen_frame_mem (V4SImode, addr);
20532 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20534 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20536 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20537 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20538 GEN_INT (info->gp_save_offset
20539 + sp_offset + reg_size * i));
20540 rtx mem = gen_frame_mem (reg_mode, addr);
20542 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20546 /* CR register traditionally saved as CR2. */
20547 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20548 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20549 GEN_INT (info->cr_save_offset
20551 rtx mem = gen_frame_mem (reg_mode, addr);
20553 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20555 /* Explain about use of R0. */
20556 if (info->lr_save_p)
20558 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20559 GEN_INT (info->lr_save_offset
20561 rtx mem = gen_frame_mem (reg_mode, addr);
20563 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20565 /* Explain what happens to the stack pointer. */
20567 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20568 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20571 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20572 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20573 treg, GEN_INT (-info->total_size));
20574 sp_offset = info->total_size;
20577 /* If we use the link register, get it into r0. */
20578 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20580 rtx addr, reg, mem;
20582 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20583 gen_rtx_REG (Pmode, LR_REGNO));
20584 RTX_FRAME_RELATED_P (insn) = 1;
20586 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20587 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20589 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20590 GEN_INT (info->lr_save_offset + sp_offset));
20591 reg = gen_rtx_REG (Pmode, 0);
20592 mem = gen_rtx_MEM (Pmode, addr);
20593 /* This should not be of rs6000_sr_alias_set, because of
20594 __builtin_return_address. */
20596 insn = emit_move_insn (mem, reg);
20597 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20598 NULL_RTX, NULL_RTX);
20602 /* If we need to save CR, put it into r12 or r11. */
20603 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20608 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20610 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20611 RTX_FRAME_RELATED_P (insn) = 1;
20612 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20613 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20614 But that's OK. All we have to do is specify that _one_ condition
20615 code register is saved in this stack slot. The thrower's epilogue
20616 will then restore all the call-saved registers.
20617 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20618 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20619 gen_rtx_REG (SImode, CR2_REGNO));
20620 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20623 /* Do any required saving of fpr's. If only one or two to save, do
20624 it ourselves. Otherwise, call function. */
20625 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20628 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20629 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20630 && ! call_used_regs[info->first_fp_reg_save+i]))
20631 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20632 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20634 info->first_fp_reg_save + i,
20635 info->fp_save_offset + sp_offset + 8 * i,
20638 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20642 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20643 info->fp_save_offset + sp_offset,
20645 /*savep=*/true, /*gpr=*/false,
20647 & SAVE_NOINLINE_FPRS_SAVES_LR)
20649 insn = emit_insn (par);
20650 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20651 NULL_RTX, NULL_RTX);
20654 /* Save GPRs. This is done as a PARALLEL if we are using
20655 the store-multiple instructions. */
20656 if (!WORLD_SAVE_P (info)
20658 && info->spe_64bit_regs_used != 0
20659 && info->first_gp_reg_save != 32)
20662 rtx spe_save_area_ptr;
20664 /* Determine whether we can address all of the registers that need
20665 to be saved with an offset from the stack pointer that fits in
20666 the small const field for SPE memory instructions. */
20667 int spe_regs_addressable_via_sp
20668 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20669 + (32 - info->first_gp_reg_save - 1) * reg_size)
20670 && saving_GPRs_inline);
20673 if (spe_regs_addressable_via_sp)
20675 spe_save_area_ptr = frame_reg_rtx;
20676 spe_offset = info->spe_gp_save_offset + sp_offset;
20680 /* Make r11 point to the start of the SPE save area. We need
20681 to be careful here if r11 is holding the static chain. If
20682 it is, then temporarily save it in r0. We would use r0 as
20683 our base register here, but using r0 as a base register in
20684 loads and stores means something different from what we
20686 int ool_adjust = (saving_GPRs_inline
20688 : (info->first_gp_reg_save
20689 - (FIRST_SAVRES_REGISTER+1))*8);
20690 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20691 + sp_offset - ool_adjust);
20693 if (using_static_chain_p)
20695 rtx r0 = gen_rtx_REG (Pmode, 0);
20696 gcc_assert (info->first_gp_reg_save > 11);
20698 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20701 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20702 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20704 GEN_INT (offset)));
20705 /* We need to make sure the move to r11 gets noted for
20706 properly outputting unwind information. */
20707 if (!saving_GPRs_inline)
20708 rs6000_frame_related (insn, frame_reg_rtx, offset,
20709 NULL_RTX, NULL_RTX);
20713 if (saving_GPRs_inline)
20715 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20716 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20718 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20719 rtx offset, addr, mem;
20721 /* We're doing all this to ensure that the offset fits into
20722 the immediate offset of 'evstdd'. */
20723 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20725 offset = GEN_INT (reg_size * i + spe_offset);
20726 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20727 mem = gen_rtx_MEM (V2SImode, addr);
20729 insn = emit_move_insn (mem, reg);
20731 rs6000_frame_related (insn, spe_save_area_ptr,
20732 info->spe_gp_save_offset
20733 + sp_offset + reg_size * i,
20734 offset, const0_rtx);
20741 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20743 /*savep=*/true, /*gpr=*/true,
20745 insn = emit_insn (par);
20746 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20747 NULL_RTX, NULL_RTX);
20751 /* Move the static chain pointer back. */
20752 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20753 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20755 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20759 /* Need to adjust r11 (r12) if we saved any FPRs. */
20760 if (info->first_fp_reg_save != 64)
20762 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20764 rtx offset = GEN_INT (sp_offset
20765 + (-8 * (64-info->first_fp_reg_save)));
20766 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20769 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20770 info->gp_save_offset + sp_offset,
20772 /*savep=*/true, /*gpr=*/true,
20774 & SAVE_NOINLINE_GPRS_SAVES_LR)
20776 insn = emit_insn (par);
20777 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20778 NULL_RTX, NULL_RTX);
20780 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20784 p = rtvec_alloc (32 - info->first_gp_reg_save);
20785 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20787 rtx addr, reg, mem;
20788 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20789 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20790 GEN_INT (info->gp_save_offset
20793 mem = gen_frame_mem (reg_mode, addr);
20795 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20797 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20798 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20799 NULL_RTX, NULL_RTX);
20801 else if (!WORLD_SAVE_P (info))
20804 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20805 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20807 rtx addr, reg, mem;
20808 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20810 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20811 GEN_INT (info->gp_save_offset
20814 mem = gen_frame_mem (reg_mode, addr);
20816 insn = emit_move_insn (mem, reg);
20817 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20818 NULL_RTX, NULL_RTX);
20822 /* ??? There's no need to emit actual instructions here, but it's the
20823 easiest way to get the frame unwind information emitted. */
20824 if (crtl->calls_eh_return)
20826 unsigned int i, regno;
20830 regno = EH_RETURN_DATA_REGNO (i);
20831 if (regno == INVALID_REGNUM)
20834 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20835 info->ehrd_offset + sp_offset
20836 + reg_size * (int) i,
20841 /* In AIX ABI we need to make sure r2 is really saved. */
20842 if (TARGET_AIX && crtl->calls_eh_return)
20844 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20845 long toc_restore_insn;
20847 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20848 || frame_reg_rtx == sp_reg_rtx);
20849 tmp_reg = gen_rtx_REG (Pmode, 11);
20850 tmp_reg_si = gen_rtx_REG (SImode, 11);
20851 if (using_static_chain_p)
20852 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20853 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20854 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20855 /* Peek at instruction to which this function returns. If it's
20856 restoring r2, then we know we've already saved r2. We can't
20857 unconditionally save r2 because the value we have will already
20858 be updated if we arrived at this function via a plt call or
20859 toc adjusting stub. */
20860 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20861 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20862 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20863 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20864 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20865 validate_condition_mode (EQ, CCUNSmode);
20866 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20867 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20868 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20869 toc_save_done = gen_label_rtx ();
20870 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20871 gen_rtx_EQ (VOIDmode, compare_result,
20873 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20875 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20876 JUMP_LABEL (jump) = toc_save_done;
20877 LABEL_NUSES (toc_save_done) += 1;
20879 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20880 sp_offset + 5 * reg_size, info->total_size);
20881 emit_label (toc_save_done);
20882 if (using_static_chain_p)
20883 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20886 /* Save CR if we use any that must be preserved. */
20887 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20889 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20890 GEN_INT (info->cr_save_offset + sp_offset));
20891 rtx mem = gen_frame_mem (SImode, addr);
20892 /* See the large comment above about why CR2_REGNO is used. */
20893 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20895 /* If r12 was used to hold the original sp, copy cr into r0 now
20897 if (REGNO (frame_reg_rtx) == 12)
20901 cr_save_rtx = gen_rtx_REG (SImode, 0);
20902 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20903 RTX_FRAME_RELATED_P (insn) = 1;
20904 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20905 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20907 insn = emit_move_insn (mem, cr_save_rtx);
20909 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20910 NULL_RTX, NULL_RTX);
20913 /* Update stack and set back pointer unless this is V.4,
20914 for which it was done previously. */
20915 if (!WORLD_SAVE_P (info) && info->push_p
20916 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20918 rtx copy_reg = NULL;
20920 if (info->total_size < 32767)
20921 sp_offset = info->total_size;
20922 else if (info->altivec_size != 0
20923 || info->vrsave_mask != 0)
20925 copy_reg = frame_ptr_rtx;
20926 frame_reg_rtx = copy_reg;
20929 sp_offset = info->total_size;
20930 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20931 if (frame_reg_rtx != sp_reg_rtx)
20932 rs6000_emit_stack_tie ();
20935 /* Set frame pointer, if needed. */
20936 if (frame_pointer_needed)
20938 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20940 RTX_FRAME_RELATED_P (insn) = 1;
20943 /* Save AltiVec registers if needed. Save here because the red zone does
20944 not include AltiVec registers. */
20945 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20949 /* There should be a non inline version of this, for when we
20950 are saving lots of vector registers. */
20951 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20952 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20954 rtx areg, savereg, mem;
20957 offset = info->altivec_save_offset + sp_offset
20958 + 16 * (i - info->first_altivec_reg_save);
20960 savereg = gen_rtx_REG (V4SImode, i);
20962 areg = gen_rtx_REG (Pmode, 0);
20963 emit_move_insn (areg, GEN_INT (offset));
20965 /* AltiVec addressing mode is [reg+reg]. */
20966 mem = gen_frame_mem (V4SImode,
20967 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20969 insn = emit_move_insn (mem, savereg);
20971 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20972 areg, GEN_INT (offset));
20976 /* VRSAVE is a bit vector representing which AltiVec registers
20977 are used. The OS uses this to determine which vector
20978 registers to save on a context switch. We need to save
20979 VRSAVE on the stack frame, add whatever AltiVec registers we
20980 used in this function, and do the corresponding magic in the
20983 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20984 && info->vrsave_mask != 0)
20986 rtx reg, mem, vrsave;
20989 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20990 as frame_reg_rtx and r11 as the static chain pointer for
20991 nested functions. */
20992 reg = gen_rtx_REG (SImode, 0);
20993 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20995 emit_insn (gen_get_vrsave_internal (reg));
20997 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
20999 if (!WORLD_SAVE_P (info))
21002 offset = info->vrsave_save_offset + sp_offset;
21003 mem = gen_frame_mem (SImode,
21004 gen_rtx_PLUS (Pmode, frame_reg_rtx,
21005 GEN_INT (offset)));
21006 insn = emit_move_insn (mem, reg);
21009 /* Include the registers in the mask. */
21010 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
21012 insn = emit_insn (generate_set_vrsave (reg, info, 0));
21015 if (TARGET_SINGLE_PIC_BASE)
21016 return; /* Do not set PIC register */
21018 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
21019 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
21020 || (DEFAULT_ABI == ABI_V4
21021 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
21022 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
21024 /* If emit_load_toc_table will use the link register, we need to save
21025 it. We use R12 for this purpose because emit_load_toc_table
21026 can use register 0. This allows us to use a plain 'blr' to return
21027 from the procedure more often. */
21028 int save_LR_around_toc_setup = (TARGET_ELF
21029 && DEFAULT_ABI != ABI_AIX
21031 && ! info->lr_save_p
21032 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21033 if (save_LR_around_toc_setup)
21035 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21037 insn = emit_move_insn (frame_ptr_rtx, lr);
21038 RTX_FRAME_RELATED_P (insn) = 1;
21040 rs6000_emit_load_toc_table (TRUE);
21042 insn = emit_move_insn (lr, frame_ptr_rtx);
21043 RTX_FRAME_RELATED_P (insn) = 1;
21046 rs6000_emit_load_toc_table (TRUE);
21050 if (DEFAULT_ABI == ABI_DARWIN
21051 && flag_pic && crtl->uses_pic_offset_table)
21053 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21054 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21056 /* Save and restore LR locally around this call (in R0). */
21057 if (!info->lr_save_p)
21058 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21060 emit_insn (gen_load_macho_picbase (src));
21062 emit_move_insn (gen_rtx_REG (Pmode,
21063 RS6000_PIC_OFFSET_TABLE_REGNUM),
21066 if (!info->lr_save_p)
21067 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21072 /* Write function prologue. */
21075 rs6000_output_function_prologue (FILE *file,
21076 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21078 rs6000_stack_t *info = rs6000_stack_info ();
21080 if (TARGET_DEBUG_STACK)
21081 debug_stack_info (info);
21083 /* Write .extern for any function we will call to save and restore
21085 if (info->first_fp_reg_save < 64)
21088 int regno = info->first_fp_reg_save - 32;
21090 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21092 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21093 /*gpr=*/false, /*lr=*/false);
21094 fprintf (file, "\t.extern %s\n", name);
21096 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21098 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21099 /*gpr=*/false, /*lr=*/true);
21100 fprintf (file, "\t.extern %s\n", name);
21104 /* Write .extern for AIX common mode routines, if needed. */
21105 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21107 fputs ("\t.extern __mulh\n", file);
21108 fputs ("\t.extern __mull\n", file);
21109 fputs ("\t.extern __divss\n", file);
21110 fputs ("\t.extern __divus\n", file);
21111 fputs ("\t.extern __quoss\n", file);
21112 fputs ("\t.extern __quous\n", file);
21113 common_mode_defined = 1;
21116 if (! HAVE_prologue)
21122 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21123 the "toplevel" insn chain. */
21124 emit_note (NOTE_INSN_DELETED);
21125 rs6000_emit_prologue ();
21126 emit_note (NOTE_INSN_DELETED);
21128 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21132 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21134 INSN_ADDRESSES_NEW (insn, addr);
21139 prologue = get_insns ();
21142 if (TARGET_DEBUG_STACK)
21143 debug_rtx_list (prologue, 100);
21145 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21149 rs6000_pic_labelno++;
21152 /* Non-zero if vmx regs are restored before the frame pop, zero if
21153 we restore after the pop when possible. */
21154 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21156 /* Reload CR from REG. */
21159 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21164 if (using_mfcr_multiple)
21166 for (i = 0; i < 8; i++)
21167 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21169 gcc_assert (count);
21172 if (using_mfcr_multiple && count > 1)
21177 p = rtvec_alloc (count);
21180 for (i = 0; i < 8; i++)
21181 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21183 rtvec r = rtvec_alloc (2);
21184 RTVEC_ELT (r, 0) = reg;
21185 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21186 RTVEC_ELT (p, ndx) =
21187 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21188 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21191 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21192 gcc_assert (ndx == count);
21195 for (i = 0; i < 8; i++)
21196 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21198 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21204 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21205 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21206 below stack pointer not cloberred by signals. */
21209 offset_below_red_zone_p (HOST_WIDE_INT offset)
21211 return offset < (DEFAULT_ABI == ABI_V4
21213 : TARGET_32BIT ? -220 : -288);
21216 /* Emit function epilogue as insns. */
21219 rs6000_emit_epilogue (int sibcall)
21221 rs6000_stack_t *info;
21222 int restoring_GPRs_inline;
21223 int restoring_FPRs_inline;
21224 int using_load_multiple;
21225 int using_mtcr_multiple;
21226 int use_backchain_to_restore_sp;
21230 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21231 rtx frame_reg_rtx = sp_reg_rtx;
21232 rtx cfa_restores = NULL_RTX;
21234 rtx cr_save_reg = NULL_RTX;
21235 enum machine_mode reg_mode = Pmode;
21236 int reg_size = TARGET_32BIT ? 4 : 8;
21239 info = rs6000_stack_info ();
21241 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21243 reg_mode = V2SImode;
21247 strategy = info->savres_strategy;
21248 using_load_multiple = strategy & SAVRES_MULTIPLE;
21249 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21250 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21251 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21252 || rs6000_cpu == PROCESSOR_PPC603
21253 || rs6000_cpu == PROCESSOR_PPC750
21255 /* Restore via the backchain when we have a large frame, since this
21256 is more efficient than an addis, addi pair. The second condition
21257 here will not trigger at the moment; We don't actually need a
21258 frame pointer for alloca, but the generic parts of the compiler
21259 give us one anyway. */
21260 use_backchain_to_restore_sp = (info->total_size > 32767
21261 || info->total_size
21262 + (info->lr_save_p ? info->lr_save_offset : 0)
21264 || (cfun->calls_alloca
21265 && !frame_pointer_needed));
21266 restore_lr = (info->lr_save_p
21267 && (restoring_FPRs_inline
21268 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21269 && (restoring_GPRs_inline
21270 || info->first_fp_reg_save < 64));
21272 if (WORLD_SAVE_P (info))
21276 const char *alloc_rname;
21279 /* eh_rest_world_r10 will return to the location saved in the LR
21280 stack slot (which is not likely to be our caller.)
21281 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21282 rest_world is similar, except any R10 parameter is ignored.
21283 The exception-handling stuff that was here in 2.95 is no
21284 longer necessary. */
21288 + 32 - info->first_gp_reg_save
21289 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21290 + 63 + 1 - info->first_fp_reg_save);
21292 strcpy (rname, ((crtl->calls_eh_return) ?
21293 "*eh_rest_world_r10" : "*rest_world"));
21294 alloc_rname = ggc_strdup (rname);
21297 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21298 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21299 gen_rtx_REG (Pmode,
21302 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21303 /* The instruction pattern requires a clobber here;
21304 it is shared with the restVEC helper. */
21306 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21309 /* CR register traditionally saved as CR2. */
21310 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21311 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21312 GEN_INT (info->cr_save_offset));
21313 rtx mem = gen_frame_mem (reg_mode, addr);
21315 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21318 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21320 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21321 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21322 GEN_INT (info->gp_save_offset
21324 rtx mem = gen_frame_mem (reg_mode, addr);
21326 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21328 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21330 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21331 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21332 GEN_INT (info->altivec_save_offset
21334 rtx mem = gen_frame_mem (V4SImode, addr);
21336 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21338 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21340 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21341 ? DFmode : SFmode),
21342 info->first_fp_reg_save + i);
21343 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21344 GEN_INT (info->fp_save_offset
21346 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21347 ? DFmode : SFmode), addr);
21349 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21352 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21354 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21356 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21358 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21360 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21361 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21366 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21368 sp_offset = info->total_size;
21370 /* Restore AltiVec registers if we must do so before adjusting the
21372 if (TARGET_ALTIVEC_ABI
21373 && info->altivec_size != 0
21374 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21375 || (DEFAULT_ABI != ABI_V4
21376 && offset_below_red_zone_p (info->altivec_save_offset))))
21380 if (use_backchain_to_restore_sp)
21382 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21383 emit_move_insn (frame_reg_rtx,
21384 gen_rtx_MEM (Pmode, sp_reg_rtx));
21387 else if (frame_pointer_needed)
21388 frame_reg_rtx = hard_frame_pointer_rtx;
21390 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21391 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21393 rtx addr, areg, mem, reg;
21395 areg = gen_rtx_REG (Pmode, 0);
21397 (areg, GEN_INT (info->altivec_save_offset
21399 + 16 * (i - info->first_altivec_reg_save)));
21401 /* AltiVec addressing mode is [reg+reg]. */
21402 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21403 mem = gen_frame_mem (V4SImode, addr);
21405 reg = gen_rtx_REG (V4SImode, i);
21406 emit_move_insn (reg, mem);
21407 if (offset_below_red_zone_p (info->altivec_save_offset
21408 + (i - info->first_altivec_reg_save)
21410 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21415 /* Restore VRSAVE if we must do so before adjusting the stack. */
21417 && TARGET_ALTIVEC_VRSAVE
21418 && info->vrsave_mask != 0
21419 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21420 || (DEFAULT_ABI != ABI_V4
21421 && offset_below_red_zone_p (info->vrsave_save_offset))))
21423 rtx addr, mem, reg;
21425 if (frame_reg_rtx == sp_reg_rtx)
21427 if (use_backchain_to_restore_sp)
21429 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21430 emit_move_insn (frame_reg_rtx,
21431 gen_rtx_MEM (Pmode, sp_reg_rtx));
21434 else if (frame_pointer_needed)
21435 frame_reg_rtx = hard_frame_pointer_rtx;
21438 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21439 GEN_INT (info->vrsave_save_offset + sp_offset));
21440 mem = gen_frame_mem (SImode, addr);
21441 reg = gen_rtx_REG (SImode, 12);
21442 emit_move_insn (reg, mem);
21444 emit_insn (generate_set_vrsave (reg, info, 1));
21448 /* If we have a large stack frame, restore the old stack pointer
21449 using the backchain. */
21450 if (use_backchain_to_restore_sp)
21452 if (frame_reg_rtx == sp_reg_rtx)
21454 /* Under V.4, don't reset the stack pointer until after we're done
21455 loading the saved registers. */
21456 if (DEFAULT_ABI == ABI_V4)
21457 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21459 insn = emit_move_insn (frame_reg_rtx,
21460 gen_rtx_MEM (Pmode, sp_reg_rtx));
21463 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21464 && DEFAULT_ABI == ABI_V4)
21465 /* frame_reg_rtx has been set up by the altivec restore. */
21469 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21470 frame_reg_rtx = sp_reg_rtx;
21473 /* If we have a frame pointer, we can restore the old stack pointer
21475 else if (frame_pointer_needed)
21477 frame_reg_rtx = sp_reg_rtx;
21478 if (DEFAULT_ABI == ABI_V4)
21479 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21480 /* Prevent reordering memory accesses against stack pointer restore. */
21481 else if (cfun->calls_alloca
21482 || offset_below_red_zone_p (-info->total_size))
21484 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21485 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21486 MEM_NOTRAP_P (mem1) = 1;
21487 MEM_NOTRAP_P (mem2) = 1;
21488 emit_insn (gen_frame_tie (mem1, mem2));
21491 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21492 GEN_INT (info->total_size)));
21495 else if (info->push_p
21496 && DEFAULT_ABI != ABI_V4
21497 && !crtl->calls_eh_return)
21499 /* Prevent reordering memory accesses against stack pointer restore. */
21500 if (cfun->calls_alloca
21501 || offset_below_red_zone_p (-info->total_size))
21503 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21504 MEM_NOTRAP_P (mem) = 1;
21505 emit_insn (gen_stack_tie (mem));
21507 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21508 GEN_INT (info->total_size)));
21511 if (insn && frame_reg_rtx == sp_reg_rtx)
21515 REG_NOTES (insn) = cfa_restores;
21516 cfa_restores = NULL_RTX;
21518 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21519 RTX_FRAME_RELATED_P (insn) = 1;
21522 /* Restore AltiVec registers if we have not done so already. */
21523 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21524 && TARGET_ALTIVEC_ABI
21525 && info->altivec_size != 0
21526 && (DEFAULT_ABI == ABI_V4
21527 || !offset_below_red_zone_p (info->altivec_save_offset)))
21531 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21532 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21534 rtx addr, areg, mem, reg;
21536 areg = gen_rtx_REG (Pmode, 0);
21538 (areg, GEN_INT (info->altivec_save_offset
21540 + 16 * (i - info->first_altivec_reg_save)));
21542 /* AltiVec addressing mode is [reg+reg]. */
21543 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21544 mem = gen_frame_mem (V4SImode, addr);
21546 reg = gen_rtx_REG (V4SImode, i);
21547 emit_move_insn (reg, mem);
21548 if (DEFAULT_ABI == ABI_V4)
21549 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21554 /* Restore VRSAVE if we have not done so already. */
21555 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21557 && TARGET_ALTIVEC_VRSAVE
21558 && info->vrsave_mask != 0
21559 && (DEFAULT_ABI == ABI_V4
21560 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21562 rtx addr, mem, reg;
21564 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21565 GEN_INT (info->vrsave_save_offset + sp_offset));
21566 mem = gen_frame_mem (SImode, addr);
21567 reg = gen_rtx_REG (SImode, 12);
21568 emit_move_insn (reg, mem);
21570 emit_insn (generate_set_vrsave (reg, info, 1));
21573 /* Get the old lr if we saved it. If we are restoring registers
21574 out-of-line, then the out-of-line routines can do this for us. */
21575 if (restore_lr && restoring_GPRs_inline)
21577 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21578 info->lr_save_offset + sp_offset);
21580 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21583 /* Get the old cr if we saved it. */
21584 if (info->cr_save_p)
21586 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21587 GEN_INT (info->cr_save_offset + sp_offset));
21588 rtx mem = gen_frame_mem (SImode, addr);
21590 cr_save_reg = gen_rtx_REG (SImode,
21591 DEFAULT_ABI == ABI_AIX
21592 && !restoring_GPRs_inline
21593 && info->first_fp_reg_save < 64
21595 emit_move_insn (cr_save_reg, mem);
21598 /* Set LR here to try to overlap restores below. LR is always saved
21599 above incoming stack, so it never needs REG_CFA_RESTORE. */
21600 if (restore_lr && restoring_GPRs_inline)
21601 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21602 gen_rtx_REG (Pmode, 0));
21604 /* Load exception handler data registers, if needed. */
21605 if (crtl->calls_eh_return)
21607 unsigned int i, regno;
21611 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21612 GEN_INT (sp_offset + 5 * reg_size));
21613 rtx mem = gen_frame_mem (reg_mode, addr);
21615 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21622 regno = EH_RETURN_DATA_REGNO (i);
21623 if (regno == INVALID_REGNUM)
21626 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21627 info->ehrd_offset + sp_offset
21628 + reg_size * (int) i);
21630 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21634 /* Restore GPRs. This is done as a PARALLEL if we are using
21635 the load-multiple instructions. */
21637 && info->spe_64bit_regs_used != 0
21638 && info->first_gp_reg_save != 32)
21640 /* Determine whether we can address all of the registers that need
21641 to be saved with an offset from the stack pointer that fits in
21642 the small const field for SPE memory instructions. */
21643 int spe_regs_addressable_via_sp
21644 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21645 + (32 - info->first_gp_reg_save - 1) * reg_size)
21646 && restoring_GPRs_inline);
21649 if (spe_regs_addressable_via_sp)
21650 spe_offset = info->spe_gp_save_offset + sp_offset;
21653 rtx old_frame_reg_rtx = frame_reg_rtx;
21654 /* Make r11 point to the start of the SPE save area. We worried about
21655 not clobbering it when we were saving registers in the prologue.
21656 There's no need to worry here because the static chain is passed
21657 anew to every function. */
21658 int ool_adjust = (restoring_GPRs_inline
21660 : (info->first_gp_reg_save
21661 - (FIRST_SAVRES_REGISTER+1))*8);
21663 if (frame_reg_rtx == sp_reg_rtx)
21664 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21665 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21666 GEN_INT (info->spe_gp_save_offset
21669 /* Keep the invariant that frame_reg_rtx + sp_offset points
21670 at the top of the stack frame. */
21671 sp_offset = -info->spe_gp_save_offset;
21676 if (restoring_GPRs_inline)
21678 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21679 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21681 rtx offset, addr, mem, reg;
21683 /* We're doing all this to ensure that the immediate offset
21684 fits into the immediate field of 'evldd'. */
21685 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21687 offset = GEN_INT (spe_offset + reg_size * i);
21688 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21689 mem = gen_rtx_MEM (V2SImode, addr);
21690 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21692 insn = emit_move_insn (reg, mem);
21693 if (DEFAULT_ABI == ABI_V4)
21695 if (frame_pointer_needed
21696 && info->first_gp_reg_save + i
21697 == HARD_FRAME_POINTER_REGNUM)
21699 add_reg_note (insn, REG_CFA_DEF_CFA,
21700 plus_constant (frame_reg_rtx,
21702 RTX_FRAME_RELATED_P (insn) = 1;
21705 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21714 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21716 /*savep=*/false, /*gpr=*/true,
21718 emit_jump_insn (par);
21719 /* We don't want anybody else emitting things after we jumped
21724 else if (!restoring_GPRs_inline)
21726 /* We are jumping to an out-of-line function. */
21727 bool can_use_exit = info->first_fp_reg_save == 64;
21730 /* Emit stack reset code if we need it. */
21732 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21733 sp_offset, can_use_exit);
21736 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21739 GEN_INT (sp_offset - info->fp_size)));
21740 if (REGNO (frame_reg_rtx) == 11)
21741 sp_offset += info->fp_size;
21744 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21745 info->gp_save_offset, reg_mode,
21746 /*savep=*/false, /*gpr=*/true,
21747 /*lr=*/can_use_exit);
21751 if (info->cr_save_p)
21753 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21754 if (DEFAULT_ABI == ABI_V4)
21756 = alloc_reg_note (REG_CFA_RESTORE,
21757 gen_rtx_REG (SImode, CR2_REGNO),
21761 emit_jump_insn (par);
21763 /* We don't want anybody else emitting things after we jumped
21768 insn = emit_insn (par);
21769 if (DEFAULT_ABI == ABI_V4)
21771 if (frame_pointer_needed)
21773 add_reg_note (insn, REG_CFA_DEF_CFA,
21774 plus_constant (frame_reg_rtx, sp_offset));
21775 RTX_FRAME_RELATED_P (insn) = 1;
21778 for (i = info->first_gp_reg_save; i < 32; i++)
21780 = alloc_reg_note (REG_CFA_RESTORE,
21781 gen_rtx_REG (reg_mode, i), cfa_restores);
21784 else if (using_load_multiple)
21787 p = rtvec_alloc (32 - info->first_gp_reg_save);
21788 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21790 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21791 GEN_INT (info->gp_save_offset
21794 rtx mem = gen_frame_mem (reg_mode, addr);
21795 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21797 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21798 if (DEFAULT_ABI == ABI_V4)
21799 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21802 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21803 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21805 add_reg_note (insn, REG_CFA_DEF_CFA,
21806 plus_constant (frame_reg_rtx, sp_offset));
21807 RTX_FRAME_RELATED_P (insn) = 1;
21812 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21813 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21815 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21816 GEN_INT (info->gp_save_offset
21819 rtx mem = gen_frame_mem (reg_mode, addr);
21820 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21822 insn = emit_move_insn (reg, mem);
21823 if (DEFAULT_ABI == ABI_V4)
21825 if (frame_pointer_needed
21826 && info->first_gp_reg_save + i
21827 == HARD_FRAME_POINTER_REGNUM)
21829 add_reg_note (insn, REG_CFA_DEF_CFA,
21830 plus_constant (frame_reg_rtx, sp_offset));
21831 RTX_FRAME_RELATED_P (insn) = 1;
21834 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21840 if (restore_lr && !restoring_GPRs_inline)
21842 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21843 info->lr_save_offset + sp_offset);
21845 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21846 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21847 gen_rtx_REG (Pmode, 0));
21850 /* Restore fpr's if we need to do it without calling a function. */
21851 if (restoring_FPRs_inline)
21852 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21853 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21854 && ! call_used_regs[info->first_fp_reg_save+i]))
21856 rtx addr, mem, reg;
21857 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21858 GEN_INT (info->fp_save_offset
21861 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21862 ? DFmode : SFmode), addr);
21863 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21864 ? DFmode : SFmode),
21865 info->first_fp_reg_save + i);
21867 emit_move_insn (reg, mem);
21868 if (DEFAULT_ABI == ABI_V4)
21869 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21873 /* If we saved cr, restore it here. Just those that were used. */
21874 if (info->cr_save_p)
21876 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21877 if (DEFAULT_ABI == ABI_V4)
21879 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21883 /* If this is V.4, unwind the stack pointer after all of the loads
21885 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21886 sp_offset, !restoring_FPRs_inline);
21891 REG_NOTES (insn) = cfa_restores;
21892 cfa_restores = NULL_RTX;
21894 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21895 RTX_FRAME_RELATED_P (insn) = 1;
21898 if (crtl->calls_eh_return)
21900 rtx sa = EH_RETURN_STACKADJ_RTX;
21901 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21907 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21908 if (! restoring_FPRs_inline)
21909 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21911 p = rtvec_alloc (2);
21913 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21914 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21915 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21916 : gen_rtx_CLOBBER (VOIDmode,
21917 gen_rtx_REG (Pmode, 65)));
21919 /* If we have to restore more than two FP registers, branch to the
21920 restore function. It will return to our caller. */
21921 if (! restoring_FPRs_inline)
21926 sym = rs6000_savres_routine_sym (info,
21930 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21931 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21932 gen_rtx_REG (Pmode,
21933 DEFAULT_ABI == ABI_AIX
21935 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21938 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21939 GEN_INT (info->fp_save_offset + 8*i));
21940 mem = gen_frame_mem (DFmode, addr);
21942 RTVEC_ELT (p, i+4) =
21943 gen_rtx_SET (VOIDmode,
21944 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21949 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21953 /* Write function epilogue. */
21956 rs6000_output_function_epilogue (FILE *file,
21957 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21959 if (! HAVE_epilogue)
21961 rtx insn = get_last_insn ();
21962 /* If the last insn was a BARRIER, we don't have to write anything except
21963 the trace table. */
21964 if (GET_CODE (insn) == NOTE)
21965 insn = prev_nonnote_insn (insn);
21966 if (insn == 0 || GET_CODE (insn) != BARRIER)
21968 /* This is slightly ugly, but at least we don't have two
21969 copies of the epilogue-emitting code. */
21972 /* A NOTE_INSN_DELETED is supposed to be at the start
21973 and end of the "toplevel" insn chain. */
21974 emit_note (NOTE_INSN_DELETED);
21975 rs6000_emit_epilogue (FALSE);
21976 emit_note (NOTE_INSN_DELETED);
21978 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21982 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21984 INSN_ADDRESSES_NEW (insn, addr);
21989 if (TARGET_DEBUG_STACK)
21990 debug_rtx_list (get_insns (), 100);
21991 final (get_insns (), file, FALSE);
21997 macho_branch_islands ();
21998 /* Mach-O doesn't support labels at the end of objects, so if
21999 it looks like we might want one, insert a NOP. */
22001 rtx insn = get_last_insn ();
22004 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
22005 insn = PREV_INSN (insn);
22009 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
22010 fputs ("\tnop\n", file);
22014 /* Output a traceback table here. See /usr/include/sys/debug.h for info
22017 We don't output a traceback table if -finhibit-size-directive was
22018 used. The documentation for -finhibit-size-directive reads
22019 ``don't output a @code{.size} assembler directive, or anything
22020 else that would cause trouble if the function is split in the
22021 middle, and the two halves are placed at locations far apart in
22022 memory.'' The traceback table has this property, since it
22023 includes the offset from the start of the function to the
22024 traceback table itself.
22026 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22027 different traceback table. */
22028 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
22029 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22031 const char *fname = NULL;
22032 const char *language_string = lang_hooks.name;
22033 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22035 int optional_tbtab;
22036 rs6000_stack_t *info = rs6000_stack_info ();
22038 if (rs6000_traceback == traceback_full)
22039 optional_tbtab = 1;
22040 else if (rs6000_traceback == traceback_part)
22041 optional_tbtab = 0;
22043 optional_tbtab = !optimize_size && !TARGET_ELF;
22045 if (optional_tbtab)
22047 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22048 while (*fname == '.') /* V.4 encodes . in the name */
22051 /* Need label immediately before tbtab, so we can compute
22052 its offset from the function start. */
22053 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22054 ASM_OUTPUT_LABEL (file, fname);
22057 /* The .tbtab pseudo-op can only be used for the first eight
22058 expressions, since it can't handle the possibly variable
22059 length fields that follow. However, if you omit the optional
22060 fields, the assembler outputs zeros for all optional fields
22061 anyways, giving each variable length field is minimum length
22062 (as defined in sys/debug.h). Thus we can not use the .tbtab
22063 pseudo-op at all. */
22065 /* An all-zero word flags the start of the tbtab, for debuggers
22066 that have to find it by searching forward from the entry
22067 point or from the current pc. */
22068 fputs ("\t.long 0\n", file);
22070 /* Tbtab format type. Use format type 0. */
22071 fputs ("\t.byte 0,", file);
22073 /* Language type. Unfortunately, there does not seem to be any
22074 official way to discover the language being compiled, so we
22075 use language_string.
22076 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22077 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22078 a number, so for now use 9. LTO and Go aren't assigned numbers
22079 either, so for now use 0. */
22080 if (! strcmp (language_string, "GNU C")
22081 || ! strcmp (language_string, "GNU GIMPLE")
22082 || ! strcmp (language_string, "GNU Go"))
22084 else if (! strcmp (language_string, "GNU F77")
22085 || ! strcmp (language_string, "GNU Fortran"))
22087 else if (! strcmp (language_string, "GNU Pascal"))
22089 else if (! strcmp (language_string, "GNU Ada"))
22091 else if (! strcmp (language_string, "GNU C++")
22092 || ! strcmp (language_string, "GNU Objective-C++"))
22094 else if (! strcmp (language_string, "GNU Java"))
22096 else if (! strcmp (language_string, "GNU Objective-C"))
22099 gcc_unreachable ();
22100 fprintf (file, "%d,", i);
22102 /* 8 single bit fields: global linkage (not set for C extern linkage,
22103 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22104 from start of procedure stored in tbtab, internal function, function
22105 has controlled storage, function has no toc, function uses fp,
22106 function logs/aborts fp operations. */
22107 /* Assume that fp operations are used if any fp reg must be saved. */
22108 fprintf (file, "%d,",
22109 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22111 /* 6 bitfields: function is interrupt handler, name present in
22112 proc table, function calls alloca, on condition directives
22113 (controls stack walks, 3 bits), saves condition reg, saves
22115 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22116 set up as a frame pointer, even when there is no alloca call. */
22117 fprintf (file, "%d,",
22118 ((optional_tbtab << 6)
22119 | ((optional_tbtab & frame_pointer_needed) << 5)
22120 | (info->cr_save_p << 1)
22121 | (info->lr_save_p)));
22123 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22125 fprintf (file, "%d,",
22126 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22128 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22129 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22131 if (optional_tbtab)
22133 /* Compute the parameter info from the function decl argument
22136 int next_parm_info_bit = 31;
22138 for (decl = DECL_ARGUMENTS (current_function_decl);
22139 decl; decl = DECL_CHAIN (decl))
22141 rtx parameter = DECL_INCOMING_RTL (decl);
22142 enum machine_mode mode = GET_MODE (parameter);
22144 if (GET_CODE (parameter) == REG)
22146 if (SCALAR_FLOAT_MODE_P (mode))
22167 gcc_unreachable ();
22170 /* If only one bit will fit, don't or in this entry. */
22171 if (next_parm_info_bit > 0)
22172 parm_info |= (bits << (next_parm_info_bit - 1));
22173 next_parm_info_bit -= 2;
22177 fixed_parms += ((GET_MODE_SIZE (mode)
22178 + (UNITS_PER_WORD - 1))
22180 next_parm_info_bit -= 1;
22186 /* Number of fixed point parameters. */
22187 /* This is actually the number of words of fixed point parameters; thus
22188 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22189 fprintf (file, "%d,", fixed_parms);
22191 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22193 /* This is actually the number of fp registers that hold parameters;
22194 and thus the maximum value is 13. */
22195 /* Set parameters on stack bit if parameters are not in their original
22196 registers, regardless of whether they are on the stack? Xlc
22197 seems to set the bit when not optimizing. */
22198 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22200 if (! optional_tbtab)
22203 /* Optional fields follow. Some are variable length. */
22205 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22206 11 double float. */
22207 /* There is an entry for each parameter in a register, in the order that
22208 they occur in the parameter list. Any intervening arguments on the
22209 stack are ignored. If the list overflows a long (max possible length
22210 34 bits) then completely leave off all elements that don't fit. */
22211 /* Only emit this long if there was at least one parameter. */
22212 if (fixed_parms || float_parms)
22213 fprintf (file, "\t.long %d\n", parm_info);
22215 /* Offset from start of code to tb table. */
22216 fputs ("\t.long ", file);
22217 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22218 RS6000_OUTPUT_BASENAME (file, fname);
22220 rs6000_output_function_entry (file, fname);
22223 /* Interrupt handler mask. */
22224 /* Omit this long, since we never set the interrupt handler bit
22227 /* Number of CTL (controlled storage) anchors. */
22228 /* Omit this long, since the has_ctl bit is never set above. */
22230 /* Displacement into stack of each CTL anchor. */
22231 /* Omit this list of longs, because there are no CTL anchors. */
22233 /* Length of function name. */
22236 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22238 /* Function name. */
22239 assemble_string (fname, strlen (fname));
22241 /* Register for alloca automatic storage; this is always reg 31.
22242 Only emit this if the alloca bit was set above. */
22243 if (frame_pointer_needed)
22244 fputs ("\t.byte 31\n", file);
22246 fputs ("\t.align 2\n", file);
22250 /* A C compound statement that outputs the assembler code for a thunk
22251 function, used to implement C++ virtual function calls with
22252 multiple inheritance. The thunk acts as a wrapper around a virtual
22253 function, adjusting the implicit object parameter before handing
22254 control off to the real function.
22256 First, emit code to add the integer DELTA to the location that
22257 contains the incoming first argument. Assume that this argument
22258 contains a pointer, and is the one used to pass the `this' pointer
22259 in C++. This is the incoming argument *before* the function
22260 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22261 values of all other incoming arguments.
22263 After the addition, emit code to jump to FUNCTION, which is a
22264 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22265 not touch the return address. Hence returning from FUNCTION will
22266 return to whoever called the current `thunk'.
22268 The effect must be as if FUNCTION had been called directly with the
22269 adjusted first argument. This macro is responsible for emitting
22270 all of the code for a thunk function; output_function_prologue()
22271 and output_function_epilogue() are not invoked.
22273 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22274 been extracted from it.) It might possibly be useful on some
22275 targets, but probably not.
22277 If you do not define this macro, the target-independent code in the
22278 C++ frontend will generate a less efficient heavyweight thunk that
22279 calls FUNCTION instead of jumping to it. The generic approach does
22280 not support varargs. */
22283 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22284 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22287 rtx this_rtx, insn, funexp;
22289 reload_completed = 1;
22290 epilogue_completed = 1;
22292 /* Mark the end of the (empty) prologue. */
22293 emit_note (NOTE_INSN_PROLOGUE_END);
22295 /* Find the "this" pointer. If the function returns a structure,
22296 the structure return pointer is in r3. */
22297 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22298 this_rtx = gen_rtx_REG (Pmode, 4);
22300 this_rtx = gen_rtx_REG (Pmode, 3);
22302 /* Apply the constant offset, if required. */
22304 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22306 /* Apply the offset from the vtable, if required. */
22309 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22310 rtx tmp = gen_rtx_REG (Pmode, 12);
22312 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22313 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22315 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22316 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22320 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22322 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22324 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22327 /* Generate a tail call to the target function. */
22328 if (!TREE_USED (function))
22330 assemble_external (function);
22331 TREE_USED (function) = 1;
22333 funexp = XEXP (DECL_RTL (function), 0);
22334 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22337 if (MACHOPIC_INDIRECT)
22338 funexp = machopic_indirect_call_target (funexp);
22341 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22342 generate sibcall RTL explicitly. */
22343 insn = emit_call_insn (
22344 gen_rtx_PARALLEL (VOIDmode,
22346 gen_rtx_CALL (VOIDmode,
22347 funexp, const0_rtx),
22348 gen_rtx_USE (VOIDmode, const0_rtx),
22349 gen_rtx_USE (VOIDmode,
22350 gen_rtx_REG (SImode,
22352 gen_rtx_RETURN (VOIDmode))));
22353 SIBLING_CALL_P (insn) = 1;
22356 /* Run just enough of rest_of_compilation to get the insns emitted.
22357 There's not really enough bulk here to make other passes such as
22358 instruction scheduling worth while. Note that use_thunk calls
22359 assemble_start_function and assemble_end_function. */
22360 insn = get_insns ();
22361 insn_locators_alloc ();
22362 shorten_branches (insn);
22363 final_start_function (insn, file, 1);
22364 final (insn, file, 1);
22365 final_end_function ();
22367 reload_completed = 0;
22368 epilogue_completed = 0;
22371 /* A quick summary of the various types of 'constant-pool tables'
22374 Target Flags Name One table per
22375 AIX (none) AIX TOC object file
22376 AIX -mfull-toc AIX TOC object file
22377 AIX -mminimal-toc AIX minimal TOC translation unit
22378 SVR4/EABI (none) SVR4 SDATA object file
22379 SVR4/EABI -fpic SVR4 pic object file
22380 SVR4/EABI -fPIC SVR4 PIC translation unit
22381 SVR4/EABI -mrelocatable EABI TOC function
22382 SVR4/EABI -maix AIX TOC object file
22383 SVR4/EABI -maix -mminimal-toc
22384 AIX minimal TOC translation unit
22386 Name Reg. Set by entries contains:
22387 made by addrs? fp? sum?
22389 AIX TOC 2 crt0 as Y option option
22390 AIX minimal TOC 30 prolog gcc Y Y option
22391 SVR4 SDATA 13 crt0 gcc N Y N
22392 SVR4 pic 30 prolog ld Y not yet N
22393 SVR4 PIC 30 prolog gcc Y option option
22394 EABI TOC 30 prolog gcc Y option option
22398 /* Hash functions for the hash table. */
22401 rs6000_hash_constant (rtx k)
22403 enum rtx_code code = GET_CODE (k);
22404 enum machine_mode mode = GET_MODE (k);
22405 unsigned result = (code << 3) ^ mode;
22406 const char *format;
22409 format = GET_RTX_FORMAT (code);
22410 flen = strlen (format);
22416 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22419 if (mode != VOIDmode)
22420 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22432 for (; fidx < flen; fidx++)
22433 switch (format[fidx])
22438 const char *str = XSTR (k, fidx);
22439 len = strlen (str);
22440 result = result * 613 + len;
22441 for (i = 0; i < len; i++)
22442 result = result * 613 + (unsigned) str[i];
22447 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22451 result = result * 613 + (unsigned) XINT (k, fidx);
22454 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22455 result = result * 613 + (unsigned) XWINT (k, fidx);
22459 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22460 result = result * 613 + (unsigned) (XWINT (k, fidx)
22467 gcc_unreachable ();
22474 toc_hash_function (const void *hash_entry)
22476 const struct toc_hash_struct *thc =
22477 (const struct toc_hash_struct *) hash_entry;
22478 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22481 /* Compare H1 and H2 for equivalence. */
22484 toc_hash_eq (const void *h1, const void *h2)
22486 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22487 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22489 if (((const struct toc_hash_struct *) h1)->key_mode
22490 != ((const struct toc_hash_struct *) h2)->key_mode)
22493 return rtx_equal_p (r1, r2);
22496 /* These are the names given by the C++ front-end to vtables, and
22497 vtable-like objects. Ideally, this logic should not be here;
22498 instead, there should be some programmatic way of inquiring as
22499 to whether or not an object is a vtable. */
22501 #define VTABLE_NAME_P(NAME) \
22502 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22503 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22504 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22505 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22506 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22508 #ifdef NO_DOLLAR_IN_LABEL
22509 /* Return a GGC-allocated character string translating dollar signs in
22510 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22513 rs6000_xcoff_strip_dollar (const char *name)
22518 p = strchr (name, '$');
22520 if (p == 0 || p == name)
22523 len = strlen (name);
22524 strip = (char *) alloca (len + 1);
22525 strcpy (strip, name);
22526 p = strchr (strip, '$');
22530 p = strchr (p + 1, '$');
22533 return ggc_alloc_string (strip, len);
22538 rs6000_output_symbol_ref (FILE *file, rtx x)
22540 /* Currently C++ toc references to vtables can be emitted before it
22541 is decided whether the vtable is public or private. If this is
22542 the case, then the linker will eventually complain that there is
22543 a reference to an unknown section. Thus, for vtables only,
22544 we emit the TOC reference to reference the symbol and not the
22546 const char *name = XSTR (x, 0);
22548 if (VTABLE_NAME_P (name))
22550 RS6000_OUTPUT_BASENAME (file, name);
22553 assemble_name (file, name);
22556 /* Output a TOC entry. We derive the entry name from what is being
22560 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22563 const char *name = buf;
22565 HOST_WIDE_INT offset = 0;
22567 gcc_assert (!TARGET_NO_TOC);
22569 /* When the linker won't eliminate them, don't output duplicate
22570 TOC entries (this happens on AIX if there is any kind of TOC,
22571 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22573 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22575 struct toc_hash_struct *h;
22578 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22579 time because GGC is not initialized at that point. */
22580 if (toc_hash_table == NULL)
22581 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22582 toc_hash_eq, NULL);
22584 h = ggc_alloc_toc_hash_struct ();
22586 h->key_mode = mode;
22587 h->labelno = labelno;
22589 found = htab_find_slot (toc_hash_table, h, INSERT);
22590 if (*found == NULL)
22592 else /* This is indeed a duplicate.
22593 Set this label equal to that label. */
22595 fputs ("\t.set ", file);
22596 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22597 fprintf (file, "%d,", labelno);
22598 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22599 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22605 /* If we're going to put a double constant in the TOC, make sure it's
22606 aligned properly when strict alignment is on. */
22607 if (GET_CODE (x) == CONST_DOUBLE
22608 && STRICT_ALIGNMENT
22609 && GET_MODE_BITSIZE (mode) >= 64
22610 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22611 ASM_OUTPUT_ALIGN (file, 3);
22614 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22616 /* Handle FP constants specially. Note that if we have a minimal
22617 TOC, things we put here aren't actually in the TOC, so we can allow
22619 if (GET_CODE (x) == CONST_DOUBLE &&
22620 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22622 REAL_VALUE_TYPE rv;
22625 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22626 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22627 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22629 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22633 if (TARGET_MINIMAL_TOC)
22634 fputs (DOUBLE_INT_ASM_OP, file);
22636 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22637 k[0] & 0xffffffff, k[1] & 0xffffffff,
22638 k[2] & 0xffffffff, k[3] & 0xffffffff);
22639 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22640 k[0] & 0xffffffff, k[1] & 0xffffffff,
22641 k[2] & 0xffffffff, k[3] & 0xffffffff);
22646 if (TARGET_MINIMAL_TOC)
22647 fputs ("\t.long ", file);
22649 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22650 k[0] & 0xffffffff, k[1] & 0xffffffff,
22651 k[2] & 0xffffffff, k[3] & 0xffffffff);
22652 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22653 k[0] & 0xffffffff, k[1] & 0xffffffff,
22654 k[2] & 0xffffffff, k[3] & 0xffffffff);
22658 else if (GET_CODE (x) == CONST_DOUBLE &&
22659 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22661 REAL_VALUE_TYPE rv;
22664 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22666 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22667 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22669 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22673 if (TARGET_MINIMAL_TOC)
22674 fputs (DOUBLE_INT_ASM_OP, file);
22676 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22677 k[0] & 0xffffffff, k[1] & 0xffffffff);
22678 fprintf (file, "0x%lx%08lx\n",
22679 k[0] & 0xffffffff, k[1] & 0xffffffff);
22684 if (TARGET_MINIMAL_TOC)
22685 fputs ("\t.long ", file);
22687 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22688 k[0] & 0xffffffff, k[1] & 0xffffffff);
22689 fprintf (file, "0x%lx,0x%lx\n",
22690 k[0] & 0xffffffff, k[1] & 0xffffffff);
22694 else if (GET_CODE (x) == CONST_DOUBLE &&
22695 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22697 REAL_VALUE_TYPE rv;
22700 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22701 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22702 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22704 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22708 if (TARGET_MINIMAL_TOC)
22709 fputs (DOUBLE_INT_ASM_OP, file);
22711 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22712 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22717 if (TARGET_MINIMAL_TOC)
22718 fputs ("\t.long ", file);
22720 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22721 fprintf (file, "0x%lx\n", l & 0xffffffff);
22725 else if (GET_MODE (x) == VOIDmode
22726 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22728 unsigned HOST_WIDE_INT low;
22729 HOST_WIDE_INT high;
22731 if (GET_CODE (x) == CONST_DOUBLE)
22733 low = CONST_DOUBLE_LOW (x);
22734 high = CONST_DOUBLE_HIGH (x);
22737 #if HOST_BITS_PER_WIDE_INT == 32
22740 high = (low & 0x80000000) ? ~0 : 0;
22744 low = INTVAL (x) & 0xffffffff;
22745 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22749 /* TOC entries are always Pmode-sized, but since this
22750 is a bigendian machine then if we're putting smaller
22751 integer constants in the TOC we have to pad them.
22752 (This is still a win over putting the constants in
22753 a separate constant pool, because then we'd have
22754 to have both a TOC entry _and_ the actual constant.)
22756 For a 32-bit target, CONST_INT values are loaded and shifted
22757 entirely within `low' and can be stored in one TOC entry. */
22759 /* It would be easy to make this work, but it doesn't now. */
22760 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22762 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22764 #if HOST_BITS_PER_WIDE_INT == 32
22765 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22766 POINTER_SIZE, &low, &high, 0);
22769 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22770 high = (HOST_WIDE_INT) low >> 32;
22777 if (TARGET_MINIMAL_TOC)
22778 fputs (DOUBLE_INT_ASM_OP, file);
22780 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22781 (long) high & 0xffffffff, (long) low & 0xffffffff);
22782 fprintf (file, "0x%lx%08lx\n",
22783 (long) high & 0xffffffff, (long) low & 0xffffffff);
22788 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22790 if (TARGET_MINIMAL_TOC)
22791 fputs ("\t.long ", file);
22793 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22794 (long) high & 0xffffffff, (long) low & 0xffffffff);
22795 fprintf (file, "0x%lx,0x%lx\n",
22796 (long) high & 0xffffffff, (long) low & 0xffffffff);
22800 if (TARGET_MINIMAL_TOC)
22801 fputs ("\t.long ", file);
22803 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22804 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22810 if (GET_CODE (x) == CONST)
22812 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22813 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22815 base = XEXP (XEXP (x, 0), 0);
22816 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22819 switch (GET_CODE (base))
22822 name = XSTR (base, 0);
22826 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22827 CODE_LABEL_NUMBER (XEXP (base, 0)));
22831 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22835 gcc_unreachable ();
22838 if (TARGET_MINIMAL_TOC)
22839 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22842 fputs ("\t.tc ", file);
22843 RS6000_OUTPUT_BASENAME (file, name);
22846 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22848 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22850 fputs ("[TC],", file);
22853 /* Currently C++ toc references to vtables can be emitted before it
22854 is decided whether the vtable is public or private. If this is
22855 the case, then the linker will eventually complain that there is
22856 a TOC reference to an unknown section. Thus, for vtables only,
22857 we emit the TOC reference to reference the symbol and not the
22859 if (VTABLE_NAME_P (name))
22861 RS6000_OUTPUT_BASENAME (file, name);
22863 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22864 else if (offset > 0)
22865 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22868 output_addr_const (file, x);
22872 /* Output an assembler pseudo-op to write an ASCII string of N characters
22873 starting at P to FILE.
22875 On the RS/6000, we have to do this using the .byte operation and
22876 write out special characters outside the quoted string.
22877 Also, the assembler is broken; very long strings are truncated,
22878 so we must artificially break them up early. */
22881 output_ascii (FILE *file, const char *p, int n)
22884 int i, count_string;
22885 const char *for_string = "\t.byte \"";
22886 const char *for_decimal = "\t.byte ";
22887 const char *to_close = NULL;
22890 for (i = 0; i < n; i++)
22893 if (c >= ' ' && c < 0177)
22896 fputs (for_string, file);
22899 /* Write two quotes to get one. */
22907 for_decimal = "\"\n\t.byte ";
22911 if (count_string >= 512)
22913 fputs (to_close, file);
22915 for_string = "\t.byte \"";
22916 for_decimal = "\t.byte ";
22924 fputs (for_decimal, file);
22925 fprintf (file, "%d", c);
22927 for_string = "\n\t.byte \"";
22928 for_decimal = ", ";
22934 /* Now close the string if we have written one. Then end the line. */
22936 fputs (to_close, file);
22939 /* Generate a unique section name for FILENAME for a section type
22940 represented by SECTION_DESC. Output goes into BUF.
22942 SECTION_DESC can be any string, as long as it is different for each
22943 possible section type.
22945 We name the section in the same manner as xlc. The name begins with an
22946 underscore followed by the filename (after stripping any leading directory
22947 names) with the last period replaced by the string SECTION_DESC. If
22948 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22952 rs6000_gen_section_name (char **buf, const char *filename,
22953 const char *section_desc)
22955 const char *q, *after_last_slash, *last_period = 0;
22959 after_last_slash = filename;
22960 for (q = filename; *q; q++)
22963 after_last_slash = q + 1;
22964 else if (*q == '.')
22968 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22969 *buf = (char *) xmalloc (len);
22974 for (q = after_last_slash; *q; q++)
22976 if (q == last_period)
22978 strcpy (p, section_desc);
22979 p += strlen (section_desc);
22983 else if (ISALNUM (*q))
22987 if (last_period == 0)
22988 strcpy (p, section_desc);
22993 /* Emit profile function. */
22996 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
22998 /* Non-standard profiling for kernels, which just saves LR then calls
22999 _mcount without worrying about arg saves. The idea is to change
23000 the function prologue as little as possible as it isn't easy to
23001 account for arg save/restore code added just for _mcount. */
23002 if (TARGET_PROFILE_KERNEL)
23005 if (DEFAULT_ABI == ABI_AIX)
23007 #ifndef NO_PROFILE_COUNTERS
23008 # define NO_PROFILE_COUNTERS 0
23010 if (NO_PROFILE_COUNTERS)
23011 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23012 LCT_NORMAL, VOIDmode, 0);
23016 const char *label_name;
23019 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23020 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
23021 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
23023 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23024 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
23027 else if (DEFAULT_ABI == ABI_DARWIN)
23029 const char *mcount_name = RS6000_MCOUNT;
23030 int caller_addr_regno = LR_REGNO;
23032 /* Be conservative and always set this, at least for now. */
23033 crtl->uses_pic_offset_table = 1;
23036 /* For PIC code, set up a stub and collect the caller's address
23037 from r0, which is where the prologue puts it. */
23038 if (MACHOPIC_INDIRECT
23039 && crtl->uses_pic_offset_table)
23040 caller_addr_regno = 0;
23042 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23043 LCT_NORMAL, VOIDmode, 1,
23044 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23048 /* Write function profiler code. */
23051 output_function_profiler (FILE *file, int labelno)
23055 switch (DEFAULT_ABI)
23058 gcc_unreachable ();
23063 warning (0, "no profiling of 64-bit code for this ABI");
23066 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23067 fprintf (file, "\tmflr %s\n", reg_names[0]);
23068 if (NO_PROFILE_COUNTERS)
23070 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23071 reg_names[0], reg_names[1]);
23073 else if (TARGET_SECURE_PLT && flag_pic)
23075 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23076 reg_names[0], reg_names[1]);
23077 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23078 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23079 reg_names[12], reg_names[12]);
23080 assemble_name (file, buf);
23081 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23082 assemble_name (file, buf);
23083 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23085 else if (flag_pic == 1)
23087 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23088 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23089 reg_names[0], reg_names[1]);
23090 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23091 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23092 assemble_name (file, buf);
23093 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23095 else if (flag_pic > 1)
23097 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23098 reg_names[0], reg_names[1]);
23099 /* Now, we need to get the address of the label. */
23100 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23101 assemble_name (file, buf);
23102 fputs ("-.\n1:", file);
23103 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23104 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23105 reg_names[0], reg_names[11]);
23106 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23107 reg_names[0], reg_names[0], reg_names[11]);
23111 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23112 assemble_name (file, buf);
23113 fputs ("@ha\n", file);
23114 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23115 reg_names[0], reg_names[1]);
23116 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23117 assemble_name (file, buf);
23118 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23121 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23122 fprintf (file, "\tbl %s%s\n",
23123 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23128 if (!TARGET_PROFILE_KERNEL)
23130 /* Don't do anything, done in output_profile_hook (). */
23134 gcc_assert (!TARGET_32BIT);
23136 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23137 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23139 if (cfun->static_chain_decl != NULL)
23141 asm_fprintf (file, "\tstd %s,24(%s)\n",
23142 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23143 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23144 asm_fprintf (file, "\tld %s,24(%s)\n",
23145 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23148 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23156 /* The following variable value is the last issued insn. */
23158 static rtx last_scheduled_insn;
23160 /* The following variable helps to balance issuing of load and
23161 store instructions */
23163 static int load_store_pendulum;
23165 /* Power4 load update and store update instructions are cracked into a
23166 load or store and an integer insn which are executed in the same cycle.
23167 Branches have their own dispatch slot which does not count against the
23168 GCC issue rate, but it changes the program flow so there are no other
23169 instructions to issue in this cycle. */
23172 rs6000_variable_issue_1 (rtx insn, int more)
23174 last_scheduled_insn = insn;
23175 if (GET_CODE (PATTERN (insn)) == USE
23176 || GET_CODE (PATTERN (insn)) == CLOBBER)
23178 cached_can_issue_more = more;
23179 return cached_can_issue_more;
23182 if (insn_terminates_group_p (insn, current_group))
23184 cached_can_issue_more = 0;
23185 return cached_can_issue_more;
23188 /* If no reservation, but reach here */
23189 if (recog_memoized (insn) < 0)
23192 if (rs6000_sched_groups)
23194 if (is_microcoded_insn (insn))
23195 cached_can_issue_more = 0;
23196 else if (is_cracked_insn (insn))
23197 cached_can_issue_more = more > 2 ? more - 2 : 0;
23199 cached_can_issue_more = more - 1;
23201 return cached_can_issue_more;
23204 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23207 cached_can_issue_more = more - 1;
23208 return cached_can_issue_more;
23212 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23214 int r = rs6000_variable_issue_1 (insn, more);
23216 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23220 /* Adjust the cost of a scheduling dependency. Return the new cost of
23221 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23224 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23226 enum attr_type attr_type;
23228 if (! recog_memoized (insn))
23231 switch (REG_NOTE_KIND (link))
23235 /* Data dependency; DEP_INSN writes a register that INSN reads
23236 some cycles later. */
23238 /* Separate a load from a narrower, dependent store. */
23239 if (rs6000_sched_groups
23240 && GET_CODE (PATTERN (insn)) == SET
23241 && GET_CODE (PATTERN (dep_insn)) == SET
23242 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23243 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23244 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23245 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23248 attr_type = get_attr_type (insn);
23253 /* Tell the first scheduling pass about the latency between
23254 a mtctr and bctr (and mtlr and br/blr). The first
23255 scheduling pass will not know about this latency since
23256 the mtctr instruction, which has the latency associated
23257 to it, will be generated by reload. */
23258 return TARGET_POWER ? 5 : 4;
23260 /* Leave some extra cycles between a compare and its
23261 dependent branch, to inhibit expensive mispredicts. */
23262 if ((rs6000_cpu_attr == CPU_PPC603
23263 || rs6000_cpu_attr == CPU_PPC604
23264 || rs6000_cpu_attr == CPU_PPC604E
23265 || rs6000_cpu_attr == CPU_PPC620
23266 || rs6000_cpu_attr == CPU_PPC630
23267 || rs6000_cpu_attr == CPU_PPC750
23268 || rs6000_cpu_attr == CPU_PPC7400
23269 || rs6000_cpu_attr == CPU_PPC7450
23270 || rs6000_cpu_attr == CPU_POWER4
23271 || rs6000_cpu_attr == CPU_POWER5
23272 || rs6000_cpu_attr == CPU_POWER7
23273 || rs6000_cpu_attr == CPU_CELL)
23274 && recog_memoized (dep_insn)
23275 && (INSN_CODE (dep_insn) >= 0))
23277 switch (get_attr_type (dep_insn))
23281 case TYPE_DELAYED_COMPARE:
23282 case TYPE_IMUL_COMPARE:
23283 case TYPE_LMUL_COMPARE:
23284 case TYPE_FPCOMPARE:
23285 case TYPE_CR_LOGICAL:
23286 case TYPE_DELAYED_CR:
23295 case TYPE_STORE_UX:
23297 case TYPE_FPSTORE_U:
23298 case TYPE_FPSTORE_UX:
23299 if ((rs6000_cpu == PROCESSOR_POWER6)
23300 && recog_memoized (dep_insn)
23301 && (INSN_CODE (dep_insn) >= 0))
23304 if (GET_CODE (PATTERN (insn)) != SET)
23305 /* If this happens, we have to extend this to schedule
23306 optimally. Return default for now. */
23309 /* Adjust the cost for the case where the value written
23310 by a fixed point operation is used as the address
23311 gen value on a store. */
23312 switch (get_attr_type (dep_insn))
23319 if (! store_data_bypass_p (dep_insn, insn))
23323 case TYPE_LOAD_EXT:
23324 case TYPE_LOAD_EXT_U:
23325 case TYPE_LOAD_EXT_UX:
23326 case TYPE_VAR_SHIFT_ROTATE:
23327 case TYPE_VAR_DELAYED_COMPARE:
23329 if (! store_data_bypass_p (dep_insn, insn))
23335 case TYPE_FAST_COMPARE:
23338 case TYPE_INSERT_WORD:
23339 case TYPE_INSERT_DWORD:
23340 case TYPE_FPLOAD_U:
23341 case TYPE_FPLOAD_UX:
23343 case TYPE_STORE_UX:
23344 case TYPE_FPSTORE_U:
23345 case TYPE_FPSTORE_UX:
23347 if (! store_data_bypass_p (dep_insn, insn))
23355 case TYPE_IMUL_COMPARE:
23356 case TYPE_LMUL_COMPARE:
23358 if (! store_data_bypass_p (dep_insn, insn))
23364 if (! store_data_bypass_p (dep_insn, insn))
23370 if (! store_data_bypass_p (dep_insn, insn))
23383 case TYPE_LOAD_EXT:
23384 case TYPE_LOAD_EXT_U:
23385 case TYPE_LOAD_EXT_UX:
23386 if ((rs6000_cpu == PROCESSOR_POWER6)
23387 && recog_memoized (dep_insn)
23388 && (INSN_CODE (dep_insn) >= 0))
23391 /* Adjust the cost for the case where the value written
23392 by a fixed point instruction is used within the address
23393 gen portion of a subsequent load(u)(x) */
23394 switch (get_attr_type (dep_insn))
23401 if (set_to_load_agen (dep_insn, insn))
23405 case TYPE_LOAD_EXT:
23406 case TYPE_LOAD_EXT_U:
23407 case TYPE_LOAD_EXT_UX:
23408 case TYPE_VAR_SHIFT_ROTATE:
23409 case TYPE_VAR_DELAYED_COMPARE:
23411 if (set_to_load_agen (dep_insn, insn))
23417 case TYPE_FAST_COMPARE:
23420 case TYPE_INSERT_WORD:
23421 case TYPE_INSERT_DWORD:
23422 case TYPE_FPLOAD_U:
23423 case TYPE_FPLOAD_UX:
23425 case TYPE_STORE_UX:
23426 case TYPE_FPSTORE_U:
23427 case TYPE_FPSTORE_UX:
23429 if (set_to_load_agen (dep_insn, insn))
23437 case TYPE_IMUL_COMPARE:
23438 case TYPE_LMUL_COMPARE:
23440 if (set_to_load_agen (dep_insn, insn))
23446 if (set_to_load_agen (dep_insn, insn))
23452 if (set_to_load_agen (dep_insn, insn))
23463 if ((rs6000_cpu == PROCESSOR_POWER6)
23464 && recog_memoized (dep_insn)
23465 && (INSN_CODE (dep_insn) >= 0)
23466 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23473 /* Fall out to return default cost. */
23477 case REG_DEP_OUTPUT:
23478 /* Output dependency; DEP_INSN writes a register that INSN writes some
23480 if ((rs6000_cpu == PROCESSOR_POWER6)
23481 && recog_memoized (dep_insn)
23482 && (INSN_CODE (dep_insn) >= 0))
23484 attr_type = get_attr_type (insn);
23489 if (get_attr_type (dep_insn) == TYPE_FP)
23493 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23501 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23506 gcc_unreachable ();
23512 /* Debug version of rs6000_adjust_cost. */
23515 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23517 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23523 switch (REG_NOTE_KIND (link))
23525 default: dep = "unknown depencency"; break;
23526 case REG_DEP_TRUE: dep = "data dependency"; break;
23527 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23528 case REG_DEP_ANTI: dep = "anti depencency"; break;
23532 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23533 "%s, insn:\n", ret, cost, dep);
23541 /* The function returns a true if INSN is microcoded.
23542 Return false otherwise. */
23545 is_microcoded_insn (rtx insn)
23547 if (!insn || !NONDEBUG_INSN_P (insn)
23548 || GET_CODE (PATTERN (insn)) == USE
23549 || GET_CODE (PATTERN (insn)) == CLOBBER)
23552 if (rs6000_cpu_attr == CPU_CELL)
23553 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23555 if (rs6000_sched_groups)
23557 enum attr_type type = get_attr_type (insn);
23558 if (type == TYPE_LOAD_EXT_U
23559 || type == TYPE_LOAD_EXT_UX
23560 || type == TYPE_LOAD_UX
23561 || type == TYPE_STORE_UX
23562 || type == TYPE_MFCR)
23569 /* The function returns true if INSN is cracked into 2 instructions
23570 by the processor (and therefore occupies 2 issue slots). */
23573 is_cracked_insn (rtx insn)
23575 if (!insn || !NONDEBUG_INSN_P (insn)
23576 || GET_CODE (PATTERN (insn)) == USE
23577 || GET_CODE (PATTERN (insn)) == CLOBBER)
23580 if (rs6000_sched_groups)
23582 enum attr_type type = get_attr_type (insn);
23583 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23584 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23585 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23586 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23587 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23588 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23589 || type == TYPE_IDIV || type == TYPE_LDIV
23590 || type == TYPE_INSERT_WORD)
23597 /* The function returns true if INSN can be issued only from
23598 the branch slot. */
23601 is_branch_slot_insn (rtx insn)
23603 if (!insn || !NONDEBUG_INSN_P (insn)
23604 || GET_CODE (PATTERN (insn)) == USE
23605 || GET_CODE (PATTERN (insn)) == CLOBBER)
23608 if (rs6000_sched_groups)
23610 enum attr_type type = get_attr_type (insn);
23611 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23619 /* The function returns true if out_inst sets a value that is
23620 used in the address generation computation of in_insn */
23622 set_to_load_agen (rtx out_insn, rtx in_insn)
23624 rtx out_set, in_set;
23626 /* For performance reasons, only handle the simple case where
23627 both loads are a single_set. */
23628 out_set = single_set (out_insn);
23631 in_set = single_set (in_insn);
23633 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23639 /* The function returns true if the target storage location of
23640 out_insn is adjacent to the target storage location of in_insn */
23641 /* Return 1 if memory locations are adjacent. */
23644 adjacent_mem_locations (rtx insn1, rtx insn2)
23647 rtx a = get_store_dest (PATTERN (insn1));
23648 rtx b = get_store_dest (PATTERN (insn2));
23650 if ((GET_CODE (XEXP (a, 0)) == REG
23651 || (GET_CODE (XEXP (a, 0)) == PLUS
23652 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23653 && (GET_CODE (XEXP (b, 0)) == REG
23654 || (GET_CODE (XEXP (b, 0)) == PLUS
23655 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23657 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23660 if (GET_CODE (XEXP (a, 0)) == PLUS)
23662 reg0 = XEXP (XEXP (a, 0), 0);
23663 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23666 reg0 = XEXP (a, 0);
23668 if (GET_CODE (XEXP (b, 0)) == PLUS)
23670 reg1 = XEXP (XEXP (b, 0), 0);
23671 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23674 reg1 = XEXP (b, 0);
23676 val_diff = val1 - val0;
23678 return ((REGNO (reg0) == REGNO (reg1))
23679 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23680 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23686 /* A C statement (sans semicolon) to update the integer scheduling
23687 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23688 INSN earlier, reduce the priority to execute INSN later. Do not
23689 define this macro if you do not need to adjust the scheduling
23690 priorities of insns. */
23693 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23695 /* On machines (like the 750) which have asymmetric integer units,
23696 where one integer unit can do multiply and divides and the other
23697 can't, reduce the priority of multiply/divide so it is scheduled
23698 before other integer operations. */
23701 if (! INSN_P (insn))
23704 if (GET_CODE (PATTERN (insn)) == USE)
23707 switch (rs6000_cpu_attr) {
23709 switch (get_attr_type (insn))
23716 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23717 priority, priority);
23718 if (priority >= 0 && priority < 0x01000000)
23725 if (insn_must_be_first_in_group (insn)
23726 && reload_completed
23727 && current_sched_info->sched_max_insns_priority
23728 && rs6000_sched_restricted_insns_priority)
23731 /* Prioritize insns that can be dispatched only in the first
23733 if (rs6000_sched_restricted_insns_priority == 1)
23734 /* Attach highest priority to insn. This means that in
23735 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23736 precede 'priority' (critical path) considerations. */
23737 return current_sched_info->sched_max_insns_priority;
23738 else if (rs6000_sched_restricted_insns_priority == 2)
23739 /* Increase priority of insn by a minimal amount. This means that in
23740 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23741 considerations precede dispatch-slot restriction considerations. */
23742 return (priority + 1);
23745 if (rs6000_cpu == PROCESSOR_POWER6
23746 && ((load_store_pendulum == -2 && is_load_insn (insn))
23747 || (load_store_pendulum == 2 && is_store_insn (insn))))
23748 /* Attach highest priority to insn if the scheduler has just issued two
23749 stores and this instruction is a load, or two loads and this instruction
23750 is a store. Power6 wants loads and stores scheduled alternately
23752 return current_sched_info->sched_max_insns_priority;
23757 /* Return true if the instruction is nonpipelined on the Cell. */
23759 is_nonpipeline_insn (rtx insn)
23761 enum attr_type type;
23762 if (!insn || !NONDEBUG_INSN_P (insn)
23763 || GET_CODE (PATTERN (insn)) == USE
23764 || GET_CODE (PATTERN (insn)) == CLOBBER)
23767 type = get_attr_type (insn);
23768 if (type == TYPE_IMUL
23769 || type == TYPE_IMUL2
23770 || type == TYPE_IMUL3
23771 || type == TYPE_LMUL
23772 || type == TYPE_IDIV
23773 || type == TYPE_LDIV
23774 || type == TYPE_SDIV
23775 || type == TYPE_DDIV
23776 || type == TYPE_SSQRT
23777 || type == TYPE_DSQRT
23778 || type == TYPE_MFCR
23779 || type == TYPE_MFCRF
23780 || type == TYPE_MFJMPR)
23788 /* Return how many instructions the machine can issue per cycle. */
23791 rs6000_issue_rate (void)
23793 /* Unless scheduling for register pressure, use issue rate of 1 for
23794 first scheduling pass to decrease degradation. */
23795 if (!reload_completed && !flag_sched_pressure)
23798 switch (rs6000_cpu_attr) {
23799 case CPU_RIOS1: /* ? */
23801 case CPU_PPC601: /* ? */
23810 case CPU_PPCE300C2:
23811 case CPU_PPCE300C3:
23812 case CPU_PPCE500MC:
23813 case CPU_PPCE500MC64:
23833 /* Return how many instructions to look ahead for better insn
23837 rs6000_use_sched_lookahead (void)
23839 if (rs6000_cpu_attr == CPU_PPC8540)
23841 if (rs6000_cpu_attr == CPU_CELL)
23842 return (reload_completed ? 8 : 0);
23846 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23848 rs6000_use_sched_lookahead_guard (rtx insn)
23850 if (rs6000_cpu_attr != CPU_CELL)
23853 if (insn == NULL_RTX || !INSN_P (insn))
23856 if (!reload_completed
23857 || is_nonpipeline_insn (insn)
23858 || is_microcoded_insn (insn))
23864 /* Determine is PAT refers to memory. */
23867 is_mem_ref (rtx pat)
23873 /* stack_tie does not produce any real memory traffic. */
23874 if (GET_CODE (pat) == UNSPEC
23875 && XINT (pat, 1) == UNSPEC_TIE)
23878 if (GET_CODE (pat) == MEM)
23881 /* Recursively process the pattern. */
23882 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23884 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23887 ret |= is_mem_ref (XEXP (pat, i));
23888 else if (fmt[i] == 'E')
23889 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23890 ret |= is_mem_ref (XVECEXP (pat, i, j));
23896 /* Determine if PAT is a PATTERN of a load insn. */
23899 is_load_insn1 (rtx pat)
23901 if (!pat || pat == NULL_RTX)
23904 if (GET_CODE (pat) == SET)
23905 return is_mem_ref (SET_SRC (pat));
23907 if (GET_CODE (pat) == PARALLEL)
23911 for (i = 0; i < XVECLEN (pat, 0); i++)
23912 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23919 /* Determine if INSN loads from memory. */
23922 is_load_insn (rtx insn)
23924 if (!insn || !INSN_P (insn))
23927 if (GET_CODE (insn) == CALL_INSN)
23930 return is_load_insn1 (PATTERN (insn));
23933 /* Determine if PAT is a PATTERN of a store insn. */
23936 is_store_insn1 (rtx pat)
23938 if (!pat || pat == NULL_RTX)
23941 if (GET_CODE (pat) == SET)
23942 return is_mem_ref (SET_DEST (pat));
23944 if (GET_CODE (pat) == PARALLEL)
23948 for (i = 0; i < XVECLEN (pat, 0); i++)
23949 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23956 /* Determine if INSN stores to memory. */
23959 is_store_insn (rtx insn)
23961 if (!insn || !INSN_P (insn))
23964 return is_store_insn1 (PATTERN (insn));
23967 /* Return the dest of a store insn. */
23970 get_store_dest (rtx pat)
23972 gcc_assert (is_store_insn1 (pat));
23974 if (GET_CODE (pat) == SET)
23975 return SET_DEST (pat);
23976 else if (GET_CODE (pat) == PARALLEL)
23980 for (i = 0; i < XVECLEN (pat, 0); i++)
23982 rtx inner_pat = XVECEXP (pat, 0, i);
23983 if (GET_CODE (inner_pat) == SET
23984 && is_mem_ref (SET_DEST (inner_pat)))
23988 /* We shouldn't get here, because we should have either a simple
23989 store insn or a store with update which are covered above. */
23993 /* Returns whether the dependence between INSN and NEXT is considered
23994 costly by the given target. */
23997 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
24002 /* If the flag is not enabled - no dependence is considered costly;
24003 allow all dependent insns in the same group.
24004 This is the most aggressive option. */
24005 if (rs6000_sched_costly_dep == no_dep_costly)
24008 /* If the flag is set to 1 - a dependence is always considered costly;
24009 do not allow dependent instructions in the same group.
24010 This is the most conservative option. */
24011 if (rs6000_sched_costly_dep == all_deps_costly)
24014 insn = DEP_PRO (dep);
24015 next = DEP_CON (dep);
24017 if (rs6000_sched_costly_dep == store_to_load_dep_costly
24018 && is_load_insn (next)
24019 && is_store_insn (insn))
24020 /* Prevent load after store in the same group. */
24023 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
24024 && is_load_insn (next)
24025 && is_store_insn (insn)
24026 && DEP_TYPE (dep) == REG_DEP_TRUE)
24027 /* Prevent load after store in the same group if it is a true
24031 /* The flag is set to X; dependences with latency >= X are considered costly,
24032 and will not be scheduled in the same group. */
24033 if (rs6000_sched_costly_dep <= max_dep_latency
24034 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24040 /* Return the next insn after INSN that is found before TAIL is reached,
24041 skipping any "non-active" insns - insns that will not actually occupy
24042 an issue slot. Return NULL_RTX if such an insn is not found. */
24045 get_next_active_insn (rtx insn, rtx tail)
24047 if (insn == NULL_RTX || insn == tail)
24052 insn = NEXT_INSN (insn);
24053 if (insn == NULL_RTX || insn == tail)
24058 || (NONJUMP_INSN_P (insn)
24059 && GET_CODE (PATTERN (insn)) != USE
24060 && GET_CODE (PATTERN (insn)) != CLOBBER
24061 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24067 /* We are about to begin issuing insns for this clock cycle. */
24070 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24071 rtx *ready ATTRIBUTE_UNUSED,
24072 int *pn_ready ATTRIBUTE_UNUSED,
24073 int clock_var ATTRIBUTE_UNUSED)
24075 int n_ready = *pn_ready;
24078 fprintf (dump, "// rs6000_sched_reorder :\n");
24080 /* Reorder the ready list, if the second to last ready insn
24081 is a nonepipeline insn. */
24082 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24084 if (is_nonpipeline_insn (ready[n_ready - 1])
24085 && (recog_memoized (ready[n_ready - 2]) > 0))
24086 /* Simply swap first two insns. */
24088 rtx tmp = ready[n_ready - 1];
24089 ready[n_ready - 1] = ready[n_ready - 2];
24090 ready[n_ready - 2] = tmp;
24094 if (rs6000_cpu == PROCESSOR_POWER6)
24095 load_store_pendulum = 0;
24097 return rs6000_issue_rate ();
24100 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24103 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24104 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24107 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24109 /* For Power6, we need to handle some special cases to try and keep the
24110 store queue from overflowing and triggering expensive flushes.
24112 This code monitors how load and store instructions are being issued
24113 and skews the ready list one way or the other to increase the likelihood
24114 that a desired instruction is issued at the proper time.
24116 A couple of things are done. First, we maintain a "load_store_pendulum"
24117 to track the current state of load/store issue.
24119 - If the pendulum is at zero, then no loads or stores have been
24120 issued in the current cycle so we do nothing.
24122 - If the pendulum is 1, then a single load has been issued in this
24123 cycle and we attempt to locate another load in the ready list to
24126 - If the pendulum is -2, then two stores have already been
24127 issued in this cycle, so we increase the priority of the first load
24128 in the ready list to increase it's likelihood of being chosen first
24131 - If the pendulum is -1, then a single store has been issued in this
24132 cycle and we attempt to locate another store in the ready list to
24133 issue with it, preferring a store to an adjacent memory location to
24134 facilitate store pairing in the store queue.
24136 - If the pendulum is 2, then two loads have already been
24137 issued in this cycle, so we increase the priority of the first store
24138 in the ready list to increase it's likelihood of being chosen first
24141 - If the pendulum < -2 or > 2, then do nothing.
24143 Note: This code covers the most common scenarios. There exist non
24144 load/store instructions which make use of the LSU and which
24145 would need to be accounted for to strictly model the behavior
24146 of the machine. Those instructions are currently unaccounted
24147 for to help minimize compile time overhead of this code.
24149 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24155 if (is_store_insn (last_scheduled_insn))
24156 /* Issuing a store, swing the load_store_pendulum to the left */
24157 load_store_pendulum--;
24158 else if (is_load_insn (last_scheduled_insn))
24159 /* Issuing a load, swing the load_store_pendulum to the right */
24160 load_store_pendulum++;
24162 return cached_can_issue_more;
24164 /* If the pendulum is balanced, or there is only one instruction on
24165 the ready list, then all is well, so return. */
24166 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24167 return cached_can_issue_more;
24169 if (load_store_pendulum == 1)
24171 /* A load has been issued in this cycle. Scan the ready list
24172 for another load to issue with it */
24177 if (is_load_insn (ready[pos]))
24179 /* Found a load. Move it to the head of the ready list,
24180 and adjust it's priority so that it is more likely to
24183 for (i=pos; i<*pn_ready-1; i++)
24184 ready[i] = ready[i + 1];
24185 ready[*pn_ready-1] = tmp;
24187 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24188 INSN_PRIORITY (tmp)++;
24194 else if (load_store_pendulum == -2)
24196 /* Two stores have been issued in this cycle. Increase the
24197 priority of the first load in the ready list to favor it for
24198 issuing in the next cycle. */
24203 if (is_load_insn (ready[pos])
24205 && INSN_PRIORITY_KNOWN (ready[pos]))
24207 INSN_PRIORITY (ready[pos])++;
24209 /* Adjust the pendulum to account for the fact that a load
24210 was found and increased in priority. This is to prevent
24211 increasing the priority of multiple loads */
24212 load_store_pendulum--;
24219 else if (load_store_pendulum == -1)
24221 /* A store has been issued in this cycle. Scan the ready list for
24222 another store to issue with it, preferring a store to an adjacent
24224 int first_store_pos = -1;
24230 if (is_store_insn (ready[pos]))
24232 /* Maintain the index of the first store found on the
24234 if (first_store_pos == -1)
24235 first_store_pos = pos;
24237 if (is_store_insn (last_scheduled_insn)
24238 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24240 /* Found an adjacent store. Move it to the head of the
24241 ready list, and adjust it's priority so that it is
24242 more likely to stay there */
24244 for (i=pos; i<*pn_ready-1; i++)
24245 ready[i] = ready[i + 1];
24246 ready[*pn_ready-1] = tmp;
24248 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24249 INSN_PRIORITY (tmp)++;
24251 first_store_pos = -1;
24259 if (first_store_pos >= 0)
24261 /* An adjacent store wasn't found, but a non-adjacent store was,
24262 so move the non-adjacent store to the front of the ready
24263 list, and adjust its priority so that it is more likely to
24265 tmp = ready[first_store_pos];
24266 for (i=first_store_pos; i<*pn_ready-1; i++)
24267 ready[i] = ready[i + 1];
24268 ready[*pn_ready-1] = tmp;
24269 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24270 INSN_PRIORITY (tmp)++;
24273 else if (load_store_pendulum == 2)
24275 /* Two loads have been issued in this cycle. Increase the priority
24276 of the first store in the ready list to favor it for issuing in
24282 if (is_store_insn (ready[pos])
24284 && INSN_PRIORITY_KNOWN (ready[pos]))
24286 INSN_PRIORITY (ready[pos])++;
24288 /* Adjust the pendulum to account for the fact that a store
24289 was found and increased in priority. This is to prevent
24290 increasing the priority of multiple stores */
24291 load_store_pendulum++;
24300 return cached_can_issue_more;
24303 /* Return whether the presence of INSN causes a dispatch group termination
24304 of group WHICH_GROUP.
24306 If WHICH_GROUP == current_group, this function will return true if INSN
24307 causes the termination of the current group (i.e, the dispatch group to
24308 which INSN belongs). This means that INSN will be the last insn in the
24309 group it belongs to.
24311 If WHICH_GROUP == previous_group, this function will return true if INSN
24312 causes the termination of the previous group (i.e, the dispatch group that
24313 precedes the group to which INSN belongs). This means that INSN will be
24314 the first insn in the group it belongs to). */
24317 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24324 first = insn_must_be_first_in_group (insn);
24325 last = insn_must_be_last_in_group (insn);
24330 if (which_group == current_group)
24332 else if (which_group == previous_group)
24340 insn_must_be_first_in_group (rtx insn)
24342 enum attr_type type;
24345 || GET_CODE (insn) == NOTE
24346 || DEBUG_INSN_P (insn)
24347 || GET_CODE (PATTERN (insn)) == USE
24348 || GET_CODE (PATTERN (insn)) == CLOBBER)
24351 switch (rs6000_cpu)
24353 case PROCESSOR_POWER5:
24354 if (is_cracked_insn (insn))
24356 case PROCESSOR_POWER4:
24357 if (is_microcoded_insn (insn))
24360 if (!rs6000_sched_groups)
24363 type = get_attr_type (insn);
24370 case TYPE_DELAYED_CR:
24371 case TYPE_CR_LOGICAL:
24385 case PROCESSOR_POWER6:
24386 type = get_attr_type (insn);
24390 case TYPE_INSERT_DWORD:
24394 case TYPE_VAR_SHIFT_ROTATE:
24401 case TYPE_INSERT_WORD:
24402 case TYPE_DELAYED_COMPARE:
24403 case TYPE_IMUL_COMPARE:
24404 case TYPE_LMUL_COMPARE:
24405 case TYPE_FPCOMPARE:
24416 case TYPE_LOAD_EXT_UX:
24418 case TYPE_STORE_UX:
24419 case TYPE_FPLOAD_U:
24420 case TYPE_FPLOAD_UX:
24421 case TYPE_FPSTORE_U:
24422 case TYPE_FPSTORE_UX:
24428 case PROCESSOR_POWER7:
24429 type = get_attr_type (insn);
24433 case TYPE_CR_LOGICAL:
24440 case TYPE_DELAYED_COMPARE:
24441 case TYPE_VAR_DELAYED_COMPARE:
24447 case TYPE_LOAD_EXT:
24448 case TYPE_LOAD_EXT_U:
24449 case TYPE_LOAD_EXT_UX:
24451 case TYPE_STORE_UX:
24452 case TYPE_FPLOAD_U:
24453 case TYPE_FPLOAD_UX:
24454 case TYPE_FPSTORE_U:
24455 case TYPE_FPSTORE_UX:
24471 insn_must_be_last_in_group (rtx insn)
24473 enum attr_type type;
24476 || GET_CODE (insn) == NOTE
24477 || DEBUG_INSN_P (insn)
24478 || GET_CODE (PATTERN (insn)) == USE
24479 || GET_CODE (PATTERN (insn)) == CLOBBER)
24482 switch (rs6000_cpu) {
24483 case PROCESSOR_POWER4:
24484 case PROCESSOR_POWER5:
24485 if (is_microcoded_insn (insn))
24488 if (is_branch_slot_insn (insn))
24492 case PROCESSOR_POWER6:
24493 type = get_attr_type (insn);
24500 case TYPE_VAR_SHIFT_ROTATE:
24507 case TYPE_DELAYED_COMPARE:
24508 case TYPE_IMUL_COMPARE:
24509 case TYPE_LMUL_COMPARE:
24510 case TYPE_FPCOMPARE:
24524 case PROCESSOR_POWER7:
24525 type = get_attr_type (insn);
24533 case TYPE_LOAD_EXT_U:
24534 case TYPE_LOAD_EXT_UX:
24535 case TYPE_STORE_UX:
24548 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24549 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24552 is_costly_group (rtx *group_insns, rtx next_insn)
24555 int issue_rate = rs6000_issue_rate ();
24557 for (i = 0; i < issue_rate; i++)
24559 sd_iterator_def sd_it;
24561 rtx insn = group_insns[i];
24566 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24568 rtx next = DEP_CON (dep);
24570 if (next == next_insn
24571 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24579 /* Utility of the function redefine_groups.
24580 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24581 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24582 to keep it "far" (in a separate group) from GROUP_INSNS, following
24583 one of the following schemes, depending on the value of the flag
24584 -minsert_sched_nops = X:
24585 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24586 in order to force NEXT_INSN into a separate group.
24587 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24588 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24589 insertion (has a group just ended, how many vacant issue slots remain in the
24590 last group, and how many dispatch groups were encountered so far). */
24593 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24594 rtx next_insn, bool *group_end, int can_issue_more,
24599 int issue_rate = rs6000_issue_rate ();
24600 bool end = *group_end;
24603 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24604 return can_issue_more;
24606 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24607 return can_issue_more;
24609 force = is_costly_group (group_insns, next_insn);
24611 return can_issue_more;
24613 if (sched_verbose > 6)
24614 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24615 *group_count ,can_issue_more);
24617 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24620 can_issue_more = 0;
24622 /* Since only a branch can be issued in the last issue_slot, it is
24623 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24624 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24625 in this case the last nop will start a new group and the branch
24626 will be forced to the new group. */
24627 if (can_issue_more && !is_branch_slot_insn (next_insn))
24630 while (can_issue_more > 0)
24633 emit_insn_before (nop, next_insn);
24641 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24643 int n_nops = rs6000_sched_insert_nops;
24645 /* Nops can't be issued from the branch slot, so the effective
24646 issue_rate for nops is 'issue_rate - 1'. */
24647 if (can_issue_more == 0)
24648 can_issue_more = issue_rate;
24650 if (can_issue_more == 0)
24652 can_issue_more = issue_rate - 1;
24655 for (i = 0; i < issue_rate; i++)
24657 group_insns[i] = 0;
24664 emit_insn_before (nop, next_insn);
24665 if (can_issue_more == issue_rate - 1) /* new group begins */
24668 if (can_issue_more == 0)
24670 can_issue_more = issue_rate - 1;
24673 for (i = 0; i < issue_rate; i++)
24675 group_insns[i] = 0;
24681 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24684 /* Is next_insn going to start a new group? */
24687 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24688 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24689 || (can_issue_more < issue_rate &&
24690 insn_terminates_group_p (next_insn, previous_group)));
24691 if (*group_end && end)
24694 if (sched_verbose > 6)
24695 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24696 *group_count, can_issue_more);
24697 return can_issue_more;
24700 return can_issue_more;
24703 /* This function tries to synch the dispatch groups that the compiler "sees"
24704 with the dispatch groups that the processor dispatcher is expected to
24705 form in practice. It tries to achieve this synchronization by forcing the
24706 estimated processor grouping on the compiler (as opposed to the function
24707 'pad_goups' which tries to force the scheduler's grouping on the processor).
24709 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24710 examines the (estimated) dispatch groups that will be formed by the processor
24711 dispatcher. It marks these group boundaries to reflect the estimated
24712 processor grouping, overriding the grouping that the scheduler had marked.
24713 Depending on the value of the flag '-minsert-sched-nops' this function can
24714 force certain insns into separate groups or force a certain distance between
24715 them by inserting nops, for example, if there exists a "costly dependence"
24718 The function estimates the group boundaries that the processor will form as
24719 follows: It keeps track of how many vacant issue slots are available after
24720 each insn. A subsequent insn will start a new group if one of the following
24722 - no more vacant issue slots remain in the current dispatch group.
24723 - only the last issue slot, which is the branch slot, is vacant, but the next
24724 insn is not a branch.
24725 - only the last 2 or less issue slots, including the branch slot, are vacant,
24726 which means that a cracked insn (which occupies two issue slots) can't be
24727 issued in this group.
24728 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24729 start a new group. */
24732 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24734 rtx insn, next_insn;
24736 int can_issue_more;
24739 int group_count = 0;
24743 issue_rate = rs6000_issue_rate ();
24744 group_insns = XALLOCAVEC (rtx, issue_rate);
24745 for (i = 0; i < issue_rate; i++)
24747 group_insns[i] = 0;
24749 can_issue_more = issue_rate;
24751 insn = get_next_active_insn (prev_head_insn, tail);
24754 while (insn != NULL_RTX)
24756 slot = (issue_rate - can_issue_more);
24757 group_insns[slot] = insn;
24759 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24760 if (insn_terminates_group_p (insn, current_group))
24761 can_issue_more = 0;
24763 next_insn = get_next_active_insn (insn, tail);
24764 if (next_insn == NULL_RTX)
24765 return group_count + 1;
24767 /* Is next_insn going to start a new group? */
24769 = (can_issue_more == 0
24770 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24771 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24772 || (can_issue_more < issue_rate &&
24773 insn_terminates_group_p (next_insn, previous_group)));
24775 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24776 next_insn, &group_end, can_issue_more,
24782 can_issue_more = 0;
24783 for (i = 0; i < issue_rate; i++)
24785 group_insns[i] = 0;
24789 if (GET_MODE (next_insn) == TImode && can_issue_more)
24790 PUT_MODE (next_insn, VOIDmode);
24791 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24792 PUT_MODE (next_insn, TImode);
24795 if (can_issue_more == 0)
24796 can_issue_more = issue_rate;
24799 return group_count;
24802 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24803 dispatch group boundaries that the scheduler had marked. Pad with nops
24804 any dispatch groups which have vacant issue slots, in order to force the
24805 scheduler's grouping on the processor dispatcher. The function
24806 returns the number of dispatch groups found. */
24809 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24811 rtx insn, next_insn;
24814 int can_issue_more;
24816 int group_count = 0;
24818 /* Initialize issue_rate. */
24819 issue_rate = rs6000_issue_rate ();
24820 can_issue_more = issue_rate;
24822 insn = get_next_active_insn (prev_head_insn, tail);
24823 next_insn = get_next_active_insn (insn, tail);
24825 while (insn != NULL_RTX)
24828 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24830 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24832 if (next_insn == NULL_RTX)
24837 /* If the scheduler had marked group termination at this location
24838 (between insn and next_insn), and neither insn nor next_insn will
24839 force group termination, pad the group with nops to force group
24842 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24843 && !insn_terminates_group_p (insn, current_group)
24844 && !insn_terminates_group_p (next_insn, previous_group))
24846 if (!is_branch_slot_insn (next_insn))
24849 while (can_issue_more)
24852 emit_insn_before (nop, next_insn);
24857 can_issue_more = issue_rate;
24862 next_insn = get_next_active_insn (insn, tail);
24865 return group_count;
24868 /* We're beginning a new block. Initialize data structures as necessary. */
24871 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24872 int sched_verbose ATTRIBUTE_UNUSED,
24873 int max_ready ATTRIBUTE_UNUSED)
24875 last_scheduled_insn = NULL_RTX;
24876 load_store_pendulum = 0;
24879 /* The following function is called at the end of scheduling BB.
24880 After reload, it inserts nops at insn group bundling. */
24883 rs6000_sched_finish (FILE *dump, int sched_verbose)
24888 fprintf (dump, "=== Finishing schedule.\n");
24890 if (reload_completed && rs6000_sched_groups)
24892 /* Do not run sched_finish hook when selective scheduling enabled. */
24893 if (sel_sched_p ())
24896 if (rs6000_sched_insert_nops == sched_finish_none)
24899 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24900 n_groups = pad_groups (dump, sched_verbose,
24901 current_sched_info->prev_head,
24902 current_sched_info->next_tail);
24904 n_groups = redefine_groups (dump, sched_verbose,
24905 current_sched_info->prev_head,
24906 current_sched_info->next_tail);
24908 if (sched_verbose >= 6)
24910 fprintf (dump, "ngroups = %d\n", n_groups);
24911 print_rtl (dump, current_sched_info->prev_head);
24912 fprintf (dump, "Done finish_sched\n");
24917 struct _rs6000_sched_context
24919 short cached_can_issue_more;
24920 rtx last_scheduled_insn;
24921 int load_store_pendulum;
24924 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24925 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24927 /* Allocate store for new scheduling context. */
24929 rs6000_alloc_sched_context (void)
24931 return xmalloc (sizeof (rs6000_sched_context_def));
24934 /* If CLEAN_P is true then initializes _SC with clean data,
24935 and from the global context otherwise. */
24937 rs6000_init_sched_context (void *_sc, bool clean_p)
24939 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24943 sc->cached_can_issue_more = 0;
24944 sc->last_scheduled_insn = NULL_RTX;
24945 sc->load_store_pendulum = 0;
24949 sc->cached_can_issue_more = cached_can_issue_more;
24950 sc->last_scheduled_insn = last_scheduled_insn;
24951 sc->load_store_pendulum = load_store_pendulum;
24955 /* Sets the global scheduling context to the one pointed to by _SC. */
24957 rs6000_set_sched_context (void *_sc)
24959 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24961 gcc_assert (sc != NULL);
24963 cached_can_issue_more = sc->cached_can_issue_more;
24964 last_scheduled_insn = sc->last_scheduled_insn;
24965 load_store_pendulum = sc->load_store_pendulum;
24970 rs6000_free_sched_context (void *_sc)
24972 gcc_assert (_sc != NULL);
24978 /* Length in units of the trampoline for entering a nested function. */
24981 rs6000_trampoline_size (void)
24985 switch (DEFAULT_ABI)
24988 gcc_unreachable ();
24991 ret = (TARGET_32BIT) ? 12 : 24;
24996 ret = (TARGET_32BIT) ? 40 : 48;
25003 /* Emit RTL insns to initialize the variable parts of a trampoline.
25004 FNADDR is an RTX for the address of the function's pure code.
25005 CXT is an RTX for the static chain value for the function. */
25008 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
25010 int regsize = (TARGET_32BIT) ? 4 : 8;
25011 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
25012 rtx ctx_reg = force_reg (Pmode, cxt);
25013 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
25015 switch (DEFAULT_ABI)
25018 gcc_unreachable ();
25020 /* Under AIX, just build the 3 word function descriptor */
25023 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
25024 rtx fn_reg = gen_reg_rtx (Pmode);
25025 rtx toc_reg = gen_reg_rtx (Pmode);
25027 /* Macro to shorten the code expansions below. */
25028 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25030 m_tramp = replace_equiv_address (m_tramp, addr);
25032 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25033 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25034 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25035 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25036 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25042 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25045 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25046 LCT_NORMAL, VOIDmode, 4,
25048 GEN_INT (rs6000_trampoline_size ()), SImode,
25056 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25057 identifier as an argument, so the front end shouldn't look it up. */
25060 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25062 return is_attribute_p ("altivec", attr_id);
25065 /* Handle the "altivec" attribute. The attribute may have
25066 arguments as follows:
25068 __attribute__((altivec(vector__)))
25069 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25070 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25072 and may appear more than once (e.g., 'vector bool char') in a
25073 given declaration. */
25076 rs6000_handle_altivec_attribute (tree *node,
25077 tree name ATTRIBUTE_UNUSED,
25079 int flags ATTRIBUTE_UNUSED,
25080 bool *no_add_attrs)
25082 tree type = *node, result = NULL_TREE;
25083 enum machine_mode mode;
25086 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25087 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25088 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25091 while (POINTER_TYPE_P (type)
25092 || TREE_CODE (type) == FUNCTION_TYPE
25093 || TREE_CODE (type) == METHOD_TYPE
25094 || TREE_CODE (type) == ARRAY_TYPE)
25095 type = TREE_TYPE (type);
25097 mode = TYPE_MODE (type);
25099 /* Check for invalid AltiVec type qualifiers. */
25100 if (type == long_double_type_node)
25101 error ("use of %<long double%> in AltiVec types is invalid");
25102 else if (type == boolean_type_node)
25103 error ("use of boolean types in AltiVec types is invalid");
25104 else if (TREE_CODE (type) == COMPLEX_TYPE)
25105 error ("use of %<complex%> in AltiVec types is invalid");
25106 else if (DECIMAL_FLOAT_MODE_P (mode))
25107 error ("use of decimal floating point types in AltiVec types is invalid");
25108 else if (!TARGET_VSX)
25110 if (type == long_unsigned_type_node || type == long_integer_type_node)
25113 error ("use of %<long%> in AltiVec types is invalid for "
25114 "64-bit code without -mvsx");
25115 else if (rs6000_warn_altivec_long)
25116 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25119 else if (type == long_long_unsigned_type_node
25120 || type == long_long_integer_type_node)
25121 error ("use of %<long long%> in AltiVec types is invalid without "
25123 else if (type == double_type_node)
25124 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25127 switch (altivec_type)
25130 unsigned_p = TYPE_UNSIGNED (type);
25134 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25137 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25140 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25143 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25145 case SFmode: result = V4SF_type_node; break;
25146 case DFmode: result = V2DF_type_node; break;
25147 /* If the user says 'vector int bool', we may be handed the 'bool'
25148 attribute _before_ the 'vector' attribute, and so select the
25149 proper type in the 'b' case below. */
25150 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25151 case V2DImode: case V2DFmode:
25159 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25160 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25161 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25162 case QImode: case V16QImode: result = bool_V16QI_type_node;
25169 case V8HImode: result = pixel_V8HI_type_node;
25175 /* Propagate qualifiers attached to the element type
25176 onto the vector type. */
25177 if (result && result != type && TYPE_QUALS (type))
25178 result = build_qualified_type (result, TYPE_QUALS (type));
25180 *no_add_attrs = true; /* No need to hang on to the attribute. */
25183 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25188 /* AltiVec defines four built-in scalar types that serve as vector
25189 elements; we must teach the compiler how to mangle them. */
25191 static const char *
25192 rs6000_mangle_type (const_tree type)
25194 type = TYPE_MAIN_VARIANT (type);
25196 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25197 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25200 if (type == bool_char_type_node) return "U6__boolc";
25201 if (type == bool_short_type_node) return "U6__bools";
25202 if (type == pixel_type_node) return "u7__pixel";
25203 if (type == bool_int_type_node) return "U6__booli";
25204 if (type == bool_long_type_node) return "U6__booll";
25206 /* Mangle IBM extended float long double as `g' (__float128) on
25207 powerpc*-linux where long-double-64 previously was the default. */
25208 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25210 && TARGET_LONG_DOUBLE_128
25211 && !TARGET_IEEEQUAD)
25214 /* For all other types, use normal C++ mangling. */
25218 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25219 struct attribute_spec.handler. */
25222 rs6000_handle_longcall_attribute (tree *node, tree name,
25223 tree args ATTRIBUTE_UNUSED,
25224 int flags ATTRIBUTE_UNUSED,
25225 bool *no_add_attrs)
25227 if (TREE_CODE (*node) != FUNCTION_TYPE
25228 && TREE_CODE (*node) != FIELD_DECL
25229 && TREE_CODE (*node) != TYPE_DECL)
25231 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25233 *no_add_attrs = true;
25239 /* Set longcall attributes on all functions declared when
25240 rs6000_default_long_calls is true. */
25242 rs6000_set_default_type_attributes (tree type)
25244 if (rs6000_default_long_calls
25245 && (TREE_CODE (type) == FUNCTION_TYPE
25246 || TREE_CODE (type) == METHOD_TYPE))
25247 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25249 TYPE_ATTRIBUTES (type));
25252 darwin_set_default_type_attributes (type);
25256 /* Return a reference suitable for calling a function with the
25257 longcall attribute. */
25260 rs6000_longcall_ref (rtx call_ref)
25262 const char *call_name;
25265 if (GET_CODE (call_ref) != SYMBOL_REF)
25268 /* System V adds '.' to the internal name, so skip them. */
25269 call_name = XSTR (call_ref, 0);
25270 if (*call_name == '.')
25272 while (*call_name == '.')
25275 node = get_identifier (call_name);
25276 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25279 return force_reg (Pmode, call_ref);
25282 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25283 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25286 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25287 struct attribute_spec.handler. */
25289 rs6000_handle_struct_attribute (tree *node, tree name,
25290 tree args ATTRIBUTE_UNUSED,
25291 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25294 if (DECL_P (*node))
25296 if (TREE_CODE (*node) == TYPE_DECL)
25297 type = &TREE_TYPE (*node);
25302 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25303 || TREE_CODE (*type) == UNION_TYPE)))
25305 warning (OPT_Wattributes, "%qE attribute ignored", name);
25306 *no_add_attrs = true;
25309 else if ((is_attribute_p ("ms_struct", name)
25310 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25311 || ((is_attribute_p ("gcc_struct", name)
25312 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25314 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25316 *no_add_attrs = true;
25323 rs6000_ms_bitfield_layout_p (const_tree record_type)
25325 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25326 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25327 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25330 #ifdef USING_ELFOS_H
25332 /* A get_unnamed_section callback, used for switching to toc_section. */
25335 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25337 if (DEFAULT_ABI == ABI_AIX
25338 && TARGET_MINIMAL_TOC
25339 && !TARGET_RELOCATABLE)
25341 if (!toc_initialized)
25343 toc_initialized = 1;
25344 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25345 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25346 fprintf (asm_out_file, "\t.tc ");
25347 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25348 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25349 fprintf (asm_out_file, "\n");
25351 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25352 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25353 fprintf (asm_out_file, " = .+32768\n");
25356 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25358 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25359 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25362 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25363 if (!toc_initialized)
25365 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25366 fprintf (asm_out_file, " = .+32768\n");
25367 toc_initialized = 1;
25372 /* Implement TARGET_ASM_INIT_SECTIONS. */
25375 rs6000_elf_asm_init_sections (void)
25378 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25381 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25382 SDATA2_SECTION_ASM_OP);
25385 /* Implement TARGET_SELECT_RTX_SECTION. */
25388 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25389 unsigned HOST_WIDE_INT align)
25391 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25392 return toc_section;
25394 return default_elf_select_rtx_section (mode, x, align);
25397 /* For a SYMBOL_REF, set generic flags and then perform some
25398 target-specific processing.
25400 When the AIX ABI is requested on a non-AIX system, replace the
25401 function name with the real name (with a leading .) rather than the
25402 function descriptor name. This saves a lot of overriding code to
25403 read the prefixes. */
25406 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25408 default_encode_section_info (decl, rtl, first);
25411 && TREE_CODE (decl) == FUNCTION_DECL
25413 && DEFAULT_ABI == ABI_AIX)
25415 rtx sym_ref = XEXP (rtl, 0);
25416 size_t len = strlen (XSTR (sym_ref, 0));
25417 char *str = XALLOCAVEC (char, len + 2);
25419 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25420 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25425 compare_section_name (const char *section, const char *templ)
25429 len = strlen (templ);
25430 return (strncmp (section, templ, len) == 0
25431 && (section[len] == 0 || section[len] == '.'));
25435 rs6000_elf_in_small_data_p (const_tree decl)
25437 if (rs6000_sdata == SDATA_NONE)
25440 /* We want to merge strings, so we never consider them small data. */
25441 if (TREE_CODE (decl) == STRING_CST)
25444 /* Functions are never in the small data area. */
25445 if (TREE_CODE (decl) == FUNCTION_DECL)
25448 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25450 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25451 if (compare_section_name (section, ".sdata")
25452 || compare_section_name (section, ".sdata2")
25453 || compare_section_name (section, ".gnu.linkonce.s")
25454 || compare_section_name (section, ".sbss")
25455 || compare_section_name (section, ".sbss2")
25456 || compare_section_name (section, ".gnu.linkonce.sb")
25457 || strcmp (section, ".PPC.EMB.sdata0") == 0
25458 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25463 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25466 && size <= g_switch_value
25467 /* If it's not public, and we're not going to reference it there,
25468 there's no need to put it in the small data section. */
25469 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25476 #endif /* USING_ELFOS_H */
25478 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25481 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25483 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25486 /* Return a REG that occurs in ADDR with coefficient 1.
25487 ADDR can be effectively incremented by incrementing REG.
25489 r0 is special and we must not select it as an address
25490 register by this routine since our caller will try to
25491 increment the returned register via an "la" instruction. */
25494 find_addr_reg (rtx addr)
25496 while (GET_CODE (addr) == PLUS)
25498 if (GET_CODE (XEXP (addr, 0)) == REG
25499 && REGNO (XEXP (addr, 0)) != 0)
25500 addr = XEXP (addr, 0);
25501 else if (GET_CODE (XEXP (addr, 1)) == REG
25502 && REGNO (XEXP (addr, 1)) != 0)
25503 addr = XEXP (addr, 1);
25504 else if (CONSTANT_P (XEXP (addr, 0)))
25505 addr = XEXP (addr, 1);
25506 else if (CONSTANT_P (XEXP (addr, 1)))
25507 addr = XEXP (addr, 0);
25509 gcc_unreachable ();
25511 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25516 rs6000_fatal_bad_address (rtx op)
25518 fatal_insn ("bad address", op);
25523 typedef struct branch_island_d {
25524 tree function_name;
25529 DEF_VEC_O(branch_island);
25530 DEF_VEC_ALLOC_O(branch_island,gc);
25532 static VEC(branch_island,gc) *branch_islands;
25534 /* Remember to generate a branch island for far calls to the given
25538 add_compiler_branch_island (tree label_name, tree function_name,
25541 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25543 bi->function_name = function_name;
25544 bi->label_name = label_name;
25545 bi->line_number = line_number;
25548 /* Generate far-jump branch islands for everything recorded in
25549 branch_islands. Invoked immediately after the last instruction of
25550 the epilogue has been emitted; the branch islands must be appended
25551 to, and contiguous with, the function body. Mach-O stubs are
25552 generated in machopic_output_stub(). */
25555 macho_branch_islands (void)
25559 while (!VEC_empty (branch_island, branch_islands))
25561 branch_island *bi = VEC_last (branch_island, branch_islands);
25562 const char *label = IDENTIFIER_POINTER (bi->label_name);
25563 const char *name = IDENTIFIER_POINTER (bi->function_name);
25564 char name_buf[512];
25565 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25566 if (name[0] == '*' || name[0] == '&')
25567 strcpy (name_buf, name+1);
25571 strcpy (name_buf+1, name);
25573 strcpy (tmp_buf, "\n");
25574 strcat (tmp_buf, label);
25575 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25576 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25577 dbxout_stabd (N_SLINE, bi->line_number);
25578 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25581 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25582 strcat (tmp_buf, label);
25583 strcat (tmp_buf, "_pic\n");
25584 strcat (tmp_buf, label);
25585 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25587 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25588 strcat (tmp_buf, name_buf);
25589 strcat (tmp_buf, " - ");
25590 strcat (tmp_buf, label);
25591 strcat (tmp_buf, "_pic)\n");
25593 strcat (tmp_buf, "\tmtlr r0\n");
25595 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25596 strcat (tmp_buf, name_buf);
25597 strcat (tmp_buf, " - ");
25598 strcat (tmp_buf, label);
25599 strcat (tmp_buf, "_pic)\n");
25601 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25605 strcat (tmp_buf, ":\nlis r12,hi16(");
25606 strcat (tmp_buf, name_buf);
25607 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25608 strcat (tmp_buf, name_buf);
25609 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25611 output_asm_insn (tmp_buf, 0);
25612 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25613 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25614 dbxout_stabd (N_SLINE, bi->line_number);
25615 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25616 VEC_pop (branch_island, branch_islands);
25620 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25621 already there or not. */
25624 no_previous_def (tree function_name)
25629 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25630 if (function_name == bi->function_name)
25635 /* GET_PREV_LABEL gets the label name from the previous definition of
25639 get_prev_label (tree function_name)
25644 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25645 if (function_name == bi->function_name)
25646 return bi->label_name;
25650 /* INSN is either a function call or a millicode call. It may have an
25651 unconditional jump in its delay slot.
25653 CALL_DEST is the routine we are calling. */
25656 output_call (rtx insn, rtx *operands, int dest_operand_number,
25657 int cookie_operand_number)
25659 static char buf[256];
25660 if (darwin_emit_branch_islands
25661 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25662 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25665 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25667 if (no_previous_def (funname))
25669 rtx label_rtx = gen_label_rtx ();
25670 char *label_buf, temp_buf[256];
25671 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25672 CODE_LABEL_NUMBER (label_rtx));
25673 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25674 labelname = get_identifier (label_buf);
25675 add_compiler_branch_island (labelname, funname, insn_line (insn));
25678 labelname = get_prev_label (funname);
25680 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25681 instruction will reach 'foo', otherwise link as 'bl L42'".
25682 "L42" should be a 'branch island', that will do a far jump to
25683 'foo'. Branch islands are generated in
25684 macho_branch_islands(). */
25685 sprintf (buf, "jbsr %%z%d,%.246s",
25686 dest_operand_number, IDENTIFIER_POINTER (labelname));
25689 sprintf (buf, "bl %%z%d", dest_operand_number);
25693 /* Generate PIC and indirect symbol stubs. */
25696 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25698 unsigned int length;
25699 char *symbol_name, *lazy_ptr_name;
25700 char *local_label_0;
25701 static int label = 0;
25703 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25704 symb = (*targetm.strip_name_encoding) (symb);
25707 length = strlen (symb);
25708 symbol_name = XALLOCAVEC (char, length + 32);
25709 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25711 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25712 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25715 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25717 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25721 fprintf (file, "\t.align 5\n");
25723 fprintf (file, "%s:\n", stub);
25724 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25727 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25728 sprintf (local_label_0, "\"L%011d$spb\"", label);
25730 fprintf (file, "\tmflr r0\n");
25731 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25732 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25733 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25734 lazy_ptr_name, local_label_0);
25735 fprintf (file, "\tmtlr r0\n");
25736 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25737 (TARGET_64BIT ? "ldu" : "lwzu"),
25738 lazy_ptr_name, local_label_0);
25739 fprintf (file, "\tmtctr r12\n");
25740 fprintf (file, "\tbctr\n");
25744 fprintf (file, "\t.align 4\n");
25746 fprintf (file, "%s:\n", stub);
25747 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25749 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25750 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25751 (TARGET_64BIT ? "ldu" : "lwzu"),
25753 fprintf (file, "\tmtctr r12\n");
25754 fprintf (file, "\tbctr\n");
25757 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25758 fprintf (file, "%s:\n", lazy_ptr_name);
25759 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25760 fprintf (file, "%sdyld_stub_binding_helper\n",
25761 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25764 /* Legitimize PIC addresses. If the address is already
25765 position-independent, we return ORIG. Newly generated
25766 position-independent addresses go into a reg. This is REG if non
25767 zero, otherwise we allocate register(s) as necessary. */
25769 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25772 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25777 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25778 reg = gen_reg_rtx (Pmode);
25780 if (GET_CODE (orig) == CONST)
25784 if (GET_CODE (XEXP (orig, 0)) == PLUS
25785 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25788 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25790 /* Use a different reg for the intermediate value, as
25791 it will be marked UNCHANGING. */
25792 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25793 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25796 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25799 if (GET_CODE (offset) == CONST_INT)
25801 if (SMALL_INT (offset))
25802 return plus_constant (base, INTVAL (offset));
25803 else if (! reload_in_progress && ! reload_completed)
25804 offset = force_reg (Pmode, offset);
25807 rtx mem = force_const_mem (Pmode, orig);
25808 return machopic_legitimize_pic_address (mem, Pmode, reg);
25811 return gen_rtx_PLUS (Pmode, base, offset);
25814 /* Fall back on generic machopic code. */
25815 return machopic_legitimize_pic_address (orig, mode, reg);
25818 /* Output a .machine directive for the Darwin assembler, and call
25819 the generic start_file routine. */
25822 rs6000_darwin_file_start (void)
25824 static const struct
25830 { "ppc64", "ppc64", MASK_64BIT },
25831 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25832 { "power4", "ppc970", 0 },
25833 { "G5", "ppc970", 0 },
25834 { "7450", "ppc7450", 0 },
25835 { "7400", "ppc7400", MASK_ALTIVEC },
25836 { "G4", "ppc7400", 0 },
25837 { "750", "ppc750", 0 },
25838 { "740", "ppc750", 0 },
25839 { "G3", "ppc750", 0 },
25840 { "604e", "ppc604e", 0 },
25841 { "604", "ppc604", 0 },
25842 { "603e", "ppc603", 0 },
25843 { "603", "ppc603", 0 },
25844 { "601", "ppc601", 0 },
25845 { NULL, "ppc", 0 } };
25846 const char *cpu_id = "";
25849 rs6000_file_start ();
25850 darwin_file_start ();
25852 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25853 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25854 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25855 && rs6000_select[i].string[0] != '\0')
25856 cpu_id = rs6000_select[i].string;
25858 /* Look through the mapping array. Pick the first name that either
25859 matches the argument, has a bit set in IF_SET that is also set
25860 in the target flags, or has a NULL name. */
25863 while (mapping[i].arg != NULL
25864 && strcmp (mapping[i].arg, cpu_id) != 0
25865 && (mapping[i].if_set & target_flags) == 0)
25868 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25871 #endif /* TARGET_MACHO */
25875 rs6000_elf_reloc_rw_mask (void)
25879 else if (DEFAULT_ABI == ABI_AIX)
25885 /* Record an element in the table of global constructors. SYMBOL is
25886 a SYMBOL_REF of the function to be called; PRIORITY is a number
25887 between 0 and MAX_INIT_PRIORITY.
25889 This differs from default_named_section_asm_out_constructor in
25890 that we have special handling for -mrelocatable. */
25893 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25895 const char *section = ".ctors";
25898 if (priority != DEFAULT_INIT_PRIORITY)
25900 sprintf (buf, ".ctors.%.5u",
25901 /* Invert the numbering so the linker puts us in the proper
25902 order; constructors are run from right to left, and the
25903 linker sorts in increasing order. */
25904 MAX_INIT_PRIORITY - priority);
25908 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25909 assemble_align (POINTER_SIZE);
25911 if (TARGET_RELOCATABLE)
25913 fputs ("\t.long (", asm_out_file);
25914 output_addr_const (asm_out_file, symbol);
25915 fputs (")@fixup\n", asm_out_file);
25918 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25922 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25924 const char *section = ".dtors";
25927 if (priority != DEFAULT_INIT_PRIORITY)
25929 sprintf (buf, ".dtors.%.5u",
25930 /* Invert the numbering so the linker puts us in the proper
25931 order; constructors are run from right to left, and the
25932 linker sorts in increasing order. */
25933 MAX_INIT_PRIORITY - priority);
25937 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25938 assemble_align (POINTER_SIZE);
25940 if (TARGET_RELOCATABLE)
25942 fputs ("\t.long (", asm_out_file);
25943 output_addr_const (asm_out_file, symbol);
25944 fputs (")@fixup\n", asm_out_file);
25947 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25951 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25955 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25956 ASM_OUTPUT_LABEL (file, name);
25957 fputs (DOUBLE_INT_ASM_OP, file);
25958 rs6000_output_function_entry (file, name);
25959 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25962 fputs ("\t.size\t", file);
25963 assemble_name (file, name);
25964 fputs (",24\n\t.type\t.", file);
25965 assemble_name (file, name);
25966 fputs (",@function\n", file);
25967 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25969 fputs ("\t.globl\t.", file);
25970 assemble_name (file, name);
25975 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25976 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25977 rs6000_output_function_entry (file, name);
25978 fputs (":\n", file);
25982 if (TARGET_RELOCATABLE
25983 && !TARGET_SECURE_PLT
25984 && (get_pool_size () != 0 || crtl->profile)
25989 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25991 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25992 fprintf (file, "\t.long ");
25993 assemble_name (file, buf);
25995 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
25996 assemble_name (file, buf);
26000 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
26001 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
26003 if (DEFAULT_ABI == ABI_AIX)
26005 const char *desc_name, *orig_name;
26007 orig_name = (*targetm.strip_name_encoding) (name);
26008 desc_name = orig_name;
26009 while (*desc_name == '.')
26012 if (TREE_PUBLIC (decl))
26013 fprintf (file, "\t.globl %s\n", desc_name);
26015 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
26016 fprintf (file, "%s:\n", desc_name);
26017 fprintf (file, "\t.long %s\n", orig_name);
26018 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
26019 if (DEFAULT_ABI == ABI_AIX)
26020 fputs ("\t.long 0\n", file);
26021 fprintf (file, "\t.previous\n");
26023 ASM_OUTPUT_LABEL (file, name);
26027 rs6000_elf_file_end (void)
26029 #ifdef HAVE_AS_GNU_ATTRIBUTE
26030 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26032 if (rs6000_passes_float)
26033 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26034 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26035 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26037 if (rs6000_passes_vector)
26038 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26039 (TARGET_ALTIVEC_ABI ? 2
26040 : TARGET_SPE_ABI ? 3
26042 if (rs6000_returns_struct)
26043 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26044 aix_struct_return ? 2 : 1);
26047 #ifdef POWERPC_LINUX
26049 file_end_indicate_exec_stack ();
26056 rs6000_xcoff_asm_output_anchor (rtx symbol)
26060 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26061 SYMBOL_REF_BLOCK_OFFSET (symbol));
26062 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26066 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26068 fputs (GLOBAL_ASM_OP, stream);
26069 RS6000_OUTPUT_BASENAME (stream, name);
26070 putc ('\n', stream);
26073 /* A get_unnamed_decl callback, used for read-only sections. PTR
26074 points to the section string variable. */
26077 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26079 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26080 *(const char *const *) directive,
26081 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26084 /* Likewise for read-write sections. */
26087 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26089 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26090 *(const char *const *) directive,
26091 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26094 /* A get_unnamed_section callback, used for switching to toc_section. */
26097 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26099 if (TARGET_MINIMAL_TOC)
26101 /* toc_section is always selected at least once from
26102 rs6000_xcoff_file_start, so this is guaranteed to
26103 always be defined once and only once in each file. */
26104 if (!toc_initialized)
26106 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26107 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26108 toc_initialized = 1;
26110 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26111 (TARGET_32BIT ? "" : ",3"));
26114 fputs ("\t.toc\n", asm_out_file);
26117 /* Implement TARGET_ASM_INIT_SECTIONS. */
26120 rs6000_xcoff_asm_init_sections (void)
26122 read_only_data_section
26123 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26124 &xcoff_read_only_section_name);
26126 private_data_section
26127 = get_unnamed_section (SECTION_WRITE,
26128 rs6000_xcoff_output_readwrite_section_asm_op,
26129 &xcoff_private_data_section_name);
26131 read_only_private_data_section
26132 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26133 &xcoff_private_data_section_name);
26136 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26138 readonly_data_section = read_only_data_section;
26139 exception_section = data_section;
26143 rs6000_xcoff_reloc_rw_mask (void)
26149 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26150 tree decl ATTRIBUTE_UNUSED)
26153 static const char * const suffix[3] = { "PR", "RO", "RW" };
26155 if (flags & SECTION_CODE)
26157 else if (flags & SECTION_WRITE)
26162 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26163 (flags & SECTION_CODE) ? "." : "",
26164 name, suffix[smclass], flags & SECTION_ENTSIZE);
26168 rs6000_xcoff_select_section (tree decl, int reloc,
26169 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26171 if (decl_readonly_section (decl, reloc))
26173 if (TREE_PUBLIC (decl))
26174 return read_only_data_section;
26176 return read_only_private_data_section;
26180 if (TREE_PUBLIC (decl))
26181 return data_section;
26183 return private_data_section;
26188 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26192 /* Use select_section for private and uninitialized data. */
26193 if (!TREE_PUBLIC (decl)
26194 || DECL_COMMON (decl)
26195 || DECL_INITIAL (decl) == NULL_TREE
26196 || DECL_INITIAL (decl) == error_mark_node
26197 || (flag_zero_initialized_in_bss
26198 && initializer_zerop (DECL_INITIAL (decl))))
26201 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26202 name = (*targetm.strip_name_encoding) (name);
26203 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26206 /* Select section for constant in constant pool.
26208 On RS/6000, all constants are in the private read-only data area.
26209 However, if this is being placed in the TOC it must be output as a
26213 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26214 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26216 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26217 return toc_section;
26219 return read_only_private_data_section;
26222 /* Remove any trailing [DS] or the like from the symbol name. */
26224 static const char *
26225 rs6000_xcoff_strip_name_encoding (const char *name)
26230 len = strlen (name);
26231 if (name[len - 1] == ']')
26232 return ggc_alloc_string (name, len - 4);
26237 /* Section attributes. AIX is always PIC. */
26239 static unsigned int
26240 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26242 unsigned int align;
26243 unsigned int flags = default_section_type_flags (decl, name, reloc);
26245 /* Align to at least UNIT size. */
26246 if (flags & SECTION_CODE)
26247 align = MIN_UNITS_PER_WORD;
26249 /* Increase alignment of large objects if not already stricter. */
26250 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26251 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26252 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26254 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26257 /* Output at beginning of assembler file.
26259 Initialize the section names for the RS/6000 at this point.
26261 Specify filename, including full path, to assembler.
26263 We want to go into the TOC section so at least one .toc will be emitted.
26264 Also, in order to output proper .bs/.es pairs, we need at least one static
26265 [RW] section emitted.
26267 Finally, declare mcount when profiling to make the assembler happy. */
26270 rs6000_xcoff_file_start (void)
26272 rs6000_gen_section_name (&xcoff_bss_section_name,
26273 main_input_filename, ".bss_");
26274 rs6000_gen_section_name (&xcoff_private_data_section_name,
26275 main_input_filename, ".rw_");
26276 rs6000_gen_section_name (&xcoff_read_only_section_name,
26277 main_input_filename, ".ro_");
26279 fputs ("\t.file\t", asm_out_file);
26280 output_quoted_string (asm_out_file, main_input_filename);
26281 fputc ('\n', asm_out_file);
26282 if (write_symbols != NO_DEBUG)
26283 switch_to_section (private_data_section);
26284 switch_to_section (text_section);
26286 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26287 rs6000_file_start ();
26290 /* Output at end of assembler file.
26291 On the RS/6000, referencing data should automatically pull in text. */
26294 rs6000_xcoff_file_end (void)
26296 switch_to_section (text_section);
26297 fputs ("_section_.text:\n", asm_out_file);
26298 switch_to_section (data_section);
26299 fputs (TARGET_32BIT
26300 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26303 #endif /* TARGET_XCOFF */
26305 /* Compute a (partial) cost for rtx X. Return true if the complete
26306 cost has been computed, and false if subexpressions should be
26307 scanned. In either case, *TOTAL contains the cost result. */
26310 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26313 enum machine_mode mode = GET_MODE (x);
26317 /* On the RS/6000, if it is valid in the insn, it is free. */
26319 if (((outer_code == SET
26320 || outer_code == PLUS
26321 || outer_code == MINUS)
26322 && (satisfies_constraint_I (x)
26323 || satisfies_constraint_L (x)))
26324 || (outer_code == AND
26325 && (satisfies_constraint_K (x)
26327 ? satisfies_constraint_L (x)
26328 : satisfies_constraint_J (x))
26329 || mask_operand (x, mode)
26331 && mask64_operand (x, DImode))))
26332 || ((outer_code == IOR || outer_code == XOR)
26333 && (satisfies_constraint_K (x)
26335 ? satisfies_constraint_L (x)
26336 : satisfies_constraint_J (x))))
26337 || outer_code == ASHIFT
26338 || outer_code == ASHIFTRT
26339 || outer_code == LSHIFTRT
26340 || outer_code == ROTATE
26341 || outer_code == ROTATERT
26342 || outer_code == ZERO_EXTRACT
26343 || (outer_code == MULT
26344 && satisfies_constraint_I (x))
26345 || ((outer_code == DIV || outer_code == UDIV
26346 || outer_code == MOD || outer_code == UMOD)
26347 && exact_log2 (INTVAL (x)) >= 0)
26348 || (outer_code == COMPARE
26349 && (satisfies_constraint_I (x)
26350 || satisfies_constraint_K (x)))
26351 || ((outer_code == EQ || outer_code == NE)
26352 && (satisfies_constraint_I (x)
26353 || satisfies_constraint_K (x)
26355 ? satisfies_constraint_L (x)
26356 : satisfies_constraint_J (x))))
26357 || (outer_code == GTU
26358 && satisfies_constraint_I (x))
26359 || (outer_code == LTU
26360 && satisfies_constraint_P (x)))
26365 else if ((outer_code == PLUS
26366 && reg_or_add_cint_operand (x, VOIDmode))
26367 || (outer_code == MINUS
26368 && reg_or_sub_cint_operand (x, VOIDmode))
26369 || ((outer_code == SET
26370 || outer_code == IOR
26371 || outer_code == XOR)
26373 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26375 *total = COSTS_N_INSNS (1);
26381 if (mode == DImode && code == CONST_DOUBLE)
26383 if ((outer_code == IOR || outer_code == XOR)
26384 && CONST_DOUBLE_HIGH (x) == 0
26385 && (CONST_DOUBLE_LOW (x)
26386 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26391 else if ((outer_code == AND && and64_2_operand (x, DImode))
26392 || ((outer_code == SET
26393 || outer_code == IOR
26394 || outer_code == XOR)
26395 && CONST_DOUBLE_HIGH (x) == 0))
26397 *total = COSTS_N_INSNS (1);
26407 /* When optimizing for size, MEM should be slightly more expensive
26408 than generating address, e.g., (plus (reg) (const)).
26409 L1 cache latency is about two instructions. */
26410 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26419 if (FLOAT_MODE_P (mode))
26420 *total = rs6000_cost->fp;
26422 *total = COSTS_N_INSNS (1);
26426 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26427 && satisfies_constraint_I (XEXP (x, 1)))
26429 if (INTVAL (XEXP (x, 1)) >= -256
26430 && INTVAL (XEXP (x, 1)) <= 255)
26431 *total = rs6000_cost->mulsi_const9;
26433 *total = rs6000_cost->mulsi_const;
26435 else if (mode == SFmode)
26436 *total = rs6000_cost->fp;
26437 else if (FLOAT_MODE_P (mode))
26438 *total = rs6000_cost->dmul;
26439 else if (mode == DImode)
26440 *total = rs6000_cost->muldi;
26442 *total = rs6000_cost->mulsi;
26446 if (mode == SFmode)
26447 *total = rs6000_cost->fp;
26449 *total = rs6000_cost->dmul;
26454 if (FLOAT_MODE_P (mode))
26456 *total = mode == DFmode ? rs6000_cost->ddiv
26457 : rs6000_cost->sdiv;
26464 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26465 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26467 if (code == DIV || code == MOD)
26469 *total = COSTS_N_INSNS (2);
26472 *total = COSTS_N_INSNS (1);
26476 if (GET_MODE (XEXP (x, 1)) == DImode)
26477 *total = rs6000_cost->divdi;
26479 *total = rs6000_cost->divsi;
26481 /* Add in shift and subtract for MOD. */
26482 if (code == MOD || code == UMOD)
26483 *total += COSTS_N_INSNS (2);
26488 *total = COSTS_N_INSNS (4);
26492 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26496 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26500 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26512 *total = COSTS_N_INSNS (1);
26520 /* Handle mul_highpart. */
26521 if (outer_code == TRUNCATE
26522 && GET_CODE (XEXP (x, 0)) == MULT)
26524 if (mode == DImode)
26525 *total = rs6000_cost->muldi;
26527 *total = rs6000_cost->mulsi;
26530 else if (outer_code == AND)
26533 *total = COSTS_N_INSNS (1);
26538 if (GET_CODE (XEXP (x, 0)) == MEM)
26541 *total = COSTS_N_INSNS (1);
26547 if (!FLOAT_MODE_P (mode))
26549 *total = COSTS_N_INSNS (1);
26555 case UNSIGNED_FLOAT:
26558 case FLOAT_TRUNCATE:
26559 *total = rs6000_cost->fp;
26563 if (mode == DFmode)
26566 *total = rs6000_cost->fp;
26570 switch (XINT (x, 1))
26573 *total = rs6000_cost->fp;
26585 *total = COSTS_N_INSNS (1);
26588 else if (FLOAT_MODE_P (mode)
26589 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26591 *total = rs6000_cost->fp;
26599 /* Carry bit requires mode == Pmode.
26600 NEG or PLUS already counted so only add one. */
26602 && (outer_code == NEG || outer_code == PLUS))
26604 *total = COSTS_N_INSNS (1);
26607 if (outer_code == SET)
26609 if (XEXP (x, 1) == const0_rtx)
26611 if (TARGET_ISEL && !TARGET_MFCRF)
26612 *total = COSTS_N_INSNS (8);
26614 *total = COSTS_N_INSNS (2);
26617 else if (mode == Pmode)
26619 *total = COSTS_N_INSNS (3);
26628 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26630 if (TARGET_ISEL && !TARGET_MFCRF)
26631 *total = COSTS_N_INSNS (8);
26633 *total = COSTS_N_INSNS (2);
26637 if (outer_code == COMPARE)
26651 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26654 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26657 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26660 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26661 "total = %d, speed = %s, x:\n",
26662 ret ? "complete" : "scan inner",
26663 GET_RTX_NAME (code),
26664 GET_RTX_NAME (outer_code),
26666 speed ? "true" : "false");
26673 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26676 rs6000_debug_address_cost (rtx x, bool speed)
26678 int ret = TARGET_ADDRESS_COST (x, speed);
26680 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26681 ret, speed ? "true" : "false");
26688 /* A C expression returning the cost of moving data from a register of class
26689 CLASS1 to one of CLASS2. */
26692 rs6000_register_move_cost (enum machine_mode mode,
26693 reg_class_t from, reg_class_t to)
26697 /* Moves from/to GENERAL_REGS. */
26698 if (reg_classes_intersect_p (to, GENERAL_REGS)
26699 || reg_classes_intersect_p (from, GENERAL_REGS))
26701 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26704 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26705 ret = (rs6000_memory_move_cost (mode, from, false)
26706 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26708 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26710 else if (from == CR_REGS)
26713 /* Power6 has slower LR/CTR moves so make them more expensive than
26714 memory in order to bias spills to memory .*/
26715 else if (rs6000_cpu == PROCESSOR_POWER6
26716 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26717 ret = 6 * hard_regno_nregs[0][mode];
26720 /* A move will cost one instruction per GPR moved. */
26721 ret = 2 * hard_regno_nregs[0][mode];
26724 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26725 else if (VECTOR_UNIT_VSX_P (mode)
26726 && reg_classes_intersect_p (to, VSX_REGS)
26727 && reg_classes_intersect_p (from, VSX_REGS))
26728 ret = 2 * hard_regno_nregs[32][mode];
26730 /* Moving between two similar registers is just one instruction. */
26731 else if (reg_classes_intersect_p (to, from))
26732 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26734 /* Everything else has to go through GENERAL_REGS. */
26736 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26737 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26739 if (TARGET_DEBUG_COST)
26741 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26742 ret, GET_MODE_NAME (mode), reg_class_names[from],
26743 reg_class_names[to]);
26748 /* A C expressions returning the cost of moving data of MODE from a register to
26752 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26753 bool in ATTRIBUTE_UNUSED)
26757 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26758 ret = 4 * hard_regno_nregs[0][mode];
26759 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26760 ret = 4 * hard_regno_nregs[32][mode];
26761 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26762 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26764 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26766 if (TARGET_DEBUG_COST)
26768 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26769 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26774 /* Returns a code for a target-specific builtin that implements
26775 reciprocal of the function, or NULL_TREE if not available. */
26778 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26779 bool sqrt ATTRIBUTE_UNUSED)
26781 if (optimize_insn_for_size_p ())
26787 case VSX_BUILTIN_XVSQRTDP:
26788 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26791 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26793 case VSX_BUILTIN_XVSQRTSP:
26794 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26797 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26806 case BUILT_IN_SQRT:
26807 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26810 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26812 case BUILT_IN_SQRTF:
26813 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26816 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26823 /* Load up a constant. If the mode is a vector mode, splat the value across
26824 all of the vector elements. */
26827 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26831 if (mode == SFmode || mode == DFmode)
26833 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26834 reg = force_reg (mode, d);
26836 else if (mode == V4SFmode)
26838 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26839 rtvec v = gen_rtvec (4, d, d, d, d);
26840 reg = gen_reg_rtx (mode);
26841 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26843 else if (mode == V2DFmode)
26845 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26846 rtvec v = gen_rtvec (2, d, d);
26847 reg = gen_reg_rtx (mode);
26848 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26851 gcc_unreachable ();
26856 /* Generate an FMA instruction. */
26859 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26861 enum machine_mode mode = GET_MODE (target);
26864 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26865 gcc_assert (dst != NULL);
26868 emit_move_insn (target, dst);
26871 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26874 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26876 enum machine_mode mode = GET_MODE (target);
26879 /* Altivec does not support fms directly;
26880 generate in terms of fma in that case. */
26881 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26882 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26885 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26886 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26888 gcc_assert (dst != NULL);
26891 emit_move_insn (target, dst);
26894 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26897 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26899 enum machine_mode mode = GET_MODE (dst);
26902 /* This is a tad more complicated, since the fnma_optab is for
26903 a different expression: fma(-m1, m2, a), which is the same
26904 thing except in the case of signed zeros.
26906 Fortunately we know that if FMA is supported that FNMSUB is
26907 also supported in the ISA. Just expand it directly. */
26909 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26911 r = gen_rtx_NEG (mode, a);
26912 r = gen_rtx_FMA (mode, m1, m2, r);
26913 r = gen_rtx_NEG (mode, r);
26914 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26917 /* Newton-Raphson approximation of floating point divide with just 2 passes
26918 (either single precision floating point, or newer machines with higher
26919 accuracy estimates). Support both scalar and vector divide. Assumes no
26920 trapping math and finite arguments. */
26923 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26925 enum machine_mode mode = GET_MODE (dst);
26926 rtx x0, e0, e1, y1, u0, v0;
26927 enum insn_code code = optab_handler (smul_optab, mode);
26928 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26929 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26931 gcc_assert (code != CODE_FOR_nothing);
26933 /* x0 = 1./d estimate */
26934 x0 = gen_reg_rtx (mode);
26935 emit_insn (gen_rtx_SET (VOIDmode, x0,
26936 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26939 e0 = gen_reg_rtx (mode);
26940 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26942 e1 = gen_reg_rtx (mode);
26943 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26945 y1 = gen_reg_rtx (mode);
26946 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26948 u0 = gen_reg_rtx (mode);
26949 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26951 v0 = gen_reg_rtx (mode);
26952 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26954 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26957 /* Newton-Raphson approximation of floating point divide that has a low
26958 precision estimate. Assumes no trapping math and finite arguments. */
26961 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26963 enum machine_mode mode = GET_MODE (dst);
26964 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26965 enum insn_code code = optab_handler (smul_optab, mode);
26966 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26968 gcc_assert (code != CODE_FOR_nothing);
26970 one = rs6000_load_constant_and_splat (mode, dconst1);
26972 /* x0 = 1./d estimate */
26973 x0 = gen_reg_rtx (mode);
26974 emit_insn (gen_rtx_SET (VOIDmode, x0,
26975 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26978 e0 = gen_reg_rtx (mode);
26979 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26981 y1 = gen_reg_rtx (mode);
26982 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26984 e1 = gen_reg_rtx (mode);
26985 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26987 y2 = gen_reg_rtx (mode);
26988 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26990 e2 = gen_reg_rtx (mode);
26991 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26993 y3 = gen_reg_rtx (mode);
26994 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
26996 u0 = gen_reg_rtx (mode);
26997 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
26999 v0 = gen_reg_rtx (mode);
27000 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
27002 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
27005 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
27006 add a reg_note saying that this was a division. Support both scalar and
27007 vector divide. Assumes no trapping math and finite arguments. */
27010 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
27012 enum machine_mode mode = GET_MODE (dst);
27014 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
27015 rs6000_emit_swdiv_high_precision (dst, n, d);
27017 rs6000_emit_swdiv_low_precision (dst, n, d);
27020 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
27023 /* Newton-Raphson approximation of single/double-precision floating point
27024 rsqrt. Assumes no trapping math and finite arguments. */
27027 rs6000_emit_swrsqrt (rtx dst, rtx src)
27029 enum machine_mode mode = GET_MODE (src);
27030 rtx x0 = gen_reg_rtx (mode);
27031 rtx y = gen_reg_rtx (mode);
27032 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27033 REAL_VALUE_TYPE dconst3_2;
27036 enum insn_code code = optab_handler (smul_optab, mode);
27037 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27039 gcc_assert (code != CODE_FOR_nothing);
27041 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27042 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27043 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27045 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27047 /* x0 = rsqrt estimate */
27048 emit_insn (gen_rtx_SET (VOIDmode, x0,
27049 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27052 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27053 rs6000_emit_msub (y, src, halfthree, src);
27055 for (i = 0; i < passes; i++)
27057 rtx x1 = gen_reg_rtx (mode);
27058 rtx u = gen_reg_rtx (mode);
27059 rtx v = gen_reg_rtx (mode);
27061 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27062 emit_insn (gen_mul (u, x0, x0));
27063 rs6000_emit_nmsub (v, y, u, halfthree);
27064 emit_insn (gen_mul (x1, x0, v));
27068 emit_move_insn (dst, x0);
27072 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27073 (Power7) targets. DST is the target, and SRC is the argument operand. */
27076 rs6000_emit_popcount (rtx dst, rtx src)
27078 enum machine_mode mode = GET_MODE (dst);
27081 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27082 if (TARGET_POPCNTD)
27084 if (mode == SImode)
27085 emit_insn (gen_popcntdsi2 (dst, src));
27087 emit_insn (gen_popcntddi2 (dst, src));
27091 tmp1 = gen_reg_rtx (mode);
27093 if (mode == SImode)
27095 emit_insn (gen_popcntbsi2 (tmp1, src));
27096 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27098 tmp2 = force_reg (SImode, tmp2);
27099 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27103 emit_insn (gen_popcntbdi2 (tmp1, src));
27104 tmp2 = expand_mult (DImode, tmp1,
27105 GEN_INT ((HOST_WIDE_INT)
27106 0x01010101 << 32 | 0x01010101),
27108 tmp2 = force_reg (DImode, tmp2);
27109 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27114 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27115 target, and SRC is the argument operand. */
27118 rs6000_emit_parity (rtx dst, rtx src)
27120 enum machine_mode mode = GET_MODE (dst);
27123 tmp = gen_reg_rtx (mode);
27125 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27128 if (mode == SImode)
27130 emit_insn (gen_popcntbsi2 (tmp, src));
27131 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27135 emit_insn (gen_popcntbdi2 (tmp, src));
27136 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27141 if (mode == SImode)
27143 /* Is mult+shift >= shift+xor+shift+xor? */
27144 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27146 rtx tmp1, tmp2, tmp3, tmp4;
27148 tmp1 = gen_reg_rtx (SImode);
27149 emit_insn (gen_popcntbsi2 (tmp1, src));
27151 tmp2 = gen_reg_rtx (SImode);
27152 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27153 tmp3 = gen_reg_rtx (SImode);
27154 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27156 tmp4 = gen_reg_rtx (SImode);
27157 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27158 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27161 rs6000_emit_popcount (tmp, src);
27162 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27166 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27167 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27169 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27171 tmp1 = gen_reg_rtx (DImode);
27172 emit_insn (gen_popcntbdi2 (tmp1, src));
27174 tmp2 = gen_reg_rtx (DImode);
27175 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27176 tmp3 = gen_reg_rtx (DImode);
27177 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27179 tmp4 = gen_reg_rtx (DImode);
27180 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27181 tmp5 = gen_reg_rtx (DImode);
27182 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27184 tmp6 = gen_reg_rtx (DImode);
27185 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27186 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27189 rs6000_emit_popcount (tmp, src);
27190 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27194 /* Return an RTX representing where to find the function value of a
27195 function returning MODE. */
27197 rs6000_complex_function_value (enum machine_mode mode)
27199 unsigned int regno;
27201 enum machine_mode inner = GET_MODE_INNER (mode);
27202 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27204 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27205 regno = FP_ARG_RETURN;
27208 regno = GP_ARG_RETURN;
27210 /* 32-bit is OK since it'll go in r3/r4. */
27211 if (TARGET_32BIT && inner_bytes >= 4)
27212 return gen_rtx_REG (mode, regno);
27215 if (inner_bytes >= 8)
27216 return gen_rtx_REG (mode, regno);
27218 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27220 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27221 GEN_INT (inner_bytes));
27222 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27225 /* Target hook for TARGET_FUNCTION_VALUE.
27227 On the SPE, both FPs and vectors are returned in r3.
27229 On RS/6000 an integer value is in r3 and a floating-point value is in
27230 fp1, unless -msoft-float. */
27233 rs6000_function_value (const_tree valtype,
27234 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27235 bool outgoing ATTRIBUTE_UNUSED)
27237 enum machine_mode mode;
27238 unsigned int regno;
27240 /* Special handling for structs in darwin64. */
27242 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27244 CUMULATIVE_ARGS valcum;
27248 valcum.fregno = FP_ARG_MIN_REG;
27249 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27250 /* Do a trial code generation as if this were going to be passed as
27251 an argument; if any part goes in memory, we return NULL. */
27252 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27255 /* Otherwise fall through to standard ABI rules. */
27258 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27260 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27261 return gen_rtx_PARALLEL (DImode,
27263 gen_rtx_EXPR_LIST (VOIDmode,
27264 gen_rtx_REG (SImode, GP_ARG_RETURN),
27266 gen_rtx_EXPR_LIST (VOIDmode,
27267 gen_rtx_REG (SImode,
27268 GP_ARG_RETURN + 1),
27271 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27273 return gen_rtx_PARALLEL (DCmode,
27275 gen_rtx_EXPR_LIST (VOIDmode,
27276 gen_rtx_REG (SImode, GP_ARG_RETURN),
27278 gen_rtx_EXPR_LIST (VOIDmode,
27279 gen_rtx_REG (SImode,
27280 GP_ARG_RETURN + 1),
27282 gen_rtx_EXPR_LIST (VOIDmode,
27283 gen_rtx_REG (SImode,
27284 GP_ARG_RETURN + 2),
27286 gen_rtx_EXPR_LIST (VOIDmode,
27287 gen_rtx_REG (SImode,
27288 GP_ARG_RETURN + 3),
27292 mode = TYPE_MODE (valtype);
27293 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27294 || POINTER_TYPE_P (valtype))
27295 mode = TARGET_32BIT ? SImode : DImode;
27297 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27298 /* _Decimal128 must use an even/odd register pair. */
27299 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27300 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27301 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27302 regno = FP_ARG_RETURN;
27303 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27304 && targetm.calls.split_complex_arg)
27305 return rs6000_complex_function_value (mode);
27306 else if (TREE_CODE (valtype) == VECTOR_TYPE
27307 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27308 && ALTIVEC_VECTOR_MODE (mode))
27309 regno = ALTIVEC_ARG_RETURN;
27310 else if (TREE_CODE (valtype) == VECTOR_TYPE
27311 && TARGET_VSX && TARGET_ALTIVEC_ABI
27312 && VSX_VECTOR_MODE (mode))
27313 regno = ALTIVEC_ARG_RETURN;
27314 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27315 && (mode == DFmode || mode == DCmode
27316 || mode == TFmode || mode == TCmode))
27317 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27319 regno = GP_ARG_RETURN;
27321 return gen_rtx_REG (mode, regno);
27324 /* Define how to find the value returned by a library function
27325 assuming the value has mode MODE. */
27327 rs6000_libcall_value (enum machine_mode mode)
27329 unsigned int regno;
27331 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27333 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27334 return gen_rtx_PARALLEL (DImode,
27336 gen_rtx_EXPR_LIST (VOIDmode,
27337 gen_rtx_REG (SImode, GP_ARG_RETURN),
27339 gen_rtx_EXPR_LIST (VOIDmode,
27340 gen_rtx_REG (SImode,
27341 GP_ARG_RETURN + 1),
27345 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27346 /* _Decimal128 must use an even/odd register pair. */
27347 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27348 else if (SCALAR_FLOAT_MODE_P (mode)
27349 && TARGET_HARD_FLOAT && TARGET_FPRS
27350 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27351 regno = FP_ARG_RETURN;
27352 else if (ALTIVEC_VECTOR_MODE (mode)
27353 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27354 regno = ALTIVEC_ARG_RETURN;
27355 else if (VSX_VECTOR_MODE (mode)
27356 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27357 regno = ALTIVEC_ARG_RETURN;
27358 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27359 return rs6000_complex_function_value (mode);
27360 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27361 && (mode == DFmode || mode == DCmode
27362 || mode == TFmode || mode == TCmode))
27363 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27365 regno = GP_ARG_RETURN;
27367 return gen_rtx_REG (mode, regno);
27371 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27372 Frame pointer elimination is automatically handled.
27374 For the RS/6000, if frame pointer elimination is being done, we would like
27375 to convert ap into fp, not sp.
27377 We need r30 if -mminimal-toc was specified, and there are constant pool
27381 rs6000_can_eliminate (const int from, const int to)
27383 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27384 ? ! frame_pointer_needed
27385 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27386 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27390 /* Define the offset between two registers, FROM to be eliminated and its
27391 replacement TO, at the start of a routine. */
27393 rs6000_initial_elimination_offset (int from, int to)
27395 rs6000_stack_t *info = rs6000_stack_info ();
27396 HOST_WIDE_INT offset;
27398 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27399 offset = info->push_p ? 0 : -info->total_size;
27400 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27402 offset = info->push_p ? 0 : -info->total_size;
27403 if (FRAME_GROWS_DOWNWARD)
27404 offset += info->fixed_size + info->vars_size + info->parm_size;
27406 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27407 offset = FRAME_GROWS_DOWNWARD
27408 ? info->fixed_size + info->vars_size + info->parm_size
27410 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27411 offset = info->total_size;
27412 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27413 offset = info->push_p ? info->total_size : 0;
27414 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27417 gcc_unreachable ();
27423 rs6000_dwarf_register_span (rtx reg)
27427 unsigned regno = REGNO (reg);
27428 enum machine_mode mode = GET_MODE (reg);
27432 && (SPE_VECTOR_MODE (GET_MODE (reg))
27433 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27434 && mode != SFmode && mode != SDmode && mode != SCmode)))
27439 regno = REGNO (reg);
27441 /* The duality of the SPE register size wreaks all kinds of havoc.
27442 This is a way of distinguishing r0 in 32-bits from r0 in
27444 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27445 gcc_assert (words <= 4);
27446 for (i = 0; i < words; i++, regno++)
27448 if (BYTES_BIG_ENDIAN)
27450 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27451 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27455 parts[2 * i] = gen_rtx_REG (SImode, regno);
27456 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27460 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27463 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27466 rs6000_init_dwarf_reg_sizes_extra (tree address)
27471 enum machine_mode mode = TYPE_MODE (char_type_node);
27472 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27473 rtx mem = gen_rtx_MEM (BLKmode, addr);
27474 rtx value = gen_int_mode (4, mode);
27476 for (i = 1201; i < 1232; i++)
27478 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27479 HOST_WIDE_INT offset
27480 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27482 emit_move_insn (adjust_address (mem, mode, offset), value);
27487 /* Map internal gcc register numbers to DWARF2 register numbers. */
27490 rs6000_dbx_register_number (unsigned int regno)
27492 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27494 if (regno == MQ_REGNO)
27496 if (regno == LR_REGNO)
27498 if (regno == CTR_REGNO)
27500 if (CR_REGNO_P (regno))
27501 return regno - CR0_REGNO + 86;
27502 if (regno == CA_REGNO)
27503 return 101; /* XER */
27504 if (ALTIVEC_REGNO_P (regno))
27505 return regno - FIRST_ALTIVEC_REGNO + 1124;
27506 if (regno == VRSAVE_REGNO)
27508 if (regno == VSCR_REGNO)
27510 if (regno == SPE_ACC_REGNO)
27512 if (regno == SPEFSCR_REGNO)
27514 /* SPE high reg number. We get these values of regno from
27515 rs6000_dwarf_register_span. */
27516 gcc_assert (regno >= 1200 && regno < 1232);
27520 /* target hook eh_return_filter_mode */
27521 static enum machine_mode
27522 rs6000_eh_return_filter_mode (void)
27524 return TARGET_32BIT ? SImode : word_mode;
27527 /* Target hook for scalar_mode_supported_p. */
27529 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27531 if (DECIMAL_FLOAT_MODE_P (mode))
27532 return default_decimal_float_supported_p ();
27534 return default_scalar_mode_supported_p (mode);
27537 /* Target hook for vector_mode_supported_p. */
27539 rs6000_vector_mode_supported_p (enum machine_mode mode)
27542 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27545 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27548 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27555 /* Target hook for invalid_arg_for_unprototyped_fn. */
27556 static const char *
27557 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27559 return (!rs6000_darwin64_abi
27561 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27562 && (funcdecl == NULL_TREE
27563 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27564 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27565 ? N_("AltiVec argument passed to unprototyped function")
27569 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27570 setup by using __stack_chk_fail_local hidden function instead of
27571 calling __stack_chk_fail directly. Otherwise it is better to call
27572 __stack_chk_fail directly. */
27575 rs6000_stack_protect_fail (void)
27577 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27578 ? default_hidden_stack_protect_fail ()
27579 : default_external_stack_protect_fail ();
27583 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27584 int num_operands ATTRIBUTE_UNUSED)
27586 if (rs6000_warn_cell_microcode)
27589 int insn_code_number = recog_memoized (insn);
27590 location_t location = locator_location (INSN_LOCATOR (insn));
27592 /* Punt on insns we cannot recognize. */
27593 if (insn_code_number < 0)
27596 temp = get_insn_template (insn_code_number, insn);
27598 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27599 warning_at (location, OPT_mwarn_cell_microcode,
27600 "emitting microcode insn %s\t[%s] #%d",
27601 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27602 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27603 warning_at (location, OPT_mwarn_cell_microcode,
27604 "emitting conditional microcode insn %s\t[%s] #%d",
27605 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27610 /* Mask options that we want to support inside of attribute((target)) and
27611 #pragma GCC target operations. Note, we do not include things like
27612 64/32-bit, endianess, hard/soft floating point, etc. that would have
27613 different calling sequences. */
27615 struct rs6000_opt_mask {
27616 const char *name; /* option name */
27617 int mask; /* mask to set */
27618 bool invert; /* invert sense of mask */
27619 bool valid_target; /* option is a target option */
27622 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27624 { "altivec", MASK_ALTIVEC, false, true },
27625 { "cmpb", MASK_CMPB, false, true },
27626 { "dlmzb", MASK_DLMZB, false, true },
27627 { "fprnd", MASK_FPRND, false, true },
27628 { "hard-dfp", MASK_DFP, false, true },
27629 { "isel", MASK_ISEL, false, true },
27630 { "mfcrf", MASK_MFCRF, false, true },
27631 { "mfpgpr", MASK_MFPGPR, false, true },
27632 { "mulhw", MASK_MULHW, false, true },
27633 { "multiple", MASK_MULTIPLE, false, true },
27634 { "update", MASK_NO_UPDATE, true , true },
27635 { "popcntb", MASK_POPCNTB, false, true },
27636 { "popcntd", MASK_POPCNTD, false, true },
27637 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27638 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27639 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27640 { "string", MASK_STRING, false, true },
27641 { "vsx", MASK_VSX, false, true },
27644 { "aix64", MASK_64BIT, false, false },
27645 { "aix32", MASK_64BIT, true, false },
27647 { "64", MASK_64BIT, false, false },
27648 { "32", MASK_64BIT, true, false },
27652 { "eabi", MASK_EABI, false, false },
27654 #ifdef MASK_LITTLE_ENDIAN
27655 { "little", MASK_LITTLE_ENDIAN, false, false },
27656 { "big", MASK_LITTLE_ENDIAN, true, false },
27658 #ifdef MASK_RELOCATABLE
27659 { "relocatable", MASK_RELOCATABLE, false, false },
27661 #ifdef MASK_STRICT_ALIGN
27662 { "strict-align", MASK_STRICT_ALIGN, false, false },
27664 { "power", MASK_POWER, false, false },
27665 { "power2", MASK_POWER2, false, false },
27666 { "powerpc", MASK_POWERPC, false, false },
27667 { "soft-float", MASK_SOFT_FLOAT, false, false },
27668 { "string", MASK_STRING, false, false },
27671 /* Option variables that we want to support inside attribute((target)) and
27672 #pragma GCC target operations. */
27674 struct rs6000_opt_var {
27675 const char *name; /* option name */
27676 size_t global_offset; /* offset of the option in global_options. */
27677 size_t target_offset; /* offset of the option in target optiosn. */
27680 static struct rs6000_opt_var const rs6000_opt_vars[] =
27683 offsetof (struct gcc_options, x_TARGET_FRIZ),
27684 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27685 { "avoid-indexed-addresses",
27686 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27687 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27689 offsetof (struct gcc_options, x_rs6000_paired_float),
27690 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27692 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27693 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27696 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27697 parsing. Return true if there were no errors. */
27700 rs6000_inner_target_options (tree args, bool attr_p)
27704 if (args == NULL_TREE)
27707 else if (TREE_CODE (args) == STRING_CST)
27709 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27712 while ((q = strtok (p, ",")) != NULL)
27714 bool error_p = false;
27715 bool not_valid_p = false;
27716 const char *cpu_opt = NULL;
27719 if (strncmp (q, "cpu=", 4) == 0)
27721 int cpu_index = rs6000_cpu_name_lookup (q+4);
27722 if (cpu_index >= 0)
27723 rs6000_cpu_index = cpu_index;
27730 else if (strncmp (q, "tune=", 5) == 0)
27732 int tune_index = rs6000_cpu_name_lookup (q+5);
27733 if (tune_index >= 0)
27734 rs6000_tune_index = tune_index;
27744 bool invert = false;
27748 if (strncmp (r, "no-", 3) == 0)
27754 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27755 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27757 int mask = rs6000_opt_masks[i].mask;
27759 if (!rs6000_opt_masks[i].valid_target)
27760 not_valid_p = true;
27764 target_flags_explicit |= mask;
27766 if (rs6000_opt_masks[i].invert)
27770 target_flags &= ~mask;
27772 target_flags |= mask;
27777 if (error_p && !not_valid_p)
27779 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27780 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27782 size_t j = rs6000_opt_vars[i].global_offset;
27783 ((int *) &global_options)[j] = !invert;
27792 const char *eprefix, *esuffix;
27797 eprefix = "__attribute__((__target__(";
27802 eprefix = "#pragma GCC target ";
27807 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27809 else if (not_valid_p)
27810 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27812 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27817 else if (TREE_CODE (args) == TREE_LIST)
27821 tree value = TREE_VALUE (args);
27824 bool ret2 = rs6000_inner_target_options (value, attr_p);
27828 args = TREE_CHAIN (args);
27830 while (args != NULL_TREE);
27834 gcc_unreachable ();
27839 /* Print out the target options as a list for -mdebug=target. */
27842 rs6000_debug_target_options (tree args, const char *prefix)
27844 if (args == NULL_TREE)
27845 fprintf (stderr, "%s<NULL>", prefix);
27847 else if (TREE_CODE (args) == STRING_CST)
27849 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27852 while ((q = strtok (p, ",")) != NULL)
27855 fprintf (stderr, "%s\"%s\"", prefix, q);
27860 else if (TREE_CODE (args) == TREE_LIST)
27864 tree value = TREE_VALUE (args);
27867 rs6000_debug_target_options (value, prefix);
27870 args = TREE_CHAIN (args);
27872 while (args != NULL_TREE);
27876 gcc_unreachable ();
27882 /* Hook to validate attribute((target("..."))). */
27885 rs6000_valid_attribute_p (tree fndecl,
27886 tree ARG_UNUSED (name),
27890 struct cl_target_option cur_target;
27892 tree old_optimize = build_optimization_node ();
27893 tree new_target, new_optimize;
27894 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27896 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27898 if (TARGET_DEBUG_TARGET)
27900 tree tname = DECL_NAME (fndecl);
27901 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27903 fprintf (stderr, "function: %.*s\n",
27904 (int) IDENTIFIER_LENGTH (tname),
27905 IDENTIFIER_POINTER (tname));
27907 fprintf (stderr, "function: unknown\n");
27909 fprintf (stderr, "args:");
27910 rs6000_debug_target_options (args, " ");
27911 fprintf (stderr, "\n");
27914 fprintf (stderr, "flags: 0x%x\n", flags);
27916 fprintf (stderr, "--------------------\n");
27919 old_optimize = build_optimization_node ();
27920 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27922 /* If the function changed the optimization levels as well as setting target
27923 options, start with the optimizations specified. */
27924 if (func_optimize && func_optimize != old_optimize)
27925 cl_optimization_restore (&global_options,
27926 TREE_OPTIMIZATION (func_optimize));
27928 /* The target attributes may also change some optimization flags, so update
27929 the optimization options if necessary. */
27930 cl_target_option_save (&cur_target, &global_options);
27931 rs6000_cpu_index = rs6000_tune_index = -1;
27932 ret = rs6000_inner_target_options (args, true);
27934 /* Set up any additional state. */
27937 ret = rs6000_option_override_internal (false);
27938 new_target = build_target_option_node ();
27943 new_optimize = build_optimization_node ();
27950 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27952 if (old_optimize != new_optimize)
27953 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27956 cl_target_option_restore (&global_options, &cur_target);
27958 if (old_optimize != new_optimize)
27959 cl_optimization_restore (&global_options,
27960 TREE_OPTIMIZATION (old_optimize));
27966 /* Hook to validate the current #pragma GCC target and set the state, and
27967 update the macros based on what was changed. If ARGS is NULL, then
27968 POP_TARGET is used to reset the options. */
27971 rs6000_pragma_target_parse (tree args, tree pop_target)
27976 if (TARGET_DEBUG_TARGET)
27978 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27979 fprintf (stderr, "args:");
27980 rs6000_debug_target_options (args, " ");
27981 fprintf (stderr, "\n");
27985 fprintf (stderr, "pop_target:\n");
27986 debug_tree (pop_target);
27989 fprintf (stderr, "pop_target: <NULL>\n");
27991 fprintf (stderr, "--------------------\n");
27997 cur_tree = ((pop_target)
27999 : target_option_default_node);
28000 cl_target_option_restore (&global_options,
28001 TREE_TARGET_OPTION (cur_tree));
28005 rs6000_cpu_index = rs6000_tune_index = -1;
28006 ret = rs6000_inner_target_options (args, false);
28007 cur_tree = build_target_option_node ();
28014 target_option_current_node = cur_tree;
28020 /* Remember the last target of rs6000_set_current_function. */
28021 static GTY(()) tree rs6000_previous_fndecl;
28023 /* Establish appropriate back-end context for processing the function
28024 FNDECL. The argument might be NULL to indicate processing at top
28025 level, outside of any function scope. */
28027 rs6000_set_current_function (tree fndecl)
28029 tree old_tree = (rs6000_previous_fndecl
28030 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28033 tree new_tree = (fndecl
28034 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28037 if (TARGET_DEBUG_TARGET)
28039 bool print_final = false;
28040 fprintf (stderr, "\n==================== rs6000_set_current_function");
28043 fprintf (stderr, ", fndecl %s (%p)",
28044 (DECL_NAME (fndecl)
28045 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28046 : "<unknown>"), (void *)fndecl);
28048 if (rs6000_previous_fndecl)
28049 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28051 fprintf (stderr, "\n");
28054 fprintf (stderr, "\nnew fndecl target specific options:\n");
28055 debug_tree (new_tree);
28056 print_final = true;
28061 fprintf (stderr, "\nold fndecl target specific options:\n");
28062 debug_tree (old_tree);
28063 print_final = true;
28067 fprintf (stderr, "--------------------\n");
28070 /* Only change the context if the function changes. This hook is called
28071 several times in the course of compiling a function, and we don't want to
28072 slow things down too much or call target_reinit when it isn't safe. */
28073 if (fndecl && fndecl != rs6000_previous_fndecl)
28075 rs6000_previous_fndecl = fndecl;
28076 if (old_tree == new_tree)
28081 cl_target_option_restore (&global_options,
28082 TREE_TARGET_OPTION (new_tree));
28088 struct cl_target_option *def
28089 = TREE_TARGET_OPTION (target_option_current_node);
28091 cl_target_option_restore (&global_options, def);
28098 /* Save the current options */
28101 rs6000_function_specific_save (struct cl_target_option *ptr)
28103 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28106 /* Restore the current options */
28109 rs6000_function_specific_restore (struct cl_target_option *ptr)
28111 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28112 (void) rs6000_option_override_internal (false);
28115 /* Print the current options */
28118 rs6000_function_specific_print (FILE *file, int indent,
28119 struct cl_target_option *ptr)
28122 int flags = ptr->x_target_flags;
28124 /* Print the various mask options. */
28125 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28126 if ((flags & rs6000_opt_masks[i].mask) != 0)
28128 flags &= ~ rs6000_opt_masks[i].mask;
28129 fprintf (file, "%*s-m%s%s\n", indent, "",
28130 rs6000_opt_masks[i].invert ? "no-" : "",
28131 rs6000_opt_masks[i].name);
28134 /* Print the various options that are variables. */
28135 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28137 size_t j = rs6000_opt_vars[i].target_offset;
28138 if (((signed char *) ptr)[j])
28139 fprintf (file, "%*s-m%s\n", indent, "",
28140 rs6000_opt_vars[i].name);
28145 /* Hook to determine if one function can safely inline another. */
28148 rs6000_can_inline_p (tree caller, tree callee)
28151 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28152 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28154 /* If callee has no option attributes, then it is ok to inline. */
28158 /* If caller has no option attributes, but callee does then it is not ok to
28160 else if (!caller_tree)
28165 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28166 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28168 /* Callee's options should a subset of the caller's, i.e. a vsx function
28169 can inline an altivec function but a non-vsx function can't inline a
28171 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28172 == callee_opts->x_target_flags)
28176 if (TARGET_DEBUG_TARGET)
28177 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28178 (DECL_NAME (caller)
28179 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28181 (DECL_NAME (callee)
28182 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28184 (ret ? "can" : "cannot"));
28189 /* Allocate a stack temp and fixup the address so it meets the particular
28190 memory requirements (either offetable or REG+REG addressing). */
28193 rs6000_allocate_stack_temp (enum machine_mode mode,
28194 bool offsettable_p,
28197 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28198 rtx addr = XEXP (stack, 0);
28199 int strict_p = (reload_in_progress || reload_completed);
28201 if (!legitimate_indirect_address_p (addr, strict_p))
28204 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28205 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28207 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28208 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28214 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28215 to such a form to deal with memory reference instructions like STFIWX that
28216 only take reg+reg addressing. */
28219 rs6000_address_for_fpconvert (rtx x)
28221 int strict_p = (reload_in_progress || reload_completed);
28224 gcc_assert (MEM_P (x));
28225 addr = XEXP (x, 0);
28226 if (! legitimate_indirect_address_p (addr, strict_p)
28227 && ! legitimate_indexed_address_p (addr, strict_p))
28229 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28231 rtx reg = XEXP (addr, 0);
28232 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28233 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28234 gcc_assert (REG_P (reg));
28235 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28238 else if (GET_CODE (addr) == PRE_MODIFY)
28240 rtx reg = XEXP (addr, 0);
28241 rtx expr = XEXP (addr, 1);
28242 gcc_assert (REG_P (reg));
28243 gcc_assert (GET_CODE (expr) == PLUS);
28244 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28248 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28254 /* Given a memory reference, if it is not in the form for altivec memory
28255 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28256 convert to the altivec format. */
28259 rs6000_address_for_altivec (rtx x)
28261 gcc_assert (MEM_P (x));
28262 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28264 rtx addr = XEXP (x, 0);
28265 int strict_p = (reload_in_progress || reload_completed);
28267 if (!legitimate_indexed_address_p (addr, strict_p)
28268 && !legitimate_indirect_address_p (addr, strict_p))
28269 addr = copy_to_mode_reg (Pmode, addr);
28271 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28272 x = change_address (x, GET_MODE (x), addr);
28279 #include "gt-rs6000.h"