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);
1216 static bool rs6000_legitimate_constant_p (enum machine_mode, rtx);
1218 /* Hash table stuff for keeping track of TOC entries. */
1220 struct GTY(()) toc_hash_struct
1222 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
1223 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
1225 enum machine_mode key_mode;
1229 static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
1231 /* Hash table to keep track of the argument types for builtin functions. */
1233 struct GTY(()) builtin_hash_struct
1236 enum machine_mode mode[4]; /* return value + 3 arguments. */
1237 unsigned char uns_p[4]; /* and whether the types are unsigned. */
1240 static GTY ((param_is (struct builtin_hash_struct))) htab_t builtin_hash_table;
1242 static bool rs6000_valid_attribute_p (tree, tree, tree, int);
1243 static void rs6000_function_specific_save (struct cl_target_option *);
1244 static void rs6000_function_specific_restore (struct cl_target_option *);
1245 static void rs6000_function_specific_print (FILE *, int,
1246 struct cl_target_option *);
1247 static bool rs6000_can_inline_p (tree, tree);
1248 static void rs6000_set_current_function (tree);
1251 /* Default register names. */
1252 char rs6000_reg_names[][8] =
1254 "0", "1", "2", "3", "4", "5", "6", "7",
1255 "8", "9", "10", "11", "12", "13", "14", "15",
1256 "16", "17", "18", "19", "20", "21", "22", "23",
1257 "24", "25", "26", "27", "28", "29", "30", "31",
1258 "0", "1", "2", "3", "4", "5", "6", "7",
1259 "8", "9", "10", "11", "12", "13", "14", "15",
1260 "16", "17", "18", "19", "20", "21", "22", "23",
1261 "24", "25", "26", "27", "28", "29", "30", "31",
1262 "mq", "lr", "ctr","ap",
1263 "0", "1", "2", "3", "4", "5", "6", "7",
1265 /* AltiVec registers. */
1266 "0", "1", "2", "3", "4", "5", "6", "7",
1267 "8", "9", "10", "11", "12", "13", "14", "15",
1268 "16", "17", "18", "19", "20", "21", "22", "23",
1269 "24", "25", "26", "27", "28", "29", "30", "31",
1271 /* SPE registers. */
1272 "spe_acc", "spefscr",
1273 /* Soft frame pointer. */
1277 #ifdef TARGET_REGNAMES
1278 static const char alt_reg_names[][8] =
1280 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
1281 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
1282 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
1283 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
1284 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
1285 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
1286 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
1287 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
1288 "mq", "lr", "ctr", "ap",
1289 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
1291 /* AltiVec registers. */
1292 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
1293 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
1294 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
1295 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
1297 /* SPE registers. */
1298 "spe_acc", "spefscr",
1299 /* Soft frame pointer. */
1304 /* Table of valid machine attributes. */
1306 static const struct attribute_spec rs6000_attribute_table[] =
1308 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
1309 affects_type_identity } */
1310 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute,
1312 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1314 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute,
1316 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1318 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute,
1320 #ifdef SUBTARGET_ATTRIBUTE_TABLE
1321 SUBTARGET_ATTRIBUTE_TABLE,
1323 { NULL, 0, 0, false, false, false, NULL, false }
1326 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
1327 static const struct default_options rs6000_option_optimization_table[] =
1329 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
1330 { OPT_LEVELS_NONE, 0, NULL, 0 }
1333 #ifndef MASK_STRICT_ALIGN
1334 #define MASK_STRICT_ALIGN 0
1336 #ifndef TARGET_PROFILE_KERNEL
1337 #define TARGET_PROFILE_KERNEL 0
1340 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
1341 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
1343 /* Initialize the GCC target structure. */
1344 #undef TARGET_ATTRIBUTE_TABLE
1345 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
1346 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
1347 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
1348 #undef TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P
1349 #define TARGET_ATTRIBUTE_TAKES_IDENTIFIER_P rs6000_attribute_takes_identifier_p
1351 #undef TARGET_ASM_ALIGNED_DI_OP
1352 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1354 /* Default unaligned ops are only provided for ELF. Find the ops needed
1355 for non-ELF systems. */
1356 #ifndef OBJECT_FORMAT_ELF
1358 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
1360 #undef TARGET_ASM_UNALIGNED_HI_OP
1361 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1362 #undef TARGET_ASM_UNALIGNED_SI_OP
1363 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1364 #undef TARGET_ASM_UNALIGNED_DI_OP
1365 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1368 #undef TARGET_ASM_UNALIGNED_HI_OP
1369 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1370 #undef TARGET_ASM_UNALIGNED_SI_OP
1371 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
1372 #undef TARGET_ASM_UNALIGNED_DI_OP
1373 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1374 #undef TARGET_ASM_ALIGNED_DI_OP
1375 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
1379 /* This hook deals with fixups for relocatable code and DI-mode objects
1381 #undef TARGET_ASM_INTEGER
1382 #define TARGET_ASM_INTEGER rs6000_assemble_integer
1384 #ifdef HAVE_GAS_HIDDEN
1385 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
1386 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1389 #undef TARGET_HAVE_TLS
1390 #define TARGET_HAVE_TLS HAVE_AS_TLS
1392 #undef TARGET_CANNOT_FORCE_CONST_MEM
1393 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
1395 #undef TARGET_DELEGITIMIZE_ADDRESS
1396 #define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
1398 #undef TARGET_ASM_FUNCTION_PROLOGUE
1399 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1400 #undef TARGET_ASM_FUNCTION_EPILOGUE
1401 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1403 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1404 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA rs6000_output_addr_const_extra
1406 #undef TARGET_LEGITIMIZE_ADDRESS
1407 #define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
1409 #undef TARGET_SCHED_VARIABLE_ISSUE
1410 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1412 #undef TARGET_SCHED_ISSUE_RATE
1413 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1414 #undef TARGET_SCHED_ADJUST_COST
1415 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1416 #undef TARGET_SCHED_ADJUST_PRIORITY
1417 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
1418 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
1419 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
1420 #undef TARGET_SCHED_INIT
1421 #define TARGET_SCHED_INIT rs6000_sched_init
1422 #undef TARGET_SCHED_FINISH
1423 #define TARGET_SCHED_FINISH rs6000_sched_finish
1424 #undef TARGET_SCHED_REORDER
1425 #define TARGET_SCHED_REORDER rs6000_sched_reorder
1426 #undef TARGET_SCHED_REORDER2
1427 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
1429 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1430 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1432 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1433 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1435 #undef TARGET_SCHED_ALLOC_SCHED_CONTEXT
1436 #define TARGET_SCHED_ALLOC_SCHED_CONTEXT rs6000_alloc_sched_context
1437 #undef TARGET_SCHED_INIT_SCHED_CONTEXT
1438 #define TARGET_SCHED_INIT_SCHED_CONTEXT rs6000_init_sched_context
1439 #undef TARGET_SCHED_SET_SCHED_CONTEXT
1440 #define TARGET_SCHED_SET_SCHED_CONTEXT rs6000_set_sched_context
1441 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
1442 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
1444 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1445 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
1446 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1447 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1448 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1449 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
1450 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1451 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
1452 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
1453 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
1454 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
1455 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT \
1456 rs6000_builtin_support_vector_misalignment
1457 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
1458 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1459 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
1460 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
1461 rs6000_builtin_vectorization_cost
1462 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
1463 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
1464 rs6000_preferred_simd_mode
1466 #undef TARGET_INIT_BUILTINS
1467 #define TARGET_INIT_BUILTINS rs6000_init_builtins
1468 #undef TARGET_BUILTIN_DECL
1469 #define TARGET_BUILTIN_DECL rs6000_builtin_decl
1471 #undef TARGET_EXPAND_BUILTIN
1472 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1474 #undef TARGET_MANGLE_TYPE
1475 #define TARGET_MANGLE_TYPE rs6000_mangle_type
1477 #undef TARGET_INIT_LIBFUNCS
1478 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1481 #undef TARGET_BINDS_LOCAL_P
1482 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1485 #undef TARGET_MS_BITFIELD_LAYOUT_P
1486 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1488 #undef TARGET_ASM_OUTPUT_MI_THUNK
1489 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1491 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1492 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
1494 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1495 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1497 #undef TARGET_INVALID_WITHIN_DOLOOP
1498 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1500 #undef TARGET_REGISTER_MOVE_COST
1501 #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost
1502 #undef TARGET_MEMORY_MOVE_COST
1503 #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost
1504 #undef TARGET_RTX_COSTS
1505 #define TARGET_RTX_COSTS rs6000_rtx_costs
1506 #undef TARGET_ADDRESS_COST
1507 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1509 #undef TARGET_DWARF_REGISTER_SPAN
1510 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1512 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1513 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1515 /* On rs6000, function arguments are promoted, as are function return
1517 #undef TARGET_PROMOTE_FUNCTION_MODE
1518 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
1520 #undef TARGET_RETURN_IN_MEMORY
1521 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1523 #undef TARGET_SETUP_INCOMING_VARARGS
1524 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1526 /* Always strict argument naming on rs6000. */
1527 #undef TARGET_STRICT_ARGUMENT_NAMING
1528 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1529 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1530 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1531 #undef TARGET_SPLIT_COMPLEX_ARG
1532 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
1533 #undef TARGET_MUST_PASS_IN_STACK
1534 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1535 #undef TARGET_PASS_BY_REFERENCE
1536 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1537 #undef TARGET_ARG_PARTIAL_BYTES
1538 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1539 #undef TARGET_FUNCTION_ARG_ADVANCE
1540 #define TARGET_FUNCTION_ARG_ADVANCE rs6000_function_arg_advance
1541 #undef TARGET_FUNCTION_ARG
1542 #define TARGET_FUNCTION_ARG rs6000_function_arg
1543 #undef TARGET_FUNCTION_ARG_BOUNDARY
1544 #define TARGET_FUNCTION_ARG_BOUNDARY rs6000_function_arg_boundary
1546 #undef TARGET_BUILD_BUILTIN_VA_LIST
1547 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1549 #undef TARGET_EXPAND_BUILTIN_VA_START
1550 #define TARGET_EXPAND_BUILTIN_VA_START rs6000_va_start
1552 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1553 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1555 #undef TARGET_EH_RETURN_FILTER_MODE
1556 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1558 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1559 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1561 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1562 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1564 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1565 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1567 #undef TARGET_HANDLE_OPTION
1568 #define TARGET_HANDLE_OPTION rs6000_handle_option
1570 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
1571 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rs6000_loop_align_max_skip
1573 #undef TARGET_OPTION_OVERRIDE
1574 #define TARGET_OPTION_OVERRIDE rs6000_option_override
1576 #undef TARGET_OPTION_INIT_STRUCT
1577 #define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
1579 #undef TARGET_OPTION_DEFAULT_PARAMS
1580 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
1582 #undef TARGET_OPTION_OPTIMIZATION_TABLE
1583 #define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
1585 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
1586 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
1587 rs6000_builtin_vectorized_function
1589 #undef TARGET_DEFAULT_TARGET_FLAGS
1590 #define TARGET_DEFAULT_TARGET_FLAGS \
1593 #undef TARGET_STACK_PROTECT_FAIL
1594 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1596 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1597 The PowerPC architecture requires only weak consistency among
1598 processors--that is, memory accesses between processors need not be
1599 sequentially consistent and memory accesses among processors can occur
1600 in any order. The ability to order memory accesses weakly provides
1601 opportunities for more efficient use of the system bus. Unless a
1602 dependency exists, the 604e allows read operations to precede store
1604 #undef TARGET_RELAXED_ORDERING
1605 #define TARGET_RELAXED_ORDERING true
1608 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1609 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1612 /* Use a 32-bit anchor range. This leads to sequences like:
1614 addis tmp,anchor,high
1617 where tmp itself acts as an anchor, and can be shared between
1618 accesses to the same 64k page. */
1619 #undef TARGET_MIN_ANCHOR_OFFSET
1620 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1621 #undef TARGET_MAX_ANCHOR_OFFSET
1622 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1623 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1624 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1626 #undef TARGET_BUILTIN_RECIPROCAL
1627 #define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1629 #undef TARGET_EXPAND_TO_RTL_HOOK
1630 #define TARGET_EXPAND_TO_RTL_HOOK rs6000_alloc_sdmode_stack_slot
1632 #undef TARGET_INSTANTIATE_DECLS
1633 #define TARGET_INSTANTIATE_DECLS rs6000_instantiate_decls
1635 #undef TARGET_SECONDARY_RELOAD
1636 #define TARGET_SECONDARY_RELOAD rs6000_secondary_reload
1638 #undef TARGET_LEGITIMATE_ADDRESS_P
1639 #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p
1641 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
1642 #define TARGET_MODE_DEPENDENT_ADDRESS_P rs6000_mode_dependent_address_p
1644 #undef TARGET_CAN_ELIMINATE
1645 #define TARGET_CAN_ELIMINATE rs6000_can_eliminate
1647 #undef TARGET_CONDITIONAL_REGISTER_USAGE
1648 #define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
1650 #undef TARGET_TRAMPOLINE_INIT
1651 #define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
1653 #undef TARGET_FUNCTION_VALUE
1654 #define TARGET_FUNCTION_VALUE rs6000_function_value
1656 #undef TARGET_OPTION_VALID_ATTRIBUTE_P
1657 #define TARGET_OPTION_VALID_ATTRIBUTE_P rs6000_valid_attribute_p
1659 #undef TARGET_OPTION_SAVE
1660 #define TARGET_OPTION_SAVE rs6000_function_specific_save
1662 #undef TARGET_OPTION_RESTORE
1663 #define TARGET_OPTION_RESTORE rs6000_function_specific_restore
1665 #undef TARGET_OPTION_PRINT
1666 #define TARGET_OPTION_PRINT rs6000_function_specific_print
1668 #undef TARGET_CAN_INLINE_P
1669 #define TARGET_CAN_INLINE_P rs6000_can_inline_p
1671 #undef TARGET_SET_CURRENT_FUNCTION
1672 #define TARGET_SET_CURRENT_FUNCTION rs6000_set_current_function
1674 #undef TARGET_LEGITIMATE_CONSTANT_P
1675 #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p
1677 struct gcc_target targetm = TARGET_INITIALIZER;
1680 /* Simplifications for entries below. */
1683 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1684 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1687 /* Some OSs don't support saving the high part of 64-bit registers on context
1688 switch. Other OSs don't support saving Altivec registers. On those OSs, we
1689 don't touch the MASK_POWERPC64 or MASK_ALTIVEC settings; if the user wants
1690 either, the user must explicitly specify them and we won't interfere with
1691 the user's specification. */
1694 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
1695 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
1696 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
1697 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1698 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP
1699 | MASK_POPCNTD | MASK_VSX | MASK_ISEL | MASK_NO_UPDATE
1700 | MASK_RECIP_PRECISION)
1703 /* Masks for instructions set at various powerpc ISAs. */
1705 ISA_2_1_MASKS = MASK_MFCRF,
1706 ISA_2_2_MASKS = (ISA_2_1_MASKS | MASK_POPCNTB),
1707 ISA_2_4_MASKS = (ISA_2_2_MASKS | MASK_FPRND),
1709 /* For ISA 2.05, do not add MFPGPR, since it isn't in ISA 2.06, and don't add
1710 ALTIVEC, since in general it isn't a win on power6. In ISA 2.04, fsel,
1711 fre, fsqrt, etc. were no longer documented as optional. Group masks by
1712 server and embedded. */
1713 ISA_2_5_MASKS_EMBEDDED = (ISA_2_2_MASKS | MASK_CMPB | MASK_RECIP_PRECISION
1714 | MASK_PPC_GFXOPT | MASK_PPC_GPOPT),
1715 ISA_2_5_MASKS_SERVER = (ISA_2_5_MASKS_EMBEDDED | MASK_DFP),
1717 /* For ISA 2.06, don't add ISEL, since in general it isn't a win, but
1718 altivec is a win so enable it. */
1719 ISA_2_6_MASKS_EMBEDDED = (ISA_2_5_MASKS_EMBEDDED | MASK_POPCNTD),
1720 ISA_2_6_MASKS_SERVER = (ISA_2_5_MASKS_SERVER | MASK_POPCNTD | MASK_ALTIVEC
1724 /* This table occasionally claims that a processor does not support a
1725 particular feature even though it does, but the feature is slower than the
1726 alternative. Thus, it shouldn't be relied on as a complete description of
1727 the processor's support.
1729 Please keep this list in order, and don't forget to update the documentation
1730 in invoke.texi when adding a new processor or flag. */
1734 const char *const name; /* Canonical processor name. */
1735 const enum processor_type processor; /* Processor type enum value. */
1736 const int target_enable; /* Target flags to enable. */
1739 static struct rs6000_ptt const processor_target_table[] =
1741 {"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1742 {"403", PROCESSOR_PPC403,
1743 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
1744 {"405", PROCESSOR_PPC405,
1745 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1746 {"405fp", PROCESSOR_PPC405,
1747 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1748 {"440", PROCESSOR_PPC440,
1749 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1750 {"440fp", PROCESSOR_PPC440,
1751 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1752 {"464", PROCESSOR_PPC440,
1753 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1754 {"464fp", PROCESSOR_PPC440,
1755 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1756 {"476", PROCESSOR_PPC476,
1757 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF
1758 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1759 {"476fp", PROCESSOR_PPC476,
1760 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
1761 | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB},
1762 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
1763 {"601", PROCESSOR_PPC601,
1764 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1765 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1766 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1767 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1768 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1769 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1770 {"620", PROCESSOR_PPC620,
1771 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1772 {"630", PROCESSOR_PPC630,
1773 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1774 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1775 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1776 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1777 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1778 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1779 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1780 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1781 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1783 /* 8548 has a dummy entry for now. */
1784 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN
1786 {"a2", PROCESSOR_PPCA2,
1787 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB
1788 | MASK_CMPB | MASK_NO_UPDATE },
1789 {"e300c2", PROCESSOR_PPCE300C2, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1790 {"e300c3", PROCESSOR_PPCE300C3, POWERPC_BASE_MASK},
1791 {"e500mc", PROCESSOR_PPCE500MC, POWERPC_BASE_MASK | MASK_PPC_GFXOPT
1793 {"e500mc64", PROCESSOR_PPCE500MC64, POWERPC_BASE_MASK | MASK_POWERPC64
1794 | MASK_PPC_GFXOPT | MASK_ISEL},
1795 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1796 {"970", PROCESSOR_POWER4,
1797 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1798 {"cell", PROCESSOR_CELL,
1799 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1800 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1801 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1802 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1803 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1804 {"G5", PROCESSOR_POWER4,
1805 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1806 {"titan", PROCESSOR_TITAN,
1807 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
1808 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1809 {"power2", PROCESSOR_POWER,
1810 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1811 {"power3", PROCESSOR_PPC630,
1812 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1813 {"power4", PROCESSOR_POWER4,
1814 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1816 {"power5", PROCESSOR_POWER5,
1817 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1818 | MASK_MFCRF | MASK_POPCNTB},
1819 {"power5+", PROCESSOR_POWER5,
1820 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1821 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
1822 {"power6", 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_RECIP_PRECISION},
1826 {"power6x", PROCESSOR_POWER6,
1827 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_PPC_GFXOPT
1828 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP
1829 | MASK_MFPGPR | MASK_RECIP_PRECISION},
1830 {"power7", PROCESSOR_POWER7, /* Don't add MASK_ISEL by default */
1831 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_PPC_GPOPT | MASK_MFCRF
1832 | MASK_POPCNTB | MASK_FPRND | MASK_CMPB | MASK_DFP | MASK_POPCNTD
1833 | MASK_VSX | MASK_RECIP_PRECISION},
1834 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1835 {"powerpc64", PROCESSOR_POWERPC64,
1836 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1837 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1838 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1839 {"rios2", PROCESSOR_RIOS2,
1840 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1841 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1842 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1843 {"rs64", PROCESSOR_RS64A,
1844 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
1847 /* Look up a processor name for -mcpu=xxx and -mtune=xxx. Return -1 if the
1851 rs6000_cpu_name_lookup (const char *name)
1857 for (i = 0; i < ARRAY_SIZE (processor_target_table); i++)
1858 if (! strcmp (name, processor_target_table[i].name))
1866 /* Return number of consecutive hard regs needed starting at reg REGNO
1867 to hold something of mode MODE.
1868 This is ordinarily the length in words of a value of mode MODE
1869 but can be less for certain modes in special long registers.
1871 For the SPE, GPRs are 64 bits but only 32 bits are visible in
1872 scalar instructions. The upper 32 bits are only available to the
1875 POWER and PowerPC GPRs hold 32 bits worth;
1876 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
1879 rs6000_hard_regno_nregs_internal (int regno, enum machine_mode mode)
1881 unsigned HOST_WIDE_INT reg_size;
1883 if (FP_REGNO_P (regno))
1884 reg_size = (VECTOR_MEM_VSX_P (mode)
1885 ? UNITS_PER_VSX_WORD
1886 : UNITS_PER_FP_WORD);
1888 else if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1889 reg_size = UNITS_PER_SPE_WORD;
1891 else if (ALTIVEC_REGNO_P (regno))
1892 reg_size = UNITS_PER_ALTIVEC_WORD;
1894 /* The value returned for SCmode in the E500 double case is 2 for
1895 ABI compatibility; storing an SCmode value in a single register
1896 would require function_arg and rs6000_spe_function_arg to handle
1897 SCmode so as to pass the value correctly in a pair of
1899 else if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode
1900 && !DECIMAL_FLOAT_MODE_P (mode))
1901 reg_size = UNITS_PER_FP_WORD;
1904 reg_size = UNITS_PER_WORD;
1906 return (GET_MODE_SIZE (mode) + reg_size - 1) / reg_size;
1909 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1912 rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1914 int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
1916 /* VSX registers that overlap the FPR registers are larger than for non-VSX
1917 implementations. Don't allow an item to be split between a FP register
1918 and an Altivec register. */
1919 if (VECTOR_MEM_VSX_P (mode))
1921 if (FP_REGNO_P (regno))
1922 return FP_REGNO_P (last_regno);
1924 if (ALTIVEC_REGNO_P (regno))
1925 return ALTIVEC_REGNO_P (last_regno);
1928 /* The GPRs can hold any mode, but values bigger than one register
1929 cannot go past R31. */
1930 if (INT_REGNO_P (regno))
1931 return INT_REGNO_P (last_regno);
1933 /* The float registers (except for VSX vector modes) can only hold floating
1934 modes and DImode. This excludes the 32-bit decimal float mode for
1936 if (FP_REGNO_P (regno))
1938 if (SCALAR_FLOAT_MODE_P (mode)
1939 && (mode != TDmode || (regno % 2) == 0)
1940 && FP_REGNO_P (last_regno))
1943 if (GET_MODE_CLASS (mode) == MODE_INT
1944 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1947 if (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1948 && PAIRED_VECTOR_MODE (mode))
1954 /* The CR register can only hold CC modes. */
1955 if (CR_REGNO_P (regno))
1956 return GET_MODE_CLASS (mode) == MODE_CC;
1958 if (CA_REGNO_P (regno))
1959 return mode == BImode;
1961 /* AltiVec only in AldyVec registers. */
1962 if (ALTIVEC_REGNO_P (regno))
1963 return VECTOR_MEM_ALTIVEC_OR_VSX_P (mode);
1965 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1966 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1969 /* We cannot put TImode anywhere except general register and it must be able
1970 to fit within the register set. In the future, allow TImode in the
1971 Altivec or VSX registers. */
1973 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1976 /* Print interesting facts about registers. */
1978 rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
1982 for (r = first_regno; r <= last_regno; ++r)
1984 const char *comma = "";
1987 if (first_regno == last_regno)
1988 fprintf (stderr, "%s:\t", reg_name);
1990 fprintf (stderr, "%s%d:\t", reg_name, r - first_regno);
1993 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1994 if (rs6000_hard_regno_mode_ok_p[m][r] && rs6000_hard_regno_nregs[m][r])
1998 fprintf (stderr, ",\n\t");
2003 if (rs6000_hard_regno_nregs[m][r] > 1)
2004 len += fprintf (stderr, "%s%s/%d", comma, GET_MODE_NAME (m),
2005 rs6000_hard_regno_nregs[m][r]);
2007 len += fprintf (stderr, "%s%s", comma, GET_MODE_NAME (m));
2012 if (call_used_regs[r])
2016 fprintf (stderr, ",\n\t");
2021 len += fprintf (stderr, "%s%s", comma, "call-used");
2029 fprintf (stderr, ",\n\t");
2034 len += fprintf (stderr, "%s%s", comma, "fixed");
2040 fprintf (stderr, ",\n\t");
2044 fprintf (stderr, "%sregno = %d\n", comma, r);
2048 #define DEBUG_FMT_D "%-32s= %d\n"
2049 #define DEBUG_FMT_S "%-32s= %s\n"
2051 /* Print various interesting information with -mdebug=reg. */
2053 rs6000_debug_reg_global (void)
2055 static const char *const tf[2] = { "false", "true" };
2056 const char *nl = (const char *)0;
2058 char costly_num[20];
2060 const char *costly_str;
2061 const char *nop_str;
2062 const char *trace_str;
2063 const char *abi_str;
2064 const char *cmodel_str;
2066 /* Map enum rs6000_vector to string. */
2067 static const char *rs6000_debug_vector_unit[] = {
2076 fprintf (stderr, "Register information: (last virtual reg = %d)\n",
2077 LAST_VIRTUAL_REGISTER);
2078 rs6000_debug_reg_print (0, 31, "gr");
2079 rs6000_debug_reg_print (32, 63, "fp");
2080 rs6000_debug_reg_print (FIRST_ALTIVEC_REGNO,
2083 rs6000_debug_reg_print (LR_REGNO, LR_REGNO, "lr");
2084 rs6000_debug_reg_print (CTR_REGNO, CTR_REGNO, "ctr");
2085 rs6000_debug_reg_print (CR0_REGNO, CR7_REGNO, "cr");
2086 rs6000_debug_reg_print (MQ_REGNO, MQ_REGNO, "mq");
2087 rs6000_debug_reg_print (CA_REGNO, CA_REGNO, "ca");
2088 rs6000_debug_reg_print (VRSAVE_REGNO, VRSAVE_REGNO, "vrsave");
2089 rs6000_debug_reg_print (VSCR_REGNO, VSCR_REGNO, "vscr");
2090 rs6000_debug_reg_print (SPE_ACC_REGNO, SPE_ACC_REGNO, "spe_a");
2091 rs6000_debug_reg_print (SPEFSCR_REGNO, SPEFSCR_REGNO, "spe_f");
2095 "d reg_class = %s\n"
2096 "f reg_class = %s\n"
2097 "v reg_class = %s\n"
2098 "wa reg_class = %s\n"
2099 "wd reg_class = %s\n"
2100 "wf reg_class = %s\n"
2101 "ws reg_class = %s\n\n",
2102 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_d]],
2103 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_f]],
2104 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_v]],
2105 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wa]],
2106 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wd]],
2107 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_wf]],
2108 reg_class_names[rs6000_constraints[RS6000_CONSTRAINT_ws]]);
2110 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2111 if (rs6000_vector_unit[m] || rs6000_vector_mem[m])
2114 fprintf (stderr, "Vector mode: %-5s arithmetic: %-8s move: %-8s\n",
2116 rs6000_debug_vector_unit[ rs6000_vector_unit[m] ],
2117 rs6000_debug_vector_unit[ rs6000_vector_mem[m] ]);
2123 if (rs6000_recip_control)
2125 fprintf (stderr, "\nReciprocal mask = 0x%x\n", rs6000_recip_control);
2127 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2128 if (rs6000_recip_bits[m])
2131 "Reciprocal estimate mode: %-5s divide: %s rsqrt: %s\n",
2133 (RS6000_RECIP_AUTO_RE_P (m)
2135 : (RS6000_RECIP_HAVE_RE_P (m) ? "have" : "none")),
2136 (RS6000_RECIP_AUTO_RSQRTE_P (m)
2138 : (RS6000_RECIP_HAVE_RSQRTE_P (m) ? "have" : "none")));
2141 fputs ("\n", stderr);
2144 if (rs6000_cpu_index >= 0)
2145 fprintf (stderr, DEBUG_FMT_S, "cpu",
2146 processor_target_table[rs6000_cpu_index].name);
2148 if (rs6000_tune_index >= 0)
2149 fprintf (stderr, DEBUG_FMT_S, "tune",
2150 processor_target_table[rs6000_tune_index].name);
2152 switch (rs6000_sched_costly_dep)
2154 case max_dep_latency:
2155 costly_str = "max_dep_latency";
2159 costly_str = "no_dep_costly";
2162 case all_deps_costly:
2163 costly_str = "all_deps_costly";
2166 case true_store_to_load_dep_costly:
2167 costly_str = "true_store_to_load_dep_costly";
2170 case store_to_load_dep_costly:
2171 costly_str = "store_to_load_dep_costly";
2175 costly_str = costly_num;
2176 sprintf (costly_num, "%d", (int)rs6000_sched_costly_dep);
2180 fprintf (stderr, DEBUG_FMT_S, "sched_costly_dep", costly_str);
2182 switch (rs6000_sched_insert_nops)
2184 case sched_finish_regroup_exact:
2185 nop_str = "sched_finish_regroup_exact";
2188 case sched_finish_pad_groups:
2189 nop_str = "sched_finish_pad_groups";
2192 case sched_finish_none:
2193 nop_str = "sched_finish_none";
2198 sprintf (nop_num, "%d", (int)rs6000_sched_insert_nops);
2202 fprintf (stderr, DEBUG_FMT_S, "sched_insert_nops", nop_str);
2204 switch (rs6000_sdata)
2211 fprintf (stderr, DEBUG_FMT_S, "sdata", "data");
2215 fprintf (stderr, DEBUG_FMT_S, "sdata", "sysv");
2219 fprintf (stderr, DEBUG_FMT_S, "sdata", "eabi");
2224 switch (rs6000_traceback)
2226 case traceback_default: trace_str = "default"; break;
2227 case traceback_none: trace_str = "none"; break;
2228 case traceback_part: trace_str = "part"; break;
2229 case traceback_full: trace_str = "full"; break;
2230 default: trace_str = "unknown"; break;
2233 fprintf (stderr, DEBUG_FMT_S, "traceback", trace_str);
2235 switch (rs6000_current_cmodel)
2237 case CMODEL_SMALL: cmodel_str = "small"; break;
2238 case CMODEL_MEDIUM: cmodel_str = "medium"; break;
2239 case CMODEL_LARGE: cmodel_str = "large"; break;
2240 default: cmodel_str = "unknown"; break;
2243 fprintf (stderr, DEBUG_FMT_S, "cmodel", cmodel_str);
2245 switch (rs6000_current_abi)
2247 case ABI_NONE: abi_str = "none"; break;
2248 case ABI_AIX: abi_str = "aix"; break;
2249 case ABI_V4: abi_str = "V4"; break;
2250 case ABI_DARWIN: abi_str = "darwin"; break;
2251 default: abi_str = "unknown"; break;
2254 fprintf (stderr, DEBUG_FMT_S, "abi", abi_str);
2256 if (rs6000_altivec_abi)
2257 fprintf (stderr, DEBUG_FMT_S, "altivec_abi", "true");
2260 fprintf (stderr, DEBUG_FMT_S, "spe_abi", "true");
2262 if (rs6000_darwin64_abi)
2263 fprintf (stderr, DEBUG_FMT_S, "darwin64_abi", "true");
2265 if (rs6000_float_gprs)
2266 fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
2268 fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
2269 fprintf (stderr, DEBUG_FMT_S, "align_branch",
2270 tf[!!rs6000_align_branch_targets]);
2271 fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
2272 fprintf (stderr, DEBUG_FMT_D, "long_double_size",
2273 rs6000_long_double_type_size);
2274 fprintf (stderr, DEBUG_FMT_D, "sched_restricted_insns_priority",
2275 (int)rs6000_sched_restricted_insns_priority);
2278 /* Initialize the various global tables that are based on register size. */
2280 rs6000_init_hard_regno_mode_ok (bool global_init_p)
2286 /* Precalculate REGNO_REG_CLASS. */
2287 rs6000_regno_regclass[0] = GENERAL_REGS;
2288 for (r = 1; r < 32; ++r)
2289 rs6000_regno_regclass[r] = BASE_REGS;
2291 for (r = 32; r < 64; ++r)
2292 rs6000_regno_regclass[r] = FLOAT_REGS;
2294 for (r = 64; r < FIRST_PSEUDO_REGISTER; ++r)
2295 rs6000_regno_regclass[r] = NO_REGS;
2297 for (r = FIRST_ALTIVEC_REGNO; r <= LAST_ALTIVEC_REGNO; ++r)
2298 rs6000_regno_regclass[r] = ALTIVEC_REGS;
2300 rs6000_regno_regclass[CR0_REGNO] = CR0_REGS;
2301 for (r = CR1_REGNO; r <= CR7_REGNO; ++r)
2302 rs6000_regno_regclass[r] = CR_REGS;
2304 rs6000_regno_regclass[MQ_REGNO] = MQ_REGS;
2305 rs6000_regno_regclass[LR_REGNO] = LINK_REGS;
2306 rs6000_regno_regclass[CTR_REGNO] = CTR_REGS;
2307 rs6000_regno_regclass[CA_REGNO] = CA_REGS;
2308 rs6000_regno_regclass[VRSAVE_REGNO] = VRSAVE_REGS;
2309 rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
2310 rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
2311 rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
2312 rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
2313 rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
2315 /* Precalculate vector information, this must be set up before the
2316 rs6000_hard_regno_nregs_internal below. */
2317 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2319 rs6000_vector_unit[m] = rs6000_vector_mem[m] = VECTOR_NONE;
2320 rs6000_vector_reload[m][0] = CODE_FOR_nothing;
2321 rs6000_vector_reload[m][1] = CODE_FOR_nothing;
2324 for (c = 0; c < (int)(int)RS6000_CONSTRAINT_MAX; c++)
2325 rs6000_constraints[c] = NO_REGS;
2327 /* The VSX hardware allows native alignment for vectors, but control whether the compiler
2328 believes it can use native alignment or still uses 128-bit alignment. */
2329 if (TARGET_VSX && !TARGET_VSX_ALIGN_128)
2340 /* V2DF mode, VSX only. */
2343 rs6000_vector_unit[V2DFmode] = VECTOR_VSX;
2344 rs6000_vector_mem[V2DFmode] = VECTOR_VSX;
2345 rs6000_vector_align[V2DFmode] = align64;
2348 /* V4SF mode, either VSX or Altivec. */
2351 rs6000_vector_unit[V4SFmode] = VECTOR_VSX;
2352 rs6000_vector_mem[V4SFmode] = VECTOR_VSX;
2353 rs6000_vector_align[V4SFmode] = align32;
2355 else if (TARGET_ALTIVEC)
2357 rs6000_vector_unit[V4SFmode] = VECTOR_ALTIVEC;
2358 rs6000_vector_mem[V4SFmode] = VECTOR_ALTIVEC;
2359 rs6000_vector_align[V4SFmode] = align32;
2362 /* V16QImode, V8HImode, V4SImode are Altivec only, but possibly do VSX loads
2366 rs6000_vector_unit[V4SImode] = VECTOR_ALTIVEC;
2367 rs6000_vector_unit[V8HImode] = VECTOR_ALTIVEC;
2368 rs6000_vector_unit[V16QImode] = VECTOR_ALTIVEC;
2369 rs6000_vector_align[V4SImode] = align32;
2370 rs6000_vector_align[V8HImode] = align32;
2371 rs6000_vector_align[V16QImode] = align32;
2375 rs6000_vector_mem[V4SImode] = VECTOR_VSX;
2376 rs6000_vector_mem[V8HImode] = VECTOR_VSX;
2377 rs6000_vector_mem[V16QImode] = VECTOR_VSX;
2381 rs6000_vector_mem[V4SImode] = VECTOR_ALTIVEC;
2382 rs6000_vector_mem[V8HImode] = VECTOR_ALTIVEC;
2383 rs6000_vector_mem[V16QImode] = VECTOR_ALTIVEC;
2387 /* V2DImode, only allow under VSX, which can do V2DI insert/splat/extract.
2388 Altivec doesn't have 64-bit support. */
2391 rs6000_vector_mem[V2DImode] = VECTOR_VSX;
2392 rs6000_vector_unit[V2DImode] = VECTOR_NONE;
2393 rs6000_vector_align[V2DImode] = align64;
2396 /* DFmode, see if we want to use the VSX unit. */
2397 if (TARGET_VSX && TARGET_VSX_SCALAR_DOUBLE)
2399 rs6000_vector_unit[DFmode] = VECTOR_VSX;
2400 rs6000_vector_mem[DFmode]
2401 = (TARGET_VSX_SCALAR_MEMORY ? VECTOR_VSX : VECTOR_NONE);
2402 rs6000_vector_align[DFmode] = align64;
2405 /* TODO add SPE and paired floating point vector support. */
2407 /* Register class constaints for the constraints that depend on compile
2409 if (TARGET_HARD_FLOAT && TARGET_FPRS)
2410 rs6000_constraints[RS6000_CONSTRAINT_f] = FLOAT_REGS;
2412 if (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
2413 rs6000_constraints[RS6000_CONSTRAINT_d] = FLOAT_REGS;
2417 /* At present, we just use VSX_REGS, but we have different constraints
2418 based on the use, in case we want to fine tune the default register
2419 class used. wa = any VSX register, wf = register class to use for
2420 V4SF, wd = register class to use for V2DF, and ws = register classs to
2421 use for DF scalars. */
2422 rs6000_constraints[RS6000_CONSTRAINT_wa] = VSX_REGS;
2423 rs6000_constraints[RS6000_CONSTRAINT_wf] = VSX_REGS;
2424 rs6000_constraints[RS6000_CONSTRAINT_wd] = VSX_REGS;
2425 rs6000_constraints[RS6000_CONSTRAINT_ws] = (TARGET_VSX_SCALAR_MEMORY
2431 rs6000_constraints[RS6000_CONSTRAINT_v] = ALTIVEC_REGS;
2433 /* Set up the reload helper functions. */
2434 if (TARGET_VSX || TARGET_ALTIVEC)
2438 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_di_store;
2439 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_di_load;
2440 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_di_store;
2441 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_di_load;
2442 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_di_store;
2443 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_di_load;
2444 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_di_store;
2445 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_di_load;
2446 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_di_store;
2447 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_di_load;
2448 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_di_store;
2449 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_di_load;
2453 rs6000_vector_reload[V16QImode][0] = CODE_FOR_reload_v16qi_si_store;
2454 rs6000_vector_reload[V16QImode][1] = CODE_FOR_reload_v16qi_si_load;
2455 rs6000_vector_reload[V8HImode][0] = CODE_FOR_reload_v8hi_si_store;
2456 rs6000_vector_reload[V8HImode][1] = CODE_FOR_reload_v8hi_si_load;
2457 rs6000_vector_reload[V4SImode][0] = CODE_FOR_reload_v4si_si_store;
2458 rs6000_vector_reload[V4SImode][1] = CODE_FOR_reload_v4si_si_load;
2459 rs6000_vector_reload[V2DImode][0] = CODE_FOR_reload_v2di_si_store;
2460 rs6000_vector_reload[V2DImode][1] = CODE_FOR_reload_v2di_si_load;
2461 rs6000_vector_reload[V4SFmode][0] = CODE_FOR_reload_v4sf_si_store;
2462 rs6000_vector_reload[V4SFmode][1] = CODE_FOR_reload_v4sf_si_load;
2463 rs6000_vector_reload[V2DFmode][0] = CODE_FOR_reload_v2df_si_store;
2464 rs6000_vector_reload[V2DFmode][1] = CODE_FOR_reload_v2df_si_load;
2468 /* Precalculate HARD_REGNO_NREGS. */
2469 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2470 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2471 rs6000_hard_regno_nregs[m][r]
2472 = rs6000_hard_regno_nregs_internal (r, (enum machine_mode)m);
2474 /* Precalculate HARD_REGNO_MODE_OK. */
2475 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
2476 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2477 if (rs6000_hard_regno_mode_ok (r, (enum machine_mode)m))
2478 rs6000_hard_regno_mode_ok_p[m][r] = true;
2480 /* Precalculate CLASS_MAX_NREGS sizes. */
2481 for (c = 0; c < LIM_REG_CLASSES; ++c)
2485 if (TARGET_VSX && VSX_REG_CLASS_P (c))
2486 reg_size = UNITS_PER_VSX_WORD;
2488 else if (c == ALTIVEC_REGS)
2489 reg_size = UNITS_PER_ALTIVEC_WORD;
2491 else if (c == FLOAT_REGS)
2492 reg_size = UNITS_PER_FP_WORD;
2495 reg_size = UNITS_PER_WORD;
2497 for (m = 0; m < NUM_MACHINE_MODES; ++m)
2498 rs6000_class_max_nregs[m][c]
2499 = (GET_MODE_SIZE (m) + reg_size - 1) / reg_size;
2502 if (TARGET_E500_DOUBLE)
2503 rs6000_class_max_nregs[DFmode][GENERAL_REGS] = 1;
2505 /* Calculate which modes to automatically generate code to use a the
2506 reciprocal divide and square root instructions. In the future, possibly
2507 automatically generate the instructions even if the user did not specify
2508 -mrecip. The older machines double precision reciprocal sqrt estimate is
2509 not accurate enough. */
2510 memset (rs6000_recip_bits, 0, sizeof (rs6000_recip_bits));
2512 rs6000_recip_bits[SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2514 rs6000_recip_bits[DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2515 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2516 rs6000_recip_bits[V4SFmode] = RS6000_RECIP_MASK_HAVE_RE;
2517 if (VECTOR_UNIT_VSX_P (V2DFmode))
2518 rs6000_recip_bits[V2DFmode] = RS6000_RECIP_MASK_HAVE_RE;
2520 if (TARGET_FRSQRTES)
2521 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2523 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2524 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode))
2525 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2526 if (VECTOR_UNIT_VSX_P (V2DFmode))
2527 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_HAVE_RSQRTE;
2529 if (rs6000_recip_control)
2531 if (!flag_finite_math_only)
2532 warning (0, "-mrecip requires -ffinite-math or -ffast-math");
2533 if (flag_trapping_math)
2534 warning (0, "-mrecip requires -fno-trapping-math or -ffast-math");
2535 if (!flag_reciprocal_math)
2536 warning (0, "-mrecip requires -freciprocal-math or -ffast-math");
2537 if (flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math)
2539 if (RS6000_RECIP_HAVE_RE_P (SFmode)
2540 && (rs6000_recip_control & RECIP_SF_DIV) != 0)
2541 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2543 if (RS6000_RECIP_HAVE_RE_P (DFmode)
2544 && (rs6000_recip_control & RECIP_DF_DIV) != 0)
2545 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2547 if (RS6000_RECIP_HAVE_RE_P (V4SFmode)
2548 && (rs6000_recip_control & RECIP_V4SF_DIV) != 0)
2549 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2551 if (RS6000_RECIP_HAVE_RE_P (V2DFmode)
2552 && (rs6000_recip_control & RECIP_V2DF_DIV) != 0)
2553 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RE;
2555 if (RS6000_RECIP_HAVE_RSQRTE_P (SFmode)
2556 && (rs6000_recip_control & RECIP_SF_RSQRT) != 0)
2557 rs6000_recip_bits[SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2559 if (RS6000_RECIP_HAVE_RSQRTE_P (DFmode)
2560 && (rs6000_recip_control & RECIP_DF_RSQRT) != 0)
2561 rs6000_recip_bits[DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2563 if (RS6000_RECIP_HAVE_RSQRTE_P (V4SFmode)
2564 && (rs6000_recip_control & RECIP_V4SF_RSQRT) != 0)
2565 rs6000_recip_bits[V4SFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2567 if (RS6000_RECIP_HAVE_RSQRTE_P (V2DFmode)
2568 && (rs6000_recip_control & RECIP_V2DF_RSQRT) != 0)
2569 rs6000_recip_bits[V2DFmode] |= RS6000_RECIP_MASK_AUTO_RSQRTE;
2573 if (global_init_p || TARGET_DEBUG_TARGET)
2575 if (TARGET_DEBUG_REG)
2576 rs6000_debug_reg_global ();
2578 if (TARGET_DEBUG_COST || TARGET_DEBUG_REG)
2580 "SImode variable mult cost = %d\n"
2581 "SImode constant mult cost = %d\n"
2582 "SImode short constant mult cost = %d\n"
2583 "DImode multipliciation cost = %d\n"
2584 "SImode division cost = %d\n"
2585 "DImode division cost = %d\n"
2586 "Simple fp operation cost = %d\n"
2587 "DFmode multiplication cost = %d\n"
2588 "SFmode division cost = %d\n"
2589 "DFmode division cost = %d\n"
2590 "cache line size = %d\n"
2591 "l1 cache size = %d\n"
2592 "l2 cache size = %d\n"
2593 "simultaneous prefetches = %d\n"
2596 rs6000_cost->mulsi_const,
2597 rs6000_cost->mulsi_const9,
2605 rs6000_cost->cache_line_size,
2606 rs6000_cost->l1_cache_size,
2607 rs6000_cost->l2_cache_size,
2608 rs6000_cost->simultaneous_prefetches);
2613 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
2616 darwin_rs6000_override_options (void)
2618 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
2620 rs6000_altivec_abi = 1;
2621 TARGET_ALTIVEC_VRSAVE = 1;
2623 if (DEFAULT_ABI == ABI_DARWIN
2625 darwin_one_byte_bool = 1;
2627 if (TARGET_64BIT && ! TARGET_POWERPC64)
2629 target_flags |= MASK_POWERPC64;
2630 warning (0, "-m64 requires PowerPC64 architecture, enabling");
2634 rs6000_default_long_calls = 1;
2635 target_flags |= MASK_SOFT_FLOAT;
2638 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
2640 if (!flag_mkernel && !flag_apple_kext
2642 && ! (target_flags_explicit & MASK_ALTIVEC))
2643 target_flags |= MASK_ALTIVEC;
2645 /* Unless the user (not the configurer) has explicitly overridden
2646 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
2647 G4 unless targetting the kernel. */
2650 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
2651 && ! (target_flags_explicit & MASK_ALTIVEC)
2652 && ! rs6000_select[1].string)
2654 target_flags |= MASK_ALTIVEC;
2659 /* If not otherwise specified by a target, make 'long double' equivalent to
2662 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
2663 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
2666 /* Override command line options. Mostly we process the processor type and
2667 sometimes adjust other TARGET_ options. */
2670 rs6000_option_override_internal (bool global_init_p)
2673 const char *default_cpu = OPTION_TARGET_CPU_DEFAULT;
2677 struct cl_target_option *main_target_opt
2678 = ((global_init_p || target_option_default_node == NULL)
2679 ? NULL : TREE_TARGET_OPTION (target_option_default_node));
2681 /* Numerous experiment shows that IRA based loop pressure
2682 calculation works better for RTL loop invariant motion on targets
2683 with enough (>= 32) registers. It is an expensive optimization.
2684 So it is on only for peak performance. */
2685 if (optimize >= 3 && global_init_p)
2686 flag_ira_loop_pressure = 1;
2688 /* Set the pointer size. */
2691 rs6000_pmode = (int)DImode;
2692 rs6000_pointer_size = 64;
2696 rs6000_pmode = (int)SImode;
2697 rs6000_pointer_size = 32;
2700 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
2701 #ifdef OS_MISSING_POWERPC64
2702 if (OS_MISSING_POWERPC64)
2703 set_masks &= ~MASK_POWERPC64;
2705 #ifdef OS_MISSING_ALTIVEC
2706 if (OS_MISSING_ALTIVEC)
2707 set_masks &= ~MASK_ALTIVEC;
2710 /* Don't override by the processor default if given explicitly. */
2711 set_masks &= ~target_flags_explicit;
2713 /* Identify the processor type. */
2716 if (TARGET_POWERPC64)
2717 default_cpu = "powerpc64";
2718 else if (TARGET_POWERPC)
2719 default_cpu = "powerpc";
2722 /* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
2723 the cpu in a target attribute or pragma, but did not specify a tuning
2724 option, use the cpu for the tuning option rather than the option specified
2725 with -mtune on the command line. */
2726 if (rs6000_cpu_index > 0)
2727 cpu_index = rs6000_cpu_index;
2728 else if (main_target_opt != NULL && main_target_opt->x_rs6000_cpu_index > 0)
2729 rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
2731 rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
2733 if (rs6000_tune_index > 0)
2734 tune_index = rs6000_tune_index;
2736 rs6000_tune_index = tune_index = cpu_index;
2740 target_flags &= ~set_masks;
2741 target_flags |= (processor_target_table[cpu_index].target_enable
2745 rs6000_cpu = ((tune_index >= 0)
2746 ? processor_target_table[tune_index].processor
2748 ? PROCESSOR_DEFAULT64
2749 : PROCESSOR_DEFAULT));
2751 if (rs6000_cpu == PROCESSOR_PPCE300C2 || rs6000_cpu == PROCESSOR_PPCE300C3
2752 || rs6000_cpu == PROCESSOR_PPCE500MC || rs6000_cpu == PROCESSOR_PPCE500MC64)
2755 error ("AltiVec not supported in this target");
2757 error ("SPE not supported in this target");
2760 /* Disable Cell microcode if we are optimizing for the Cell
2761 and not optimizing for size. */
2762 if (rs6000_gen_cell_microcode == -1)
2763 rs6000_gen_cell_microcode = !(rs6000_cpu == PROCESSOR_CELL
2766 /* If we are optimizing big endian systems for space and it's OK to
2767 use instructions that would be microcoded on the Cell, use the
2768 load/store multiple and string instructions. */
2769 if (BYTES_BIG_ENDIAN && optimize_size && rs6000_gen_cell_microcode)
2770 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
2772 /* Don't allow -mmultiple or -mstring on little endian systems
2773 unless the cpu is a 750, because the hardware doesn't support the
2774 instructions used in little endian mode, and causes an alignment
2775 trap. The 750 does not cause an alignment trap (except when the
2776 target is unaligned). */
2778 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
2780 if (TARGET_MULTIPLE)
2782 target_flags &= ~MASK_MULTIPLE;
2783 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
2784 warning (0, "-mmultiple is not supported on little endian systems");
2789 target_flags &= ~MASK_STRING;
2790 if ((target_flags_explicit & MASK_STRING) != 0)
2791 warning (0, "-mstring is not supported on little endian systems");
2795 /* Add some warnings for VSX. */
2798 const char *msg = NULL;
2799 if (!TARGET_HARD_FLOAT || !TARGET_FPRS
2800 || !TARGET_SINGLE_FLOAT || !TARGET_DOUBLE_FLOAT)
2802 if (target_flags_explicit & MASK_VSX)
2803 msg = N_("-mvsx requires hardware floating point");
2805 target_flags &= ~ MASK_VSX;
2807 else if (TARGET_PAIRED_FLOAT)
2808 msg = N_("-mvsx and -mpaired are incompatible");
2809 /* The hardware will allow VSX and little endian, but until we make sure
2810 things like vector select, etc. work don't allow VSX on little endian
2811 systems at this point. */
2812 else if (!BYTES_BIG_ENDIAN)
2813 msg = N_("-mvsx used with little endian code");
2814 else if (TARGET_AVOID_XFORM > 0)
2815 msg = N_("-mvsx needs indexed addressing");
2816 else if (!TARGET_ALTIVEC && (target_flags_explicit & MASK_ALTIVEC))
2818 if (target_flags_explicit & MASK_VSX)
2819 msg = N_("-mvsx and -mno-altivec are incompatible");
2821 msg = N_("-mno-altivec disables vsx");
2827 target_flags &= ~ MASK_VSX;
2828 target_flags_explicit |= MASK_VSX;
2832 /* For the newer switches (vsx, dfp, etc.) set some of the older options,
2833 unless the user explicitly used the -mno-<option> to disable the code. */
2835 target_flags |= (ISA_2_6_MASKS_SERVER & ~target_flags_explicit);
2836 else if (TARGET_POPCNTD)
2837 target_flags |= (ISA_2_6_MASKS_EMBEDDED & ~target_flags_explicit);
2838 else if (TARGET_DFP)
2839 target_flags |= (ISA_2_5_MASKS_SERVER & ~target_flags_explicit);
2840 else if (TARGET_CMPB)
2841 target_flags |= (ISA_2_5_MASKS_EMBEDDED & ~target_flags_explicit);
2842 else if (TARGET_FPRND)
2843 target_flags |= (ISA_2_4_MASKS & ~target_flags_explicit);
2844 else if (TARGET_POPCNTB)
2845 target_flags |= (ISA_2_2_MASKS & ~target_flags_explicit);
2846 else if (TARGET_ALTIVEC)
2847 target_flags |= (MASK_PPC_GFXOPT & ~target_flags_explicit);
2849 /* E500mc does "better" if we inline more aggressively. Respect the
2850 user's opinion, though. */
2851 if (rs6000_block_move_inline_limit == 0
2852 && (rs6000_cpu == PROCESSOR_PPCE500MC
2853 || rs6000_cpu == PROCESSOR_PPCE500MC64))
2854 rs6000_block_move_inline_limit = 128;
2856 /* store_one_arg depends on expand_block_move to handle at least the
2857 size of reg_parm_stack_space. */
2858 if (rs6000_block_move_inline_limit < (TARGET_POWERPC64 ? 64 : 32))
2859 rs6000_block_move_inline_limit = (TARGET_POWERPC64 ? 64 : 32);
2863 /* If the appropriate debug option is enabled, replace the target hooks
2864 with debug versions that call the real version and then prints
2865 debugging information. */
2866 if (TARGET_DEBUG_COST)
2868 targetm.rtx_costs = rs6000_debug_rtx_costs;
2869 targetm.address_cost = rs6000_debug_address_cost;
2870 targetm.sched.adjust_cost = rs6000_debug_adjust_cost;
2873 if (TARGET_DEBUG_ADDR)
2875 targetm.legitimate_address_p = rs6000_debug_legitimate_address_p;
2876 targetm.legitimize_address = rs6000_debug_legitimize_address;
2877 rs6000_secondary_reload_class_ptr
2878 = rs6000_debug_secondary_reload_class;
2879 rs6000_secondary_memory_needed_ptr
2880 = rs6000_debug_secondary_memory_needed;
2881 rs6000_cannot_change_mode_class_ptr
2882 = rs6000_debug_cannot_change_mode_class;
2883 rs6000_preferred_reload_class_ptr
2884 = rs6000_debug_preferred_reload_class;
2885 rs6000_legitimize_reload_address_ptr
2886 = rs6000_debug_legitimize_reload_address;
2887 rs6000_mode_dependent_address_ptr
2888 = rs6000_debug_mode_dependent_address;
2891 if (rs6000_veclibabi_name)
2893 if (strcmp (rs6000_veclibabi_name, "mass") == 0)
2894 rs6000_veclib_handler = rs6000_builtin_vectorized_libmass;
2897 error ("unknown vectorization library ABI type (%s) for "
2898 "-mveclibabi= switch", rs6000_veclibabi_name);
2904 if (!rs6000_explicit_options.long_double)
2906 if (main_target_opt != NULL
2907 && (main_target_opt->x_rs6000_long_double_type_size
2908 != RS6000_DEFAULT_LONG_DOUBLE_SIZE))
2909 error ("target attribute or pragma changes long double size");
2911 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2914 #ifndef POWERPC_LINUX
2915 if (!rs6000_explicit_options.ieee)
2916 rs6000_ieeequad = 1;
2919 /* Disable VSX and Altivec silently if the user switched cpus to power7 in a
2920 target attribute or pragma which automatically enables both options,
2921 unless the altivec ABI was set. This is set by default for 64-bit, but
2923 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2924 target_flags &= ~((MASK_VSX | MASK_ALTIVEC) & ~target_flags_explicit);
2926 /* Enable Altivec ABI for AIX -maltivec. */
2927 if (TARGET_XCOFF && (TARGET_ALTIVEC || TARGET_VSX))
2929 if (main_target_opt != NULL && !main_target_opt->x_rs6000_altivec_abi)
2930 error ("target attribute or pragma changes AltiVec ABI");
2932 rs6000_altivec_abi = 1;
2935 /* The AltiVec ABI is the default for PowerPC-64 GNU/Linux. For
2936 PowerPC-32 GNU/Linux, -maltivec implies the AltiVec ABI. It can
2937 be explicitly overridden in either case. */
2940 if (!rs6000_explicit_options.altivec_abi
2941 && (TARGET_64BIT || TARGET_ALTIVEC || TARGET_VSX))
2943 if (main_target_opt != NULL &&
2944 !main_target_opt->x_rs6000_altivec_abi)
2945 error ("target attribute or pragma changes AltiVec ABI");
2947 rs6000_altivec_abi = 1;
2950 /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
2951 if (!rs6000_explicit_options.vrsave)
2952 TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
2955 /* Set the Darwin64 ABI as default for 64-bit Darwin.
2956 So far, the only darwin64 targets are also MACH-O. */
2958 && DEFAULT_ABI == ABI_DARWIN
2961 if (main_target_opt != NULL && !main_target_opt->x_rs6000_darwin64_abi)
2962 error ("target attribute or pragma changes darwin64 ABI");
2965 rs6000_darwin64_abi = 1;
2966 /* Default to natural alignment, for better performance. */
2967 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2971 /* Place FP constants in the constant pool instead of TOC
2972 if section anchors enabled. */
2973 if (flag_section_anchors)
2974 TARGET_NO_FP_IN_TOC = 1;
2976 #ifdef SUBTARGET_OVERRIDE_OPTIONS
2977 SUBTARGET_OVERRIDE_OPTIONS;
2979 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
2980 SUBSUBTARGET_OVERRIDE_OPTIONS;
2982 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
2983 SUB3TARGET_OVERRIDE_OPTIONS;
2986 if (TARGET_E500 || rs6000_cpu == PROCESSOR_PPCE500MC
2987 || rs6000_cpu == PROCESSOR_PPCE500MC64)
2989 /* The e500 and e500mc do not have string instructions, and we set
2990 MASK_STRING above when optimizing for size. */
2991 if ((target_flags & MASK_STRING) != 0)
2992 target_flags = target_flags & ~MASK_STRING;
2994 else if (rs6000_select[1].string != NULL)
2996 /* For the powerpc-eabispe configuration, we set all these by
2997 default, so let's unset them if we manually set another
2998 CPU that is not the E500. */
2999 if (main_target_opt != NULL
3000 && ((main_target_opt->x_rs6000_spe_abi != rs6000_spe_abi)
3001 || (main_target_opt->x_rs6000_spe != rs6000_spe)
3002 || (main_target_opt->x_rs6000_float_gprs != rs6000_float_gprs)))
3003 error ("target attribute or pragma changes SPE ABI");
3006 if (!rs6000_explicit_options.spe_abi)
3008 if (!rs6000_explicit_options.spe)
3010 if (!rs6000_explicit_options.float_gprs)
3011 rs6000_float_gprs = 0;
3013 if (!(target_flags_explicit & MASK_ISEL))
3014 target_flags &= ~MASK_ISEL;
3017 /* Detect invalid option combinations with E500. */
3020 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
3021 && rs6000_cpu != PROCESSOR_POWER5
3022 && rs6000_cpu != PROCESSOR_POWER6
3023 && rs6000_cpu != PROCESSOR_POWER7
3024 && rs6000_cpu != PROCESSOR_PPCA2
3025 && rs6000_cpu != PROCESSOR_CELL);
3026 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
3027 || rs6000_cpu == PROCESSOR_POWER5
3028 || rs6000_cpu == PROCESSOR_POWER7);
3029 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
3030 || rs6000_cpu == PROCESSOR_POWER5
3031 || rs6000_cpu == PROCESSOR_POWER6
3032 || rs6000_cpu == PROCESSOR_POWER7
3033 || rs6000_cpu == PROCESSOR_PPCE500MC
3034 || rs6000_cpu == PROCESSOR_PPCE500MC64);
3036 /* Allow debug switches to override the above settings. These are set to -1
3037 in rs6000.opt to indicate the user hasn't directly set the switch. */
3038 if (TARGET_ALWAYS_HINT >= 0)
3039 rs6000_always_hint = TARGET_ALWAYS_HINT;
3041 if (TARGET_SCHED_GROUPS >= 0)
3042 rs6000_sched_groups = TARGET_SCHED_GROUPS;
3044 if (TARGET_ALIGN_BRANCH_TARGETS >= 0)
3045 rs6000_align_branch_targets = TARGET_ALIGN_BRANCH_TARGETS;
3047 rs6000_sched_restricted_insns_priority
3048 = (rs6000_sched_groups ? 1 : 0);
3050 /* Handle -msched-costly-dep option. */
3051 rs6000_sched_costly_dep
3052 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
3054 if (rs6000_sched_costly_dep_str)
3056 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
3057 rs6000_sched_costly_dep = no_dep_costly;
3058 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
3059 rs6000_sched_costly_dep = all_deps_costly;
3060 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
3061 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
3062 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
3063 rs6000_sched_costly_dep = store_to_load_dep_costly;
3065 rs6000_sched_costly_dep = ((enum rs6000_dependence_cost)
3066 atoi (rs6000_sched_costly_dep_str));
3069 /* Handle -minsert-sched-nops option. */
3070 rs6000_sched_insert_nops
3071 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
3073 if (rs6000_sched_insert_nops_str)
3075 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
3076 rs6000_sched_insert_nops = sched_finish_none;
3077 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
3078 rs6000_sched_insert_nops = sched_finish_pad_groups;
3079 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
3080 rs6000_sched_insert_nops = sched_finish_regroup_exact;
3082 rs6000_sched_insert_nops = ((enum rs6000_nop_insertion)
3083 atoi (rs6000_sched_insert_nops_str));
3088 #ifdef TARGET_REGNAMES
3089 /* If the user desires alternate register names, copy in the
3090 alternate names now. */
3091 if (TARGET_REGNAMES)
3092 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
3095 /* Set aix_struct_return last, after the ABI is determined.
3096 If -maix-struct-return or -msvr4-struct-return was explicitly
3097 used, don't override with the ABI default. */
3098 if (!rs6000_explicit_options.aix_struct_ret)
3099 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
3102 /* IBM XL compiler defaults to unsigned bitfields. */
3103 if (TARGET_XL_COMPAT)
3104 flag_signed_bitfields = 0;
3107 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
3108 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
3111 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
3113 /* We can only guarantee the availability of DI pseudo-ops when
3114 assembling for 64-bit targets. */
3117 targetm.asm_out.aligned_op.di = NULL;
3118 targetm.asm_out.unaligned_op.di = NULL;
3122 /* Set branch target alignment, if not optimizing for size. */
3125 /* Cell wants to be aligned 8byte for dual issue. Titan wants to be
3126 aligned 8byte to avoid misprediction by the branch predictor. */
3127 if (rs6000_cpu == PROCESSOR_TITAN
3128 || rs6000_cpu == PROCESSOR_CELL)
3130 if (align_functions <= 0)
3131 align_functions = 8;
3132 if (align_jumps <= 0)
3134 if (align_loops <= 0)
3137 if (rs6000_align_branch_targets)
3139 if (align_functions <= 0)
3140 align_functions = 16;
3141 if (align_jumps <= 0)
3143 if (align_loops <= 0)
3145 can_override_loop_align = 1;
3149 if (align_jumps_max_skip <= 0)
3150 align_jumps_max_skip = 15;
3151 if (align_loops_max_skip <= 0)
3152 align_loops_max_skip = 15;
3155 /* Arrange to save and restore machine status around nested functions. */
3156 init_machine_status = rs6000_init_machine_status;
3158 /* We should always be splitting complex arguments, but we can't break
3159 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
3160 if (DEFAULT_ABI != ABI_AIX)
3161 targetm.calls.split_complex_arg = NULL;
3164 /* Initialize rs6000_cost with the appropriate target costs. */
3166 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
3170 case PROCESSOR_RIOS1:
3171 rs6000_cost = &rios1_cost;
3174 case PROCESSOR_RIOS2:
3175 rs6000_cost = &rios2_cost;
3178 case PROCESSOR_RS64A:
3179 rs6000_cost = &rs64a_cost;
3182 case PROCESSOR_MPCCORE:
3183 rs6000_cost = &mpccore_cost;
3186 case PROCESSOR_PPC403:
3187 rs6000_cost = &ppc403_cost;
3190 case PROCESSOR_PPC405:
3191 rs6000_cost = &ppc405_cost;
3194 case PROCESSOR_PPC440:
3195 rs6000_cost = &ppc440_cost;
3198 case PROCESSOR_PPC476:
3199 rs6000_cost = &ppc476_cost;
3202 case PROCESSOR_PPC601:
3203 rs6000_cost = &ppc601_cost;
3206 case PROCESSOR_PPC603:
3207 rs6000_cost = &ppc603_cost;
3210 case PROCESSOR_PPC604:
3211 rs6000_cost = &ppc604_cost;
3214 case PROCESSOR_PPC604e:
3215 rs6000_cost = &ppc604e_cost;
3218 case PROCESSOR_PPC620:
3219 rs6000_cost = &ppc620_cost;
3222 case PROCESSOR_PPC630:
3223 rs6000_cost = &ppc630_cost;
3226 case PROCESSOR_CELL:
3227 rs6000_cost = &ppccell_cost;
3230 case PROCESSOR_PPC750:
3231 case PROCESSOR_PPC7400:
3232 rs6000_cost = &ppc750_cost;
3235 case PROCESSOR_PPC7450:
3236 rs6000_cost = &ppc7450_cost;
3239 case PROCESSOR_PPC8540:
3240 rs6000_cost = &ppc8540_cost;
3243 case PROCESSOR_PPCE300C2:
3244 case PROCESSOR_PPCE300C3:
3245 rs6000_cost = &ppce300c2c3_cost;
3248 case PROCESSOR_PPCE500MC:
3249 rs6000_cost = &ppce500mc_cost;
3252 case PROCESSOR_PPCE500MC64:
3253 rs6000_cost = &ppce500mc64_cost;
3256 case PROCESSOR_TITAN:
3257 rs6000_cost = &titan_cost;
3260 case PROCESSOR_POWER4:
3261 case PROCESSOR_POWER5:
3262 rs6000_cost = &power4_cost;
3265 case PROCESSOR_POWER6:
3266 rs6000_cost = &power6_cost;
3269 case PROCESSOR_POWER7:
3270 rs6000_cost = &power7_cost;
3273 case PROCESSOR_PPCA2:
3274 rs6000_cost = &ppca2_cost;
3283 maybe_set_param_value (PARAM_SIMULTANEOUS_PREFETCHES,
3284 rs6000_cost->simultaneous_prefetches,
3285 global_options.x_param_values,
3286 global_options_set.x_param_values);
3287 maybe_set_param_value (PARAM_L1_CACHE_SIZE, rs6000_cost->l1_cache_size,
3288 global_options.x_param_values,
3289 global_options_set.x_param_values);
3290 maybe_set_param_value (PARAM_L1_CACHE_LINE_SIZE,
3291 rs6000_cost->cache_line_size,
3292 global_options.x_param_values,
3293 global_options_set.x_param_values);
3294 maybe_set_param_value (PARAM_L2_CACHE_SIZE, rs6000_cost->l2_cache_size,
3295 global_options.x_param_values,
3296 global_options_set.x_param_values);
3298 /* If using typedef char *va_list, signal that
3299 __builtin_va_start (&ap, 0) can be optimized to
3300 ap = __builtin_next_arg (0). */
3301 if (DEFAULT_ABI != ABI_V4)
3302 targetm.expand_builtin_va_start = NULL;
3305 /* Set up single/double float flags.
3306 If TARGET_HARD_FLOAT is set, but neither single or double is set,
3307 then set both flags. */
3308 if (TARGET_HARD_FLOAT && TARGET_FPRS
3309 && rs6000_single_float == 0 && rs6000_double_float == 0)
3310 rs6000_single_float = rs6000_double_float = 1;
3312 /* Reset single and double FP flags if target is E500. */
3315 rs6000_single_float = rs6000_double_float = 0;
3316 if (TARGET_E500_SINGLE)
3317 rs6000_single_float = 1;
3318 if (TARGET_E500_DOUBLE)
3319 rs6000_single_float = rs6000_double_float = 1;
3322 if (main_target_opt)
3324 if (main_target_opt->x_rs6000_single_float != rs6000_single_float)
3325 error ("target attribute or pragma changes single precision floating "
3327 if (main_target_opt->x_rs6000_double_float != rs6000_double_float)
3328 error ("target attribute or pragma changes double precision floating "
3332 /* If not explicitly specified via option, decide whether to generate indexed
3333 load/store instructions. */
3334 if (TARGET_AVOID_XFORM == -1)
3335 /* Avoid indexed addressing when targeting Power6 in order to avoid the
3336 DERAT mispredict penalty. However the LVE and STVE altivec instructions
3337 need indexed accesses and the type used is the scalar type of the element
3338 being loaded or stored. */
3339 TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB
3340 && !TARGET_ALTIVEC);
3342 /* Set the -mrecip options. */
3343 if (rs6000_recip_name)
3345 char *p = ASTRDUP (rs6000_recip_name);
3347 unsigned int mask, i;
3350 while ((q = strtok (p, ",")) != NULL)
3361 if (!strcmp (q, "default"))
3362 mask = ((TARGET_RECIP_PRECISION)
3363 ? RECIP_HIGH_PRECISION : RECIP_LOW_PRECISION);
3366 for (i = 0; i < ARRAY_SIZE (recip_options); i++)
3367 if (!strcmp (q, recip_options[i].string))
3369 mask = recip_options[i].mask;
3373 if (i == ARRAY_SIZE (recip_options))
3375 error ("unknown option for -mrecip=%s", q);
3383 rs6000_recip_control &= ~mask;
3385 rs6000_recip_control |= mask;
3389 rs6000_init_hard_regno_mode_ok (global_init_p);
3391 /* Save the initial options in case the user does function specific options */
3393 target_option_default_node = target_option_current_node
3394 = build_target_option_node ();
3399 /* Implement TARGET_OPTION_OVERRIDE. On the RS/6000 this is used to
3400 define the target cpu type. */
3403 rs6000_option_override (void)
3405 (void) rs6000_option_override_internal (true);
3409 /* Implement targetm.vectorize.builtin_mask_for_load. */
3411 rs6000_builtin_mask_for_load (void)
3413 if (TARGET_ALTIVEC || TARGET_VSX)
3414 return altivec_builtin_mask_for_load;
3419 /* Implement LOOP_ALIGN. */
3421 rs6000_loop_align (rtx label)
3426 /* Don't override loop alignment if -falign-loops was specified. */
3427 if (!can_override_loop_align)
3428 return align_loops_log;
3430 bb = BLOCK_FOR_INSN (label);
3431 ninsns = num_loop_insns(bb->loop_father);
3433 /* Align small loops to 32 bytes to fit in an icache sector, otherwise return default. */
3434 if (ninsns > 4 && ninsns <= 8
3435 && (rs6000_cpu == PROCESSOR_POWER4
3436 || rs6000_cpu == PROCESSOR_POWER5
3437 || rs6000_cpu == PROCESSOR_POWER6
3438 || rs6000_cpu == PROCESSOR_POWER7))
3441 return align_loops_log;
3444 /* Implement TARGET_LOOP_ALIGN_MAX_SKIP. */
3446 rs6000_loop_align_max_skip (rtx label)
3448 return (1 << rs6000_loop_align (label)) - 1;
3451 /* Implement targetm.vectorize.builtin_conversion.
3452 Returns a decl of a function that implements conversion of an integer vector
3453 into a floating-point vector, or vice-versa. DEST_TYPE is the
3454 destination type and SRC_TYPE the source type of the conversion.
3455 Return NULL_TREE if it is not available. */
3457 rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
3459 enum tree_code code = (enum tree_code) tcode;
3463 case FIX_TRUNC_EXPR:
3464 switch (TYPE_MODE (dest_type))
3467 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3470 return TYPE_UNSIGNED (dest_type)
3471 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
3472 : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
3475 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3478 return TYPE_UNSIGNED (dest_type)
3479 ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
3480 : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
3487 switch (TYPE_MODE (src_type))
3490 if (!VECTOR_UNIT_VSX_P (V2DFmode))
3493 return TYPE_UNSIGNED (src_type)
3494 ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
3495 : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
3498 if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
3501 return TYPE_UNSIGNED (src_type)
3502 ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
3503 : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
3514 /* Implement targetm.vectorize.builtin_mul_widen_even. */
3516 rs6000_builtin_mul_widen_even (tree type)
3518 if (!TARGET_ALTIVEC)
3521 switch (TYPE_MODE (type))
3524 return TYPE_UNSIGNED (type)
3525 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH_UNS]
3526 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
3529 return TYPE_UNSIGNED (type)
3530 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB_UNS]
3531 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
3537 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
3539 rs6000_builtin_mul_widen_odd (tree type)
3541 if (!TARGET_ALTIVEC)
3544 switch (TYPE_MODE (type))
3547 return TYPE_UNSIGNED (type)
3548 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH_UNS]
3549 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
3552 return TYPE_UNSIGNED (type)
3553 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB_UNS]
3554 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
3561 /* Return true iff, data reference of TYPE can reach vector alignment (16)
3562 after applying N number of iterations. This routine does not determine
3563 how may iterations are required to reach desired alignment. */
3566 rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
3573 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
3576 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
3586 /* Assuming that all other types are naturally aligned. CHECKME! */
3591 /* Return true if the vector misalignment factor is supported by the
3594 rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
3601 /* Return if movmisalign pattern is not supported for this mode. */
3602 if (optab_handler (movmisalign_optab, mode) == CODE_FOR_nothing)
3605 if (misalignment == -1)
3607 /* Misalignment factor is unknown at compile time but we know
3608 it's word aligned. */
3609 if (rs6000_vector_alignment_reachable (type, is_packed))
3611 int element_size = TREE_INT_CST_LOW (TYPE_SIZE (type));
3613 if (element_size == 64 || element_size == 32)
3620 /* VSX supports word-aligned vector. */
3621 if (misalignment % 4 == 0)
3627 /* Implement targetm.vectorize.builtin_vec_perm. */
3629 rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
3631 tree inner_type = TREE_TYPE (type);
3632 bool uns_p = TYPE_UNSIGNED (inner_type);
3635 *mask_element_type = unsigned_char_type_node;
3637 switch (TYPE_MODE (type))
3641 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
3642 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
3647 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
3648 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
3653 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
3654 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
3658 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
3662 if (!TARGET_ALLOW_DF_PERMUTE)
3665 d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
3669 if (!TARGET_ALLOW_DF_PERMUTE)
3673 ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
3674 : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
3686 /* Implement targetm.vectorize.builtin_vectorization_cost. */
3688 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
3689 tree vectype, int misalign)
3693 switch (type_of_cost)
3703 case cond_branch_not_taken:
3707 case cond_branch_taken:
3710 case unaligned_load:
3711 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3713 elements = TYPE_VECTOR_SUBPARTS (vectype);
3715 /* Double word aligned. */
3723 /* Double word aligned. */
3727 /* Unknown misalignment. */
3740 /* Misaligned loads are not supported. */
3745 case unaligned_store:
3746 if (TARGET_VSX && TARGET_ALLOW_MOVMISALIGN)
3748 elements = TYPE_VECTOR_SUBPARTS (vectype);
3750 /* Double word aligned. */
3758 /* Double word aligned. */
3762 /* Unknown misalignment. */
3775 /* Misaligned stores are not supported. */
3785 /* Implement targetm.vectorize.preferred_simd_mode. */
3787 static enum machine_mode
3788 rs6000_preferred_simd_mode (enum machine_mode mode)
3797 if (TARGET_ALTIVEC || TARGET_VSX)
3821 if (TARGET_PAIRED_FLOAT
3827 /* Implement TARGET_OPTION_INIT_STRUCT. */
3830 rs6000_option_init_struct (struct gcc_options *opts)
3832 if (DEFAULT_ABI == ABI_DARWIN)
3833 /* The Darwin libraries never set errno, so we might as well
3834 avoid calling them when that's the only reason we would. */
3835 opts->x_flag_errno_math = 0;
3837 /* Enable section anchors by default. */
3839 opts->x_flag_section_anchors = 1;
3842 /* Implement TARGET_OPTION_DEFAULT_PARAMS. */
3845 rs6000_option_default_params (void)
3847 /* Double growth factor to counter reduced min jump length. */
3848 set_default_param_value (PARAM_MAX_GROW_COPY_BB_INSNS, 16);
3851 static enum fpu_type_t
3852 rs6000_parse_fpu_option (const char *option)
3854 if (!strcmp("none", option)) return FPU_NONE;
3855 if (!strcmp("sp_lite", option)) return FPU_SF_LITE;
3856 if (!strcmp("dp_lite", option)) return FPU_DF_LITE;
3857 if (!strcmp("sp_full", option)) return FPU_SF_FULL;
3858 if (!strcmp("dp_full", option)) return FPU_DF_FULL;
3859 error("unknown value %s for -mfpu", option);
3864 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
3865 library with vectorized intrinsics. */
3868 rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in)
3871 const char *suffix = NULL;
3872 tree fntype, new_fndecl, bdecl = NULL_TREE;
3875 enum machine_mode el_mode, in_mode;
3878 /* Libmass is suitable for unsafe math only as it does not correctly support
3879 parts of IEEE with the required precision such as denormals. Only support
3880 it if we have VSX to use the simd d2 or f4 functions.
3881 XXX: Add variable length support. */
3882 if (!flag_unsafe_math_optimizations || !TARGET_VSX)
3885 el_mode = TYPE_MODE (TREE_TYPE (type_out));
3886 n = TYPE_VECTOR_SUBPARTS (type_out);
3887 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3888 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3889 if (el_mode != in_mode
3893 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3895 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
3898 case BUILT_IN_ATAN2:
3899 case BUILT_IN_HYPOT:
3905 case BUILT_IN_ACOSH:
3907 case BUILT_IN_ASINH:
3909 case BUILT_IN_ATANH:
3917 case BUILT_IN_EXPM1:
3918 case BUILT_IN_LGAMMA:
3919 case BUILT_IN_LOG10:
3920 case BUILT_IN_LOG1P:
3928 bdecl = implicit_built_in_decls[fn];
3929 suffix = "d2"; /* pow -> powd2 */
3930 if (el_mode != DFmode
3935 case BUILT_IN_ATAN2F:
3936 case BUILT_IN_HYPOTF:
3941 case BUILT_IN_ACOSF:
3942 case BUILT_IN_ACOSHF:
3943 case BUILT_IN_ASINF:
3944 case BUILT_IN_ASINHF:
3945 case BUILT_IN_ATANF:
3946 case BUILT_IN_ATANHF:
3947 case BUILT_IN_CBRTF:
3949 case BUILT_IN_COSHF:
3951 case BUILT_IN_ERFCF:
3952 case BUILT_IN_EXP2F:
3954 case BUILT_IN_EXPM1F:
3955 case BUILT_IN_LGAMMAF:
3956 case BUILT_IN_LOG10F:
3957 case BUILT_IN_LOG1PF:
3958 case BUILT_IN_LOG2F:
3961 case BUILT_IN_SINHF:
3962 case BUILT_IN_SQRTF:
3964 case BUILT_IN_TANHF:
3965 bdecl = implicit_built_in_decls[fn];
3966 suffix = "4"; /* powf -> powf4 */
3967 if (el_mode != SFmode
3979 gcc_assert (suffix != NULL);
3980 bname = IDENTIFIER_POINTER (DECL_NAME (bdecl));
3981 strcpy (name, bname + sizeof ("__builtin_") - 1);
3982 strcat (name, suffix);
3985 fntype = build_function_type_list (type_out, type_in, NULL);
3986 else if (n_args == 2)
3987 fntype = build_function_type_list (type_out, type_in, type_in, NULL);
3991 /* Build a function declaration for the vectorized function. */
3992 new_fndecl = build_decl (BUILTINS_LOCATION,
3993 FUNCTION_DECL, get_identifier (name), fntype);
3994 TREE_PUBLIC (new_fndecl) = 1;
3995 DECL_EXTERNAL (new_fndecl) = 1;
3996 DECL_IS_NOVOPS (new_fndecl) = 1;
3997 TREE_READONLY (new_fndecl) = 1;
4002 /* Returns a function decl for a vectorized version of the builtin function
4003 with builtin function code FN and the result vector type TYPE, or NULL_TREE
4004 if it is not available. */
4007 rs6000_builtin_vectorized_function (tree fndecl, tree type_out,
4010 enum machine_mode in_mode, out_mode;
4013 if (TREE_CODE (type_out) != VECTOR_TYPE
4014 || TREE_CODE (type_in) != VECTOR_TYPE
4015 || !TARGET_VECTORIZE_BUILTINS)
4018 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4019 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4020 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4021 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4023 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
4025 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
4028 case BUILT_IN_COPYSIGN:
4029 if (VECTOR_UNIT_VSX_P (V2DFmode)
4030 && out_mode == DFmode && out_n == 2
4031 && in_mode == DFmode && in_n == 2)
4032 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNDP];
4034 case BUILT_IN_COPYSIGNF:
4035 if (out_mode != SFmode || out_n != 4
4036 || in_mode != SFmode || in_n != 4)
4038 if (VECTOR_UNIT_VSX_P (V4SFmode))
4039 return rs6000_builtin_decls[VSX_BUILTIN_CPSGNSP];
4040 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4041 return rs6000_builtin_decls[ALTIVEC_BUILTIN_COPYSIGN_V4SF];
4044 if (VECTOR_UNIT_VSX_P (V2DFmode)
4045 && out_mode == DFmode && out_n == 2
4046 && in_mode == DFmode && in_n == 2)
4047 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTDP];
4049 case BUILT_IN_SQRTF:
4050 if (VECTOR_UNIT_VSX_P (V4SFmode)
4051 && out_mode == SFmode && out_n == 4
4052 && in_mode == SFmode && in_n == 4)
4053 return rs6000_builtin_decls[VSX_BUILTIN_XVSQRTSP];
4056 if (VECTOR_UNIT_VSX_P (V2DFmode)
4057 && out_mode == DFmode && out_n == 2
4058 && in_mode == DFmode && in_n == 2)
4059 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIP];
4061 case BUILT_IN_CEILF:
4062 if (out_mode != SFmode || out_n != 4
4063 || in_mode != SFmode || in_n != 4)
4065 if (VECTOR_UNIT_VSX_P (V4SFmode))
4066 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIP];
4067 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4068 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIP];
4070 case BUILT_IN_FLOOR:
4071 if (VECTOR_UNIT_VSX_P (V2DFmode)
4072 && out_mode == DFmode && out_n == 2
4073 && in_mode == DFmode && in_n == 2)
4074 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIM];
4076 case BUILT_IN_FLOORF:
4077 if (out_mode != SFmode || out_n != 4
4078 || in_mode != SFmode || in_n != 4)
4080 if (VECTOR_UNIT_VSX_P (V4SFmode))
4081 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIM];
4082 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4083 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIM];
4086 if (VECTOR_UNIT_VSX_P (V2DFmode)
4087 && out_mode == DFmode && out_n == 2
4088 && in_mode == DFmode && in_n == 2)
4089 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDDP];
4092 if (VECTOR_UNIT_VSX_P (V4SFmode)
4093 && out_mode == SFmode && out_n == 4
4094 && in_mode == SFmode && in_n == 4)
4095 return rs6000_builtin_decls[VSX_BUILTIN_XVMADDSP];
4096 else if (VECTOR_UNIT_ALTIVEC_P (V4SFmode)
4097 && out_mode == SFmode && out_n == 4
4098 && in_mode == SFmode && in_n == 4)
4099 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VMADDFP];
4101 case BUILT_IN_TRUNC:
4102 if (VECTOR_UNIT_VSX_P (V2DFmode)
4103 && out_mode == DFmode && out_n == 2
4104 && in_mode == DFmode && in_n == 2)
4105 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIZ];
4107 case BUILT_IN_TRUNCF:
4108 if (out_mode != SFmode || out_n != 4
4109 || in_mode != SFmode || in_n != 4)
4111 if (VECTOR_UNIT_VSX_P (V4SFmode))
4112 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIZ];
4113 if (VECTOR_UNIT_ALTIVEC_P (V4SFmode))
4114 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRFIZ];
4116 case BUILT_IN_NEARBYINT:
4117 if (VECTOR_UNIT_VSX_P (V2DFmode)
4118 && flag_unsafe_math_optimizations
4119 && out_mode == DFmode && out_n == 2
4120 && in_mode == DFmode && in_n == 2)
4121 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPI];
4123 case BUILT_IN_NEARBYINTF:
4124 if (VECTOR_UNIT_VSX_P (V4SFmode)
4125 && flag_unsafe_math_optimizations
4126 && out_mode == SFmode && out_n == 4
4127 && in_mode == SFmode && in_n == 4)
4128 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPI];
4131 if (VECTOR_UNIT_VSX_P (V2DFmode)
4132 && !flag_trapping_math
4133 && out_mode == DFmode && out_n == 2
4134 && in_mode == DFmode && in_n == 2)
4135 return rs6000_builtin_decls[VSX_BUILTIN_XVRDPIC];
4137 case BUILT_IN_RINTF:
4138 if (VECTOR_UNIT_VSX_P (V4SFmode)
4139 && !flag_trapping_math
4140 && out_mode == SFmode && out_n == 4
4141 && in_mode == SFmode && in_n == 4)
4142 return rs6000_builtin_decls[VSX_BUILTIN_XVRSPIC];
4149 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4151 enum rs6000_builtins fn
4152 = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
4155 case RS6000_BUILTIN_RSQRTF:
4156 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4157 && out_mode == SFmode && out_n == 4
4158 && in_mode == SFmode && in_n == 4)
4159 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRSQRTFP];
4161 case RS6000_BUILTIN_RSQRT:
4162 if (VECTOR_UNIT_VSX_P (V2DFmode)
4163 && out_mode == DFmode && out_n == 2
4164 && in_mode == DFmode && in_n == 2)
4165 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
4167 case RS6000_BUILTIN_RECIPF:
4168 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
4169 && out_mode == SFmode && out_n == 4
4170 && in_mode == SFmode && in_n == 4)
4171 return rs6000_builtin_decls[ALTIVEC_BUILTIN_VRECIPFP];
4173 case RS6000_BUILTIN_RECIP:
4174 if (VECTOR_UNIT_VSX_P (V2DFmode)
4175 && out_mode == DFmode && out_n == 2
4176 && in_mode == DFmode && in_n == 2)
4177 return rs6000_builtin_decls[VSX_BUILTIN_RECIP_V2DF];
4184 /* Generate calls to libmass if appropriate. */
4185 if (rs6000_veclib_handler)
4186 return rs6000_veclib_handler (fndecl, type_out, type_in);
4192 /* Implement TARGET_HANDLE_OPTION. */
4195 rs6000_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
4196 const struct cl_decoded_option *decoded,
4197 location_t loc ATTRIBUTE_UNUSED)
4199 enum fpu_type_t fpu_type = FPU_NONE;
4201 size_t code = decoded->opt_index;
4202 const char *arg = decoded->arg;
4203 int value = decoded->value;
4205 gcc_assert (opts == &global_options);
4206 gcc_assert (opts_set == &global_options_set);
4211 target_flags &= ~(MASK_POWER | MASK_POWER2
4212 | MASK_MULTIPLE | MASK_STRING);
4213 target_flags_explicit |= (MASK_POWER | MASK_POWER2
4214 | MASK_MULTIPLE | MASK_STRING);
4216 case OPT_mno_powerpc:
4217 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
4218 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4219 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
4220 | MASK_PPC_GFXOPT | MASK_POWERPC64);
4223 target_flags &= ~MASK_MINIMAL_TOC;
4224 TARGET_NO_FP_IN_TOC = 0;
4225 TARGET_NO_SUM_IN_TOC = 0;
4226 target_flags_explicit |= MASK_MINIMAL_TOC;
4227 #ifdef TARGET_USES_SYSV4_OPT
4228 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
4229 just the same as -mminimal-toc. */
4230 target_flags |= MASK_MINIMAL_TOC;
4231 target_flags_explicit |= MASK_MINIMAL_TOC;
4235 #ifdef TARGET_USES_SYSV4_OPT
4237 /* Make -mtoc behave like -mminimal-toc. */
4238 target_flags |= MASK_MINIMAL_TOC;
4239 target_flags_explicit |= MASK_MINIMAL_TOC;
4243 #if defined (HAVE_LD_LARGE_TOC) && defined (TARGET_USES_LINUX64_OPT)
4245 if (strcmp (arg, "small") == 0)
4246 rs6000_current_cmodel = CMODEL_SMALL;
4247 else if (strcmp (arg, "medium") == 0)
4248 rs6000_current_cmodel = CMODEL_MEDIUM;
4249 else if (strcmp (arg, "large") == 0)
4250 rs6000_current_cmodel = CMODEL_LARGE;
4253 error ("invalid option for -mcmodel: '%s'", arg);
4256 rs6000_explicit_options.cmodel = true;
4259 #ifdef TARGET_USES_AIX64_OPT
4264 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
4265 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
4266 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
4269 #ifdef TARGET_USES_AIX64_OPT
4274 target_flags &= ~MASK_POWERPC64;
4275 target_flags_explicit |= MASK_POWERPC64;
4278 case OPT_minsert_sched_nops_:
4279 rs6000_sched_insert_nops_str = arg;
4282 case OPT_mminimal_toc:
4285 TARGET_NO_FP_IN_TOC = 0;
4286 TARGET_NO_SUM_IN_TOC = 0;
4293 target_flags |= (MASK_MULTIPLE | MASK_STRING);
4294 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
4301 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4302 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
4306 case OPT_mpowerpc_gpopt:
4307 case OPT_mpowerpc_gfxopt:
4310 target_flags |= MASK_POWERPC;
4311 target_flags_explicit |= MASK_POWERPC;
4315 case OPT_maix_struct_return:
4316 case OPT_msvr4_struct_return:
4317 rs6000_explicit_options.aix_struct_ret = true;
4321 rs6000_explicit_options.vrsave = true;
4322 TARGET_ALTIVEC_VRSAVE = value;
4326 rs6000_explicit_options.spe = true;
4334 while ((q = strtok (p, ",")) != NULL)
4348 if (! strcmp (q, "all"))
4349 mask = MASK_DEBUG_ALL;
4350 else if (! strcmp (q, "stack"))
4351 mask = MASK_DEBUG_STACK;
4352 else if (! strcmp (q, "arg"))
4353 mask = MASK_DEBUG_ARG;
4354 else if (! strcmp (q, "reg"))
4355 mask = MASK_DEBUG_REG;
4356 else if (! strcmp (q, "addr"))
4357 mask = MASK_DEBUG_ADDR;
4358 else if (! strcmp (q, "cost"))
4359 mask = MASK_DEBUG_COST;
4360 else if (! strcmp (q, "target"))
4361 mask = MASK_DEBUG_TARGET;
4363 error ("unknown -mdebug-%s switch", q);
4366 rs6000_debug &= ~mask;
4368 rs6000_debug |= mask;
4372 #ifdef TARGET_USES_SYSV4_OPT
4374 rs6000_abi_name = arg;
4378 rs6000_sdata_name = arg;
4381 case OPT_mtls_size_:
4382 if (strcmp (arg, "16") == 0)
4383 rs6000_tls_size = 16;
4384 else if (strcmp (arg, "32") == 0)
4385 rs6000_tls_size = 32;
4386 else if (strcmp (arg, "64") == 0)
4387 rs6000_tls_size = 64;
4389 error ("bad value %qs for -mtls-size switch", arg);
4392 case OPT_mrelocatable:
4395 target_flags |= MASK_MINIMAL_TOC;
4396 target_flags_explicit |= MASK_MINIMAL_TOC;
4397 TARGET_NO_FP_IN_TOC = 1;
4401 case OPT_mrelocatable_lib:
4404 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4405 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
4406 TARGET_NO_FP_IN_TOC = 1;
4410 target_flags &= ~MASK_RELOCATABLE;
4411 target_flags_explicit |= MASK_RELOCATABLE;
4417 if (!strcmp (arg, "altivec"))
4419 rs6000_explicit_options.altivec_abi = true;
4420 rs6000_altivec_abi = 1;
4422 /* Enabling the AltiVec ABI turns off the SPE ABI. */
4425 else if (! strcmp (arg, "no-altivec"))
4427 rs6000_explicit_options.altivec_abi = true;
4428 rs6000_altivec_abi = 0;
4430 else if (! strcmp (arg, "spe"))
4432 rs6000_explicit_options.spe_abi = true;
4434 rs6000_altivec_abi = 0;
4435 if (!TARGET_SPE_ABI)
4436 error ("not configured for ABI: '%s'", arg);
4438 else if (! strcmp (arg, "no-spe"))
4440 rs6000_explicit_options.spe_abi = true;
4444 /* These are here for testing during development only, do not
4445 document in the manual please. */
4446 else if (! strcmp (arg, "d64"))
4448 rs6000_darwin64_abi = 1;
4449 warning (0, "using darwin64 ABI");
4451 else if (! strcmp (arg, "d32"))
4453 rs6000_darwin64_abi = 0;
4454 warning (0, "using old darwin ABI");
4457 else if (! strcmp (arg, "ibmlongdouble"))
4459 rs6000_explicit_options.ieee = true;
4460 rs6000_ieeequad = 0;
4461 warning (0, "using IBM extended precision long double");
4463 else if (! strcmp (arg, "ieeelongdouble"))
4465 rs6000_explicit_options.ieee = true;
4466 rs6000_ieeequad = 1;
4467 warning (0, "using IEEE extended precision long double");
4472 error ("unknown ABI specified: '%s'", arg);
4478 rs6000_select[1].string = arg;
4479 rs6000_cpu_index = rs6000_cpu_name_lookup (arg);
4480 if (rs6000_cpu_index < 0)
4481 error ("bad value (%s) for -mcpu", arg);
4485 rs6000_select[2].string = arg;
4486 rs6000_tune_index = rs6000_cpu_name_lookup (arg);
4487 if (rs6000_tune_index < 0)
4488 error ("bad value (%s) for -mtune", arg);
4491 case OPT_mtraceback_:
4492 if (! strncmp (arg, "full", 4))
4493 rs6000_traceback = traceback_full;
4494 else if (! strncmp (arg, "part", 4))
4495 rs6000_traceback = traceback_part;
4496 else if (! strncmp (arg, "no", 2))
4497 rs6000_traceback = traceback_none;
4499 error ("unknown -mtraceback arg %qs; expecting %<full%>, "
4500 "%<partial%> or %<none%>", arg);
4503 case OPT_mfloat_gprs_:
4504 rs6000_explicit_options.float_gprs = true;
4505 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
4506 rs6000_float_gprs = 1;
4507 else if (! strcmp (arg, "double"))
4508 rs6000_float_gprs = 2;
4509 else if (! strcmp (arg, "no"))
4510 rs6000_float_gprs = 0;
4513 error ("invalid option for -mfloat-gprs: '%s'", arg);
4518 case OPT_mlong_double_:
4519 rs6000_explicit_options.long_double = true;
4520 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4521 if (value != 64 && value != 128)
4523 error ("unknown switch -mlong-double-%s", arg);
4524 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
4528 rs6000_long_double_type_size = value;
4531 case OPT_msched_costly_dep_:
4532 rs6000_sched_costly_dep_str = arg;
4536 rs6000_explicit_options.alignment = true;
4537 if (! strcmp (arg, "power"))
4539 /* On 64-bit Darwin, power alignment is ABI-incompatible with
4540 some C library functions, so warn about it. The flag may be
4541 useful for performance studies from time to time though, so
4542 don't disable it entirely. */
4543 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
4544 warning (0, "-malign-power is not supported for 64-bit Darwin;"
4545 " it is incompatible with the installed C and C++ libraries");
4546 rs6000_alignment_flags = MASK_ALIGN_POWER;
4548 else if (! strcmp (arg, "natural"))
4549 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
4552 error ("unknown -malign-XXXXX option specified: '%s'", arg);
4557 case OPT_msingle_float:
4558 if (!TARGET_SINGLE_FPU)
4559 warning (0, "-msingle-float option equivalent to -mhard-float");
4560 /* -msingle-float implies -mno-double-float and TARGET_HARD_FLOAT. */
4561 rs6000_double_float = 0;
4562 target_flags &= ~MASK_SOFT_FLOAT;
4563 target_flags_explicit |= MASK_SOFT_FLOAT;
4566 case OPT_mdouble_float:
4567 /* -mdouble-float implies -msingle-float and TARGET_HARD_FLOAT. */
4568 rs6000_single_float = 1;
4569 target_flags &= ~MASK_SOFT_FLOAT;
4570 target_flags_explicit |= MASK_SOFT_FLOAT;
4573 case OPT_msimple_fpu:
4574 if (!TARGET_SINGLE_FPU)
4575 warning (0, "-msimple-fpu option ignored");
4578 case OPT_mhard_float:
4579 /* -mhard_float implies -msingle-float and -mdouble-float. */
4580 rs6000_single_float = rs6000_double_float = 1;
4583 case OPT_msoft_float:
4584 /* -msoft_float implies -mnosingle-float and -mnodouble-float. */
4585 rs6000_single_float = rs6000_double_float = 0;
4589 fpu_type = rs6000_parse_fpu_option(arg);
4590 if (fpu_type != FPU_NONE)
4591 /* If -mfpu is not none, then turn off SOFT_FLOAT, turn on HARD_FLOAT. */
4593 target_flags &= ~MASK_SOFT_FLOAT;
4594 target_flags_explicit |= MASK_SOFT_FLOAT;
4595 rs6000_xilinx_fpu = 1;
4596 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_SF_FULL)
4597 rs6000_single_float = 1;
4598 if (fpu_type == FPU_DF_LITE || fpu_type == FPU_DF_FULL)
4599 rs6000_single_float = rs6000_double_float = 1;
4600 if (fpu_type == FPU_SF_LITE || fpu_type == FPU_DF_LITE)
4601 rs6000_simple_fpu = 1;
4605 /* -mfpu=none is equivalent to -msoft-float */
4606 target_flags |= MASK_SOFT_FLOAT;
4607 target_flags_explicit |= MASK_SOFT_FLOAT;
4608 rs6000_single_float = rs6000_double_float = 0;
4612 rs6000_recip_name = (value) ? "default" : "none";
4616 rs6000_recip_name = arg;
4622 /* Do anything needed at the start of the asm file. */
4625 rs6000_file_start (void)
4629 const char *start = buffer;
4630 struct rs6000_cpu_select *ptr;
4631 const char *default_cpu = TARGET_CPU_DEFAULT;
4632 FILE *file = asm_out_file;
4634 default_file_start ();
4636 #ifdef TARGET_BI_ARCH
4637 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
4641 if (flag_verbose_asm)
4643 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
4644 rs6000_select[0].string = default_cpu;
4646 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
4648 ptr = &rs6000_select[i];
4649 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
4651 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
4656 if (PPC405_ERRATUM77)
4658 fprintf (file, "%s PPC405CR_ERRATUM77", start);
4662 #ifdef USING_ELFOS_H
4663 switch (rs6000_sdata)
4665 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
4666 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
4667 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
4668 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
4671 if (rs6000_sdata && g_switch_value)
4673 fprintf (file, "%s -G %d", start,
4683 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
4685 switch_to_section (toc_section);
4686 switch_to_section (text_section);
4691 /* Return nonzero if this function is known to have a null epilogue. */
4694 direct_return (void)
4696 if (reload_completed)
4698 rs6000_stack_t *info = rs6000_stack_info ();
4700 if (info->first_gp_reg_save == 32
4701 && info->first_fp_reg_save == 64
4702 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
4703 && ! info->lr_save_p
4704 && ! info->cr_save_p
4705 && info->vrsave_mask == 0
4713 /* Return the number of instructions it takes to form a constant in an
4714 integer register. */
4717 num_insns_constant_wide (HOST_WIDE_INT value)
4719 /* signed constant loadable with {cal|addi} */
4720 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
4723 /* constant loadable with {cau|addis} */
4724 else if ((value & 0xffff) == 0
4725 && (value >> 31 == -1 || value >> 31 == 0))
4728 #if HOST_BITS_PER_WIDE_INT == 64
4729 else if (TARGET_POWERPC64)
4731 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
4732 HOST_WIDE_INT high = value >> 31;
4734 if (high == 0 || high == -1)
4740 return num_insns_constant_wide (high) + 1;
4742 return num_insns_constant_wide (low) + 1;
4744 return (num_insns_constant_wide (high)
4745 + num_insns_constant_wide (low) + 1);
4754 num_insns_constant (rtx op, enum machine_mode mode)
4756 HOST_WIDE_INT low, high;
4758 switch (GET_CODE (op))
4761 #if HOST_BITS_PER_WIDE_INT == 64
4762 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
4763 && mask64_operand (op, mode))
4767 return num_insns_constant_wide (INTVAL (op));
4770 if (mode == SFmode || mode == SDmode)
4775 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4776 if (DECIMAL_FLOAT_MODE_P (mode))
4777 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
4779 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
4780 return num_insns_constant_wide ((HOST_WIDE_INT) l);
4783 if (mode == VOIDmode || mode == DImode)
4785 high = CONST_DOUBLE_HIGH (op);
4786 low = CONST_DOUBLE_LOW (op);
4793 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
4794 if (DECIMAL_FLOAT_MODE_P (mode))
4795 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
4797 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
4798 high = l[WORDS_BIG_ENDIAN == 0];
4799 low = l[WORDS_BIG_ENDIAN != 0];
4803 return (num_insns_constant_wide (low)
4804 + num_insns_constant_wide (high));
4807 if ((high == 0 && low >= 0)
4808 || (high == -1 && low < 0))
4809 return num_insns_constant_wide (low);
4811 else if (mask64_operand (op, mode))
4815 return num_insns_constant_wide (high) + 1;
4818 return (num_insns_constant_wide (high)
4819 + num_insns_constant_wide (low) + 1);
4827 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
4828 If the mode of OP is MODE_VECTOR_INT, this simply returns the
4829 corresponding element of the vector, but for V4SFmode and V2SFmode,
4830 the corresponding "float" is interpreted as an SImode integer. */
4833 const_vector_elt_as_int (rtx op, unsigned int elt)
4837 /* We can't handle V2DImode and V2DFmode vector constants here yet. */
4838 gcc_assert (GET_MODE (op) != V2DImode
4839 && GET_MODE (op) != V2DFmode);
4841 tmp = CONST_VECTOR_ELT (op, elt);
4842 if (GET_MODE (op) == V4SFmode
4843 || GET_MODE (op) == V2SFmode)
4844 tmp = gen_lowpart (SImode, tmp);
4845 return INTVAL (tmp);
4848 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
4849 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
4850 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
4851 all items are set to the same value and contain COPIES replicas of the
4852 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
4853 operand and the others are set to the value of the operand's msb. */
4856 vspltis_constant (rtx op, unsigned step, unsigned copies)
4858 enum machine_mode mode = GET_MODE (op);
4859 enum machine_mode inner = GET_MODE_INNER (mode);
4867 HOST_WIDE_INT splat_val;
4868 HOST_WIDE_INT msb_val;
4870 if (mode == V2DImode || mode == V2DFmode)
4873 nunits = GET_MODE_NUNITS (mode);
4874 bitsize = GET_MODE_BITSIZE (inner);
4875 mask = GET_MODE_MASK (inner);
4877 val = const_vector_elt_as_int (op, nunits - 1);
4879 msb_val = val > 0 ? 0 : -1;
4881 /* Construct the value to be splatted, if possible. If not, return 0. */
4882 for (i = 2; i <= copies; i *= 2)
4884 HOST_WIDE_INT small_val;
4886 small_val = splat_val >> bitsize;
4888 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
4890 splat_val = small_val;
4893 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
4894 if (EASY_VECTOR_15 (splat_val))
4897 /* Also check if we can splat, and then add the result to itself. Do so if
4898 the value is positive, of if the splat instruction is using OP's mode;
4899 for splat_val < 0, the splat and the add should use the same mode. */
4900 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
4901 && (splat_val >= 0 || (step == 1 && copies == 1)))
4904 /* Also check if are loading up the most significant bit which can be done by
4905 loading up -1 and shifting the value left by -1. */
4906 else if (EASY_VECTOR_MSB (splat_val, inner))
4912 /* Check if VAL is present in every STEP-th element, and the
4913 other elements are filled with its most significant bit. */
4914 for (i = 0; i < nunits - 1; ++i)
4916 HOST_WIDE_INT desired_val;
4917 if (((i + 1) & (step - 1)) == 0)
4920 desired_val = msb_val;
4922 if (desired_val != const_vector_elt_as_int (op, i))
4930 /* Return true if OP is of the given MODE and can be synthesized
4931 with a vspltisb, vspltish or vspltisw. */
4934 easy_altivec_constant (rtx op, enum machine_mode mode)
4936 unsigned step, copies;
4938 if (mode == VOIDmode)
4939 mode = GET_MODE (op);
4940 else if (mode != GET_MODE (op))
4943 /* V2DI/V2DF was added with VSX. Only allow 0 and all 1's as easy
4945 if (mode == V2DFmode)
4946 return zero_constant (op, mode);
4948 if (mode == V2DImode)
4950 /* In case the compiler is built 32-bit, CONST_DOUBLE constants are not
4952 if (GET_CODE (CONST_VECTOR_ELT (op, 0)) != CONST_INT
4953 || GET_CODE (CONST_VECTOR_ELT (op, 1)) != CONST_INT)
4956 if (zero_constant (op, mode))
4959 if (INTVAL (CONST_VECTOR_ELT (op, 0)) == -1
4960 && INTVAL (CONST_VECTOR_ELT (op, 1)) == -1)
4966 /* Start with a vspltisw. */
4967 step = GET_MODE_NUNITS (mode) / 4;
4970 if (vspltis_constant (op, step, copies))
4973 /* Then try with a vspltish. */
4979 if (vspltis_constant (op, step, copies))
4982 /* And finally a vspltisb. */
4988 if (vspltis_constant (op, step, copies))
4994 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
4995 result is OP. Abort if it is not possible. */
4998 gen_easy_altivec_constant (rtx op)
5000 enum machine_mode mode = GET_MODE (op);
5001 int nunits = GET_MODE_NUNITS (mode);
5002 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
5003 unsigned step = nunits / 4;
5004 unsigned copies = 1;
5006 /* Start with a vspltisw. */
5007 if (vspltis_constant (op, step, copies))
5008 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
5010 /* Then try with a vspltish. */
5016 if (vspltis_constant (op, step, copies))
5017 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
5019 /* And finally a vspltisb. */
5025 if (vspltis_constant (op, step, copies))
5026 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
5032 output_vec_const_move (rtx *operands)
5035 enum machine_mode mode;
5040 mode = GET_MODE (dest);
5044 if (zero_constant (vec, mode))
5045 return "xxlxor %x0,%x0,%x0";
5047 if (mode == V2DImode
5048 && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
5049 && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
5050 return "vspltisw %0,-1";
5056 if (zero_constant (vec, mode))
5057 return "vxor %0,%0,%0";
5059 splat_vec = gen_easy_altivec_constant (vec);
5060 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
5061 operands[1] = XEXP (splat_vec, 0);
5062 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
5065 switch (GET_MODE (splat_vec))
5068 return "vspltisw %0,%1";
5071 return "vspltish %0,%1";
5074 return "vspltisb %0,%1";
5081 gcc_assert (TARGET_SPE);
5083 /* Vector constant 0 is handled as a splitter of V2SI, and in the
5084 pattern of V1DI, V4HI, and V2SF.
5086 FIXME: We should probably return # and add post reload
5087 splitters for these, but this way is so easy ;-). */
5088 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
5089 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
5090 operands[1] = CONST_VECTOR_ELT (vec, 0);
5091 operands[2] = CONST_VECTOR_ELT (vec, 1);
5093 return "li %0,%1\n\tevmergelo %0,%0,%0";
5095 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
5098 /* Initialize TARGET of vector PAIRED to VALS. */
5101 paired_expand_vector_init (rtx target, rtx vals)
5103 enum machine_mode mode = GET_MODE (target);
5104 int n_elts = GET_MODE_NUNITS (mode);
5106 rtx x, new_rtx, tmp, constant_op, op1, op2;
5109 for (i = 0; i < n_elts; ++i)
5111 x = XVECEXP (vals, 0, i);
5112 if (!CONSTANT_P (x))
5117 /* Load from constant pool. */
5118 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
5124 /* The vector is initialized only with non-constants. */
5125 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
5126 XVECEXP (vals, 0, 1));
5128 emit_move_insn (target, new_rtx);
5132 /* One field is non-constant and the other one is a constant. Load the
5133 constant from the constant pool and use ps_merge instruction to
5134 construct the whole vector. */
5135 op1 = XVECEXP (vals, 0, 0);
5136 op2 = XVECEXP (vals, 0, 1);
5138 constant_op = (CONSTANT_P (op1)) ? op1 : op2;
5140 tmp = gen_reg_rtx (GET_MODE (constant_op));
5141 emit_move_insn (tmp, constant_op);
5143 if (CONSTANT_P (op1))
5144 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
5146 new_rtx = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
5148 emit_move_insn (target, new_rtx);
5152 paired_expand_vector_move (rtx operands[])
5154 rtx op0 = operands[0], op1 = operands[1];
5156 emit_move_insn (op0, op1);
5159 /* Emit vector compare for code RCODE. DEST is destination, OP1 and
5160 OP2 are two VEC_COND_EXPR operands, CC_OP0 and CC_OP1 are the two
5161 operands for the relation operation COND. This is a recursive
5165 paired_emit_vector_compare (enum rtx_code rcode,
5166 rtx dest, rtx op0, rtx op1,
5167 rtx cc_op0, rtx cc_op1)
5169 rtx tmp = gen_reg_rtx (V2SFmode);
5172 gcc_assert (TARGET_PAIRED_FLOAT);
5173 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
5179 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5183 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5184 emit_insn (gen_selv2sf4 (dest, tmp, op0, op1, CONST0_RTX (SFmode)));
5188 paired_emit_vector_compare (GE, dest, op0, op1, cc_op1, cc_op0);
5191 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5194 tmp1 = gen_reg_rtx (V2SFmode);
5195 max = gen_reg_rtx (V2SFmode);
5196 min = gen_reg_rtx (V2SFmode);
5197 gen_reg_rtx (V2SFmode);
5199 emit_insn (gen_subv2sf3 (tmp, cc_op0, cc_op1));
5200 emit_insn (gen_selv2sf4
5201 (max, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5202 emit_insn (gen_subv2sf3 (tmp, cc_op1, cc_op0));
5203 emit_insn (gen_selv2sf4
5204 (min, tmp, cc_op0, cc_op1, CONST0_RTX (SFmode)));
5205 emit_insn (gen_subv2sf3 (tmp1, min, max));
5206 emit_insn (gen_selv2sf4 (dest, tmp1, op0, op1, CONST0_RTX (SFmode)));
5209 paired_emit_vector_compare (EQ, dest, op1, op0, cc_op0, cc_op1);
5212 paired_emit_vector_compare (LE, dest, op1, op0, cc_op0, cc_op1);
5215 paired_emit_vector_compare (LT, dest, op1, op0, cc_op0, cc_op1);
5218 paired_emit_vector_compare (GE, dest, op1, op0, cc_op0, cc_op1);
5221 paired_emit_vector_compare (GT, dest, op1, op0, cc_op0, cc_op1);
5230 /* Emit vector conditional expression.
5231 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
5232 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
5235 paired_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
5236 rtx cond, rtx cc_op0, rtx cc_op1)
5238 enum rtx_code rcode = GET_CODE (cond);
5240 if (!TARGET_PAIRED_FLOAT)
5243 paired_emit_vector_compare (rcode, dest, op1, op2, cc_op0, cc_op1);
5248 /* Initialize vector TARGET to VALS. */
5251 rs6000_expand_vector_init (rtx target, rtx vals)
5253 enum machine_mode mode = GET_MODE (target);
5254 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5255 int n_elts = GET_MODE_NUNITS (mode);
5256 int n_var = 0, one_var = -1;
5257 bool all_same = true, all_const_zero = true;
5261 for (i = 0; i < n_elts; ++i)
5263 x = XVECEXP (vals, 0, i);
5264 if (!CONSTANT_P (x))
5265 ++n_var, one_var = i;
5266 else if (x != CONST0_RTX (inner_mode))
5267 all_const_zero = false;
5269 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
5275 rtx const_vec = gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0));
5276 bool int_vector_p = (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
5277 if ((int_vector_p || TARGET_VSX) && all_const_zero)
5279 /* Zero register. */
5280 emit_insn (gen_rtx_SET (VOIDmode, target,
5281 gen_rtx_XOR (mode, target, target)));
5284 else if (int_vector_p && easy_vector_constant (const_vec, mode))
5286 /* Splat immediate. */
5287 emit_insn (gen_rtx_SET (VOIDmode, target, const_vec));
5292 /* Load from constant pool. */
5293 emit_move_insn (target, const_vec);
5298 /* Double word values on VSX can use xxpermdi or lxvdsx. */
5299 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5303 rtx element = XVECEXP (vals, 0, 0);
5304 if (mode == V2DFmode)
5305 emit_insn (gen_vsx_splat_v2df (target, element));
5307 emit_insn (gen_vsx_splat_v2di (target, element));
5311 if (mode == V2DFmode)
5313 rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
5314 rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
5315 emit_insn (gen_vsx_concat_v2df (target, op0, op1));
5319 rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
5320 rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
5321 emit_insn (gen_vsx_concat_v2di (target, op0, op1));
5327 /* With single precision floating point on VSX, know that internally single
5328 precision is actually represented as a double, and either make 2 V2DF
5329 vectors, and convert these vectors to single precision, or do one
5330 conversion, and splat the result to the other elements. */
5331 if (mode == V4SFmode && VECTOR_MEM_VSX_P (mode))
5335 rtx freg = gen_reg_rtx (V4SFmode);
5336 rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
5338 emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
5339 emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
5343 rtx dbl_even = gen_reg_rtx (V2DFmode);
5344 rtx dbl_odd = gen_reg_rtx (V2DFmode);
5345 rtx flt_even = gen_reg_rtx (V4SFmode);
5346 rtx flt_odd = gen_reg_rtx (V4SFmode);
5348 emit_insn (gen_vsx_concat_v2sf (dbl_even,
5349 copy_to_reg (XVECEXP (vals, 0, 0)),
5350 copy_to_reg (XVECEXP (vals, 0, 1))));
5351 emit_insn (gen_vsx_concat_v2sf (dbl_odd,
5352 copy_to_reg (XVECEXP (vals, 0, 2)),
5353 copy_to_reg (XVECEXP (vals, 0, 3))));
5354 emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
5355 emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
5356 emit_insn (gen_vec_extract_evenv4sf (target, flt_even, flt_odd));
5361 /* Store value to stack temp. Load vector element. Splat. However, splat
5362 of 64-bit items is not supported on Altivec. */
5363 if (all_same && GET_MODE_SIZE (mode) <= 4)
5365 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5366 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
5367 XVECEXP (vals, 0, 0));
5368 x = gen_rtx_UNSPEC (VOIDmode,
5369 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5370 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5372 gen_rtx_SET (VOIDmode,
5375 x = gen_rtx_VEC_SELECT (inner_mode, target,
5376 gen_rtx_PARALLEL (VOIDmode,
5377 gen_rtvec (1, const0_rtx)));
5378 emit_insn (gen_rtx_SET (VOIDmode, target,
5379 gen_rtx_VEC_DUPLICATE (mode, x)));
5383 /* One field is non-constant. Load constant then overwrite
5387 rtx copy = copy_rtx (vals);
5389 /* Load constant part of vector, substitute neighboring value for
5391 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
5392 rs6000_expand_vector_init (target, copy);
5394 /* Insert variable. */
5395 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
5399 /* Construct the vector in memory one field at a time
5400 and load the whole vector. */
5401 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5402 for (i = 0; i < n_elts; i++)
5403 emit_move_insn (adjust_address_nv (mem, inner_mode,
5404 i * GET_MODE_SIZE (inner_mode)),
5405 XVECEXP (vals, 0, i));
5406 emit_move_insn (target, mem);
5409 /* Set field ELT of TARGET to VAL. */
5412 rs6000_expand_vector_set (rtx target, rtx val, int elt)
5414 enum machine_mode mode = GET_MODE (target);
5415 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5416 rtx reg = gen_reg_rtx (mode);
5418 int width = GET_MODE_SIZE (inner_mode);
5421 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5423 rtx (*set_func) (rtx, rtx, rtx, rtx)
5424 = ((mode == V2DFmode) ? gen_vsx_set_v2df : gen_vsx_set_v2di);
5425 emit_insn (set_func (target, target, val, GEN_INT (elt)));
5429 /* Load single variable value. */
5430 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
5431 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
5432 x = gen_rtx_UNSPEC (VOIDmode,
5433 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
5434 emit_insn (gen_rtx_PARALLEL (VOIDmode,
5436 gen_rtx_SET (VOIDmode,
5440 /* Linear sequence. */
5441 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
5442 for (i = 0; i < 16; ++i)
5443 XVECEXP (mask, 0, i) = GEN_INT (i);
5445 /* Set permute mask to insert element into target. */
5446 for (i = 0; i < width; ++i)
5447 XVECEXP (mask, 0, elt*width + i)
5448 = GEN_INT (i + 0x10);
5449 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
5450 x = gen_rtx_UNSPEC (mode,
5451 gen_rtvec (3, target, reg,
5452 force_reg (V16QImode, x)),
5454 emit_insn (gen_rtx_SET (VOIDmode, target, x));
5457 /* Extract field ELT from VEC into TARGET. */
5460 rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
5462 enum machine_mode mode = GET_MODE (vec);
5463 enum machine_mode inner_mode = GET_MODE_INNER (mode);
5466 if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
5468 rtx (*extract_func) (rtx, rtx, rtx)
5469 = ((mode == V2DFmode) ? gen_vsx_extract_v2df : gen_vsx_extract_v2di);
5470 emit_insn (extract_func (target, vec, GEN_INT (elt)));
5474 /* Allocate mode-sized buffer. */
5475 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
5477 emit_move_insn (mem, vec);
5479 /* Add offset to field within buffer matching vector element. */
5480 mem = adjust_address_nv (mem, inner_mode, elt * GET_MODE_SIZE (inner_mode));
5482 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
5485 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
5486 implement ANDing by the mask IN. */
5488 build_mask64_2_operands (rtx in, rtx *out)
5490 #if HOST_BITS_PER_WIDE_INT >= 64
5491 unsigned HOST_WIDE_INT c, lsb, m1, m2;
5494 gcc_assert (GET_CODE (in) == CONST_INT);
5499 /* Assume c initially something like 0x00fff000000fffff. The idea
5500 is to rotate the word so that the middle ^^^^^^ group of zeros
5501 is at the MS end and can be cleared with an rldicl mask. We then
5502 rotate back and clear off the MS ^^ group of zeros with a
5504 c = ~c; /* c == 0xff000ffffff00000 */
5505 lsb = c & -c; /* lsb == 0x0000000000100000 */
5506 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
5507 c = ~c; /* c == 0x00fff000000fffff */
5508 c &= -lsb; /* c == 0x00fff00000000000 */
5509 lsb = c & -c; /* lsb == 0x0000100000000000 */
5510 c = ~c; /* c == 0xff000fffffffffff */
5511 c &= -lsb; /* c == 0xff00000000000000 */
5513 while ((lsb >>= 1) != 0)
5514 shift++; /* shift == 44 on exit from loop */
5515 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
5516 m1 = ~m1; /* m1 == 0x000000ffffffffff */
5517 m2 = ~c; /* m2 == 0x00ffffffffffffff */
5521 /* Assume c initially something like 0xff000f0000000000. The idea
5522 is to rotate the word so that the ^^^ middle group of zeros
5523 is at the LS end and can be cleared with an rldicr mask. We then
5524 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
5526 lsb = c & -c; /* lsb == 0x0000010000000000 */
5527 m2 = -lsb; /* m2 == 0xffffff0000000000 */
5528 c = ~c; /* c == 0x00fff0ffffffffff */
5529 c &= -lsb; /* c == 0x00fff00000000000 */
5530 lsb = c & -c; /* lsb == 0x0000100000000000 */
5531 c = ~c; /* c == 0xff000fffffffffff */
5532 c &= -lsb; /* c == 0xff00000000000000 */
5534 while ((lsb >>= 1) != 0)
5535 shift++; /* shift == 44 on exit from loop */
5536 m1 = ~c; /* m1 == 0x00ffffffffffffff */
5537 m1 >>= shift; /* m1 == 0x0000000000000fff */
5538 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
5541 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
5542 masks will be all 1's. We are guaranteed more than one transition. */
5543 out[0] = GEN_INT (64 - shift);
5544 out[1] = GEN_INT (m1);
5545 out[2] = GEN_INT (shift);
5546 out[3] = GEN_INT (m2);
5554 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
5557 invalid_e500_subreg (rtx op, enum machine_mode mode)
5559 if (TARGET_E500_DOUBLE)
5561 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
5562 subreg:TI and reg:TF. Decimal float modes are like integer
5563 modes (only low part of each register used) for this
5565 if (GET_CODE (op) == SUBREG
5566 && (mode == SImode || mode == DImode || mode == TImode
5567 || mode == DDmode || mode == TDmode)
5568 && REG_P (SUBREG_REG (op))
5569 && (GET_MODE (SUBREG_REG (op)) == DFmode
5570 || GET_MODE (SUBREG_REG (op)) == TFmode))
5573 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
5575 if (GET_CODE (op) == SUBREG
5576 && (mode == DFmode || mode == TFmode)
5577 && REG_P (SUBREG_REG (op))
5578 && (GET_MODE (SUBREG_REG (op)) == DImode
5579 || GET_MODE (SUBREG_REG (op)) == TImode
5580 || GET_MODE (SUBREG_REG (op)) == DDmode
5581 || GET_MODE (SUBREG_REG (op)) == TDmode))
5586 && GET_CODE (op) == SUBREG
5588 && REG_P (SUBREG_REG (op))
5589 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
5595 /* AIX increases natural record alignment to doubleword if the first
5596 field is an FP double while the FP fields remain word aligned. */
5599 rs6000_special_round_type_align (tree type, unsigned int computed,
5600 unsigned int specified)
5602 unsigned int align = MAX (computed, specified);
5603 tree field = TYPE_FIELDS (type);
5605 /* Skip all non field decls */
5606 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5607 field = DECL_CHAIN (field);
5609 if (field != NULL && field != type)
5611 type = TREE_TYPE (field);
5612 while (TREE_CODE (type) == ARRAY_TYPE)
5613 type = TREE_TYPE (type);
5615 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
5616 align = MAX (align, 64);
5622 /* Darwin increases record alignment to the natural alignment of
5626 darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
5627 unsigned int specified)
5629 unsigned int align = MAX (computed, specified);
5631 if (TYPE_PACKED (type))
5634 /* Find the first field, looking down into aggregates. */
5636 tree field = TYPE_FIELDS (type);
5637 /* Skip all non field decls */
5638 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
5639 field = DECL_CHAIN (field);
5642 /* A packed field does not contribute any extra alignment. */
5643 if (DECL_PACKED (field))
5645 type = TREE_TYPE (field);
5646 while (TREE_CODE (type) == ARRAY_TYPE)
5647 type = TREE_TYPE (type);
5648 } while (AGGREGATE_TYPE_P (type));
5650 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
5651 align = MAX (align, TYPE_ALIGN (type));
5656 /* Return 1 for an operand in small memory on V.4/eabi. */
5659 small_data_operand (rtx op ATTRIBUTE_UNUSED,
5660 enum machine_mode mode ATTRIBUTE_UNUSED)
5665 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
5668 if (DEFAULT_ABI != ABI_V4)
5671 /* Vector and float memory instructions have a limited offset on the
5672 SPE, so using a vector or float variable directly as an operand is
5675 && (SPE_VECTOR_MODE (mode) || FLOAT_MODE_P (mode)))
5678 if (GET_CODE (op) == SYMBOL_REF)
5681 else if (GET_CODE (op) != CONST
5682 || GET_CODE (XEXP (op, 0)) != PLUS
5683 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
5684 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
5689 rtx sum = XEXP (op, 0);
5690 HOST_WIDE_INT summand;
5692 /* We have to be careful here, because it is the referenced address
5693 that must be 32k from _SDA_BASE_, not just the symbol. */
5694 summand = INTVAL (XEXP (sum, 1));
5695 if (summand < 0 || summand > g_switch_value)
5698 sym_ref = XEXP (sum, 0);
5701 return SYMBOL_REF_SMALL_P (sym_ref);
5707 /* Return true if either operand is a general purpose register. */
5710 gpr_or_gpr_p (rtx op0, rtx op1)
5712 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
5713 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
5717 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address_p. */
5720 reg_offset_addressing_ok_p (enum machine_mode mode)
5730 /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. */
5731 if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
5739 /* Paired vector modes. Only reg+reg addressing is valid. */
5740 if (TARGET_PAIRED_FLOAT)
5752 virtual_stack_registers_memory_p (rtx op)
5756 if (GET_CODE (op) == REG)
5757 regnum = REGNO (op);
5759 else if (GET_CODE (op) == PLUS
5760 && GET_CODE (XEXP (op, 0)) == REG
5761 && GET_CODE (XEXP (op, 1)) == CONST_INT)
5762 regnum = REGNO (XEXP (op, 0));
5767 return (regnum >= FIRST_VIRTUAL_REGISTER
5768 && regnum <= LAST_VIRTUAL_POINTER_REGISTER);
5771 /* Return true if memory accesses to OP are known to never straddle
5775 offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
5776 enum machine_mode mode)
5779 unsigned HOST_WIDE_INT dsize, dalign;
5781 if (GET_CODE (op) != SYMBOL_REF)
5784 decl = SYMBOL_REF_DECL (op);
5787 if (GET_MODE_SIZE (mode) == 0)
5790 /* -fsection-anchors loses the original SYMBOL_REF_DECL when
5791 replacing memory addresses with an anchor plus offset. We
5792 could find the decl by rummaging around in the block->objects
5793 VEC for the given offset but that seems like too much work. */
5795 if (SYMBOL_REF_HAS_BLOCK_INFO_P (op)
5796 && SYMBOL_REF_ANCHOR_P (op)
5797 && SYMBOL_REF_BLOCK (op) != NULL)
5799 struct object_block *block = SYMBOL_REF_BLOCK (op);
5800 HOST_WIDE_INT lsb, mask;
5802 /* Given the alignment of the block.. */
5803 dalign = block->alignment;
5804 mask = dalign / BITS_PER_UNIT - 1;
5806 /* ..and the combined offset of the anchor and any offset
5807 to this block object.. */
5808 offset += SYMBOL_REF_BLOCK_OFFSET (op);
5809 lsb = offset & -offset;
5811 /* ..find how many bits of the alignment we know for the
5816 return dalign >= GET_MODE_SIZE (mode);
5821 if (TREE_CODE (decl) == FUNCTION_DECL)
5824 if (!DECL_SIZE_UNIT (decl))
5827 if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
5830 dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
5834 dalign = DECL_ALIGN_UNIT (decl);
5835 return dalign >= dsize;
5838 type = TREE_TYPE (decl);
5840 if (TREE_CODE (decl) == STRING_CST)
5841 dsize = TREE_STRING_LENGTH (decl);
5842 else if (TYPE_SIZE_UNIT (type)
5843 && host_integerp (TYPE_SIZE_UNIT (type), 1))
5844 dsize = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5850 dalign = TYPE_ALIGN (type);
5851 if (CONSTANT_CLASS_P (decl))
5852 dalign = CONSTANT_ALIGNMENT (decl, dalign);
5854 dalign = DATA_ALIGNMENT (decl, dalign);
5855 dalign /= BITS_PER_UNIT;
5856 return dalign >= dsize;
5860 constant_pool_expr_p (rtx op)
5864 split_const (op, &base, &offset);
5865 return (GET_CODE (base) == SYMBOL_REF
5866 && CONSTANT_POOL_ADDRESS_P (base)
5867 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
5870 static rtx tocrel_base, tocrel_offset;
5873 toc_relative_expr_p (rtx op)
5875 if (GET_CODE (op) != CONST)
5878 split_const (op, &tocrel_base, &tocrel_offset);
5879 return (GET_CODE (tocrel_base) == UNSPEC
5880 && XINT (tocrel_base, 1) == UNSPEC_TOCREL);
5883 /* Return true if X is a constant pool address, and also for cmodel=medium
5884 if X is a toc-relative address known to be offsettable within MODE. */
5887 legitimate_constant_pool_address_p (const_rtx x, enum machine_mode mode,
5891 && (GET_CODE (x) == PLUS || GET_CODE (x) == LO_SUM)
5892 && GET_CODE (XEXP (x, 0)) == REG
5893 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
5894 || ((TARGET_MINIMAL_TOC
5895 || TARGET_CMODEL != CMODEL_SMALL)
5896 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)))
5897 && toc_relative_expr_p (XEXP (x, 1))
5898 && (TARGET_CMODEL != CMODEL_MEDIUM
5899 || constant_pool_expr_p (XVECEXP (tocrel_base, 0, 0))
5901 || offsettable_ok_by_alignment (XVECEXP (tocrel_base, 0, 0),
5902 INTVAL (tocrel_offset), mode)));
5906 legitimate_small_data_p (enum machine_mode mode, rtx x)
5908 return (DEFAULT_ABI == ABI_V4
5909 && !flag_pic && !TARGET_TOC
5910 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
5911 && small_data_operand (x, mode));
5914 /* SPE offset addressing is limited to 5-bits worth of double words. */
5915 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
5918 rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
5920 unsigned HOST_WIDE_INT offset, extra;
5922 if (GET_CODE (x) != PLUS)
5924 if (GET_CODE (XEXP (x, 0)) != REG)
5926 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
5928 if (!reg_offset_addressing_ok_p (mode))
5929 return virtual_stack_registers_memory_p (x);
5930 if (legitimate_constant_pool_address_p (x, mode, strict))
5932 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5935 offset = INTVAL (XEXP (x, 1));
5943 /* SPE vector modes. */
5944 return SPE_CONST_OFFSET_OK (offset);
5947 if (TARGET_E500_DOUBLE)
5948 return SPE_CONST_OFFSET_OK (offset);
5950 /* If we are using VSX scalar loads, restrict ourselves to reg+reg
5952 if (VECTOR_MEM_VSX_P (DFmode))
5957 /* On e500v2, we may have:
5959 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
5961 Which gets addressed with evldd instructions. */
5962 if (TARGET_E500_DOUBLE)
5963 return SPE_CONST_OFFSET_OK (offset);
5965 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
5967 else if (offset & 3)
5972 if (TARGET_E500_DOUBLE)
5973 return (SPE_CONST_OFFSET_OK (offset)
5974 && SPE_CONST_OFFSET_OK (offset + 8));
5978 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
5980 else if (offset & 3)
5991 return (offset < 0x10000) && (offset + extra < 0x10000);
5995 legitimate_indexed_address_p (rtx x, int strict)
5999 if (GET_CODE (x) != PLUS)
6005 /* Recognize the rtl generated by reload which we know will later be
6006 replaced with proper base and index regs. */
6008 && reload_in_progress
6009 && (REG_P (op0) || GET_CODE (op0) == PLUS)
6013 return (REG_P (op0) && REG_P (op1)
6014 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
6015 && INT_REG_OK_FOR_INDEX_P (op1, strict))
6016 || (INT_REG_OK_FOR_BASE_P (op1, strict)
6017 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
6021 avoiding_indexed_address_p (enum machine_mode mode)
6023 /* Avoid indexed addressing for modes that have non-indexed
6024 load/store instruction forms. */
6025 return (TARGET_AVOID_XFORM && VECTOR_MEM_NONE_P (mode));
6029 legitimate_indirect_address_p (rtx x, int strict)
6031 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
6035 macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
6037 if (!TARGET_MACHO || !flag_pic
6038 || mode != SImode || GET_CODE (x) != MEM)
6042 if (GET_CODE (x) != LO_SUM)
6044 if (GET_CODE (XEXP (x, 0)) != REG)
6046 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
6050 return CONSTANT_P (x);
6054 legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
6056 if (GET_CODE (x) != LO_SUM)
6058 if (GET_CODE (XEXP (x, 0)) != REG)
6060 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
6062 /* Restrict addressing for DI because of our SUBREG hackery. */
6063 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6064 || mode == DDmode || mode == TDmode
6069 if (TARGET_ELF || TARGET_MACHO)
6071 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
6075 if (GET_MODE_NUNITS (mode) != 1)
6077 if (GET_MODE_BITSIZE (mode) > 64
6078 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
6079 && !(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6080 && (mode == DFmode || mode == DDmode))))
6083 return CONSTANT_P (x);
6090 /* Try machine-dependent ways of modifying an illegitimate address
6091 to be legitimate. If we find one, return the new, valid address.
6092 This is used from only one place: `memory_address' in explow.c.
6094 OLDX is the address as it was before break_out_memory_refs was
6095 called. In some cases it is useful to look at this to decide what
6098 It is always safe for this function to do nothing. It exists to
6099 recognize opportunities to optimize the output.
6101 On RS/6000, first check for the sum of a register with a constant
6102 integer that is out of range. If so, generate code to add the
6103 constant with the low-order 16 bits masked to the register and force
6104 this result into another register (this can be done with `cau').
6105 Then generate an address of REG+(CONST&0xffff), allowing for the
6106 possibility of bit 16 being a one.
6108 Then check for the sum of a register and something not constant, try to
6109 load the other things into a register and return the sum. */
6112 rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
6113 enum machine_mode mode)
6115 unsigned int extra = 0;
6117 if (!reg_offset_addressing_ok_p (mode))
6119 if (virtual_stack_registers_memory_p (x))
6122 /* In theory we should not be seeing addresses of the form reg+0,
6123 but just in case it is generated, optimize it away. */
6124 if (GET_CODE (x) == PLUS && XEXP (x, 1) == const0_rtx)
6125 return force_reg (Pmode, XEXP (x, 0));
6127 /* Make sure both operands are registers. */
6128 else if (GET_CODE (x) == PLUS)
6129 return gen_rtx_PLUS (Pmode,
6130 force_reg (Pmode, XEXP (x, 0)),
6131 force_reg (Pmode, XEXP (x, 1)));
6133 return force_reg (Pmode, x);
6135 if (GET_CODE (x) == SYMBOL_REF)
6137 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
6139 return rs6000_legitimize_tls_address (x, model);
6149 if (!TARGET_POWERPC64)
6157 extra = TARGET_POWERPC64 ? 8 : 12;
6163 if (GET_CODE (x) == PLUS
6164 && GET_CODE (XEXP (x, 0)) == REG
6165 && GET_CODE (XEXP (x, 1)) == CONST_INT
6166 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
6168 && !((TARGET_POWERPC64
6169 && (mode == DImode || mode == TImode)
6170 && (INTVAL (XEXP (x, 1)) & 3) != 0)
6171 || SPE_VECTOR_MODE (mode)
6172 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6173 || mode == DImode || mode == DDmode
6174 || mode == TDmode))))
6176 HOST_WIDE_INT high_int, low_int;
6178 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
6179 if (low_int >= 0x8000 - extra)
6181 high_int = INTVAL (XEXP (x, 1)) - low_int;
6182 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
6183 GEN_INT (high_int)), 0);
6184 return plus_constant (sum, low_int);
6186 else if (GET_CODE (x) == PLUS
6187 && GET_CODE (XEXP (x, 0)) == REG
6188 && GET_CODE (XEXP (x, 1)) != CONST_INT
6189 && GET_MODE_NUNITS (mode) == 1
6190 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6192 || ((mode != DImode && mode != DFmode && mode != DDmode)
6193 || (TARGET_E500_DOUBLE && mode != DDmode)))
6194 && (TARGET_POWERPC64 || mode != DImode)
6195 && !avoiding_indexed_address_p (mode)
6200 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
6201 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
6203 else if (SPE_VECTOR_MODE (mode)
6204 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6205 || mode == DDmode || mode == TDmode
6206 || mode == DImode)))
6210 /* We accept [reg + reg] and [reg + OFFSET]. */
6212 if (GET_CODE (x) == PLUS)
6214 rtx op1 = XEXP (x, 0);
6215 rtx op2 = XEXP (x, 1);
6218 op1 = force_reg (Pmode, op1);
6220 if (GET_CODE (op2) != REG
6221 && (GET_CODE (op2) != CONST_INT
6222 || !SPE_CONST_OFFSET_OK (INTVAL (op2))
6223 || (GET_MODE_SIZE (mode) > 8
6224 && !SPE_CONST_OFFSET_OK (INTVAL (op2) + 8))))
6225 op2 = force_reg (Pmode, op2);
6227 /* We can't always do [reg + reg] for these, because [reg +
6228 reg + offset] is not a legitimate addressing mode. */
6229 y = gen_rtx_PLUS (Pmode, op1, op2);
6231 if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2))
6232 return force_reg (Pmode, y);
6237 return force_reg (Pmode, x);
6243 && GET_CODE (x) != CONST_INT
6244 && GET_CODE (x) != CONST_DOUBLE
6246 && GET_MODE_NUNITS (mode) == 1
6247 && (GET_MODE_BITSIZE (mode) <= 32
6248 || ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6249 && (mode == DFmode || mode == DDmode))))
6251 rtx reg = gen_reg_rtx (Pmode);
6252 emit_insn (gen_elf_high (reg, x));
6253 return gen_rtx_LO_SUM (Pmode, reg, x);
6255 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
6258 && ! MACHO_DYNAMIC_NO_PIC_P
6260 && GET_CODE (x) != CONST_INT
6261 && GET_CODE (x) != CONST_DOUBLE
6263 && GET_MODE_NUNITS (mode) == 1
6264 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6265 || (mode != DFmode && mode != DDmode))
6269 rtx reg = gen_reg_rtx (Pmode);
6270 emit_insn (gen_macho_high (reg, x));
6271 return gen_rtx_LO_SUM (Pmode, reg, x);
6274 && GET_CODE (x) == SYMBOL_REF
6275 && constant_pool_expr_p (x)
6276 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
6278 rtx reg = TARGET_CMODEL != CMODEL_SMALL ? gen_reg_rtx (Pmode) : NULL_RTX;
6279 return create_TOC_reference (x, reg);
6285 /* Debug version of rs6000_legitimize_address. */
6287 rs6000_debug_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
6293 ret = rs6000_legitimize_address (x, oldx, mode);
6294 insns = get_insns ();
6300 "\nrs6000_legitimize_address: mode %s, old code %s, "
6301 "new code %s, modified\n",
6302 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)),
6303 GET_RTX_NAME (GET_CODE (ret)));
6305 fprintf (stderr, "Original address:\n");
6308 fprintf (stderr, "oldx:\n");
6311 fprintf (stderr, "New address:\n");
6316 fprintf (stderr, "Insns added:\n");
6317 debug_rtx_list (insns, 20);
6323 "\nrs6000_legitimize_address: mode %s, code %s, no change:\n",
6324 GET_MODE_NAME (mode), GET_RTX_NAME (GET_CODE (x)));
6335 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
6336 We need to emit DTP-relative relocations. */
6339 rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
6344 fputs ("\t.long\t", file);
6347 fputs (DOUBLE_INT_ASM_OP, file);
6352 output_addr_const (file, x);
6353 fputs ("@dtprel+0x8000", file);
6356 /* In the name of slightly smaller debug output, and to cater to
6357 general assembler lossage, recognize various UNSPEC sequences
6358 and turn them back into a direct symbol reference. */
6361 rs6000_delegitimize_address (rtx orig_x)
6365 orig_x = delegitimize_mem_from_attrs (orig_x);
6370 if (GET_CODE (x) == (TARGET_CMODEL != CMODEL_SMALL ? LO_SUM : PLUS)
6371 && GET_CODE (XEXP (x, 1)) == CONST)
6373 y = XEXP (XEXP (x, 1), 0);
6374 if (GET_CODE (y) == UNSPEC
6375 && XINT (y, 1) == UNSPEC_TOCREL
6376 && ((GET_CODE (XEXP (x, 0)) == REG
6377 && (REGNO (XEXP (x, 0)) == TOC_REGISTER
6378 || TARGET_MINIMAL_TOC
6379 || TARGET_CMODEL != CMODEL_SMALL))
6380 || (TARGET_CMODEL != CMODEL_SMALL
6381 && GET_CODE (XEXP (x, 0)) == PLUS
6382 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6383 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6384 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6385 && rtx_equal_p (XEXP (x, 1),
6386 XEXP (XEXP (XEXP (x, 0), 1), 0)))))
6388 y = XVECEXP (y, 0, 0);
6389 if (!MEM_P (orig_x))
6392 return replace_equiv_address_nv (orig_x, y);
6397 && GET_CODE (orig_x) == LO_SUM
6398 && GET_CODE (XEXP (x, 1)) == CONST)
6400 y = XEXP (XEXP (x, 1), 0);
6401 if (GET_CODE (y) == UNSPEC
6402 && XINT (y, 1) == UNSPEC_MACHOPIC_OFFSET)
6403 return XVECEXP (y, 0, 0);
6409 /* Construct the SYMBOL_REF for the tls_get_addr function. */
6411 static GTY(()) rtx rs6000_tls_symbol;
6413 rs6000_tls_get_addr (void)
6415 if (!rs6000_tls_symbol)
6416 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
6418 return rs6000_tls_symbol;
6421 /* Construct the SYMBOL_REF for TLS GOT references. */
6423 static GTY(()) rtx rs6000_got_symbol;
6425 rs6000_got_sym (void)
6427 if (!rs6000_got_symbol)
6429 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
6430 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
6431 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
6434 return rs6000_got_symbol;
6437 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
6438 this (thread-local) address. */
6441 rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
6445 dest = gen_reg_rtx (Pmode);
6446 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
6452 tlsreg = gen_rtx_REG (Pmode, 13);
6453 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
6457 tlsreg = gen_rtx_REG (Pmode, 2);
6458 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
6462 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
6466 tmp = gen_reg_rtx (Pmode);
6469 tlsreg = gen_rtx_REG (Pmode, 13);
6470 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
6474 tlsreg = gen_rtx_REG (Pmode, 2);
6475 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
6479 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
6481 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
6486 rtx r3, got, tga, tmp1, tmp2, call_insn;
6488 /* We currently use relocations like @got@tlsgd for tls, which
6489 means the linker will handle allocation of tls entries, placing
6490 them in the .got section. So use a pointer to the .got section,
6491 not one to secondary TOC sections used by 64-bit -mminimal-toc,
6492 or to secondary GOT sections used by 32-bit -fPIC. */
6494 got = gen_rtx_REG (Pmode, 2);
6498 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
6501 rtx gsym = rs6000_got_sym ();
6502 got = gen_reg_rtx (Pmode);
6504 rs6000_emit_move (got, gsym, Pmode);
6509 tmp1 = gen_reg_rtx (Pmode);
6510 tmp2 = gen_reg_rtx (Pmode);
6511 mem = gen_const_mem (Pmode, tmp1);
6512 lab = gen_label_rtx ();
6513 emit_insn (gen_load_toc_v4_PIC_1b (gsym, lab));
6514 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
6515 emit_move_insn (tmp2, mem);
6516 last = emit_insn (gen_addsi3 (got, tmp1, tmp2));
6517 set_unique_reg_note (last, REG_EQUAL, gsym);
6522 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
6524 r3 = gen_rtx_REG (Pmode, 3);
6525 tga = rs6000_tls_get_addr ();
6526 emit_library_call_value (tga, dest, LCT_CONST, Pmode, 1, r3, Pmode);
6528 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6529 insn = gen_tls_gd_aix64 (r3, got, addr, tga, const0_rtx);
6530 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6531 insn = gen_tls_gd_aix32 (r3, got, addr, tga, const0_rtx);
6532 else if (DEFAULT_ABI == ABI_V4)
6533 insn = gen_tls_gd_sysvsi (r3, got, addr, tga, const0_rtx);
6536 call_insn = last_call_insn ();
6537 PATTERN (call_insn) = insn;
6538 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6539 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6540 pic_offset_table_rtx);
6542 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
6544 r3 = gen_rtx_REG (Pmode, 3);
6545 tga = rs6000_tls_get_addr ();
6546 tmp1 = gen_reg_rtx (Pmode);
6547 emit_library_call_value (tga, tmp1, LCT_CONST, Pmode, 1, r3, Pmode);
6549 if (DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
6550 insn = gen_tls_ld_aix64 (r3, got, tga, const0_rtx);
6551 else if (DEFAULT_ABI == ABI_AIX && !TARGET_64BIT)
6552 insn = gen_tls_ld_aix32 (r3, got, tga, const0_rtx);
6553 else if (DEFAULT_ABI == ABI_V4)
6554 insn = gen_tls_ld_sysvsi (r3, got, tga, const0_rtx);
6557 call_insn = last_call_insn ();
6558 PATTERN (call_insn) = insn;
6559 if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
6560 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
6561 pic_offset_table_rtx);
6563 if (rs6000_tls_size == 16)
6566 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
6568 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
6570 else if (rs6000_tls_size == 32)
6572 tmp2 = gen_reg_rtx (Pmode);
6574 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
6576 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
6579 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
6581 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
6585 tmp2 = gen_reg_rtx (Pmode);
6587 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
6589 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
6591 insn = gen_rtx_SET (Pmode, dest,
6592 gen_rtx_PLUS (Pmode, tmp2, tmp1));
6598 /* IE, or 64-bit offset LE. */
6599 tmp2 = gen_reg_rtx (Pmode);
6601 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
6603 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
6606 insn = gen_tls_tls_64 (dest, tmp2, addr);
6608 insn = gen_tls_tls_32 (dest, tmp2, addr);
6616 /* Return 1 if X contains a thread-local symbol. */
6619 rs6000_tls_referenced_p (rtx x)
6621 if (! TARGET_HAVE_TLS)
6624 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
6627 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
6630 rs6000_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
6632 return rs6000_tls_referenced_p (x);
6635 /* Return 1 if *X is a thread-local symbol. This is the same as
6636 rs6000_tls_symbol_ref except for the type of the unused argument. */
6639 rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
6641 return RS6000_SYMBOL_REF_TLS_P (*x);
6644 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
6645 replace the input X, or the original X if no replacement is called for.
6646 The output parameter *WIN is 1 if the calling macro should goto WIN,
6649 For RS/6000, we wish to handle large displacements off a base
6650 register by splitting the addend across an addiu/addis and the mem insn.
6651 This cuts number of extra insns needed from 3 to 1.
6653 On Darwin, we use this to generate code for floating point constants.
6654 A movsf_low is generated so we wind up with 2 instructions rather than 3.
6655 The Darwin code is inside #if TARGET_MACHO because only then are the
6656 machopic_* functions defined. */
6658 rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
6659 int opnum, int type,
6660 int ind_levels ATTRIBUTE_UNUSED, int *win)
6662 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6664 /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
6665 DFmode/DImode MEM. */
6668 && ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
6669 || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
6670 reg_offset_p = false;
6672 /* We must recognize output that we have already generated ourselves. */
6673 if (GET_CODE (x) == PLUS
6674 && GET_CODE (XEXP (x, 0)) == PLUS
6675 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6676 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6677 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6679 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6680 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6681 opnum, (enum reload_type)type);
6686 /* Likewise for (lo_sum (high ...) ...) output we have generated. */
6687 if (GET_CODE (x) == LO_SUM
6688 && GET_CODE (XEXP (x, 0)) == HIGH)
6690 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6691 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6692 opnum, (enum reload_type)type);
6698 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
6699 && GET_CODE (x) == LO_SUM
6700 && GET_CODE (XEXP (x, 0)) == PLUS
6701 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
6702 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6703 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
6704 && machopic_operand_p (XEXP (x, 1)))
6706 /* Result of previous invocation of this function on Darwin
6707 floating point constant. */
6708 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6709 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6710 opnum, (enum reload_type)type);
6716 if (TARGET_CMODEL != CMODEL_SMALL
6717 && GET_CODE (x) == LO_SUM
6718 && GET_CODE (XEXP (x, 0)) == PLUS
6719 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6720 && REGNO (XEXP (XEXP (x, 0), 0)) == TOC_REGISTER
6721 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
6722 && GET_CODE (XEXP (x, 1)) == CONST
6723 && GET_CODE (XEXP (XEXP (x, 1), 0)) == UNSPEC
6724 && XINT (XEXP (XEXP (x, 1), 0), 1) == UNSPEC_TOCREL
6725 && rtx_equal_p (XEXP (XEXP (XEXP (x, 0), 1), 0), XEXP (x, 1)))
6727 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6728 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6729 opnum, (enum reload_type) type);
6734 /* Force ld/std non-word aligned offset into base register by wrapping
6736 if (GET_CODE (x) == PLUS
6737 && GET_CODE (XEXP (x, 0)) == REG
6738 && REGNO (XEXP (x, 0)) < 32
6739 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6740 && GET_CODE (XEXP (x, 1)) == CONST_INT
6742 && (INTVAL (XEXP (x, 1)) & 3) != 0
6743 && VECTOR_MEM_NONE_P (mode)
6744 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
6745 && TARGET_POWERPC64)
6747 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
6748 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6749 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6750 opnum, (enum reload_type) type);
6755 if (GET_CODE (x) == PLUS
6756 && GET_CODE (XEXP (x, 0)) == REG
6757 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
6758 && INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 1)
6759 && GET_CODE (XEXP (x, 1)) == CONST_INT
6761 && !SPE_VECTOR_MODE (mode)
6762 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
6763 || mode == DDmode || mode == TDmode
6765 && VECTOR_MEM_NONE_P (mode))
6767 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
6768 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
6770 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
6772 /* Check for 32-bit overflow. */
6773 if (high + low != val)
6779 /* Reload the high part into a base reg; leave the low part
6780 in the mem directly. */
6782 x = gen_rtx_PLUS (GET_MODE (x),
6783 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
6787 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6788 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
6789 opnum, (enum reload_type)type);
6794 if (GET_CODE (x) == SYMBOL_REF
6796 && VECTOR_MEM_NONE_P (mode)
6797 && !SPE_VECTOR_MODE (mode)
6799 && DEFAULT_ABI == ABI_DARWIN
6800 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
6802 && DEFAULT_ABI == ABI_V4
6805 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
6806 The same goes for DImode without 64-bit gprs and DFmode and DDmode
6810 && (mode != DImode || TARGET_POWERPC64)
6811 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
6812 || (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)))
6817 rtx offset = machopic_gen_offset (x);
6818 x = gen_rtx_LO_SUM (GET_MODE (x),
6819 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
6820 gen_rtx_HIGH (Pmode, offset)), offset);
6824 x = gen_rtx_LO_SUM (GET_MODE (x),
6825 gen_rtx_HIGH (Pmode, x), x);
6827 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6828 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6829 opnum, (enum reload_type)type);
6834 /* Reload an offset address wrapped by an AND that represents the
6835 masking of the lower bits. Strip the outer AND and let reload
6836 convert the offset address into an indirect address. For VSX,
6837 force reload to create the address with an AND in a separate
6838 register, because we can't guarantee an altivec register will
6840 if (VECTOR_MEM_ALTIVEC_P (mode)
6841 && GET_CODE (x) == AND
6842 && GET_CODE (XEXP (x, 0)) == PLUS
6843 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
6844 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
6845 && GET_CODE (XEXP (x, 1)) == CONST_INT
6846 && INTVAL (XEXP (x, 1)) == -16)
6855 && GET_CODE (x) == SYMBOL_REF
6856 && constant_pool_expr_p (x)
6857 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
6859 x = create_TOC_reference (x, NULL_RTX);
6860 if (TARGET_CMODEL != CMODEL_SMALL)
6861 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
6862 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
6863 opnum, (enum reload_type) type);
6871 /* Debug version of rs6000_legitimize_reload_address. */
6873 rs6000_debug_legitimize_reload_address (rtx x, enum machine_mode mode,
6874 int opnum, int type,
6875 int ind_levels, int *win)
6877 rtx ret = rs6000_legitimize_reload_address (x, mode, opnum, type,
6880 "\nrs6000_legitimize_reload_address: mode = %s, opnum = %d, "
6881 "type = %d, ind_levels = %d, win = %d, original addr:\n",
6882 GET_MODE_NAME (mode), opnum, type, ind_levels, *win);
6886 fprintf (stderr, "Same address returned\n");
6888 fprintf (stderr, "NULL returned\n");
6891 fprintf (stderr, "New address:\n");
6898 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
6899 that is a valid memory address for an instruction.
6900 The MODE argument is the machine mode for the MEM expression
6901 that wants to use this address.
6903 On the RS/6000, there are four valid address: a SYMBOL_REF that
6904 refers to a constant pool entry of an address (or the sum of it
6905 plus a constant), a short (16-bit signed) constant plus a register,
6906 the sum of two registers, or a register indirect, possibly with an
6907 auto-increment. For DFmode, DDmode and DImode with a constant plus
6908 register, we must ensure that both words are addressable or PowerPC64
6909 with offset word aligned.
6911 For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
6912 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
6913 because adjacent memory cells are accessed by adding word-sized offsets
6914 during assembly output. */
6916 rs6000_legitimate_address_p (enum machine_mode mode, rtx x, bool reg_ok_strict)
6918 bool reg_offset_p = reg_offset_addressing_ok_p (mode);
6920 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
6921 if (VECTOR_MEM_ALTIVEC_P (mode)
6922 && GET_CODE (x) == AND
6923 && GET_CODE (XEXP (x, 1)) == CONST_INT
6924 && INTVAL (XEXP (x, 1)) == -16)
6927 if (RS6000_SYMBOL_REF_TLS_P (x))
6929 if (legitimate_indirect_address_p (x, reg_ok_strict))
6931 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
6932 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6933 && !SPE_VECTOR_MODE (mode)
6936 /* Restrict addressing for DI because of our SUBREG hackery. */
6937 && !(TARGET_E500_DOUBLE
6938 && (mode == DFmode || mode == DDmode || mode == DImode))
6940 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
6942 if (virtual_stack_registers_memory_p (x))
6944 if (reg_offset_p && legitimate_small_data_p (mode, x))
6947 && legitimate_constant_pool_address_p (x, mode, reg_ok_strict))
6949 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
6952 && GET_CODE (x) == PLUS
6953 && GET_CODE (XEXP (x, 0)) == REG
6954 && (XEXP (x, 0) == virtual_stack_vars_rtx
6955 || XEXP (x, 0) == arg_pointer_rtx)
6956 && GET_CODE (XEXP (x, 1)) == CONST_INT)
6958 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
6963 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6965 || (mode != DFmode && mode != DDmode)
6966 || (TARGET_E500_DOUBLE && mode != DDmode))
6967 && (TARGET_POWERPC64 || mode != DImode)
6968 && !avoiding_indexed_address_p (mode)
6969 && legitimate_indexed_address_p (x, reg_ok_strict))
6971 if (GET_CODE (x) == PRE_MODIFY
6975 && ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
6977 || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
6978 && (TARGET_POWERPC64 || mode != DImode)
6979 && !VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)
6980 && !SPE_VECTOR_MODE (mode)
6981 /* Restrict addressing for DI because of our SUBREG hackery. */
6982 && !(TARGET_E500_DOUBLE
6983 && (mode == DFmode || mode == DDmode || mode == DImode))
6985 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
6986 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
6987 || (!avoiding_indexed_address_p (mode)
6988 && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
6989 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
6991 if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
6996 /* Debug version of rs6000_legitimate_address_p. */
6998 rs6000_debug_legitimate_address_p (enum machine_mode mode, rtx x,
7001 bool ret = rs6000_legitimate_address_p (mode, x, reg_ok_strict);
7003 "\nrs6000_legitimate_address_p: return = %s, mode = %s, "
7004 "strict = %d, code = %s\n",
7005 ret ? "true" : "false",
7006 GET_MODE_NAME (mode),
7008 GET_RTX_NAME (GET_CODE (x)));
7014 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
7017 rs6000_mode_dependent_address_p (const_rtx addr)
7019 return rs6000_mode_dependent_address_ptr (addr);
7022 /* Go to LABEL if ADDR (a legitimate address expression)
7023 has an effect that depends on the machine mode it is used for.
7025 On the RS/6000 this is true of all integral offsets (since AltiVec
7026 and VSX modes don't allow them) or is a pre-increment or decrement.
7028 ??? Except that due to conceptual problems in offsettable_address_p
7029 we can't really report the problems of integral offsets. So leave
7030 this assuming that the adjustable offset must be valid for the
7031 sub-words of a TFmode operand, which is what we had before. */
7034 rs6000_mode_dependent_address (const_rtx addr)
7036 switch (GET_CODE (addr))
7039 /* Any offset from virtual_stack_vars_rtx and arg_pointer_rtx
7040 is considered a legitimate address before reload, so there
7041 are no offset restrictions in that case. Note that this
7042 condition is safe in strict mode because any address involving
7043 virtual_stack_vars_rtx or arg_pointer_rtx would already have
7044 been rejected as illegitimate. */
7045 if (XEXP (addr, 0) != virtual_stack_vars_rtx
7046 && XEXP (addr, 0) != arg_pointer_rtx
7047 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
7049 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
7050 return val + 12 + 0x8000 >= 0x10000;
7055 /* Anything in the constant pool is sufficiently aligned that
7056 all bytes have the same high part address. */
7057 return !legitimate_constant_pool_address_p (addr, QImode, false);
7059 /* Auto-increment cases are now treated generically in recog.c. */
7061 return TARGET_UPDATE;
7063 /* AND is only allowed in Altivec loads. */
7074 /* Debug version of rs6000_mode_dependent_address. */
7076 rs6000_debug_mode_dependent_address (const_rtx addr)
7078 bool ret = rs6000_mode_dependent_address (addr);
7080 fprintf (stderr, "\nrs6000_mode_dependent_address: ret = %s\n",
7081 ret ? "true" : "false");
7087 /* Implement FIND_BASE_TERM. */
7090 rs6000_find_base_term (rtx op)
7094 split_const (op, &base, &offset);
7095 if (GET_CODE (base) == UNSPEC)
7096 switch (XINT (base, 1))
7099 case UNSPEC_MACHOPIC_OFFSET:
7100 /* OP represents SYM [+ OFFSET] - ANCHOR. SYM is the base term
7101 for aliasing purposes. */
7102 return XVECEXP (base, 0, 0);
7108 /* More elaborate version of recog's offsettable_memref_p predicate
7109 that works around the ??? note of rs6000_mode_dependent_address.
7110 In particular it accepts
7112 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
7114 in 32-bit mode, that the recog predicate rejects. */
7117 rs6000_offsettable_memref_p (rtx op)
7122 /* First mimic offsettable_memref_p. */
7123 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
7126 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
7127 the latter predicate knows nothing about the mode of the memory
7128 reference and, therefore, assumes that it is the largest supported
7129 mode (TFmode). As a consequence, legitimate offsettable memory
7130 references are rejected. rs6000_legitimate_offset_address_p contains
7131 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
7132 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
7135 /* Change register usage conditional on target flags. */
7137 rs6000_conditional_register_usage (void)
7141 if (TARGET_DEBUG_TARGET)
7142 fprintf (stderr, "rs6000_conditional_register_usage called\n");
7144 /* Set MQ register fixed (already call_used) if not POWER
7145 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
7150 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
7152 fixed_regs[13] = call_used_regs[13]
7153 = call_really_used_regs[13] = 1;
7155 /* Conditionally disable FPRs. */
7156 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
7157 for (i = 32; i < 64; i++)
7158 fixed_regs[i] = call_used_regs[i]
7159 = call_really_used_regs[i] = 1;
7161 /* The TOC register is not killed across calls in a way that is
7162 visible to the compiler. */
7163 if (DEFAULT_ABI == ABI_AIX)
7164 call_really_used_regs[2] = 0;
7166 if (DEFAULT_ABI == ABI_V4
7167 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7169 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7171 if (DEFAULT_ABI == ABI_V4
7172 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
7174 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7175 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7176 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7178 if (DEFAULT_ABI == ABI_DARWIN
7179 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
7180 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7181 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7182 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7184 if (TARGET_TOC && TARGET_MINIMAL_TOC)
7185 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
7186 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
7190 global_regs[SPEFSCR_REGNO] = 1;
7191 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
7192 registers in prologues and epilogues. We no longer use r14
7193 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
7194 pool for link-compatibility with older versions of GCC. Once
7195 "old" code has died out, we can return r14 to the allocation
7198 = call_used_regs[14]
7199 = call_really_used_regs[14] = 1;
7202 if (!TARGET_ALTIVEC && !TARGET_VSX)
7204 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
7205 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7206 call_really_used_regs[VRSAVE_REGNO] = 1;
7209 if (TARGET_ALTIVEC || TARGET_VSX)
7210 global_regs[VSCR_REGNO] = 1;
7212 if (TARGET_ALTIVEC_ABI)
7214 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
7215 call_used_regs[i] = call_really_used_regs[i] = 1;
7217 /* AIX reserves VR20:31 in non-extended ABI mode. */
7219 for (i = FIRST_ALTIVEC_REGNO + 20; i < FIRST_ALTIVEC_REGNO + 32; ++i)
7220 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
7224 /* Try to output insns to set TARGET equal to the constant C if it can
7225 be done in less than N insns. Do all computations in MODE.
7226 Returns the place where the output has been placed if it can be
7227 done and the insns have been emitted. If it would take more than N
7228 insns, zero is returned and no insns and emitted. */
7231 rs6000_emit_set_const (rtx dest, enum machine_mode mode,
7232 rtx source, int n ATTRIBUTE_UNUSED)
7234 rtx result, insn, set;
7235 HOST_WIDE_INT c0, c1;
7242 dest = gen_reg_rtx (mode);
7243 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
7247 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
7249 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
7250 GEN_INT (INTVAL (source)
7251 & (~ (HOST_WIDE_INT) 0xffff))));
7252 emit_insn (gen_rtx_SET (VOIDmode, dest,
7253 gen_rtx_IOR (SImode, copy_rtx (result),
7254 GEN_INT (INTVAL (source) & 0xffff))));
7259 switch (GET_CODE (source))
7262 c0 = INTVAL (source);
7267 #if HOST_BITS_PER_WIDE_INT >= 64
7268 c0 = CONST_DOUBLE_LOW (source);
7271 c0 = CONST_DOUBLE_LOW (source);
7272 c1 = CONST_DOUBLE_HIGH (source);
7280 result = rs6000_emit_set_long_const (dest, c0, c1);
7287 insn = get_last_insn ();
7288 set = single_set (insn);
7289 if (! CONSTANT_P (SET_SRC (set)))
7290 set_unique_reg_note (insn, REG_EQUAL, source);
7295 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
7296 fall back to a straight forward decomposition. We do this to avoid
7297 exponential run times encountered when looking for longer sequences
7298 with rs6000_emit_set_const. */
7300 rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
7302 if (!TARGET_POWERPC64)
7304 rtx operand1, operand2;
7306 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
7308 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
7310 emit_move_insn (operand1, GEN_INT (c1));
7311 emit_move_insn (operand2, GEN_INT (c2));
7315 HOST_WIDE_INT ud1, ud2, ud3, ud4;
7318 ud2 = (c1 & 0xffff0000) >> 16;
7319 #if HOST_BITS_PER_WIDE_INT >= 64
7323 ud4 = (c2 & 0xffff0000) >> 16;
7325 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
7326 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
7329 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
7331 emit_move_insn (dest, GEN_INT (ud1));
7334 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
7335 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
7338 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7341 emit_move_insn (dest, GEN_INT (ud2 << 16));
7343 emit_move_insn (copy_rtx (dest),
7344 gen_rtx_IOR (DImode, copy_rtx (dest),
7347 else if (ud3 == 0 && ud4 == 0)
7349 gcc_assert (ud2 & 0x8000);
7350 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
7353 emit_move_insn (copy_rtx (dest),
7354 gen_rtx_IOR (DImode, copy_rtx (dest),
7356 emit_move_insn (copy_rtx (dest),
7357 gen_rtx_ZERO_EXTEND (DImode,
7358 gen_lowpart (SImode,
7361 else if ((ud4 == 0xffff && (ud3 & 0x8000))
7362 || (ud4 == 0 && ! (ud3 & 0x8000)))
7365 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
7368 emit_move_insn (dest, GEN_INT (ud3 << 16));
7371 emit_move_insn (copy_rtx (dest),
7372 gen_rtx_IOR (DImode, copy_rtx (dest),
7374 emit_move_insn (copy_rtx (dest),
7375 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7378 emit_move_insn (copy_rtx (dest),
7379 gen_rtx_IOR (DImode, copy_rtx (dest),
7385 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
7388 emit_move_insn (dest, GEN_INT (ud4 << 16));
7391 emit_move_insn (copy_rtx (dest),
7392 gen_rtx_IOR (DImode, copy_rtx (dest),
7395 emit_move_insn (copy_rtx (dest),
7396 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
7399 emit_move_insn (copy_rtx (dest),
7400 gen_rtx_IOR (DImode, copy_rtx (dest),
7401 GEN_INT (ud2 << 16)));
7403 emit_move_insn (copy_rtx (dest),
7404 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
7410 /* Helper for the following. Get rid of [r+r] memory refs
7411 in cases where it won't work (TImode, TFmode, TDmode). */
7414 rs6000_eliminate_indexed_memrefs (rtx operands[2])
7416 if (reload_in_progress)
7419 if (GET_CODE (operands[0]) == MEM
7420 && GET_CODE (XEXP (operands[0], 0)) != REG
7421 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0),
7422 GET_MODE (operands[0]), false))
7424 = replace_equiv_address (operands[0],
7425 copy_addr_to_reg (XEXP (operands[0], 0)));
7427 if (GET_CODE (operands[1]) == MEM
7428 && GET_CODE (XEXP (operands[1], 0)) != REG
7429 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0),
7430 GET_MODE (operands[1]), false))
7432 = replace_equiv_address (operands[1],
7433 copy_addr_to_reg (XEXP (operands[1], 0)));
7436 /* Emit a move from SOURCE to DEST in mode MODE. */
7438 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
7442 operands[1] = source;
7444 if (TARGET_DEBUG_ADDR)
7447 "\nrs6000_emit_move: mode = %s, reload_in_progress = %d, "
7448 "reload_completed = %d, can_create_pseudos = %d.\ndest:\n",
7449 GET_MODE_NAME (mode),
7452 can_create_pseudo_p ());
7454 fprintf (stderr, "source:\n");
7458 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
7459 if (GET_CODE (operands[1]) == CONST_DOUBLE
7460 && ! FLOAT_MODE_P (mode)
7461 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
7463 /* FIXME. This should never happen. */
7464 /* Since it seems that it does, do the safe thing and convert
7466 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
7468 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
7469 || FLOAT_MODE_P (mode)
7470 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
7471 || CONST_DOUBLE_LOW (operands[1]) < 0)
7472 && (CONST_DOUBLE_HIGH (operands[1]) != -1
7473 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
7475 /* Check if GCC is setting up a block move that will end up using FP
7476 registers as temporaries. We must make sure this is acceptable. */
7477 if (GET_CODE (operands[0]) == MEM
7478 && GET_CODE (operands[1]) == MEM
7480 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
7481 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
7482 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
7483 ? 32 : MEM_ALIGN (operands[0])))
7484 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
7486 : MEM_ALIGN (operands[1]))))
7487 && ! MEM_VOLATILE_P (operands [0])
7488 && ! MEM_VOLATILE_P (operands [1]))
7490 emit_move_insn (adjust_address (operands[0], SImode, 0),
7491 adjust_address (operands[1], SImode, 0));
7492 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
7493 adjust_address (copy_rtx (operands[1]), SImode, 4));
7497 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
7498 && !gpc_reg_operand (operands[1], mode))
7499 operands[1] = force_reg (mode, operands[1]);
7501 if (mode == SFmode && ! TARGET_POWERPC
7502 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
7503 && GET_CODE (operands[0]) == MEM)
7507 if (reload_in_progress || reload_completed)
7508 regnum = true_regnum (operands[1]);
7509 else if (GET_CODE (operands[1]) == REG)
7510 regnum = REGNO (operands[1]);
7514 /* If operands[1] is a register, on POWER it may have
7515 double-precision data in it, so truncate it to single
7517 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
7520 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
7521 : gen_reg_rtx (mode));
7522 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
7523 operands[1] = newreg;
7527 /* Recognize the case where operand[1] is a reference to thread-local
7528 data and load its address to a register. */
7529 if (rs6000_tls_referenced_p (operands[1]))
7531 enum tls_model model;
7532 rtx tmp = operands[1];
7535 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
7537 addend = XEXP (XEXP (tmp, 0), 1);
7538 tmp = XEXP (XEXP (tmp, 0), 0);
7541 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
7542 model = SYMBOL_REF_TLS_MODEL (tmp);
7543 gcc_assert (model != 0);
7545 tmp = rs6000_legitimize_tls_address (tmp, model);
7548 tmp = gen_rtx_PLUS (mode, tmp, addend);
7549 tmp = force_operand (tmp, operands[0]);
7554 /* Handle the case where reload calls us with an invalid address. */
7555 if (reload_in_progress && mode == Pmode
7556 && (! general_operand (operands[1], mode)
7557 || ! nonimmediate_operand (operands[0], mode)))
7560 /* 128-bit constant floating-point values on Darwin should really be
7561 loaded as two parts. */
7562 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
7563 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
7565 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
7566 know how to get a DFmode SUBREG of a TFmode. */
7567 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
7568 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
7569 simplify_gen_subreg (imode, operands[1], mode, 0),
7571 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
7572 GET_MODE_SIZE (imode)),
7573 simplify_gen_subreg (imode, operands[1], mode,
7574 GET_MODE_SIZE (imode)),
7579 if (reload_in_progress && cfun->machine->sdmode_stack_slot != NULL_RTX)
7580 cfun->machine->sdmode_stack_slot =
7581 eliminate_regs (cfun->machine->sdmode_stack_slot, VOIDmode, NULL_RTX);
7583 if (reload_in_progress
7585 && MEM_P (operands[0])
7586 && rtx_equal_p (operands[0], cfun->machine->sdmode_stack_slot)
7587 && REG_P (operands[1]))
7589 if (FP_REGNO_P (REGNO (operands[1])))
7591 rtx mem = adjust_address_nv (operands[0], DDmode, 0);
7592 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7593 emit_insn (gen_movsd_store (mem, operands[1]));
7595 else if (INT_REGNO_P (REGNO (operands[1])))
7597 rtx mem = adjust_address_nv (operands[0], mode, 4);
7598 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7599 emit_insn (gen_movsd_hardfloat (mem, operands[1]));
7605 if (reload_in_progress
7607 && REG_P (operands[0])
7608 && MEM_P (operands[1])
7609 && rtx_equal_p (operands[1], cfun->machine->sdmode_stack_slot))
7611 if (FP_REGNO_P (REGNO (operands[0])))
7613 rtx mem = adjust_address_nv (operands[1], DDmode, 0);
7614 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7615 emit_insn (gen_movsd_load (operands[0], mem));
7617 else if (INT_REGNO_P (REGNO (operands[0])))
7619 rtx mem = adjust_address_nv (operands[1], mode, 4);
7620 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
7621 emit_insn (gen_movsd_hardfloat (operands[0], mem));
7628 /* FIXME: In the long term, this switch statement should go away
7629 and be replaced by a sequence of tests based on things like
7635 if (CONSTANT_P (operands[1])
7636 && GET_CODE (operands[1]) != CONST_INT)
7637 operands[1] = force_const_mem (mode, operands[1]);
7642 rs6000_eliminate_indexed_memrefs (operands);
7649 if (CONSTANT_P (operands[1])
7650 && ! easy_fp_constant (operands[1], mode))
7651 operands[1] = force_const_mem (mode, operands[1]);
7664 if (CONSTANT_P (operands[1])
7665 && !easy_vector_constant (operands[1], mode))
7666 operands[1] = force_const_mem (mode, operands[1]);
7671 /* Use default pattern for address of ELF small data */
7674 && DEFAULT_ABI == ABI_V4
7675 && (GET_CODE (operands[1]) == SYMBOL_REF
7676 || GET_CODE (operands[1]) == CONST)
7677 && small_data_operand (operands[1], mode))
7679 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7683 if (DEFAULT_ABI == ABI_V4
7684 && mode == Pmode && mode == SImode
7685 && flag_pic == 1 && got_operand (operands[1], mode))
7687 emit_insn (gen_movsi_got (operands[0], operands[1]));
7691 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
7695 && CONSTANT_P (operands[1])
7696 && GET_CODE (operands[1]) != HIGH
7697 && GET_CODE (operands[1]) != CONST_INT)
7699 rtx target = (!can_create_pseudo_p ()
7701 : gen_reg_rtx (mode));
7703 /* If this is a function address on -mcall-aixdesc,
7704 convert it to the address of the descriptor. */
7705 if (DEFAULT_ABI == ABI_AIX
7706 && GET_CODE (operands[1]) == SYMBOL_REF
7707 && XSTR (operands[1], 0)[0] == '.')
7709 const char *name = XSTR (operands[1], 0);
7711 while (*name == '.')
7713 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
7714 CONSTANT_POOL_ADDRESS_P (new_ref)
7715 = CONSTANT_POOL_ADDRESS_P (operands[1]);
7716 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
7717 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
7718 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
7719 operands[1] = new_ref;
7722 if (DEFAULT_ABI == ABI_DARWIN)
7725 if (MACHO_DYNAMIC_NO_PIC_P)
7727 /* Take care of any required data indirection. */
7728 operands[1] = rs6000_machopic_legitimize_pic_address (
7729 operands[1], mode, operands[0]);
7730 if (operands[0] != operands[1])
7731 emit_insn (gen_rtx_SET (VOIDmode,
7732 operands[0], operands[1]));
7736 emit_insn (gen_macho_high (target, operands[1]));
7737 emit_insn (gen_macho_low (operands[0], target, operands[1]));
7741 emit_insn (gen_elf_high (target, operands[1]));
7742 emit_insn (gen_elf_low (operands[0], target, operands[1]));
7746 /* If this is a SYMBOL_REF that refers to a constant pool entry,
7747 and we have put it in the TOC, we just need to make a TOC-relative
7750 && GET_CODE (operands[1]) == SYMBOL_REF
7751 && constant_pool_expr_p (operands[1])
7752 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
7753 get_pool_mode (operands[1])))
7754 || (TARGET_CMODEL == CMODEL_MEDIUM
7755 && GET_CODE (operands[1]) == SYMBOL_REF
7756 && !CONSTANT_POOL_ADDRESS_P (operands[1])
7757 && SYMBOL_REF_LOCAL_P (operands[1])))
7760 if (TARGET_CMODEL != CMODEL_SMALL)
7762 if (can_create_pseudo_p ())
7763 reg = gen_reg_rtx (Pmode);
7767 operands[1] = create_TOC_reference (operands[1], reg);
7769 else if (mode == Pmode
7770 && CONSTANT_P (operands[1])
7771 && ((GET_CODE (operands[1]) != CONST_INT
7772 && ! easy_fp_constant (operands[1], mode))
7773 || (GET_CODE (operands[1]) == CONST_INT
7774 && (num_insns_constant (operands[1], mode)
7775 > (TARGET_CMODEL != CMODEL_SMALL ? 3 : 2)))
7776 || (GET_CODE (operands[0]) == REG
7777 && FP_REGNO_P (REGNO (operands[0]))))
7778 && GET_CODE (operands[1]) != HIGH
7779 && ! legitimate_constant_pool_address_p (operands[1], mode,
7781 && ! toc_relative_expr_p (operands[1])
7782 && (TARGET_CMODEL == CMODEL_SMALL
7783 || can_create_pseudo_p ()
7784 || (REG_P (operands[0])
7785 && INT_REG_OK_FOR_BASE_P (operands[0], true))))
7789 /* Darwin uses a special PIC legitimizer. */
7790 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
7793 rs6000_machopic_legitimize_pic_address (operands[1], mode,
7795 if (operands[0] != operands[1])
7796 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7801 /* If we are to limit the number of things we put in the TOC and
7802 this is a symbol plus a constant we can add in one insn,
7803 just put the symbol in the TOC and add the constant. Don't do
7804 this if reload is in progress. */
7805 if (GET_CODE (operands[1]) == CONST
7806 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
7807 && GET_CODE (XEXP (operands[1], 0)) == PLUS
7808 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
7809 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
7810 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
7811 && ! side_effects_p (operands[0]))
7814 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
7815 rtx other = XEXP (XEXP (operands[1], 0), 1);
7817 sym = force_reg (mode, sym);
7818 emit_insn (gen_add3_insn (operands[0], sym, other));
7822 operands[1] = force_const_mem (mode, operands[1]);
7825 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7826 && constant_pool_expr_p (XEXP (operands[1], 0))
7827 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
7828 get_pool_constant (XEXP (operands[1], 0)),
7829 get_pool_mode (XEXP (operands[1], 0))))
7833 if (TARGET_CMODEL != CMODEL_SMALL)
7835 if (can_create_pseudo_p ())
7836 reg = gen_reg_rtx (Pmode);
7840 tocref = create_TOC_reference (XEXP (operands[1], 0), reg);
7841 operands[1] = gen_const_mem (mode, tocref);
7842 set_mem_alias_set (operands[1], get_TOC_alias_set ());
7848 rs6000_eliminate_indexed_memrefs (operands);
7852 emit_insn (gen_rtx_PARALLEL (VOIDmode,
7854 gen_rtx_SET (VOIDmode,
7855 operands[0], operands[1]),
7856 gen_rtx_CLOBBER (VOIDmode,
7857 gen_rtx_SCRATCH (SImode)))));
7863 fatal_insn ("bad move", gen_rtx_SET (VOIDmode, dest, source));
7866 /* Above, we may have called force_const_mem which may have returned
7867 an invalid address. If we can, fix this up; otherwise, reload will
7868 have to deal with it. */
7869 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
7870 operands[1] = validize_mem (operands[1]);
7873 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
7876 /* Nonzero if we can use a floating-point register to pass this arg. */
7877 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
7878 (SCALAR_FLOAT_MODE_P (MODE) \
7879 && (CUM)->fregno <= FP_ARG_MAX_REG \
7880 && TARGET_HARD_FLOAT && TARGET_FPRS)
7882 /* Nonzero if we can use an AltiVec register to pass this arg. */
7883 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
7884 ((ALTIVEC_VECTOR_MODE (MODE) || VSX_VECTOR_MODE (MODE)) \
7885 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
7886 && TARGET_ALTIVEC_ABI \
7889 /* Return a nonzero value to say to return the function value in
7890 memory, just as large structures are always returned. TYPE will be
7891 the data type of the value, and FNTYPE will be the type of the
7892 function doing the returning, or @code{NULL} for libcalls.
7894 The AIX ABI for the RS/6000 specifies that all structures are
7895 returned in memory. The Darwin ABI does the same.
7897 For the Darwin 64 Bit ABI, a function result can be returned in
7898 registers or in memory, depending on the size of the return data
7899 type. If it is returned in registers, the value occupies the same
7900 registers as it would if it were the first and only function
7901 argument. Otherwise, the function places its result in memory at
7902 the location pointed to by GPR3.
7904 The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
7905 but a draft put them in memory, and GCC used to implement the draft
7906 instead of the final standard. Therefore, aix_struct_return
7907 controls this instead of DEFAULT_ABI; V.4 targets needing backward
7908 compatibility can change DRAFT_V4_STRUCT_RET to override the
7909 default, and -m switches get the final word. See
7910 rs6000_option_override_internal for more details.
7912 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
7913 long double support is enabled. These values are returned in memory.
7915 int_size_in_bytes returns -1 for variable size objects, which go in
7916 memory always. The cast to unsigned makes -1 > 8. */
7919 rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7921 /* For the Darwin64 ABI, test if we can fit the return value in regs. */
7923 && rs6000_darwin64_abi
7924 && TREE_CODE (type) == RECORD_TYPE
7925 && int_size_in_bytes (type) > 0)
7927 CUMULATIVE_ARGS valcum;
7931 valcum.fregno = FP_ARG_MIN_REG;
7932 valcum.vregno = ALTIVEC_ARG_MIN_REG;
7933 /* Do a trial code generation as if this were going to be passed
7934 as an argument; if any part goes in memory, we return NULL. */
7935 valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
7938 /* Otherwise fall through to more conventional ABI rules. */
7941 if (AGGREGATE_TYPE_P (type)
7942 && (aix_struct_return
7943 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
7946 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
7947 modes only exist for GCC vector types if -maltivec. */
7948 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
7949 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
7952 /* Return synthetic vectors in memory. */
7953 if (TREE_CODE (type) == VECTOR_TYPE
7954 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
7956 static bool warned_for_return_big_vectors = false;
7957 if (!warned_for_return_big_vectors)
7959 warning (0, "GCC vector returned by reference: "
7960 "non-standard ABI extension with no compatibility guarantee");
7961 warned_for_return_big_vectors = true;
7966 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
7972 #ifdef HAVE_AS_GNU_ATTRIBUTE
7973 /* Return TRUE if a call to function FNDECL may be one that
7974 potentially affects the function calling ABI of the object file. */
7977 call_ABI_of_interest (tree fndecl)
7979 if (cgraph_state == CGRAPH_STATE_EXPANSION)
7981 struct cgraph_node *c_node;
7983 /* Libcalls are always interesting. */
7984 if (fndecl == NULL_TREE)
7987 /* Any call to an external function is interesting. */
7988 if (DECL_EXTERNAL (fndecl))
7991 /* Interesting functions that we are emitting in this object file. */
7992 c_node = cgraph_get_node (fndecl);
7993 return !cgraph_only_called_directly_p (c_node);
7999 /* Initialize a variable CUM of type CUMULATIVE_ARGS
8000 for a call to a function whose data type is FNTYPE.
8001 For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
8003 For incoming args we set the number of arguments in the prototype large
8004 so we never return a PARALLEL. */
8007 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
8008 rtx libname ATTRIBUTE_UNUSED, int incoming,
8009 int libcall, int n_named_args,
8010 tree fndecl ATTRIBUTE_UNUSED,
8011 enum machine_mode return_mode ATTRIBUTE_UNUSED)
8013 static CUMULATIVE_ARGS zero_cumulative;
8015 *cum = zero_cumulative;
8017 cum->fregno = FP_ARG_MIN_REG;
8018 cum->vregno = ALTIVEC_ARG_MIN_REG;
8019 cum->prototype = (fntype && prototype_p (fntype));
8020 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
8021 ? CALL_LIBCALL : CALL_NORMAL);
8022 cum->sysv_gregno = GP_ARG_MIN_REG;
8023 cum->stdarg = stdarg_p (fntype);
8025 cum->nargs_prototype = 0;
8026 if (incoming || cum->prototype)
8027 cum->nargs_prototype = n_named_args;
8029 /* Check for a longcall attribute. */
8030 if ((!fntype && rs6000_default_long_calls)
8032 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
8033 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
8034 cum->call_cookie |= CALL_LONG;
8036 if (TARGET_DEBUG_ARG)
8038 fprintf (stderr, "\ninit_cumulative_args:");
8041 tree ret_type = TREE_TYPE (fntype);
8042 fprintf (stderr, " ret code = %s,",
8043 tree_code_name[ (int)TREE_CODE (ret_type) ]);
8046 if (cum->call_cookie & CALL_LONG)
8047 fprintf (stderr, " longcall,");
8049 fprintf (stderr, " proto = %d, nargs = %d\n",
8050 cum->prototype, cum->nargs_prototype);
8053 #ifdef HAVE_AS_GNU_ATTRIBUTE
8054 if (DEFAULT_ABI == ABI_V4)
8056 cum->escapes = call_ABI_of_interest (fndecl);
8063 return_type = TREE_TYPE (fntype);
8064 return_mode = TYPE_MODE (return_type);
8067 return_type = lang_hooks.types.type_for_mode (return_mode, 0);
8069 if (return_type != NULL)
8071 if (TREE_CODE (return_type) == RECORD_TYPE
8072 && TYPE_TRANSPARENT_AGGR (return_type))
8074 return_type = TREE_TYPE (first_field (return_type));
8075 return_mode = TYPE_MODE (return_type);
8077 if (AGGREGATE_TYPE_P (return_type)
8078 && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
8080 rs6000_returns_struct = true;
8082 if (SCALAR_FLOAT_MODE_P (return_mode))
8083 rs6000_passes_float = true;
8084 else if (ALTIVEC_VECTOR_MODE (return_mode)
8085 || VSX_VECTOR_MODE (return_mode)
8086 || SPE_VECTOR_MODE (return_mode))
8087 rs6000_passes_vector = true;
8094 && TARGET_ALTIVEC_ABI
8095 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
8097 error ("cannot return value in vector register because"
8098 " altivec instructions are disabled, use -maltivec"
8103 /* Return true if TYPE must be passed on the stack and not in registers. */
8106 rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
8108 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
8109 return must_pass_in_stack_var_size (mode, type);
8111 return must_pass_in_stack_var_size_or_pad (mode, type);
8114 /* If defined, a C expression which determines whether, and in which
8115 direction, to pad out an argument with extra space. The value
8116 should be of type `enum direction': either `upward' to pad above
8117 the argument, `downward' to pad below, or `none' to inhibit
8120 For the AIX ABI structs are always stored left shifted in their
8124 function_arg_padding (enum machine_mode mode, const_tree type)
8126 #ifndef AGGREGATE_PADDING_FIXED
8127 #define AGGREGATE_PADDING_FIXED 0
8129 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
8130 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
8133 if (!AGGREGATE_PADDING_FIXED)
8135 /* GCC used to pass structures of the same size as integer types as
8136 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
8137 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
8138 passed padded downward, except that -mstrict-align further
8139 muddied the water in that multi-component structures of 2 and 4
8140 bytes in size were passed padded upward.
8142 The following arranges for best compatibility with previous
8143 versions of gcc, but removes the -mstrict-align dependency. */
8144 if (BYTES_BIG_ENDIAN)
8146 HOST_WIDE_INT size = 0;
8148 if (mode == BLKmode)
8150 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
8151 size = int_size_in_bytes (type);
8154 size = GET_MODE_SIZE (mode);
8156 if (size == 1 || size == 2 || size == 4)
8162 if (AGGREGATES_PAD_UPWARD_ALWAYS)
8164 if (type != 0 && AGGREGATE_TYPE_P (type))
8168 /* Fall back to the default. */
8169 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
8172 /* If defined, a C expression that gives the alignment boundary, in bits,
8173 of an argument with the specified mode and type. If it is not defined,
8174 PARM_BOUNDARY is used for all arguments.
8176 V.4 wants long longs and doubles to be double word aligned. Just
8177 testing the mode size is a boneheaded way to do this as it means
8178 that other types such as complex int are also double word aligned.
8179 However, we're stuck with this because changing the ABI might break
8180 existing library interfaces.
8182 Doubleword align SPE vectors.
8183 Quadword align Altivec vectors.
8184 Quadword align large synthetic vector types. */
8187 rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
8189 if (DEFAULT_ABI == ABI_V4
8190 && (GET_MODE_SIZE (mode) == 8
8191 || (TARGET_HARD_FLOAT
8193 && (mode == TFmode || mode == TDmode))))
8195 else if (SPE_VECTOR_MODE (mode)
8196 || (type && TREE_CODE (type) == VECTOR_TYPE
8197 && int_size_in_bytes (type) >= 8
8198 && int_size_in_bytes (type) < 16))
8200 else if ((ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode))
8201 || (type && TREE_CODE (type) == VECTOR_TYPE
8202 && int_size_in_bytes (type) >= 16))
8204 else if (TARGET_MACHO
8205 && rs6000_darwin64_abi
8207 && type && TYPE_ALIGN (type) > 64)
8210 return PARM_BOUNDARY;
8213 /* For a function parm of MODE and TYPE, return the starting word in
8214 the parameter area. NWORDS of the parameter area are already used. */
8217 rs6000_parm_start (enum machine_mode mode, const_tree type,
8218 unsigned int nwords)
8221 unsigned int parm_offset;
8223 align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
8224 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
8225 return nwords + (-(parm_offset + nwords) & align);
8228 /* Compute the size (in words) of a function argument. */
8230 static unsigned long
8231 rs6000_arg_size (enum machine_mode mode, const_tree type)
8235 if (mode != BLKmode)
8236 size = GET_MODE_SIZE (mode);
8238 size = int_size_in_bytes (type);
8241 return (size + 3) >> 2;
8243 return (size + 7) >> 3;
8246 /* Use this to flush pending int fields. */
8249 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
8250 HOST_WIDE_INT bitpos, int final)
8252 unsigned int startbit, endbit;
8253 int intregs, intoffset;
8254 enum machine_mode mode;
8256 /* Handle the situations where a float is taking up the first half
8257 of the GPR, and the other half is empty (typically due to
8258 alignment restrictions). We can detect this by a 8-byte-aligned
8259 int field, or by seeing that this is the final flush for this
8260 argument. Count the word and continue on. */
8261 if (cum->floats_in_gpr == 1
8262 && (cum->intoffset % 64 == 0
8263 || (cum->intoffset == -1 && final)))
8266 cum->floats_in_gpr = 0;
8269 if (cum->intoffset == -1)
8272 intoffset = cum->intoffset;
8273 cum->intoffset = -1;
8274 cum->floats_in_gpr = 0;
8276 if (intoffset % BITS_PER_WORD != 0)
8278 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8280 if (mode == BLKmode)
8282 /* We couldn't find an appropriate mode, which happens,
8283 e.g., in packed structs when there are 3 bytes to load.
8284 Back intoffset back to the beginning of the word in this
8286 intoffset = intoffset & -BITS_PER_WORD;
8290 startbit = intoffset & -BITS_PER_WORD;
8291 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8292 intregs = (endbit - startbit) / BITS_PER_WORD;
8293 cum->words += intregs;
8294 /* words should be unsigned. */
8295 if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
8297 int pad = (endbit/BITS_PER_WORD) - cum->words;
8302 /* The darwin64 ABI calls for us to recurse down through structs,
8303 looking for elements passed in registers. Unfortunately, we have
8304 to track int register count here also because of misalignments
8305 in powerpc alignment mode. */
8308 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
8310 HOST_WIDE_INT startbitpos)
8314 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8315 if (TREE_CODE (f) == FIELD_DECL)
8317 HOST_WIDE_INT bitpos = startbitpos;
8318 tree ftype = TREE_TYPE (f);
8319 enum machine_mode mode;
8320 if (ftype == error_mark_node)
8322 mode = TYPE_MODE (ftype);
8324 if (DECL_SIZE (f) != 0
8325 && host_integerp (bit_position (f), 1))
8326 bitpos += int_bit_position (f);
8328 /* ??? FIXME: else assume zero offset. */
8330 if (TREE_CODE (ftype) == RECORD_TYPE)
8331 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
8332 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
8334 unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
8335 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8336 cum->fregno += n_fpregs;
8337 /* Single-precision floats present a special problem for
8338 us, because they are smaller than an 8-byte GPR, and so
8339 the structure-packing rules combined with the standard
8340 varargs behavior mean that we want to pack float/float
8341 and float/int combinations into a single register's
8342 space. This is complicated by the arg advance flushing,
8343 which works on arbitrarily large groups of int-type
8347 if (cum->floats_in_gpr == 1)
8349 /* Two floats in a word; count the word and reset
8352 cum->floats_in_gpr = 0;
8354 else if (bitpos % 64 == 0)
8356 /* A float at the beginning of an 8-byte word;
8357 count it and put off adjusting cum->words until
8358 we see if a arg advance flush is going to do it
8360 cum->floats_in_gpr++;
8364 /* The float is at the end of a word, preceded
8365 by integer fields, so the arg advance flush
8366 just above has already set cum->words and
8367 everything is taken care of. */
8371 cum->words += n_fpregs;
8373 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
8375 rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
8379 else if (cum->intoffset == -1)
8380 cum->intoffset = bitpos;
8384 /* Check for an item that needs to be considered specially under the darwin 64
8385 bit ABI. These are record types where the mode is BLK or the structure is
8388 rs6000_darwin64_struct_check_p (enum machine_mode mode, const_tree type)
8390 return rs6000_darwin64_abi
8391 && ((mode == BLKmode
8392 && TREE_CODE (type) == RECORD_TYPE
8393 && int_size_in_bytes (type) > 0)
8394 || (type && TREE_CODE (type) == RECORD_TYPE
8395 && int_size_in_bytes (type) == 8)) ? 1 : 0;
8398 /* Update the data in CUM to advance over an argument
8399 of mode MODE and data type TYPE.
8400 (TYPE is null for libcalls where that information may not be available.)
8402 Note that for args passed by reference, function_arg will be called
8403 with MODE and TYPE set to that of the pointer to the arg, not the arg
8407 rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8408 const_tree type, bool named, int depth)
8410 /* Only tick off an argument if we're not recursing. */
8412 cum->nargs_prototype--;
8414 #ifdef HAVE_AS_GNU_ATTRIBUTE
8415 if (DEFAULT_ABI == ABI_V4
8418 if (SCALAR_FLOAT_MODE_P (mode))
8419 rs6000_passes_float = true;
8420 else if (named && (ALTIVEC_VECTOR_MODE (mode) || VSX_VECTOR_MODE (mode)))
8421 rs6000_passes_vector = true;
8422 else if (SPE_VECTOR_MODE (mode)
8424 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8425 rs6000_passes_vector = true;
8429 if (TARGET_ALTIVEC_ABI
8430 && (ALTIVEC_VECTOR_MODE (mode)
8431 || VSX_VECTOR_MODE (mode)
8432 || (type && TREE_CODE (type) == VECTOR_TYPE
8433 && int_size_in_bytes (type) == 16)))
8437 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
8440 if (!TARGET_ALTIVEC)
8441 error ("cannot pass argument in vector register because"
8442 " altivec instructions are disabled, use -maltivec"
8445 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
8446 even if it is going to be passed in a vector register.
8447 Darwin does the same for variable-argument functions. */
8448 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
8449 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
8459 /* Vector parameters must be 16-byte aligned. This places
8460 them at 2 mod 4 in terms of words in 32-bit mode, since
8461 the parameter save area starts at offset 24 from the
8462 stack. In 64-bit mode, they just have to start on an
8463 even word, since the parameter save area is 16-byte
8464 aligned. Space for GPRs is reserved even if the argument
8465 will be passed in memory. */
8467 align = (2 - cum->words) & 3;
8469 align = cum->words & 1;
8470 cum->words += align + rs6000_arg_size (mode, type);
8472 if (TARGET_DEBUG_ARG)
8474 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
8476 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
8477 cum->nargs_prototype, cum->prototype,
8478 GET_MODE_NAME (mode));
8482 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
8484 && cum->sysv_gregno <= GP_ARG_MAX_REG)
8487 else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
8489 int size = int_size_in_bytes (type);
8490 /* Variable sized types have size == -1 and are
8491 treated as if consisting entirely of ints.
8492 Pad to 16 byte boundary if needed. */
8493 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8494 && (cum->words % 2) != 0)
8496 /* For varargs, we can just go up by the size of the struct. */
8498 cum->words += (size + 7) / 8;
8501 /* It is tempting to say int register count just goes up by
8502 sizeof(type)/8, but this is wrong in a case such as
8503 { int; double; int; } [powerpc alignment]. We have to
8504 grovel through the fields for these too. */
8506 cum->floats_in_gpr = 0;
8507 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
8508 rs6000_darwin64_record_arg_advance_flush (cum,
8509 size * BITS_PER_UNIT, 1);
8511 if (TARGET_DEBUG_ARG)
8513 fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
8514 cum->words, TYPE_ALIGN (type), size);
8516 "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
8517 cum->nargs_prototype, cum->prototype,
8518 GET_MODE_NAME (mode));
8521 else if (DEFAULT_ABI == ABI_V4)
8523 if (TARGET_HARD_FLOAT && TARGET_FPRS
8524 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
8525 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
8526 || (mode == TFmode && !TARGET_IEEEQUAD)
8527 || mode == SDmode || mode == DDmode || mode == TDmode))
8529 /* _Decimal128 must use an even/odd register pair. This assumes
8530 that the register number is odd when fregno is odd. */
8531 if (mode == TDmode && (cum->fregno % 2) == 1)
8534 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
8535 <= FP_ARG_V4_MAX_REG)
8536 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8539 cum->fregno = FP_ARG_V4_MAX_REG + 1;
8540 if (mode == DFmode || mode == TFmode
8541 || mode == DDmode || mode == TDmode)
8542 cum->words += cum->words & 1;
8543 cum->words += rs6000_arg_size (mode, type);
8548 int n_words = rs6000_arg_size (mode, type);
8549 int gregno = cum->sysv_gregno;
8551 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
8552 (r7,r8) or (r9,r10). As does any other 2 word item such
8553 as complex int due to a historical mistake. */
8555 gregno += (1 - gregno) & 1;
8557 /* Multi-reg args are not split between registers and stack. */
8558 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8560 /* Long long and SPE vectors are aligned on the stack.
8561 So are other 2 word items such as complex int due to
8562 a historical mistake. */
8564 cum->words += cum->words & 1;
8565 cum->words += n_words;
8568 /* Note: continuing to accumulate gregno past when we've started
8569 spilling to the stack indicates the fact that we've started
8570 spilling to the stack to expand_builtin_saveregs. */
8571 cum->sysv_gregno = gregno + n_words;
8574 if (TARGET_DEBUG_ARG)
8576 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8577 cum->words, cum->fregno);
8578 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
8579 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
8580 fprintf (stderr, "mode = %4s, named = %d\n",
8581 GET_MODE_NAME (mode), named);
8586 int n_words = rs6000_arg_size (mode, type);
8587 int start_words = cum->words;
8588 int align_words = rs6000_parm_start (mode, type, start_words);
8590 cum->words = align_words + n_words;
8592 if (SCALAR_FLOAT_MODE_P (mode)
8593 && TARGET_HARD_FLOAT && TARGET_FPRS)
8595 /* _Decimal128 must be passed in an even/odd float register pair.
8596 This assumes that the register number is odd when fregno is
8598 if (mode == TDmode && (cum->fregno % 2) == 1)
8600 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
8603 if (TARGET_DEBUG_ARG)
8605 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
8606 cum->words, cum->fregno);
8607 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
8608 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
8609 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
8610 named, align_words - start_words, depth);
8616 rs6000_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8617 const_tree type, bool named)
8619 rs6000_function_arg_advance_1 (cum, mode, type, named, 0);
8623 spe_build_register_parallel (enum machine_mode mode, int gregno)
8630 r1 = gen_rtx_REG (DImode, gregno);
8631 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8632 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
8636 r1 = gen_rtx_REG (DImode, gregno);
8637 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8638 r3 = gen_rtx_REG (DImode, gregno + 2);
8639 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8640 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
8643 r1 = gen_rtx_REG (DImode, gregno);
8644 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
8645 r3 = gen_rtx_REG (DImode, gregno + 2);
8646 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
8647 r5 = gen_rtx_REG (DImode, gregno + 4);
8648 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
8649 r7 = gen_rtx_REG (DImode, gregno + 6);
8650 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
8651 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
8658 /* Determine where to put a SIMD argument on the SPE. */
8660 rs6000_spe_function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
8663 int gregno = cum->sysv_gregno;
8665 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
8666 are passed and returned in a pair of GPRs for ABI compatibility. */
8667 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
8668 || mode == DCmode || mode == TCmode))
8670 int n_words = rs6000_arg_size (mode, type);
8672 /* Doubles go in an odd/even register pair (r5/r6, etc). */
8674 gregno += (1 - gregno) & 1;
8676 /* Multi-reg args are not split between registers and stack. */
8677 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
8680 return spe_build_register_parallel (mode, gregno);
8684 int n_words = rs6000_arg_size (mode, type);
8686 /* SPE vectors are put in odd registers. */
8687 if (n_words == 2 && (gregno & 1) == 0)
8690 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
8693 enum machine_mode m = SImode;
8695 r1 = gen_rtx_REG (m, gregno);
8696 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
8697 r2 = gen_rtx_REG (m, gregno + 1);
8698 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
8699 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
8706 if (gregno <= GP_ARG_MAX_REG)
8707 return gen_rtx_REG (mode, gregno);
8713 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
8714 structure between cum->intoffset and bitpos to integer registers. */
8717 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
8718 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
8720 enum machine_mode mode;
8722 unsigned int startbit, endbit;
8723 int this_regno, intregs, intoffset;
8726 if (cum->intoffset == -1)
8729 intoffset = cum->intoffset;
8730 cum->intoffset = -1;
8732 /* If this is the trailing part of a word, try to only load that
8733 much into the register. Otherwise load the whole register. Note
8734 that in the latter case we may pick up unwanted bits. It's not a
8735 problem at the moment but may wish to revisit. */
8737 if (intoffset % BITS_PER_WORD != 0)
8739 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
8741 if (mode == BLKmode)
8743 /* We couldn't find an appropriate mode, which happens,
8744 e.g., in packed structs when there are 3 bytes to load.
8745 Back intoffset back to the beginning of the word in this
8747 intoffset = intoffset & -BITS_PER_WORD;
8754 startbit = intoffset & -BITS_PER_WORD;
8755 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
8756 intregs = (endbit - startbit) / BITS_PER_WORD;
8757 this_regno = cum->words + intoffset / BITS_PER_WORD;
8759 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
8762 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
8766 intoffset /= BITS_PER_UNIT;
8769 regno = GP_ARG_MIN_REG + this_regno;
8770 reg = gen_rtx_REG (mode, regno);
8772 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
8775 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
8779 while (intregs > 0);
8782 /* Recursive workhorse for the following. */
8785 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
8786 HOST_WIDE_INT startbitpos, rtx rvec[],
8791 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
8792 if (TREE_CODE (f) == FIELD_DECL)
8794 HOST_WIDE_INT bitpos = startbitpos;
8795 tree ftype = TREE_TYPE (f);
8796 enum machine_mode mode;
8797 if (ftype == error_mark_node)
8799 mode = TYPE_MODE (ftype);
8801 if (DECL_SIZE (f) != 0
8802 && host_integerp (bit_position (f), 1))
8803 bitpos += int_bit_position (f);
8805 /* ??? FIXME: else assume zero offset. */
8807 if (TREE_CODE (ftype) == RECORD_TYPE)
8808 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
8809 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
8811 unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
8815 case SCmode: mode = SFmode; break;
8816 case DCmode: mode = DFmode; break;
8817 case TCmode: mode = TFmode; break;
8821 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8822 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
8824 gcc_assert (cum->fregno == FP_ARG_MAX_REG
8825 && (mode == TFmode || mode == TDmode));
8826 /* Long double or _Decimal128 split over regs and memory. */
8827 mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
8831 = gen_rtx_EXPR_LIST (VOIDmode,
8832 gen_rtx_REG (mode, cum->fregno++),
8833 GEN_INT (bitpos / BITS_PER_UNIT));
8834 if (mode == TFmode || mode == TDmode)
8837 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
8839 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
8841 = gen_rtx_EXPR_LIST (VOIDmode,
8842 gen_rtx_REG (mode, cum->vregno++),
8843 GEN_INT (bitpos / BITS_PER_UNIT));
8845 else if (cum->intoffset == -1)
8846 cum->intoffset = bitpos;
8850 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
8851 the register(s) to be used for each field and subfield of a struct
8852 being passed by value, along with the offset of where the
8853 register's value may be found in the block. FP fields go in FP
8854 register, vector fields go in vector registers, and everything
8855 else goes in int registers, packed as in memory.
8857 This code is also used for function return values. RETVAL indicates
8858 whether this is the case.
8860 Much of this is taken from the SPARC V9 port, which has a similar
8861 calling convention. */
8864 rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
8865 bool named, bool retval)
8867 rtx rvec[FIRST_PSEUDO_REGISTER];
8868 int k = 1, kbase = 1;
8869 HOST_WIDE_INT typesize = int_size_in_bytes (type);
8870 /* This is a copy; modifications are not visible to our caller. */
8871 CUMULATIVE_ARGS copy_cum = *orig_cum;
8872 CUMULATIVE_ARGS *cum = ©_cum;
8874 /* Pad to 16 byte boundary if needed. */
8875 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
8876 && (cum->words % 2) != 0)
8883 /* Put entries into rvec[] for individual FP and vector fields, and
8884 for the chunks of memory that go in int regs. Note we start at
8885 element 1; 0 is reserved for an indication of using memory, and
8886 may or may not be filled in below. */
8887 rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
8888 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
8890 /* If any part of the struct went on the stack put all of it there.
8891 This hack is because the generic code for
8892 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
8893 parts of the struct are not at the beginning. */
8897 return NULL_RTX; /* doesn't go in registers at all */
8899 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8901 if (k > 1 || cum->use_stack)
8902 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
8907 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
8910 rs6000_mixed_function_arg (enum machine_mode mode, const_tree type,
8915 rtx rvec[GP_ARG_NUM_REG + 1];
8917 if (align_words >= GP_ARG_NUM_REG)
8920 n_units = rs6000_arg_size (mode, type);
8922 /* Optimize the simple case where the arg fits in one gpr, except in
8923 the case of BLKmode due to assign_parms assuming that registers are
8924 BITS_PER_WORD wide. */
8926 || (n_units == 1 && mode != BLKmode))
8927 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
8930 if (align_words + n_units > GP_ARG_NUM_REG)
8931 /* Not all of the arg fits in gprs. Say that it goes in memory too,
8932 using a magic NULL_RTX component.
8933 This is not strictly correct. Only some of the arg belongs in
8934 memory, not all of it. However, the normal scheme using
8935 function_arg_partial_nregs can result in unusual subregs, eg.
8936 (subreg:SI (reg:DF) 4), which are not handled well. The code to
8937 store the whole arg to memory is often more efficient than code
8938 to store pieces, and we know that space is available in the right
8939 place for the whole arg. */
8940 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
8945 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
8946 rtx off = GEN_INT (i++ * 4);
8947 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
8949 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
8951 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
8954 /* Determine where to put an argument to a function.
8955 Value is zero to push the argument on the stack,
8956 or a hard register in which to store the argument.
8958 MODE is the argument's machine mode.
8959 TYPE is the data type of the argument (as a tree).
8960 This is null for libcalls where that information may
8962 CUM is a variable of type CUMULATIVE_ARGS which gives info about
8963 the preceding args and about the function being called. It is
8964 not modified in this routine.
8965 NAMED is nonzero if this argument is a named parameter
8966 (otherwise it is an extra parameter matching an ellipsis).
8968 On RS/6000 the first eight words of non-FP are normally in registers
8969 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
8970 Under V.4, the first 8 FP args are in registers.
8972 If this is floating-point and no prototype is specified, we use
8973 both an FP and integer register (or possibly FP reg and stack). Library
8974 functions (when CALL_LIBCALL is set) always have the proper types for args,
8975 so we can pass the FP value just in one register. emit_library_function
8976 doesn't support PARALLEL anyway.
8978 Note that for args passed by reference, function_arg will be called
8979 with MODE and TYPE set to that of the pointer to the arg, not the arg
8983 rs6000_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
8984 const_tree type, bool named)
8986 enum rs6000_abi abi = DEFAULT_ABI;
8988 /* Return a marker to indicate whether CR1 needs to set or clear the
8989 bit that V.4 uses to say fp args were passed in registers.
8990 Assume that we don't need the marker for software floating point,
8991 or compiler generated library calls. */
8992 if (mode == VOIDmode)
8995 && (cum->call_cookie & CALL_LIBCALL) == 0
8997 || (cum->nargs_prototype < 0
8998 && (cum->prototype || TARGET_NO_PROTOTYPE))))
9000 /* For the SPE, we need to crxor CR6 always. */
9002 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
9003 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
9004 return GEN_INT (cum->call_cookie
9005 | ((cum->fregno == FP_ARG_MIN_REG)
9006 ? CALL_V4_SET_FP_ARGS
9007 : CALL_V4_CLEAR_FP_ARGS));
9010 return GEN_INT (cum->call_cookie);
9013 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9015 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
9016 if (rslt != NULL_RTX)
9018 /* Else fall through to usual handling. */
9021 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
9022 if (TARGET_64BIT && ! cum->prototype)
9024 /* Vector parameters get passed in vector register
9025 and also in GPRs or memory, in absence of prototype. */
9028 align_words = (cum->words + 1) & ~1;
9030 if (align_words >= GP_ARG_NUM_REG)
9036 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9038 return gen_rtx_PARALLEL (mode,
9040 gen_rtx_EXPR_LIST (VOIDmode,
9042 gen_rtx_EXPR_LIST (VOIDmode,
9043 gen_rtx_REG (mode, cum->vregno),
9047 return gen_rtx_REG (mode, cum->vregno);
9048 else if (TARGET_ALTIVEC_ABI
9049 && (ALTIVEC_VECTOR_MODE (mode)
9050 || VSX_VECTOR_MODE (mode)
9051 || (type && TREE_CODE (type) == VECTOR_TYPE
9052 && int_size_in_bytes (type) == 16)))
9054 if (named || abi == ABI_V4)
9058 /* Vector parameters to varargs functions under AIX or Darwin
9059 get passed in memory and possibly also in GPRs. */
9060 int align, align_words, n_words;
9061 enum machine_mode part_mode;
9063 /* Vector parameters must be 16-byte aligned. This places them at
9064 2 mod 4 in terms of words in 32-bit mode, since the parameter
9065 save area starts at offset 24 from the stack. In 64-bit mode,
9066 they just have to start on an even word, since the parameter
9067 save area is 16-byte aligned. */
9069 align = (2 - cum->words) & 3;
9071 align = cum->words & 1;
9072 align_words = cum->words + align;
9074 /* Out of registers? Memory, then. */
9075 if (align_words >= GP_ARG_NUM_REG)
9078 if (TARGET_32BIT && TARGET_POWERPC64)
9079 return rs6000_mixed_function_arg (mode, type, align_words);
9081 /* The vector value goes in GPRs. Only the part of the
9082 value in GPRs is reported here. */
9084 n_words = rs6000_arg_size (mode, type);
9085 if (align_words + n_words > GP_ARG_NUM_REG)
9086 /* Fortunately, there are only two possibilities, the value
9087 is either wholly in GPRs or half in GPRs and half not. */
9090 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
9093 else if (TARGET_SPE_ABI && TARGET_SPE
9094 && (SPE_VECTOR_MODE (mode)
9095 || (TARGET_E500_DOUBLE && (mode == DFmode
9098 || mode == TCmode))))
9099 return rs6000_spe_function_arg (cum, mode, type);
9101 else if (abi == ABI_V4)
9103 if (TARGET_HARD_FLOAT && TARGET_FPRS
9104 && ((TARGET_SINGLE_FLOAT && mode == SFmode)
9105 || (TARGET_DOUBLE_FLOAT && mode == DFmode)
9106 || (mode == TFmode && !TARGET_IEEEQUAD)
9107 || mode == SDmode || mode == DDmode || mode == TDmode))
9109 /* _Decimal128 must use an even/odd register pair. This assumes
9110 that the register number is odd when fregno is odd. */
9111 if (mode == TDmode && (cum->fregno % 2) == 1)
9114 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
9115 <= FP_ARG_V4_MAX_REG)
9116 return gen_rtx_REG (mode, cum->fregno);
9122 int n_words = rs6000_arg_size (mode, type);
9123 int gregno = cum->sysv_gregno;
9125 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
9126 (r7,r8) or (r9,r10). As does any other 2 word item such
9127 as complex int due to a historical mistake. */
9129 gregno += (1 - gregno) & 1;
9131 /* Multi-reg args are not split between registers and stack. */
9132 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
9135 if (TARGET_32BIT && TARGET_POWERPC64)
9136 return rs6000_mixed_function_arg (mode, type,
9137 gregno - GP_ARG_MIN_REG);
9138 return gen_rtx_REG (mode, gregno);
9143 int align_words = rs6000_parm_start (mode, type, cum->words);
9145 /* _Decimal128 must be passed in an even/odd float register pair.
9146 This assumes that the register number is odd when fregno is odd. */
9147 if (mode == TDmode && (cum->fregno % 2) == 1)
9150 if (USE_FP_FOR_ARG_P (cum, mode, type))
9152 rtx rvec[GP_ARG_NUM_REG + 1];
9156 enum machine_mode fmode = mode;
9157 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
9159 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
9161 /* Currently, we only ever need one reg here because complex
9162 doubles are split. */
9163 gcc_assert (cum->fregno == FP_ARG_MAX_REG
9164 && (fmode == TFmode || fmode == TDmode));
9166 /* Long double or _Decimal128 split over regs and memory. */
9167 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
9170 /* Do we also need to pass this arg in the parameter save
9173 && (cum->nargs_prototype <= 0
9174 || (DEFAULT_ABI == ABI_AIX
9176 && align_words >= GP_ARG_NUM_REG)));
9178 if (!needs_psave && mode == fmode)
9179 return gen_rtx_REG (fmode, cum->fregno);
9184 /* Describe the part that goes in gprs or the stack.
9185 This piece must come first, before the fprs. */
9186 if (align_words < GP_ARG_NUM_REG)
9188 unsigned long n_words = rs6000_arg_size (mode, type);
9190 if (align_words + n_words > GP_ARG_NUM_REG
9191 || (TARGET_32BIT && TARGET_POWERPC64))
9193 /* If this is partially on the stack, then we only
9194 include the portion actually in registers here. */
9195 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
9198 if (align_words + n_words > GP_ARG_NUM_REG)
9199 /* Not all of the arg fits in gprs. Say that it
9200 goes in memory too, using a magic NULL_RTX
9201 component. Also see comment in
9202 rs6000_mixed_function_arg for why the normal
9203 function_arg_partial_nregs scheme doesn't work
9205 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
9209 r = gen_rtx_REG (rmode,
9210 GP_ARG_MIN_REG + align_words);
9211 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
9212 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
9214 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
9218 /* The whole arg fits in gprs. */
9219 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9220 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9224 /* It's entirely in memory. */
9225 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
9228 /* Describe where this piece goes in the fprs. */
9229 r = gen_rtx_REG (fmode, cum->fregno);
9230 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
9232 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
9234 else if (align_words < GP_ARG_NUM_REG)
9236 if (TARGET_32BIT && TARGET_POWERPC64)
9237 return rs6000_mixed_function_arg (mode, type, align_words);
9239 if (mode == BLKmode)
9242 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
9249 /* For an arg passed partly in registers and partly in memory, this is
9250 the number of bytes passed in registers. For args passed entirely in
9251 registers or entirely in memory, zero. When an arg is described by a
9252 PARALLEL, perhaps using more than one register type, this function
9253 returns the number of bytes used by the first element of the PARALLEL. */
9256 rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9257 tree type, bool named)
9262 if (DEFAULT_ABI == ABI_V4)
9265 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
9266 && cum->nargs_prototype >= 0)
9269 /* In this complicated case we just disable the partial_nregs code. */
9270 if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
9273 align_words = rs6000_parm_start (mode, type, cum->words);
9275 if (USE_FP_FOR_ARG_P (cum, mode, type))
9277 /* If we are passing this arg in the fixed parameter save area
9278 (gprs or memory) as well as fprs, then this function should
9279 return the number of partial bytes passed in the parameter
9280 save area rather than partial bytes passed in fprs. */
9282 && (cum->nargs_prototype <= 0
9283 || (DEFAULT_ABI == ABI_AIX
9285 && align_words >= GP_ARG_NUM_REG)))
9287 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
9288 > FP_ARG_MAX_REG + 1)
9289 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
9290 else if (cum->nargs_prototype >= 0)
9294 if (align_words < GP_ARG_NUM_REG
9295 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
9296 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
9298 if (ret != 0 && TARGET_DEBUG_ARG)
9299 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
9304 /* A C expression that indicates when an argument must be passed by
9305 reference. If nonzero for an argument, a copy of that argument is
9306 made in memory and a pointer to the argument is passed instead of
9307 the argument itself. The pointer is passed in whatever way is
9308 appropriate for passing a pointer to that type.
9310 Under V.4, aggregates and long double are passed by reference.
9312 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
9313 reference unless the AltiVec vector extension ABI is in force.
9315 As an extension to all ABIs, variable sized types are passed by
9319 rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
9320 enum machine_mode mode, const_tree type,
9321 bool named ATTRIBUTE_UNUSED)
9323 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
9325 if (TARGET_DEBUG_ARG)
9326 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
9333 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
9335 if (TARGET_DEBUG_ARG)
9336 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
9340 if (int_size_in_bytes (type) < 0)
9342 if (TARGET_DEBUG_ARG)
9343 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
9347 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
9348 modes only exist for GCC vector types if -maltivec. */
9349 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
9351 if (TARGET_DEBUG_ARG)
9352 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
9356 /* Pass synthetic vectors in memory. */
9357 if (TREE_CODE (type) == VECTOR_TYPE
9358 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
9360 static bool warned_for_pass_big_vectors = false;
9361 if (TARGET_DEBUG_ARG)
9362 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
9363 if (!warned_for_pass_big_vectors)
9365 warning (0, "GCC vector passed by reference: "
9366 "non-standard ABI extension with no compatibility guarantee");
9367 warned_for_pass_big_vectors = true;
9376 rs6000_move_block_from_reg (int regno, rtx x, int nregs)
9379 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
9384 for (i = 0; i < nregs; i++)
9386 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
9387 if (reload_completed)
9389 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
9392 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9393 i * GET_MODE_SIZE (reg_mode));
9396 tem = replace_equiv_address (tem, XEXP (tem, 0));
9400 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
9404 /* Perform any needed actions needed for a function that is receiving a
9405 variable number of arguments.
9409 MODE and TYPE are the mode and type of the current parameter.
9411 PRETEND_SIZE is a variable that should be set to the amount of stack
9412 that must be pushed by the prolog to pretend that our caller pushed
9415 Normally, this macro will push all remaining incoming registers on the
9416 stack and set PRETEND_SIZE to the length of the registers pushed. */
9419 setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
9420 tree type, int *pretend_size ATTRIBUTE_UNUSED,
9423 CUMULATIVE_ARGS next_cum;
9424 int reg_size = TARGET_32BIT ? 4 : 8;
9425 rtx save_area = NULL_RTX, mem;
9426 int first_reg_offset;
9429 /* Skip the last named argument. */
9431 rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
9433 if (DEFAULT_ABI == ABI_V4)
9435 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
9439 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
9440 HOST_WIDE_INT offset = 0;
9442 /* Try to optimize the size of the varargs save area.
9443 The ABI requires that ap.reg_save_area is doubleword
9444 aligned, but we don't need to allocate space for all
9445 the bytes, only those to which we actually will save
9447 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
9448 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
9449 if (TARGET_HARD_FLOAT && TARGET_FPRS
9450 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9451 && cfun->va_list_fpr_size)
9454 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
9455 * UNITS_PER_FP_WORD;
9456 if (cfun->va_list_fpr_size
9457 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9458 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
9460 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
9461 * UNITS_PER_FP_WORD;
9465 offset = -((first_reg_offset * reg_size) & ~7);
9466 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
9468 gpr_reg_num = cfun->va_list_gpr_size;
9469 if (reg_size == 4 && (first_reg_offset & 1))
9472 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
9475 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
9477 - (int) (GP_ARG_NUM_REG * reg_size);
9479 if (gpr_size + fpr_size)
9482 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
9483 gcc_assert (GET_CODE (reg_save_area) == MEM);
9484 reg_save_area = XEXP (reg_save_area, 0);
9485 if (GET_CODE (reg_save_area) == PLUS)
9487 gcc_assert (XEXP (reg_save_area, 0)
9488 == virtual_stack_vars_rtx);
9489 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
9490 offset += INTVAL (XEXP (reg_save_area, 1));
9493 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
9496 cfun->machine->varargs_save_offset = offset;
9497 save_area = plus_constant (virtual_stack_vars_rtx, offset);
9502 first_reg_offset = next_cum.words;
9503 save_area = virtual_incoming_args_rtx;
9505 if (targetm.calls.must_pass_in_stack (mode, type))
9506 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
9509 set = get_varargs_alias_set ();
9510 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
9511 && cfun->va_list_gpr_size)
9513 int nregs = GP_ARG_NUM_REG - first_reg_offset;
9515 if (va_list_gpr_counter_field)
9517 /* V4 va_list_gpr_size counts number of registers needed. */
9518 if (nregs > cfun->va_list_gpr_size)
9519 nregs = cfun->va_list_gpr_size;
9523 /* char * va_list instead counts number of bytes needed. */
9524 if (nregs > cfun->va_list_gpr_size / reg_size)
9525 nregs = cfun->va_list_gpr_size / reg_size;
9528 mem = gen_rtx_MEM (BLKmode,
9529 plus_constant (save_area,
9530 first_reg_offset * reg_size));
9531 MEM_NOTRAP_P (mem) = 1;
9532 set_mem_alias_set (mem, set);
9533 set_mem_align (mem, BITS_PER_WORD);
9535 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9539 /* Save FP registers if needed. */
9540 if (DEFAULT_ABI == ABI_V4
9541 && TARGET_HARD_FLOAT && TARGET_FPRS
9543 && next_cum.fregno <= FP_ARG_V4_MAX_REG
9544 && cfun->va_list_fpr_size)
9546 int fregno = next_cum.fregno, nregs;
9547 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
9548 rtx lab = gen_label_rtx ();
9549 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
9550 * UNITS_PER_FP_WORD);
9553 (gen_rtx_SET (VOIDmode,
9555 gen_rtx_IF_THEN_ELSE (VOIDmode,
9556 gen_rtx_NE (VOIDmode, cr1,
9558 gen_rtx_LABEL_REF (VOIDmode, lab),
9562 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
9563 fregno++, off += UNITS_PER_FP_WORD, nregs++)
9565 mem = gen_rtx_MEM ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9567 plus_constant (save_area, off));
9568 MEM_NOTRAP_P (mem) = 1;
9569 set_mem_alias_set (mem, set);
9570 set_mem_align (mem, GET_MODE_ALIGNMENT (
9571 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9572 ? DFmode : SFmode));
9573 emit_move_insn (mem, gen_rtx_REG (
9574 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
9575 ? DFmode : SFmode, fregno));
9582 /* Create the va_list data type. */
9585 rs6000_build_builtin_va_list (void)
9587 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
9589 /* For AIX, prefer 'char *' because that's what the system
9590 header files like. */
9591 if (DEFAULT_ABI != ABI_V4)
9592 return build_pointer_type (char_type_node);
9594 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
9595 type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
9596 get_identifier ("__va_list_tag"), record);
9598 f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
9599 unsigned_char_type_node);
9600 f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
9601 unsigned_char_type_node);
9602 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
9604 f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9605 get_identifier ("reserved"), short_unsigned_type_node);
9606 f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9607 get_identifier ("overflow_arg_area"),
9609 f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
9610 get_identifier ("reg_save_area"),
9613 va_list_gpr_counter_field = f_gpr;
9614 va_list_fpr_counter_field = f_fpr;
9616 DECL_FIELD_CONTEXT (f_gpr) = record;
9617 DECL_FIELD_CONTEXT (f_fpr) = record;
9618 DECL_FIELD_CONTEXT (f_res) = record;
9619 DECL_FIELD_CONTEXT (f_ovf) = record;
9620 DECL_FIELD_CONTEXT (f_sav) = record;
9622 TYPE_STUB_DECL (record) = type_decl;
9623 TYPE_NAME (record) = type_decl;
9624 TYPE_FIELDS (record) = f_gpr;
9625 DECL_CHAIN (f_gpr) = f_fpr;
9626 DECL_CHAIN (f_fpr) = f_res;
9627 DECL_CHAIN (f_res) = f_ovf;
9628 DECL_CHAIN (f_ovf) = f_sav;
9630 layout_type (record);
9632 /* The correct type is an array type of one element. */
9633 return build_array_type (record, build_index_type (size_zero_node));
9636 /* Implement va_start. */
9639 rs6000_va_start (tree valist, rtx nextarg)
9641 HOST_WIDE_INT words, n_gpr, n_fpr;
9642 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9643 tree gpr, fpr, ovf, sav, t;
9645 /* Only SVR4 needs something special. */
9646 if (DEFAULT_ABI != ABI_V4)
9648 std_expand_builtin_va_start (valist, nextarg);
9652 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9653 f_fpr = DECL_CHAIN (f_gpr);
9654 f_res = DECL_CHAIN (f_fpr);
9655 f_ovf = DECL_CHAIN (f_res);
9656 f_sav = DECL_CHAIN (f_ovf);
9658 valist = build_simple_mem_ref (valist);
9659 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9660 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9662 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9664 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9667 /* Count number of gp and fp argument registers used. */
9668 words = crtl->args.info.words;
9669 n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
9671 n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
9674 if (TARGET_DEBUG_ARG)
9675 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
9676 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
9677 words, n_gpr, n_fpr);
9679 if (cfun->va_list_gpr_size)
9681 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
9682 build_int_cst (NULL_TREE, n_gpr));
9683 TREE_SIDE_EFFECTS (t) = 1;
9684 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9687 if (cfun->va_list_fpr_size)
9689 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
9690 build_int_cst (NULL_TREE, n_fpr));
9691 TREE_SIDE_EFFECTS (t) = 1;
9692 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9694 #ifdef HAVE_AS_GNU_ATTRIBUTE
9695 if (call_ABI_of_interest (cfun->decl))
9696 rs6000_passes_float = true;
9700 /* Find the overflow area. */
9701 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
9703 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
9704 size_int (words * UNITS_PER_WORD));
9705 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
9706 TREE_SIDE_EFFECTS (t) = 1;
9707 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9709 /* If there were no va_arg invocations, don't set up the register
9711 if (!cfun->va_list_gpr_size
9712 && !cfun->va_list_fpr_size
9713 && n_gpr < GP_ARG_NUM_REG
9714 && n_fpr < FP_ARG_V4_MAX_REG)
9717 /* Find the register save area. */
9718 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
9719 if (cfun->machine->varargs_save_offset)
9720 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
9721 size_int (cfun->machine->varargs_save_offset));
9722 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
9723 TREE_SIDE_EFFECTS (t) = 1;
9724 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
9727 /* Implement va_arg. */
9730 rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
9733 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
9734 tree gpr, fpr, ovf, sav, reg, t, u;
9735 int size, rsize, n_reg, sav_ofs, sav_scale;
9736 tree lab_false, lab_over, addr;
9738 tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
9742 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
9744 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
9745 return build_va_arg_indirect_ref (t);
9748 /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
9749 earlier version of gcc, with the property that it always applied alignment
9750 adjustments to the va-args (even for zero-sized types). The cheapest way
9751 to deal with this is to replicate the effect of the part of
9752 std_gimplify_va_arg_expr that carries out the align adjust, for the case
9754 We don't need to check for pass-by-reference because of the test above.
9755 We can return a simplifed answer, since we know there's no offset to add. */
9758 && rs6000_darwin64_abi
9759 && integer_zerop (TYPE_SIZE (type)))
9761 unsigned HOST_WIDE_INT align, boundary;
9762 tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
9763 align = PARM_BOUNDARY / BITS_PER_UNIT;
9764 boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
9765 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
9766 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
9767 boundary /= BITS_PER_UNIT;
9768 if (boundary > align)
9771 /* This updates arg ptr by the amount that would be necessary
9772 to align the zero-sized (but not zero-alignment) item. */
9773 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9774 fold_build2 (POINTER_PLUS_EXPR,
9776 valist_tmp, size_int (boundary - 1)));
9777 gimplify_and_add (t, pre_p);
9779 t = fold_convert (sizetype, valist_tmp);
9780 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
9781 fold_convert (TREE_TYPE (valist),
9782 fold_build2 (BIT_AND_EXPR, sizetype, t,
9783 size_int (-boundary))));
9784 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
9785 gimplify_and_add (t, pre_p);
9787 /* Since it is zero-sized there's no increment for the item itself. */
9788 valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
9789 return build_va_arg_indirect_ref (valist_tmp);
9792 if (DEFAULT_ABI != ABI_V4)
9794 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
9796 tree elem_type = TREE_TYPE (type);
9797 enum machine_mode elem_mode = TYPE_MODE (elem_type);
9798 int elem_size = GET_MODE_SIZE (elem_mode);
9800 if (elem_size < UNITS_PER_WORD)
9802 tree real_part, imag_part;
9803 gimple_seq post = NULL;
9805 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9807 /* Copy the value into a temporary, lest the formal temporary
9808 be reused out from under us. */
9809 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
9810 gimple_seq_add_seq (pre_p, post);
9812 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
9815 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
9819 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
9822 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
9823 f_fpr = DECL_CHAIN (f_gpr);
9824 f_res = DECL_CHAIN (f_fpr);
9825 f_ovf = DECL_CHAIN (f_res);
9826 f_sav = DECL_CHAIN (f_ovf);
9828 valist = build_va_arg_indirect_ref (valist);
9829 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
9830 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
9832 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
9834 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
9837 size = int_size_in_bytes (type);
9838 rsize = (size + 3) / 4;
9841 if (TARGET_HARD_FLOAT && TARGET_FPRS
9842 && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
9843 || (TARGET_DOUBLE_FLOAT
9844 && (TYPE_MODE (type) == DFmode
9845 || TYPE_MODE (type) == TFmode
9846 || TYPE_MODE (type) == SDmode
9847 || TYPE_MODE (type) == DDmode
9848 || TYPE_MODE (type) == TDmode))))
9850 /* FP args go in FP registers, if present. */
9852 n_reg = (size + 7) / 8;
9853 sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
9854 sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
9855 if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
9860 /* Otherwise into GP registers. */
9869 /* Pull the value out of the saved registers.... */
9872 addr = create_tmp_var (ptr_type_node, "addr");
9874 /* AltiVec vectors never go in registers when -mabi=altivec. */
9875 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
9879 lab_false = create_artificial_label (input_location);
9880 lab_over = create_artificial_label (input_location);
9882 /* Long long and SPE vectors are aligned in the registers.
9883 As are any other 2 gpr item such as complex int due to a
9884 historical mistake. */
9886 if (n_reg == 2 && reg == gpr)
9889 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9890 build_int_cst (TREE_TYPE (reg), n_reg - 1));
9891 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
9892 unshare_expr (reg), u);
9894 /* _Decimal128 is passed in even/odd fpr pairs; the stored
9895 reg number is 0 for f1, so we want to make it odd. */
9896 else if (reg == fpr && TYPE_MODE (type) == TDmode)
9898 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9899 build_int_cst (TREE_TYPE (reg), 1));
9900 u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
9903 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
9904 t = build2 (GE_EXPR, boolean_type_node, u, t);
9905 u = build1 (GOTO_EXPR, void_type_node, lab_false);
9906 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
9907 gimplify_and_add (t, pre_p);
9911 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
9913 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
9914 build_int_cst (TREE_TYPE (reg), n_reg));
9915 u = fold_convert (sizetype, u);
9916 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
9917 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
9919 /* _Decimal32 varargs are located in the second word of the 64-bit
9920 FP register for 32-bit binaries. */
9921 if (!TARGET_POWERPC64
9922 && TARGET_HARD_FLOAT && TARGET_FPRS
9923 && TYPE_MODE (type) == SDmode)
9924 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9926 gimplify_assign (addr, t, pre_p);
9928 gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
9930 stmt = gimple_build_label (lab_false);
9931 gimple_seq_add_stmt (pre_p, stmt);
9933 if ((n_reg == 2 && !regalign) || n_reg > 2)
9935 /* Ensure that we don't find any more args in regs.
9936 Alignment has taken care of for special cases. */
9937 gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
9941 /* ... otherwise out of the overflow area. */
9943 /* Care for on-stack alignment if needed. */
9947 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
9948 t = fold_convert (sizetype, t);
9949 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
9951 t = fold_convert (TREE_TYPE (ovf), t);
9953 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
9955 gimplify_assign (unshare_expr (addr), t, pre_p);
9957 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
9958 gimplify_assign (unshare_expr (ovf), t, pre_p);
9962 stmt = gimple_build_label (lab_over);
9963 gimple_seq_add_stmt (pre_p, stmt);
9966 if (STRICT_ALIGNMENT
9967 && (TYPE_ALIGN (type)
9968 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
9970 /* The value (of type complex double, for example) may not be
9971 aligned in memory in the saved registers, so copy via a
9972 temporary. (This is the same code as used for SPARC.) */
9973 tree tmp = create_tmp_var (type, "va_arg_tmp");
9974 tree dest_addr = build_fold_addr_expr (tmp);
9976 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
9977 3, dest_addr, addr, size_int (rsize * 4));
9979 gimplify_and_add (copy, pre_p);
9983 addr = fold_convert (ptrtype, addr);
9984 return build_va_arg_indirect_ref (addr);
9990 def_builtin (int mask, const char *name, tree type, int code)
9992 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
9995 if (rs6000_builtin_decls[code])
9996 fatal_error ("internal error: builtin function to %s already processed",
9999 rs6000_builtin_decls[code] = t =
10000 add_builtin_function (name, type, code, BUILT_IN_MD,
10003 gcc_assert (code >= 0 && code < (int)RS6000_BUILTIN_COUNT);
10004 switch (builtin_classify[code])
10007 gcc_unreachable ();
10009 /* assume builtin can do anything. */
10010 case RS6000_BTC_MISC:
10013 /* const function, function only depends on the inputs. */
10014 case RS6000_BTC_CONST:
10015 TREE_READONLY (t) = 1;
10016 TREE_NOTHROW (t) = 1;
10019 /* pure function, function can read global memory. */
10020 case RS6000_BTC_PURE:
10021 DECL_PURE_P (t) = 1;
10022 TREE_NOTHROW (t) = 1;
10025 /* Function is a math function. If rounding mode is on, then treat
10026 the function as not reading global memory, but it can have
10027 arbitrary side effects. If it is off, then assume the function is
10028 a const function. This mimics the ATTR_MATHFN_FPROUNDING
10029 attribute in builtin-attribute.def that is used for the math
10031 case RS6000_BTC_FP_PURE:
10032 TREE_NOTHROW (t) = 1;
10033 if (flag_rounding_math)
10035 DECL_PURE_P (t) = 1;
10036 DECL_IS_NOVOPS (t) = 1;
10039 TREE_READONLY (t) = 1;
10045 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
10047 static const struct builtin_description bdesc_3arg[] =
10049 { MASK_ALTIVEC, CODE_FOR_fmav4sf4, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
10050 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
10051 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
10052 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
10053 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
10054 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
10055 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
10056 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
10057 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
10058 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
10059 { MASK_ALTIVEC, CODE_FOR_nfmsv4sf4, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
10060 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2df, "__builtin_altivec_vperm_2df", ALTIVEC_BUILTIN_VPERM_2DF },
10061 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di, "__builtin_altivec_vperm_2di", ALTIVEC_BUILTIN_VPERM_2DI },
10062 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
10063 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
10064 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
10065 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
10066 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_altivec_vperm_2di_uns", ALTIVEC_BUILTIN_VPERM_2DI_UNS },
10067 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_altivec_vperm_4si_uns", ALTIVEC_BUILTIN_VPERM_4SI_UNS },
10068 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_altivec_vperm_8hi_uns", ALTIVEC_BUILTIN_VPERM_8HI_UNS },
10069 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_altivec_vperm_16qi_uns", ALTIVEC_BUILTIN_VPERM_16QI_UNS },
10070 { MASK_ALTIVEC, CODE_FOR_vector_select_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
10071 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
10072 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
10073 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
10074 { MASK_ALTIVEC, CODE_FOR_vector_select_v2df, "__builtin_altivec_vsel_2df", ALTIVEC_BUILTIN_VSEL_2DF },
10075 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di, "__builtin_altivec_vsel_2di", ALTIVEC_BUILTIN_VSEL_2DI },
10076 { MASK_ALTIVEC, CODE_FOR_vector_select_v4si_uns, "__builtin_altivec_vsel_4si_uns", ALTIVEC_BUILTIN_VSEL_4SI_UNS },
10077 { MASK_ALTIVEC, CODE_FOR_vector_select_v8hi_uns, "__builtin_altivec_vsel_8hi_uns", ALTIVEC_BUILTIN_VSEL_8HI_UNS },
10078 { MASK_ALTIVEC, CODE_FOR_vector_select_v16qi_uns, "__builtin_altivec_vsel_16qi_uns", ALTIVEC_BUILTIN_VSEL_16QI_UNS },
10079 { MASK_ALTIVEC, CODE_FOR_vector_select_v2di_uns, "__builtin_altivec_vsel_2di_uns", ALTIVEC_BUILTIN_VSEL_2DI_UNS },
10080 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
10081 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
10082 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
10083 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
10085 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
10086 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
10087 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
10088 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
10089 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
10090 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
10091 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
10092 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
10093 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
10094 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
10095 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
10096 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
10097 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
10098 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
10099 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
10101 { MASK_VSX, CODE_FOR_fmav2df4, "__builtin_vsx_xvmadddp", VSX_BUILTIN_XVMADDDP },
10102 { MASK_VSX, CODE_FOR_fmsv2df4, "__builtin_vsx_xvmsubdp", VSX_BUILTIN_XVMSUBDP },
10103 { MASK_VSX, CODE_FOR_nfmav2df4, "__builtin_vsx_xvnmadddp", VSX_BUILTIN_XVNMADDDP },
10104 { MASK_VSX, CODE_FOR_nfmsv2df4, "__builtin_vsx_xvnmsubdp", VSX_BUILTIN_XVNMSUBDP },
10106 { MASK_VSX, CODE_FOR_fmav4sf4, "__builtin_vsx_xvmaddsp", VSX_BUILTIN_XVMADDSP },
10107 { MASK_VSX, CODE_FOR_fmsv4sf4, "__builtin_vsx_xvmsubsp", VSX_BUILTIN_XVMSUBSP },
10108 { MASK_VSX, CODE_FOR_nfmav4sf4, "__builtin_vsx_xvnmaddsp", VSX_BUILTIN_XVNMADDSP },
10109 { MASK_VSX, CODE_FOR_nfmsv4sf4, "__builtin_vsx_xvnmsubsp", VSX_BUILTIN_XVNMSUBSP },
10111 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msub", VSX_BUILTIN_VEC_MSUB },
10112 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmadd", VSX_BUILTIN_VEC_NMADD },
10114 { MASK_VSX, CODE_FOR_vector_select_v2di, "__builtin_vsx_xxsel_2di", VSX_BUILTIN_XXSEL_2DI },
10115 { MASK_VSX, CODE_FOR_vector_select_v2df, "__builtin_vsx_xxsel_2df", VSX_BUILTIN_XXSEL_2DF },
10116 { MASK_VSX, CODE_FOR_vector_select_v4sf, "__builtin_vsx_xxsel_4sf", VSX_BUILTIN_XXSEL_4SF },
10117 { MASK_VSX, CODE_FOR_vector_select_v4si, "__builtin_vsx_xxsel_4si", VSX_BUILTIN_XXSEL_4SI },
10118 { MASK_VSX, CODE_FOR_vector_select_v8hi, "__builtin_vsx_xxsel_8hi", VSX_BUILTIN_XXSEL_8HI },
10119 { MASK_VSX, CODE_FOR_vector_select_v16qi, "__builtin_vsx_xxsel_16qi", VSX_BUILTIN_XXSEL_16QI },
10120 { MASK_VSX, CODE_FOR_vector_select_v2di_uns, "__builtin_vsx_xxsel_2di_uns", VSX_BUILTIN_XXSEL_2DI_UNS },
10121 { MASK_VSX, CODE_FOR_vector_select_v4si_uns, "__builtin_vsx_xxsel_4si_uns", VSX_BUILTIN_XXSEL_4SI_UNS },
10122 { MASK_VSX, CODE_FOR_vector_select_v8hi_uns, "__builtin_vsx_xxsel_8hi_uns", VSX_BUILTIN_XXSEL_8HI_UNS },
10123 { MASK_VSX, CODE_FOR_vector_select_v16qi_uns, "__builtin_vsx_xxsel_16qi_uns", VSX_BUILTIN_XXSEL_16QI_UNS },
10125 { MASK_VSX, CODE_FOR_altivec_vperm_v2di, "__builtin_vsx_vperm_2di", VSX_BUILTIN_VPERM_2DI },
10126 { MASK_VSX, CODE_FOR_altivec_vperm_v2df, "__builtin_vsx_vperm_2df", VSX_BUILTIN_VPERM_2DF },
10127 { MASK_VSX, CODE_FOR_altivec_vperm_v4sf, "__builtin_vsx_vperm_4sf", VSX_BUILTIN_VPERM_4SF },
10128 { MASK_VSX, CODE_FOR_altivec_vperm_v4si, "__builtin_vsx_vperm_4si", VSX_BUILTIN_VPERM_4SI },
10129 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi, "__builtin_vsx_vperm_8hi", VSX_BUILTIN_VPERM_8HI },
10130 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi, "__builtin_vsx_vperm_16qi", VSX_BUILTIN_VPERM_16QI },
10131 { MASK_VSX, CODE_FOR_altivec_vperm_v2di_uns, "__builtin_vsx_vperm_2di_uns", VSX_BUILTIN_VPERM_2DI_UNS },
10132 { MASK_VSX, CODE_FOR_altivec_vperm_v4si_uns, "__builtin_vsx_vperm_4si_uns", VSX_BUILTIN_VPERM_4SI_UNS },
10133 { MASK_VSX, CODE_FOR_altivec_vperm_v8hi_uns, "__builtin_vsx_vperm_8hi_uns", VSX_BUILTIN_VPERM_8HI_UNS },
10134 { MASK_VSX, CODE_FOR_altivec_vperm_v16qi_uns, "__builtin_vsx_vperm_16qi_uns", VSX_BUILTIN_VPERM_16QI_UNS },
10136 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2df, "__builtin_vsx_xxpermdi_2df", VSX_BUILTIN_XXPERMDI_2DF },
10137 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v2di, "__builtin_vsx_xxpermdi_2di", VSX_BUILTIN_XXPERMDI_2DI },
10138 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4sf, "__builtin_vsx_xxpermdi_4sf", VSX_BUILTIN_XXPERMDI_4SF },
10139 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v4si, "__builtin_vsx_xxpermdi_4si", VSX_BUILTIN_XXPERMDI_4SI },
10140 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v8hi, "__builtin_vsx_xxpermdi_8hi", VSX_BUILTIN_XXPERMDI_8HI },
10141 { MASK_VSX, CODE_FOR_vsx_xxpermdi_v16qi, "__builtin_vsx_xxpermdi_16qi", VSX_BUILTIN_XXPERMDI_16QI },
10142 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxpermdi", VSX_BUILTIN_VEC_XXPERMDI },
10143 { MASK_VSX, CODE_FOR_vsx_set_v2df, "__builtin_vsx_set_2df", VSX_BUILTIN_SET_2DF },
10144 { MASK_VSX, CODE_FOR_vsx_set_v2di, "__builtin_vsx_set_2di", VSX_BUILTIN_SET_2DI },
10146 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2di, "__builtin_vsx_xxsldwi_2di", VSX_BUILTIN_XXSLDWI_2DI },
10147 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v2df, "__builtin_vsx_xxsldwi_2df", VSX_BUILTIN_XXSLDWI_2DF },
10148 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4sf, "__builtin_vsx_xxsldwi_4sf", VSX_BUILTIN_XXSLDWI_4SF },
10149 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v4si, "__builtin_vsx_xxsldwi_4si", VSX_BUILTIN_XXSLDWI_4SI },
10150 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v8hi, "__builtin_vsx_xxsldwi_8hi", VSX_BUILTIN_XXSLDWI_8HI },
10151 { MASK_VSX, CODE_FOR_vsx_xxsldwi_v16qi, "__builtin_vsx_xxsldwi_16qi", VSX_BUILTIN_XXSLDWI_16QI },
10152 { MASK_VSX, CODE_FOR_nothing, "__builtin_vsx_xxsldwi", VSX_BUILTIN_VEC_XXSLDWI },
10154 { 0, CODE_FOR_fmsv2sf4, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
10155 { 0, CODE_FOR_fmav2sf4, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
10156 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
10157 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
10158 { 0, CODE_FOR_nfmsv2sf4, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
10159 { 0, CODE_FOR_nfmav2sf4, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
10160 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
10161 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
10162 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
10165 /* DST operations: void foo (void *, const int, const char). */
10167 static const struct builtin_description bdesc_dst[] =
10169 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
10170 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
10171 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
10172 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
10174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
10175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
10176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
10177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
10180 /* Simple binary operations: VECc = foo (VECa, VECb). */
10182 static struct builtin_description bdesc_2arg[] =
10184 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
10185 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
10186 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
10187 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
10188 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
10189 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
10190 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
10191 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
10192 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
10193 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
10194 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
10195 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
10196 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
10197 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
10198 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
10199 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
10200 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
10201 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
10202 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
10203 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
10204 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
10205 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
10206 { MASK_ALTIVEC, CODE_FOR_vector_eqv16qi, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
10207 { MASK_ALTIVEC, CODE_FOR_vector_eqv8hi, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
10208 { MASK_ALTIVEC, CODE_FOR_vector_eqv4si, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
10209 { MASK_ALTIVEC, CODE_FOR_vector_eqv4sf, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
10210 { MASK_ALTIVEC, CODE_FOR_vector_gev4sf, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
10211 { MASK_ALTIVEC, CODE_FOR_vector_gtuv16qi, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
10212 { MASK_ALTIVEC, CODE_FOR_vector_gtv16qi, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
10213 { MASK_ALTIVEC, CODE_FOR_vector_gtuv8hi, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
10214 { MASK_ALTIVEC, CODE_FOR_vector_gtv8hi, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
10215 { MASK_ALTIVEC, CODE_FOR_vector_gtuv4si, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
10216 { MASK_ALTIVEC, CODE_FOR_vector_gtv4si, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
10217 { MASK_ALTIVEC, CODE_FOR_vector_gtv4sf, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
10218 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
10219 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
10220 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
10221 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
10222 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
10223 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
10224 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
10225 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
10226 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
10227 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
10228 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
10229 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
10230 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
10231 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
10232 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
10233 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
10234 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
10235 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
10236 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
10237 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
10238 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
10239 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
10240 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
10241 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub_uns", ALTIVEC_BUILTIN_VMULEUB_UNS },
10242 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
10243 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
10244 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh_uns", ALTIVEC_BUILTIN_VMULEUH_UNS },
10245 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
10246 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
10247 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub_uns", ALTIVEC_BUILTIN_VMULOUB_UNS },
10248 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
10249 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
10250 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh_uns", ALTIVEC_BUILTIN_VMULOUH_UNS },
10251 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
10252 { MASK_ALTIVEC, CODE_FOR_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
10253 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
10254 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
10255 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
10256 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
10257 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
10258 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
10259 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
10260 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
10261 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
10262 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
10263 { MASK_ALTIVEC, CODE_FOR_recipv4sf3, "__builtin_altivec_vrecipdivfp", ALTIVEC_BUILTIN_VRECIPFP },
10264 { MASK_ALTIVEC, CODE_FOR_vrotlv16qi3, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
10265 { MASK_ALTIVEC, CODE_FOR_vrotlv8hi3, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
10266 { MASK_ALTIVEC, CODE_FOR_vrotlv4si3, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
10267 { MASK_ALTIVEC, CODE_FOR_vashlv16qi3, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
10268 { MASK_ALTIVEC, CODE_FOR_vashlv8hi3, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
10269 { MASK_ALTIVEC, CODE_FOR_vashlv4si3, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
10270 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
10271 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
10272 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
10273 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
10274 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
10275 { MASK_ALTIVEC, CODE_FOR_vlshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
10276 { MASK_ALTIVEC, CODE_FOR_vlshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
10277 { MASK_ALTIVEC, CODE_FOR_vlshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
10278 { MASK_ALTIVEC, CODE_FOR_vashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
10279 { MASK_ALTIVEC, CODE_FOR_vashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
10280 { MASK_ALTIVEC, CODE_FOR_vashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
10281 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
10282 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
10283 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
10284 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
10285 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
10286 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
10287 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
10288 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
10289 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
10290 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
10291 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
10292 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
10293 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
10294 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
10295 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
10296 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
10297 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
10298 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
10299 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
10300 { MASK_ALTIVEC, CODE_FOR_vector_copysignv4sf3, "__builtin_altivec_copysignfp", ALTIVEC_BUILTIN_COPYSIGN_V4SF },
10302 { MASK_VSX, CODE_FOR_addv2df3, "__builtin_vsx_xvadddp", VSX_BUILTIN_XVADDDP },
10303 { MASK_VSX, CODE_FOR_subv2df3, "__builtin_vsx_xvsubdp", VSX_BUILTIN_XVSUBDP },
10304 { MASK_VSX, CODE_FOR_mulv2df3, "__builtin_vsx_xvmuldp", VSX_BUILTIN_XVMULDP },
10305 { MASK_VSX, CODE_FOR_divv2df3, "__builtin_vsx_xvdivdp", VSX_BUILTIN_XVDIVDP },
10306 { MASK_VSX, CODE_FOR_recipv2df3, "__builtin_vsx_xvrecipdivdp", VSX_BUILTIN_RECIP_V2DF },
10307 { MASK_VSX, CODE_FOR_sminv2df3, "__builtin_vsx_xvmindp", VSX_BUILTIN_XVMINDP },
10308 { MASK_VSX, CODE_FOR_smaxv2df3, "__builtin_vsx_xvmaxdp", VSX_BUILTIN_XVMAXDP },
10309 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fe, "__builtin_vsx_xvtdivdp_fe", VSX_BUILTIN_XVTDIVDP_FE },
10310 { MASK_VSX, CODE_FOR_vsx_tdivv2df3_fg, "__builtin_vsx_xvtdivdp_fg", VSX_BUILTIN_XVTDIVDP_FG },
10311 { MASK_VSX, CODE_FOR_vector_eqv2df, "__builtin_vsx_xvcmpeqdp", VSX_BUILTIN_XVCMPEQDP },
10312 { MASK_VSX, CODE_FOR_vector_gtv2df, "__builtin_vsx_xvcmpgtdp", VSX_BUILTIN_XVCMPGTDP },
10313 { MASK_VSX, CODE_FOR_vector_gev2df, "__builtin_vsx_xvcmpgedp", VSX_BUILTIN_XVCMPGEDP },
10315 { MASK_VSX, CODE_FOR_addv4sf3, "__builtin_vsx_xvaddsp", VSX_BUILTIN_XVADDSP },
10316 { MASK_VSX, CODE_FOR_subv4sf3, "__builtin_vsx_xvsubsp", VSX_BUILTIN_XVSUBSP },
10317 { MASK_VSX, CODE_FOR_mulv4sf3, "__builtin_vsx_xvmulsp", VSX_BUILTIN_XVMULSP },
10318 { MASK_VSX, CODE_FOR_divv4sf3, "__builtin_vsx_xvdivsp", VSX_BUILTIN_XVDIVSP },
10319 { MASK_VSX, CODE_FOR_recipv4sf3, "__builtin_vsx_xvrecipdivsp", VSX_BUILTIN_RECIP_V4SF },
10320 { MASK_VSX, CODE_FOR_sminv4sf3, "__builtin_vsx_xvminsp", VSX_BUILTIN_XVMINSP },
10321 { MASK_VSX, CODE_FOR_smaxv4sf3, "__builtin_vsx_xvmaxsp", VSX_BUILTIN_XVMAXSP },
10322 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fe, "__builtin_vsx_xvtdivsp_fe", VSX_BUILTIN_XVTDIVSP_FE },
10323 { MASK_VSX, CODE_FOR_vsx_tdivv4sf3_fg, "__builtin_vsx_xvtdivsp_fg", VSX_BUILTIN_XVTDIVSP_FG },
10324 { MASK_VSX, CODE_FOR_vector_eqv4sf, "__builtin_vsx_xvcmpeqsp", VSX_BUILTIN_XVCMPEQSP },
10325 { MASK_VSX, CODE_FOR_vector_gtv4sf, "__builtin_vsx_xvcmpgtsp", VSX_BUILTIN_XVCMPGTSP },
10326 { MASK_VSX, CODE_FOR_vector_gev4sf, "__builtin_vsx_xvcmpgesp", VSX_BUILTIN_XVCMPGESP },
10328 { MASK_VSX, CODE_FOR_smindf3, "__builtin_vsx_xsmindp", VSX_BUILTIN_XSMINDP },
10329 { MASK_VSX, CODE_FOR_smaxdf3, "__builtin_vsx_xsmaxdp", VSX_BUILTIN_XSMAXDP },
10330 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fe, "__builtin_vsx_xstdivdp_fe", VSX_BUILTIN_XSTDIVDP_FE },
10331 { MASK_VSX, CODE_FOR_vsx_tdivdf3_fg, "__builtin_vsx_xstdivdp_fg", VSX_BUILTIN_XSTDIVDP_FG },
10332 { MASK_VSX, CODE_FOR_vector_copysignv2df3, "__builtin_vsx_cpsgndp", VSX_BUILTIN_CPSGNDP },
10333 { MASK_VSX, CODE_FOR_vector_copysignv4sf3, "__builtin_vsx_cpsgnsp", VSX_BUILTIN_CPSGNSP },
10335 { MASK_VSX, CODE_FOR_vsx_concat_v2df, "__builtin_vsx_concat_2df", VSX_BUILTIN_CONCAT_2DF },
10336 { MASK_VSX, CODE_FOR_vsx_concat_v2di, "__builtin_vsx_concat_2di", VSX_BUILTIN_CONCAT_2DI },
10337 { MASK_VSX, CODE_FOR_vsx_splat_v2df, "__builtin_vsx_splat_2df", VSX_BUILTIN_SPLAT_2DF },
10338 { MASK_VSX, CODE_FOR_vsx_splat_v2di, "__builtin_vsx_splat_2di", VSX_BUILTIN_SPLAT_2DI },
10339 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4sf, "__builtin_vsx_xxmrghw", VSX_BUILTIN_XXMRGHW_4SF },
10340 { MASK_VSX, CODE_FOR_vsx_xxmrghw_v4si, "__builtin_vsx_xxmrghw_4si", VSX_BUILTIN_XXMRGHW_4SI },
10341 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4sf, "__builtin_vsx_xxmrglw", VSX_BUILTIN_XXMRGLW_4SF },
10342 { MASK_VSX, CODE_FOR_vsx_xxmrglw_v4si, "__builtin_vsx_xxmrglw_4si", VSX_BUILTIN_XXMRGLW_4SI },
10343 { MASK_VSX, CODE_FOR_vec_interleave_lowv2df, "__builtin_vsx_mergel_2df", VSX_BUILTIN_VEC_MERGEL_V2DF },
10344 { MASK_VSX, CODE_FOR_vec_interleave_lowv2di, "__builtin_vsx_mergel_2di", VSX_BUILTIN_VEC_MERGEL_V2DI },
10345 { MASK_VSX, CODE_FOR_vec_interleave_highv2df, "__builtin_vsx_mergeh_2df", VSX_BUILTIN_VEC_MERGEH_V2DF },
10346 { MASK_VSX, CODE_FOR_vec_interleave_highv2di, "__builtin_vsx_mergeh_2di", VSX_BUILTIN_VEC_MERGEH_V2DI },
10348 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
10349 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
10350 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
10351 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
10352 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
10353 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
10354 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
10355 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
10356 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
10357 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
10358 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
10359 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
10360 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
10361 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
10362 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
10363 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
10364 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
10365 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
10366 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
10367 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
10368 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
10369 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
10370 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
10371 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
10372 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
10373 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
10374 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
10375 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
10376 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
10377 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
10378 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
10379 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
10380 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
10381 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
10382 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
10383 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
10384 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
10385 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
10386 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
10387 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_copysign", ALTIVEC_BUILTIN_VEC_COPYSIGN },
10388 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
10389 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
10390 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
10391 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
10392 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
10393 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
10394 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
10395 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
10396 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
10397 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
10398 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
10399 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
10400 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
10401 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
10402 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
10403 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
10404 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
10405 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
10406 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
10407 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
10408 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
10409 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
10410 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
10411 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
10412 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
10413 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
10414 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
10415 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
10416 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
10417 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
10418 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
10419 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
10420 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
10421 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
10422 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
10423 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
10424 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
10425 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
10426 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
10427 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
10428 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
10429 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
10430 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
10431 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
10432 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
10433 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
10434 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
10435 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
10436 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_recipdiv", ALTIVEC_BUILTIN_VEC_RECIP },
10437 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
10438 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
10439 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
10440 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
10441 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
10442 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
10443 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
10444 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
10445 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
10446 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
10447 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
10448 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
10449 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
10450 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
10451 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
10452 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
10453 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
10454 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
10455 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
10456 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
10457 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
10458 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
10459 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
10460 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
10461 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
10462 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
10463 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
10464 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
10465 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
10466 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
10467 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
10468 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
10469 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
10470 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
10471 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
10472 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
10473 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
10474 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
10475 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
10476 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
10478 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_mul", VSX_BUILTIN_VEC_MUL },
10479 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_div", VSX_BUILTIN_VEC_DIV },
10481 { 0, CODE_FOR_paired_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
10482 { 0, CODE_FOR_paired_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
10483 { 0, CODE_FOR_paired_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
10484 { 0, CODE_FOR_paired_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
10485 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
10486 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
10487 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
10488 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
10489 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
10490 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
10492 /* Place holder, leave as first spe builtin. */
10493 { 0, CODE_FOR_addv2si3, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
10494 { 0, CODE_FOR_andv2si3, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
10495 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
10496 { 0, CODE_FOR_divv2si3, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
10497 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
10498 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
10499 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
10500 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
10501 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
10502 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
10503 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
10504 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
10505 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
10506 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
10507 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
10508 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
10509 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
10510 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
10511 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
10512 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
10513 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
10514 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
10515 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
10516 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
10517 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
10518 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
10519 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
10520 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
10521 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
10522 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
10523 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
10524 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
10525 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
10526 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
10527 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
10528 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
10529 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
10530 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
10531 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
10532 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
10533 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
10534 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
10535 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
10536 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
10537 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
10538 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
10539 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
10540 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
10541 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
10542 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
10543 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
10544 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
10545 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
10546 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
10547 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
10548 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
10549 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
10550 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
10551 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
10552 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
10553 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
10554 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
10555 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
10556 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
10557 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
10558 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
10559 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
10560 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
10561 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
10562 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
10563 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
10564 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
10565 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
10566 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
10567 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
10568 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
10569 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
10570 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
10571 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
10572 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
10573 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
10574 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
10575 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
10576 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
10577 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
10578 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
10579 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
10580 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
10581 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
10582 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
10583 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
10584 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
10585 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
10586 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
10587 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
10588 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
10589 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
10590 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
10591 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
10592 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
10593 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
10594 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
10595 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
10596 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
10597 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
10598 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
10599 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
10600 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
10601 { 0, CODE_FOR_subv2si3, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
10603 /* SPE binary operations expecting a 5-bit unsigned literal. */
10604 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
10606 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
10607 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
10608 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
10609 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
10610 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
10611 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
10612 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
10613 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
10614 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
10615 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
10616 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
10617 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
10618 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
10619 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
10620 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
10621 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
10622 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
10623 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
10624 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
10625 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
10626 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
10627 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
10628 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
10629 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
10630 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
10631 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
10633 /* Place-holder. Leave as last binary SPE builtin. */
10634 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
10637 /* AltiVec predicates. */
10639 struct builtin_description_predicates
10641 const unsigned int mask;
10642 const enum insn_code icode;
10643 const char *const name;
10644 const enum rs6000_builtins code;
10647 static const struct builtin_description_predicates bdesc_altivec_preds[] =
10649 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp_p, "__builtin_altivec_vcmpbfp_p",
10650 ALTIVEC_BUILTIN_VCMPBFP_P },
10651 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_eq_v4sf_p,
10652 "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
10653 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_ge_v4sf_p,
10654 "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
10655 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_vector_gt_v4sf_p,
10656 "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
10657 { MASK_ALTIVEC, CODE_FOR_vector_eq_v4si_p, "__builtin_altivec_vcmpequw_p",
10658 ALTIVEC_BUILTIN_VCMPEQUW_P },
10659 { MASK_ALTIVEC, CODE_FOR_vector_gt_v4si_p, "__builtin_altivec_vcmpgtsw_p",
10660 ALTIVEC_BUILTIN_VCMPGTSW_P },
10661 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v4si_p, "__builtin_altivec_vcmpgtuw_p",
10662 ALTIVEC_BUILTIN_VCMPGTUW_P },
10663 { MASK_ALTIVEC, CODE_FOR_vector_eq_v8hi_p, "__builtin_altivec_vcmpequh_p",
10664 ALTIVEC_BUILTIN_VCMPEQUH_P },
10665 { MASK_ALTIVEC, CODE_FOR_vector_gt_v8hi_p, "__builtin_altivec_vcmpgtsh_p",
10666 ALTIVEC_BUILTIN_VCMPGTSH_P },
10667 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v8hi_p, "__builtin_altivec_vcmpgtuh_p",
10668 ALTIVEC_BUILTIN_VCMPGTUH_P },
10669 { MASK_ALTIVEC, CODE_FOR_vector_eq_v16qi_p, "__builtin_altivec_vcmpequb_p",
10670 ALTIVEC_BUILTIN_VCMPEQUB_P },
10671 { MASK_ALTIVEC, CODE_FOR_vector_gt_v16qi_p, "__builtin_altivec_vcmpgtsb_p",
10672 ALTIVEC_BUILTIN_VCMPGTSB_P },
10673 { MASK_ALTIVEC, CODE_FOR_vector_gtu_v16qi_p, "__builtin_altivec_vcmpgtub_p",
10674 ALTIVEC_BUILTIN_VCMPGTUB_P },
10676 { MASK_VSX, CODE_FOR_vector_eq_v4sf_p, "__builtin_vsx_xvcmpeqsp_p",
10677 VSX_BUILTIN_XVCMPEQSP_P },
10678 { MASK_VSX, CODE_FOR_vector_ge_v4sf_p, "__builtin_vsx_xvcmpgesp_p",
10679 VSX_BUILTIN_XVCMPGESP_P },
10680 { MASK_VSX, CODE_FOR_vector_gt_v4sf_p, "__builtin_vsx_xvcmpgtsp_p",
10681 VSX_BUILTIN_XVCMPGTSP_P },
10682 { MASK_VSX, CODE_FOR_vector_eq_v2df_p, "__builtin_vsx_xvcmpeqdp_p",
10683 VSX_BUILTIN_XVCMPEQDP_P },
10684 { MASK_VSX, CODE_FOR_vector_ge_v2df_p, "__builtin_vsx_xvcmpgedp_p",
10685 VSX_BUILTIN_XVCMPGEDP_P },
10686 { MASK_VSX, CODE_FOR_vector_gt_v2df_p, "__builtin_vsx_xvcmpgtdp_p",
10687 VSX_BUILTIN_XVCMPGTDP_P },
10689 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpeq_p",
10690 ALTIVEC_BUILTIN_VCMPEQ_P },
10691 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpgt_p",
10692 ALTIVEC_BUILTIN_VCMPGT_P },
10693 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_nothing, "__builtin_vec_vcmpge_p",
10694 ALTIVEC_BUILTIN_VCMPGE_P }
10697 /* SPE predicates. */
10698 static struct builtin_description bdesc_spe_predicates[] =
10700 /* Place-holder. Leave as first. */
10701 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
10702 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
10703 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
10704 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
10705 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
10706 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
10707 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
10708 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
10709 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
10710 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
10711 /* Place-holder. Leave as last. */
10712 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
10715 /* SPE evsel predicates. */
10716 static struct builtin_description bdesc_spe_evsel[] =
10718 /* Place-holder. Leave as first. */
10719 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
10720 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
10721 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
10722 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
10723 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
10724 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
10725 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
10726 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
10727 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
10728 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
10729 /* Place-holder. Leave as last. */
10730 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
10733 /* PAIRED predicates. */
10734 static const struct builtin_description bdesc_paired_preds[] =
10736 /* Place-holder. Leave as first. */
10737 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
10738 /* Place-holder. Leave as last. */
10739 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
10742 /* ABS* operations. */
10744 static const struct builtin_description bdesc_abs[] =
10746 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
10747 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
10748 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
10749 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
10750 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
10751 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
10752 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI },
10753 { MASK_VSX, CODE_FOR_absv2df2, "__builtin_vsx_xvabsdp", VSX_BUILTIN_XVABSDP },
10754 { MASK_VSX, CODE_FOR_vsx_nabsv2df2, "__builtin_vsx_xvnabsdp", VSX_BUILTIN_XVNABSDP },
10755 { MASK_VSX, CODE_FOR_absv4sf2, "__builtin_vsx_xvabssp", VSX_BUILTIN_XVABSSP },
10756 { MASK_VSX, CODE_FOR_vsx_nabsv4sf2, "__builtin_vsx_xvnabssp", VSX_BUILTIN_XVNABSSP },
10759 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
10762 static struct builtin_description bdesc_1arg[] =
10764 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
10765 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
10766 { MASK_ALTIVEC, CODE_FOR_rev4sf2, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
10767 { MASK_ALTIVEC, CODE_FOR_vector_floorv4sf2, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
10768 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
10769 { MASK_ALTIVEC, CODE_FOR_vector_ceilv4sf2, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
10770 { MASK_ALTIVEC, CODE_FOR_vector_btruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
10771 { MASK_ALTIVEC, CODE_FOR_rsqrtv4sf2, "__builtin_altivec_vrsqrtfp", ALTIVEC_BUILTIN_VRSQRTFP },
10772 { MASK_ALTIVEC, CODE_FOR_rsqrtev4sf2, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
10773 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
10774 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
10775 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
10776 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
10777 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
10778 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
10779 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
10780 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
10781 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
10783 { MASK_VSX, CODE_FOR_negv2df2, "__builtin_vsx_xvnegdp", VSX_BUILTIN_XVNEGDP },
10784 { MASK_VSX, CODE_FOR_sqrtv2df2, "__builtin_vsx_xvsqrtdp", VSX_BUILTIN_XVSQRTDP },
10785 { MASK_VSX, CODE_FOR_rsqrtv2df2, "__builtin_vsx_xvrsqrtdp", VSX_BUILTIN_VEC_RSQRT_V2DF },
10786 { MASK_VSX, CODE_FOR_rsqrtev2df2, "__builtin_vsx_xvrsqrtedp", VSX_BUILTIN_XVRSQRTEDP },
10787 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fe, "__builtin_vsx_xvtsqrtdp_fe", VSX_BUILTIN_XVTSQRTDP_FE },
10788 { MASK_VSX, CODE_FOR_vsx_tsqrtv2df2_fg, "__builtin_vsx_xvtsqrtdp_fg", VSX_BUILTIN_XVTSQRTDP_FG },
10789 { MASK_VSX, CODE_FOR_vsx_frev2df2, "__builtin_vsx_xvredp", VSX_BUILTIN_XVREDP },
10791 { MASK_VSX, CODE_FOR_negv4sf2, "__builtin_vsx_xvnegsp", VSX_BUILTIN_XVNEGSP },
10792 { MASK_VSX, CODE_FOR_sqrtv4sf2, "__builtin_vsx_xvsqrtsp", VSX_BUILTIN_XVSQRTSP },
10793 { MASK_VSX, CODE_FOR_rsqrtv4sf2, "__builtin_vsx_xvrsqrtsp", VSX_BUILTIN_VEC_RSQRT_V4SF },
10794 { MASK_VSX, CODE_FOR_rsqrtev4sf2, "__builtin_vsx_xvrsqrtesp", VSX_BUILTIN_XVRSQRTESP },
10795 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fe, "__builtin_vsx_xvtsqrtsp_fe", VSX_BUILTIN_XVTSQRTSP_FE },
10796 { MASK_VSX, CODE_FOR_vsx_tsqrtv4sf2_fg, "__builtin_vsx_xvtsqrtsp_fg", VSX_BUILTIN_XVTSQRTSP_FG },
10797 { MASK_VSX, CODE_FOR_vsx_frev4sf2, "__builtin_vsx_xvresp", VSX_BUILTIN_XVRESP },
10799 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvdpsp", VSX_BUILTIN_XSCVDPSP },
10800 { MASK_VSX, CODE_FOR_vsx_xscvdpsp, "__builtin_vsx_xscvspdp", VSX_BUILTIN_XSCVSPDP },
10801 { MASK_VSX, CODE_FOR_vsx_xvcvdpsp, "__builtin_vsx_xvcvdpsp", VSX_BUILTIN_XVCVDPSP },
10802 { MASK_VSX, CODE_FOR_vsx_xvcvspdp, "__builtin_vsx_xvcvspdp", VSX_BUILTIN_XVCVSPDP },
10803 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fe, "__builtin_vsx_xstsqrtdp_fe", VSX_BUILTIN_XSTSQRTDP_FE },
10804 { MASK_VSX, CODE_FOR_vsx_tsqrtdf2_fg, "__builtin_vsx_xstsqrtdp_fg", VSX_BUILTIN_XSTSQRTDP_FG },
10806 { MASK_VSX, CODE_FOR_vsx_fix_truncv2dfv2di2, "__builtin_vsx_xvcvdpsxds", VSX_BUILTIN_XVCVDPSXDS },
10807 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds", VSX_BUILTIN_XVCVDPUXDS },
10808 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv2dfv2di2, "__builtin_vsx_xvcvdpuxds_uns", VSX_BUILTIN_XVCVDPUXDS_UNS },
10809 { MASK_VSX, CODE_FOR_vsx_floatv2div2df2, "__builtin_vsx_xvcvsxddp", VSX_BUILTIN_XVCVSXDDP },
10810 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp", VSX_BUILTIN_XVCVUXDDP },
10811 { MASK_VSX, CODE_FOR_vsx_floatunsv2div2df2, "__builtin_vsx_xvcvuxddp_uns", VSX_BUILTIN_XVCVUXDDP_UNS },
10813 { MASK_VSX, CODE_FOR_vsx_fix_truncv4sfv4si2, "__builtin_vsx_xvcvspsxws", VSX_BUILTIN_XVCVSPSXWS },
10814 { MASK_VSX, CODE_FOR_vsx_fixuns_truncv4sfv4si2, "__builtin_vsx_xvcvspuxws", VSX_BUILTIN_XVCVSPUXWS },
10815 { MASK_VSX, CODE_FOR_vsx_floatv4siv4sf2, "__builtin_vsx_xvcvsxwsp", VSX_BUILTIN_XVCVSXWSP },
10816 { MASK_VSX, CODE_FOR_vsx_floatunsv4siv4sf2, "__builtin_vsx_xvcvuxwsp", VSX_BUILTIN_XVCVUXWSP },
10818 { MASK_VSX, CODE_FOR_vsx_xvcvdpsxws, "__builtin_vsx_xvcvdpsxws", VSX_BUILTIN_XVCVDPSXWS },
10819 { MASK_VSX, CODE_FOR_vsx_xvcvdpuxws, "__builtin_vsx_xvcvdpuxws", VSX_BUILTIN_XVCVDPUXWS },
10820 { MASK_VSX, CODE_FOR_vsx_xvcvsxwdp, "__builtin_vsx_xvcvsxwdp", VSX_BUILTIN_XVCVSXWDP },
10821 { MASK_VSX, CODE_FOR_vsx_xvcvuxwdp, "__builtin_vsx_xvcvuxwdp", VSX_BUILTIN_XVCVUXWDP },
10822 { MASK_VSX, CODE_FOR_vsx_xvrdpi, "__builtin_vsx_xvrdpi", VSX_BUILTIN_XVRDPI },
10823 { MASK_VSX, CODE_FOR_vsx_xvrdpic, "__builtin_vsx_xvrdpic", VSX_BUILTIN_XVRDPIC },
10824 { MASK_VSX, CODE_FOR_vsx_floorv2df2, "__builtin_vsx_xvrdpim", VSX_BUILTIN_XVRDPIM },
10825 { MASK_VSX, CODE_FOR_vsx_ceilv2df2, "__builtin_vsx_xvrdpip", VSX_BUILTIN_XVRDPIP },
10826 { MASK_VSX, CODE_FOR_vsx_btruncv2df2, "__builtin_vsx_xvrdpiz", VSX_BUILTIN_XVRDPIZ },
10828 { MASK_VSX, CODE_FOR_vsx_xvcvspsxds, "__builtin_vsx_xvcvspsxds", VSX_BUILTIN_XVCVSPSXDS },
10829 { MASK_VSX, CODE_FOR_vsx_xvcvspuxds, "__builtin_vsx_xvcvspuxds", VSX_BUILTIN_XVCVSPUXDS },
10830 { MASK_VSX, CODE_FOR_vsx_xvcvsxdsp, "__builtin_vsx_xvcvsxdsp", VSX_BUILTIN_XVCVSXDSP },
10831 { MASK_VSX, CODE_FOR_vsx_xvcvuxdsp, "__builtin_vsx_xvcvuxdsp", VSX_BUILTIN_XVCVUXDSP },
10832 { MASK_VSX, CODE_FOR_vsx_xvrspi, "__builtin_vsx_xvrspi", VSX_BUILTIN_XVRSPI },
10833 { MASK_VSX, CODE_FOR_vsx_xvrspic, "__builtin_vsx_xvrspic", VSX_BUILTIN_XVRSPIC },
10834 { MASK_VSX, CODE_FOR_vsx_floorv4sf2, "__builtin_vsx_xvrspim", VSX_BUILTIN_XVRSPIM },
10835 { MASK_VSX, CODE_FOR_vsx_ceilv4sf2, "__builtin_vsx_xvrspip", VSX_BUILTIN_XVRSPIP },
10836 { MASK_VSX, CODE_FOR_vsx_btruncv4sf2, "__builtin_vsx_xvrspiz", VSX_BUILTIN_XVRSPIZ },
10838 { MASK_VSX, CODE_FOR_vsx_xsrdpi, "__builtin_vsx_xsrdpi", VSX_BUILTIN_XSRDPI },
10839 { MASK_VSX, CODE_FOR_vsx_xsrdpic, "__builtin_vsx_xsrdpic", VSX_BUILTIN_XSRDPIC },
10840 { MASK_VSX, CODE_FOR_vsx_floordf2, "__builtin_vsx_xsrdpim", VSX_BUILTIN_XSRDPIM },
10841 { MASK_VSX, CODE_FOR_vsx_ceildf2, "__builtin_vsx_xsrdpip", VSX_BUILTIN_XSRDPIP },
10842 { MASK_VSX, CODE_FOR_vsx_btruncdf2, "__builtin_vsx_xsrdpiz", VSX_BUILTIN_XSRDPIZ },
10844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
10845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
10846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
10847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
10848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
10849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
10850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
10851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
10852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
10853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrt", ALTIVEC_BUILTIN_VEC_RSQRT },
10854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
10855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
10856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
10857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
10858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
10859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
10860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
10861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
10862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
10863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
10865 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_nearbyint", ALTIVEC_BUILTIN_VEC_NEARBYINT },
10866 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_rint", ALTIVEC_BUILTIN_VEC_RINT },
10867 { MASK_VSX, CODE_FOR_nothing, "__builtin_vec_sqrt", ALTIVEC_BUILTIN_VEC_SQRT },
10869 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_floatv4siv4sf2, "__builtin_vec_float_sisf", VECTOR_BUILTIN_FLOAT_V4SI_V4SF },
10870 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_unsigned_floatv4siv4sf2, "__builtin_vec_uns_float_sisf", VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF },
10871 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fix_truncv4sfv4si2, "__builtin_vec_fix_sfsi", VECTOR_BUILTIN_FIX_V4SF_V4SI },
10872 { MASK_ALTIVEC|MASK_VSX, CODE_FOR_fixuns_truncv4sfv4si2, "__builtin_vec_fixuns_sfsi", VECTOR_BUILTIN_FIXUNS_V4SF_V4SI },
10874 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
10875 end with SPE_BUILTIN_EVSUBFUSIAAW. */
10876 { 0, CODE_FOR_absv2si2, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
10877 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
10878 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
10879 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
10880 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
10881 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
10882 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
10883 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
10884 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
10885 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
10886 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
10887 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
10888 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
10889 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
10890 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
10891 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
10892 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
10893 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
10894 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
10895 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
10896 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
10897 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
10898 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
10899 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
10900 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
10901 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
10902 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
10903 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
10905 /* Place-holder. Leave as last unary SPE builtin. */
10906 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
10908 { 0, CODE_FOR_paired_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
10909 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
10910 { 0, CODE_FOR_paired_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
10911 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
10912 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
10916 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
10919 tree arg0 = CALL_EXPR_ARG (exp, 0);
10920 rtx op0 = expand_normal (arg0);
10921 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10922 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10924 if (icode == CODE_FOR_nothing)
10925 /* Builtin not supported on this processor. */
10928 /* If we got invalid arguments bail out before generating bad rtl. */
10929 if (arg0 == error_mark_node)
10932 if (icode == CODE_FOR_altivec_vspltisb
10933 || icode == CODE_FOR_altivec_vspltish
10934 || icode == CODE_FOR_altivec_vspltisw
10935 || icode == CODE_FOR_spe_evsplatfi
10936 || icode == CODE_FOR_spe_evsplati)
10938 /* Only allow 5-bit *signed* literals. */
10939 if (GET_CODE (op0) != CONST_INT
10940 || INTVAL (op0) > 15
10941 || INTVAL (op0) < -16)
10943 error ("argument 1 must be a 5-bit signed literal");
10949 || GET_MODE (target) != tmode
10950 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10951 target = gen_reg_rtx (tmode);
10953 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10954 op0 = copy_to_mode_reg (mode0, op0);
10956 pat = GEN_FCN (icode) (target, op0);
10965 altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
10967 rtx pat, scratch1, scratch2;
10968 tree arg0 = CALL_EXPR_ARG (exp, 0);
10969 rtx op0 = expand_normal (arg0);
10970 enum machine_mode tmode = insn_data[icode].operand[0].mode;
10971 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
10973 /* If we have invalid arguments, bail out before generating bad rtl. */
10974 if (arg0 == error_mark_node)
10978 || GET_MODE (target) != tmode
10979 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
10980 target = gen_reg_rtx (tmode);
10982 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
10983 op0 = copy_to_mode_reg (mode0, op0);
10985 scratch1 = gen_reg_rtx (mode0);
10986 scratch2 = gen_reg_rtx (mode0);
10988 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
10997 rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
11000 tree arg0 = CALL_EXPR_ARG (exp, 0);
11001 tree arg1 = CALL_EXPR_ARG (exp, 1);
11002 rtx op0 = expand_normal (arg0);
11003 rtx op1 = expand_normal (arg1);
11004 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11005 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11006 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11008 if (icode == CODE_FOR_nothing)
11009 /* Builtin not supported on this processor. */
11012 /* If we got invalid arguments bail out before generating bad rtl. */
11013 if (arg0 == error_mark_node || arg1 == error_mark_node)
11016 if (icode == CODE_FOR_altivec_vcfux
11017 || icode == CODE_FOR_altivec_vcfsx
11018 || icode == CODE_FOR_altivec_vctsxs
11019 || icode == CODE_FOR_altivec_vctuxs
11020 || icode == CODE_FOR_altivec_vspltb
11021 || icode == CODE_FOR_altivec_vsplth
11022 || icode == CODE_FOR_altivec_vspltw
11023 || icode == CODE_FOR_spe_evaddiw
11024 || icode == CODE_FOR_spe_evldd
11025 || icode == CODE_FOR_spe_evldh
11026 || icode == CODE_FOR_spe_evldw
11027 || icode == CODE_FOR_spe_evlhhesplat
11028 || icode == CODE_FOR_spe_evlhhossplat
11029 || icode == CODE_FOR_spe_evlhhousplat
11030 || icode == CODE_FOR_spe_evlwhe
11031 || icode == CODE_FOR_spe_evlwhos
11032 || icode == CODE_FOR_spe_evlwhou
11033 || icode == CODE_FOR_spe_evlwhsplat
11034 || icode == CODE_FOR_spe_evlwwsplat
11035 || icode == CODE_FOR_spe_evrlwi
11036 || icode == CODE_FOR_spe_evslwi
11037 || icode == CODE_FOR_spe_evsrwis
11038 || icode == CODE_FOR_spe_evsubifw
11039 || icode == CODE_FOR_spe_evsrwiu)
11041 /* Only allow 5-bit unsigned literals. */
11043 if (TREE_CODE (arg1) != INTEGER_CST
11044 || TREE_INT_CST_LOW (arg1) & ~0x1f)
11046 error ("argument 2 must be a 5-bit unsigned literal");
11052 || GET_MODE (target) != tmode
11053 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11054 target = gen_reg_rtx (tmode);
11056 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11057 op0 = copy_to_mode_reg (mode0, op0);
11058 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11059 op1 = copy_to_mode_reg (mode1, op1);
11061 pat = GEN_FCN (icode) (target, op0, op1);
11070 altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
11073 tree cr6_form = CALL_EXPR_ARG (exp, 0);
11074 tree arg0 = CALL_EXPR_ARG (exp, 1);
11075 tree arg1 = CALL_EXPR_ARG (exp, 2);
11076 rtx op0 = expand_normal (arg0);
11077 rtx op1 = expand_normal (arg1);
11078 enum machine_mode tmode = SImode;
11079 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11080 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11083 if (TREE_CODE (cr6_form) != INTEGER_CST)
11085 error ("argument 1 of __builtin_altivec_predicate must be a constant");
11089 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
11091 gcc_assert (mode0 == mode1);
11093 /* If we have invalid arguments, bail out before generating bad rtl. */
11094 if (arg0 == error_mark_node || arg1 == error_mark_node)
11098 || GET_MODE (target) != tmode
11099 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11100 target = gen_reg_rtx (tmode);
11102 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11103 op0 = copy_to_mode_reg (mode0, op0);
11104 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11105 op1 = copy_to_mode_reg (mode1, op1);
11107 scratch = gen_reg_rtx (mode0);
11109 pat = GEN_FCN (icode) (scratch, op0, op1);
11114 /* The vec_any* and vec_all* predicates use the same opcodes for two
11115 different operations, but the bits in CR6 will be different
11116 depending on what information we want. So we have to play tricks
11117 with CR6 to get the right bits out.
11119 If you think this is disgusting, look at the specs for the
11120 AltiVec predicates. */
11122 switch (cr6_form_int)
11125 emit_insn (gen_cr6_test_for_zero (target));
11128 emit_insn (gen_cr6_test_for_zero_reverse (target));
11131 emit_insn (gen_cr6_test_for_lt (target));
11134 emit_insn (gen_cr6_test_for_lt_reverse (target));
11137 error ("argument 1 of __builtin_altivec_predicate is out of range");
11145 paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
11148 tree arg0 = CALL_EXPR_ARG (exp, 0);
11149 tree arg1 = CALL_EXPR_ARG (exp, 1);
11150 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11151 enum machine_mode mode0 = Pmode;
11152 enum machine_mode mode1 = Pmode;
11153 rtx op0 = expand_normal (arg0);
11154 rtx op1 = expand_normal (arg1);
11156 if (icode == CODE_FOR_nothing)
11157 /* Builtin not supported on this processor. */
11160 /* If we got invalid arguments bail out before generating bad rtl. */
11161 if (arg0 == error_mark_node || arg1 == error_mark_node)
11165 || GET_MODE (target) != tmode
11166 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11167 target = gen_reg_rtx (tmode);
11169 op1 = copy_to_mode_reg (mode1, op1);
11171 if (op0 == const0_rtx)
11173 addr = gen_rtx_MEM (tmode, op1);
11177 op0 = copy_to_mode_reg (mode0, op0);
11178 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
11181 pat = GEN_FCN (icode) (target, addr);
11191 altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
11194 tree arg0 = CALL_EXPR_ARG (exp, 0);
11195 tree arg1 = CALL_EXPR_ARG (exp, 1);
11196 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11197 enum machine_mode mode0 = Pmode;
11198 enum machine_mode mode1 = Pmode;
11199 rtx op0 = expand_normal (arg0);
11200 rtx op1 = expand_normal (arg1);
11202 if (icode == CODE_FOR_nothing)
11203 /* Builtin not supported on this processor. */
11206 /* If we got invalid arguments bail out before generating bad rtl. */
11207 if (arg0 == error_mark_node || arg1 == error_mark_node)
11211 || GET_MODE (target) != tmode
11212 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11213 target = gen_reg_rtx (tmode);
11215 op1 = copy_to_mode_reg (mode1, op1);
11217 if (op0 == const0_rtx)
11219 addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
11223 op0 = copy_to_mode_reg (mode0, op0);
11224 addr = gen_rtx_MEM (blk ? BLKmode : tmode, gen_rtx_PLUS (Pmode, op0, op1));
11227 pat = GEN_FCN (icode) (target, addr);
11237 spe_expand_stv_builtin (enum insn_code icode, tree exp)
11239 tree arg0 = CALL_EXPR_ARG (exp, 0);
11240 tree arg1 = CALL_EXPR_ARG (exp, 1);
11241 tree arg2 = CALL_EXPR_ARG (exp, 2);
11242 rtx op0 = expand_normal (arg0);
11243 rtx op1 = expand_normal (arg1);
11244 rtx op2 = expand_normal (arg2);
11246 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
11247 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
11248 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
11250 /* Invalid arguments. Bail before doing anything stoopid! */
11251 if (arg0 == error_mark_node
11252 || arg1 == error_mark_node
11253 || arg2 == error_mark_node)
11256 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
11257 op0 = copy_to_mode_reg (mode2, op0);
11258 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
11259 op1 = copy_to_mode_reg (mode0, op1);
11260 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
11261 op2 = copy_to_mode_reg (mode1, op2);
11263 pat = GEN_FCN (icode) (op1, op2, op0);
11270 paired_expand_stv_builtin (enum insn_code icode, tree exp)
11272 tree arg0 = CALL_EXPR_ARG (exp, 0);
11273 tree arg1 = CALL_EXPR_ARG (exp, 1);
11274 tree arg2 = CALL_EXPR_ARG (exp, 2);
11275 rtx op0 = expand_normal (arg0);
11276 rtx op1 = expand_normal (arg1);
11277 rtx op2 = expand_normal (arg2);
11279 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11280 enum machine_mode mode1 = Pmode;
11281 enum machine_mode mode2 = Pmode;
11283 /* Invalid arguments. Bail before doing anything stoopid! */
11284 if (arg0 == error_mark_node
11285 || arg1 == error_mark_node
11286 || arg2 == error_mark_node)
11289 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
11290 op0 = copy_to_mode_reg (tmode, op0);
11292 op2 = copy_to_mode_reg (mode2, op2);
11294 if (op1 == const0_rtx)
11296 addr = gen_rtx_MEM (tmode, op2);
11300 op1 = copy_to_mode_reg (mode1, op1);
11301 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11304 pat = GEN_FCN (icode) (addr, op0);
11311 altivec_expand_stv_builtin (enum insn_code icode, tree exp)
11313 tree arg0 = CALL_EXPR_ARG (exp, 0);
11314 tree arg1 = CALL_EXPR_ARG (exp, 1);
11315 tree arg2 = CALL_EXPR_ARG (exp, 2);
11316 rtx op0 = expand_normal (arg0);
11317 rtx op1 = expand_normal (arg1);
11318 rtx op2 = expand_normal (arg2);
11320 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11321 enum machine_mode smode = insn_data[icode].operand[1].mode;
11322 enum machine_mode mode1 = Pmode;
11323 enum machine_mode mode2 = Pmode;
11325 /* Invalid arguments. Bail before doing anything stoopid! */
11326 if (arg0 == error_mark_node
11327 || arg1 == error_mark_node
11328 || arg2 == error_mark_node)
11331 if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
11332 op0 = copy_to_mode_reg (smode, op0);
11334 op2 = copy_to_mode_reg (mode2, op2);
11336 if (op1 == const0_rtx)
11338 addr = gen_rtx_MEM (tmode, op2);
11342 op1 = copy_to_mode_reg (mode1, op1);
11343 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
11346 pat = GEN_FCN (icode) (addr, op0);
11353 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
11356 tree arg0 = CALL_EXPR_ARG (exp, 0);
11357 tree arg1 = CALL_EXPR_ARG (exp, 1);
11358 tree arg2 = CALL_EXPR_ARG (exp, 2);
11359 rtx op0 = expand_normal (arg0);
11360 rtx op1 = expand_normal (arg1);
11361 rtx op2 = expand_normal (arg2);
11362 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11363 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11364 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11365 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
11367 if (icode == CODE_FOR_nothing)
11368 /* Builtin not supported on this processor. */
11371 /* If we got invalid arguments bail out before generating bad rtl. */
11372 if (arg0 == error_mark_node
11373 || arg1 == error_mark_node
11374 || arg2 == error_mark_node)
11377 /* Check and prepare argument depending on the instruction code.
11379 Note that a switch statement instead of the sequence of tests
11380 would be incorrect as many of the CODE_FOR values could be
11381 CODE_FOR_nothing and that would yield multiple alternatives
11382 with identical values. We'd never reach here at runtime in
11384 if (icode == CODE_FOR_altivec_vsldoi_v4sf
11385 || icode == CODE_FOR_altivec_vsldoi_v4si
11386 || icode == CODE_FOR_altivec_vsldoi_v8hi
11387 || icode == CODE_FOR_altivec_vsldoi_v16qi)
11389 /* Only allow 4-bit unsigned literals. */
11391 if (TREE_CODE (arg2) != INTEGER_CST
11392 || TREE_INT_CST_LOW (arg2) & ~0xf)
11394 error ("argument 3 must be a 4-bit unsigned literal");
11398 else if (icode == CODE_FOR_vsx_xxpermdi_v2df
11399 || icode == CODE_FOR_vsx_xxpermdi_v2di
11400 || icode == CODE_FOR_vsx_xxsldwi_v16qi
11401 || icode == CODE_FOR_vsx_xxsldwi_v8hi
11402 || icode == CODE_FOR_vsx_xxsldwi_v4si
11403 || icode == CODE_FOR_vsx_xxsldwi_v4sf
11404 || icode == CODE_FOR_vsx_xxsldwi_v2di
11405 || icode == CODE_FOR_vsx_xxsldwi_v2df)
11407 /* Only allow 2-bit unsigned literals. */
11409 if (TREE_CODE (arg2) != INTEGER_CST
11410 || TREE_INT_CST_LOW (arg2) & ~0x3)
11412 error ("argument 3 must be a 2-bit unsigned literal");
11416 else if (icode == CODE_FOR_vsx_set_v2df
11417 || icode == CODE_FOR_vsx_set_v2di)
11419 /* Only allow 1-bit unsigned literals. */
11421 if (TREE_CODE (arg2) != INTEGER_CST
11422 || TREE_INT_CST_LOW (arg2) & ~0x1)
11424 error ("argument 3 must be a 1-bit unsigned literal");
11430 || GET_MODE (target) != tmode
11431 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11432 target = gen_reg_rtx (tmode);
11434 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11435 op0 = copy_to_mode_reg (mode0, op0);
11436 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11437 op1 = copy_to_mode_reg (mode1, op1);
11438 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11439 op2 = copy_to_mode_reg (mode2, op2);
11441 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
11442 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
11444 pat = GEN_FCN (icode) (target, op0, op1, op2);
11452 /* Expand the lvx builtins. */
11454 altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
11456 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11457 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11459 enum machine_mode tmode, mode0;
11461 enum insn_code icode;
11465 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
11466 icode = CODE_FOR_vector_altivec_load_v16qi;
11468 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
11469 icode = CODE_FOR_vector_altivec_load_v8hi;
11471 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
11472 icode = CODE_FOR_vector_altivec_load_v4si;
11474 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
11475 icode = CODE_FOR_vector_altivec_load_v4sf;
11477 case ALTIVEC_BUILTIN_LD_INTERNAL_2df:
11478 icode = CODE_FOR_vector_altivec_load_v2df;
11480 case ALTIVEC_BUILTIN_LD_INTERNAL_2di:
11481 icode = CODE_FOR_vector_altivec_load_v2di;
11484 *expandedp = false;
11490 arg0 = CALL_EXPR_ARG (exp, 0);
11491 op0 = expand_normal (arg0);
11492 tmode = insn_data[icode].operand[0].mode;
11493 mode0 = insn_data[icode].operand[1].mode;
11496 || GET_MODE (target) != tmode
11497 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11498 target = gen_reg_rtx (tmode);
11500 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11501 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11503 pat = GEN_FCN (icode) (target, op0);
11510 /* Expand the stvx builtins. */
11512 altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11515 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11516 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11518 enum machine_mode mode0, mode1;
11520 enum insn_code icode;
11524 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
11525 icode = CODE_FOR_vector_altivec_store_v16qi;
11527 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
11528 icode = CODE_FOR_vector_altivec_store_v8hi;
11530 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
11531 icode = CODE_FOR_vector_altivec_store_v4si;
11533 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
11534 icode = CODE_FOR_vector_altivec_store_v4sf;
11536 case ALTIVEC_BUILTIN_ST_INTERNAL_2df:
11537 icode = CODE_FOR_vector_altivec_store_v2df;
11539 case ALTIVEC_BUILTIN_ST_INTERNAL_2di:
11540 icode = CODE_FOR_vector_altivec_store_v2di;
11543 *expandedp = false;
11547 arg0 = CALL_EXPR_ARG (exp, 0);
11548 arg1 = CALL_EXPR_ARG (exp, 1);
11549 op0 = expand_normal (arg0);
11550 op1 = expand_normal (arg1);
11551 mode0 = insn_data[icode].operand[0].mode;
11552 mode1 = insn_data[icode].operand[1].mode;
11554 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11555 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11556 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
11557 op1 = copy_to_mode_reg (mode1, op1);
11559 pat = GEN_FCN (icode) (op0, op1);
11567 /* Expand the dst builtins. */
11569 altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
11572 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11573 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11574 tree arg0, arg1, arg2;
11575 enum machine_mode mode0, mode1;
11576 rtx pat, op0, op1, op2;
11577 const struct builtin_description *d;
11580 *expandedp = false;
11582 /* Handle DST variants. */
11584 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
11585 if (d->code == fcode)
11587 arg0 = CALL_EXPR_ARG (exp, 0);
11588 arg1 = CALL_EXPR_ARG (exp, 1);
11589 arg2 = CALL_EXPR_ARG (exp, 2);
11590 op0 = expand_normal (arg0);
11591 op1 = expand_normal (arg1);
11592 op2 = expand_normal (arg2);
11593 mode0 = insn_data[d->icode].operand[0].mode;
11594 mode1 = insn_data[d->icode].operand[1].mode;
11596 /* Invalid arguments, bail out before generating bad rtl. */
11597 if (arg0 == error_mark_node
11598 || arg1 == error_mark_node
11599 || arg2 == error_mark_node)
11604 if (TREE_CODE (arg2) != INTEGER_CST
11605 || TREE_INT_CST_LOW (arg2) & ~0x3)
11607 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
11611 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
11612 op0 = copy_to_mode_reg (Pmode, op0);
11613 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
11614 op1 = copy_to_mode_reg (mode1, op1);
11616 pat = GEN_FCN (d->icode) (op0, op1, op2);
11626 /* Expand vec_init builtin. */
11628 altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
11630 enum machine_mode tmode = TYPE_MODE (type);
11631 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
11632 int i, n_elt = GET_MODE_NUNITS (tmode);
11633 rtvec v = rtvec_alloc (n_elt);
11635 gcc_assert (VECTOR_MODE_P (tmode));
11636 gcc_assert (n_elt == call_expr_nargs (exp));
11638 for (i = 0; i < n_elt; ++i)
11640 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
11641 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
11644 if (!target || !register_operand (target, tmode))
11645 target = gen_reg_rtx (tmode);
11647 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
11651 /* Return the integer constant in ARG. Constrain it to be in the range
11652 of the subparts of VEC_TYPE; issue an error if not. */
11655 get_element_number (tree vec_type, tree arg)
11657 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
11659 if (!host_integerp (arg, 1)
11660 || (elt = tree_low_cst (arg, 1), elt > max))
11662 error ("selector must be an integer constant in the range 0..%wi", max);
11669 /* Expand vec_set builtin. */
11671 altivec_expand_vec_set_builtin (tree exp)
11673 enum machine_mode tmode, mode1;
11674 tree arg0, arg1, arg2;
11678 arg0 = CALL_EXPR_ARG (exp, 0);
11679 arg1 = CALL_EXPR_ARG (exp, 1);
11680 arg2 = CALL_EXPR_ARG (exp, 2);
11682 tmode = TYPE_MODE (TREE_TYPE (arg0));
11683 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11684 gcc_assert (VECTOR_MODE_P (tmode));
11686 op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
11687 op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
11688 elt = get_element_number (TREE_TYPE (arg0), arg2);
11690 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
11691 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
11693 op0 = force_reg (tmode, op0);
11694 op1 = force_reg (mode1, op1);
11696 rs6000_expand_vector_set (op0, op1, elt);
11701 /* Expand vec_ext builtin. */
11703 altivec_expand_vec_ext_builtin (tree exp, rtx target)
11705 enum machine_mode tmode, mode0;
11710 arg0 = CALL_EXPR_ARG (exp, 0);
11711 arg1 = CALL_EXPR_ARG (exp, 1);
11713 op0 = expand_normal (arg0);
11714 elt = get_element_number (TREE_TYPE (arg0), arg1);
11716 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
11717 mode0 = TYPE_MODE (TREE_TYPE (arg0));
11718 gcc_assert (VECTOR_MODE_P (mode0));
11720 op0 = force_reg (mode0, op0);
11722 if (optimize || !target || !register_operand (target, tmode))
11723 target = gen_reg_rtx (tmode);
11725 rs6000_expand_vector_extract (target, op0, elt);
11730 /* Expand the builtin in EXP and store the result in TARGET. Store
11731 true in *EXPANDEDP if we found a builtin to expand. */
11733 altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
11735 const struct builtin_description *d;
11736 const struct builtin_description_predicates *dp;
11738 enum insn_code icode;
11739 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11742 enum machine_mode tmode, mode0;
11743 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11745 if ((fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
11746 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
11747 || (fcode >= VSX_BUILTIN_OVERLOADED_FIRST
11748 && fcode <= VSX_BUILTIN_OVERLOADED_LAST))
11751 error ("unresolved overload for Altivec builtin %qF", fndecl);
11755 target = altivec_expand_ld_builtin (exp, target, expandedp);
11759 target = altivec_expand_st_builtin (exp, target, expandedp);
11763 target = altivec_expand_dst_builtin (exp, target, expandedp);
11771 case ALTIVEC_BUILTIN_STVX:
11772 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
11773 case ALTIVEC_BUILTIN_STVEBX:
11774 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
11775 case ALTIVEC_BUILTIN_STVEHX:
11776 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
11777 case ALTIVEC_BUILTIN_STVEWX:
11778 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
11779 case ALTIVEC_BUILTIN_STVXL:
11780 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
11782 case ALTIVEC_BUILTIN_STVLX:
11783 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
11784 case ALTIVEC_BUILTIN_STVLXL:
11785 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
11786 case ALTIVEC_BUILTIN_STVRX:
11787 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
11788 case ALTIVEC_BUILTIN_STVRXL:
11789 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
11791 case VSX_BUILTIN_STXVD2X_V2DF:
11792 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
11793 case VSX_BUILTIN_STXVD2X_V2DI:
11794 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
11795 case VSX_BUILTIN_STXVW4X_V4SF:
11796 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
11797 case VSX_BUILTIN_STXVW4X_V4SI:
11798 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
11799 case VSX_BUILTIN_STXVW4X_V8HI:
11800 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
11801 case VSX_BUILTIN_STXVW4X_V16QI:
11802 return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
11804 case ALTIVEC_BUILTIN_MFVSCR:
11805 icode = CODE_FOR_altivec_mfvscr;
11806 tmode = insn_data[icode].operand[0].mode;
11809 || GET_MODE (target) != tmode
11810 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11811 target = gen_reg_rtx (tmode);
11813 pat = GEN_FCN (icode) (target);
11819 case ALTIVEC_BUILTIN_MTVSCR:
11820 icode = CODE_FOR_altivec_mtvscr;
11821 arg0 = CALL_EXPR_ARG (exp, 0);
11822 op0 = expand_normal (arg0);
11823 mode0 = insn_data[icode].operand[0].mode;
11825 /* If we got invalid arguments bail out before generating bad rtl. */
11826 if (arg0 == error_mark_node)
11829 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11830 op0 = copy_to_mode_reg (mode0, op0);
11832 pat = GEN_FCN (icode) (op0);
11837 case ALTIVEC_BUILTIN_DSSALL:
11838 emit_insn (gen_altivec_dssall ());
11841 case ALTIVEC_BUILTIN_DSS:
11842 icode = CODE_FOR_altivec_dss;
11843 arg0 = CALL_EXPR_ARG (exp, 0);
11845 op0 = expand_normal (arg0);
11846 mode0 = insn_data[icode].operand[0].mode;
11848 /* If we got invalid arguments bail out before generating bad rtl. */
11849 if (arg0 == error_mark_node)
11852 if (TREE_CODE (arg0) != INTEGER_CST
11853 || TREE_INT_CST_LOW (arg0) & ~0x3)
11855 error ("argument to dss must be a 2-bit unsigned literal");
11859 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
11860 op0 = copy_to_mode_reg (mode0, op0);
11862 emit_insn (gen_altivec_dss (op0));
11865 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
11866 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
11867 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
11868 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
11869 case VSX_BUILTIN_VEC_INIT_V2DF:
11870 case VSX_BUILTIN_VEC_INIT_V2DI:
11871 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
11873 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
11874 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
11875 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
11876 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
11877 case VSX_BUILTIN_VEC_SET_V2DF:
11878 case VSX_BUILTIN_VEC_SET_V2DI:
11879 return altivec_expand_vec_set_builtin (exp);
11881 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
11882 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
11883 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
11884 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
11885 case VSX_BUILTIN_VEC_EXT_V2DF:
11886 case VSX_BUILTIN_VEC_EXT_V2DI:
11887 return altivec_expand_vec_ext_builtin (exp, target);
11891 /* Fall through. */
11894 /* Expand abs* operations. */
11896 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
11897 if (d->code == fcode)
11898 return altivec_expand_abs_builtin (d->icode, exp, target);
11900 /* Expand the AltiVec predicates. */
11901 dp = bdesc_altivec_preds;
11902 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
11903 if (dp->code == fcode)
11904 return altivec_expand_predicate_builtin (dp->icode, exp, target);
11906 /* LV* are funky. We initialized them differently. */
11909 case ALTIVEC_BUILTIN_LVSL:
11910 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
11911 exp, target, false);
11912 case ALTIVEC_BUILTIN_LVSR:
11913 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
11914 exp, target, false);
11915 case ALTIVEC_BUILTIN_LVEBX:
11916 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
11917 exp, target, false);
11918 case ALTIVEC_BUILTIN_LVEHX:
11919 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
11920 exp, target, false);
11921 case ALTIVEC_BUILTIN_LVEWX:
11922 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
11923 exp, target, false);
11924 case ALTIVEC_BUILTIN_LVXL:
11925 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
11926 exp, target, false);
11927 case ALTIVEC_BUILTIN_LVX:
11928 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
11929 exp, target, false);
11930 case ALTIVEC_BUILTIN_LVLX:
11931 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
11932 exp, target, true);
11933 case ALTIVEC_BUILTIN_LVLXL:
11934 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
11935 exp, target, true);
11936 case ALTIVEC_BUILTIN_LVRX:
11937 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
11938 exp, target, true);
11939 case ALTIVEC_BUILTIN_LVRXL:
11940 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
11941 exp, target, true);
11942 case VSX_BUILTIN_LXVD2X_V2DF:
11943 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
11944 exp, target, false);
11945 case VSX_BUILTIN_LXVD2X_V2DI:
11946 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
11947 exp, target, false);
11948 case VSX_BUILTIN_LXVW4X_V4SF:
11949 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
11950 exp, target, false);
11951 case VSX_BUILTIN_LXVW4X_V4SI:
11952 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
11953 exp, target, false);
11954 case VSX_BUILTIN_LXVW4X_V8HI:
11955 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
11956 exp, target, false);
11957 case VSX_BUILTIN_LXVW4X_V16QI:
11958 return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
11959 exp, target, false);
11963 /* Fall through. */
11966 *expandedp = false;
11970 /* Expand the builtin in EXP and store the result in TARGET. Store
11971 true in *EXPANDEDP if we found a builtin to expand. */
11973 paired_expand_builtin (tree exp, rtx target, bool * expandedp)
11975 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
11976 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
11977 const struct builtin_description *d;
11984 case PAIRED_BUILTIN_STX:
11985 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
11986 case PAIRED_BUILTIN_LX:
11987 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
11990 /* Fall through. */
11993 /* Expand the paired predicates. */
11994 d = bdesc_paired_preds;
11995 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
11996 if (d->code == fcode)
11997 return paired_expand_predicate_builtin (d->icode, exp, target);
11999 *expandedp = false;
12003 /* Binops that need to be initialized manually, but can be expanded
12004 automagically by rs6000_expand_binop_builtin. */
12005 static struct builtin_description bdesc_2arg_spe[] =
12007 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
12008 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
12009 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
12010 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
12011 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
12012 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
12013 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
12014 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
12015 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
12016 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
12017 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
12018 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
12019 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
12020 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
12021 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
12022 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
12023 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
12024 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
12025 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
12026 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
12027 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
12028 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
12031 /* Expand the builtin in EXP and store the result in TARGET. Store
12032 true in *EXPANDEDP if we found a builtin to expand.
12034 This expands the SPE builtins that are not simple unary and binary
12037 spe_expand_builtin (tree exp, rtx target, bool *expandedp)
12039 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12041 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12042 enum insn_code icode;
12043 enum machine_mode tmode, mode0;
12045 struct builtin_description *d;
12050 /* Syntax check for a 5-bit unsigned immediate. */
12053 case SPE_BUILTIN_EVSTDD:
12054 case SPE_BUILTIN_EVSTDH:
12055 case SPE_BUILTIN_EVSTDW:
12056 case SPE_BUILTIN_EVSTWHE:
12057 case SPE_BUILTIN_EVSTWHO:
12058 case SPE_BUILTIN_EVSTWWE:
12059 case SPE_BUILTIN_EVSTWWO:
12060 arg1 = CALL_EXPR_ARG (exp, 2);
12061 if (TREE_CODE (arg1) != INTEGER_CST
12062 || TREE_INT_CST_LOW (arg1) & ~0x1f)
12064 error ("argument 2 must be a 5-bit unsigned literal");
12072 /* The evsplat*i instructions are not quite generic. */
12075 case SPE_BUILTIN_EVSPLATFI:
12076 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
12078 case SPE_BUILTIN_EVSPLATI:
12079 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
12085 d = (struct builtin_description *) bdesc_2arg_spe;
12086 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
12087 if (d->code == fcode)
12088 return rs6000_expand_binop_builtin (d->icode, exp, target);
12090 d = (struct builtin_description *) bdesc_spe_predicates;
12091 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
12092 if (d->code == fcode)
12093 return spe_expand_predicate_builtin (d->icode, exp, target);
12095 d = (struct builtin_description *) bdesc_spe_evsel;
12096 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
12097 if (d->code == fcode)
12098 return spe_expand_evsel_builtin (d->icode, exp, target);
12102 case SPE_BUILTIN_EVSTDDX:
12103 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
12104 case SPE_BUILTIN_EVSTDHX:
12105 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
12106 case SPE_BUILTIN_EVSTDWX:
12107 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
12108 case SPE_BUILTIN_EVSTWHEX:
12109 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
12110 case SPE_BUILTIN_EVSTWHOX:
12111 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
12112 case SPE_BUILTIN_EVSTWWEX:
12113 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
12114 case SPE_BUILTIN_EVSTWWOX:
12115 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
12116 case SPE_BUILTIN_EVSTDD:
12117 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
12118 case SPE_BUILTIN_EVSTDH:
12119 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
12120 case SPE_BUILTIN_EVSTDW:
12121 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
12122 case SPE_BUILTIN_EVSTWHE:
12123 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
12124 case SPE_BUILTIN_EVSTWHO:
12125 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
12126 case SPE_BUILTIN_EVSTWWE:
12127 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
12128 case SPE_BUILTIN_EVSTWWO:
12129 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
12130 case SPE_BUILTIN_MFSPEFSCR:
12131 icode = CODE_FOR_spe_mfspefscr;
12132 tmode = insn_data[icode].operand[0].mode;
12135 || GET_MODE (target) != tmode
12136 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12137 target = gen_reg_rtx (tmode);
12139 pat = GEN_FCN (icode) (target);
12144 case SPE_BUILTIN_MTSPEFSCR:
12145 icode = CODE_FOR_spe_mtspefscr;
12146 arg0 = CALL_EXPR_ARG (exp, 0);
12147 op0 = expand_normal (arg0);
12148 mode0 = insn_data[icode].operand[0].mode;
12150 if (arg0 == error_mark_node)
12153 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
12154 op0 = copy_to_mode_reg (mode0, op0);
12156 pat = GEN_FCN (icode) (op0);
12164 *expandedp = false;
12169 paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12171 rtx pat, scratch, tmp;
12172 tree form = CALL_EXPR_ARG (exp, 0);
12173 tree arg0 = CALL_EXPR_ARG (exp, 1);
12174 tree arg1 = CALL_EXPR_ARG (exp, 2);
12175 rtx op0 = expand_normal (arg0);
12176 rtx op1 = expand_normal (arg1);
12177 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12178 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12180 enum rtx_code code;
12182 if (TREE_CODE (form) != INTEGER_CST)
12184 error ("argument 1 of __builtin_paired_predicate must be a constant");
12188 form_int = TREE_INT_CST_LOW (form);
12190 gcc_assert (mode0 == mode1);
12192 if (arg0 == error_mark_node || arg1 == error_mark_node)
12196 || GET_MODE (target) != SImode
12197 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
12198 target = gen_reg_rtx (SImode);
12199 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
12200 op0 = copy_to_mode_reg (mode0, op0);
12201 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
12202 op1 = copy_to_mode_reg (mode1, op1);
12204 scratch = gen_reg_rtx (CCFPmode);
12206 pat = GEN_FCN (icode) (scratch, op0, op1);
12228 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12231 error ("argument 1 of __builtin_paired_predicate is out of range");
12235 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12236 emit_move_insn (target, tmp);
12241 spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
12243 rtx pat, scratch, tmp;
12244 tree form = CALL_EXPR_ARG (exp, 0);
12245 tree arg0 = CALL_EXPR_ARG (exp, 1);
12246 tree arg1 = CALL_EXPR_ARG (exp, 2);
12247 rtx op0 = expand_normal (arg0);
12248 rtx op1 = expand_normal (arg1);
12249 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12250 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12252 enum rtx_code code;
12254 if (TREE_CODE (form) != INTEGER_CST)
12256 error ("argument 1 of __builtin_spe_predicate must be a constant");
12260 form_int = TREE_INT_CST_LOW (form);
12262 gcc_assert (mode0 == mode1);
12264 if (arg0 == error_mark_node || arg1 == error_mark_node)
12268 || GET_MODE (target) != SImode
12269 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
12270 target = gen_reg_rtx (SImode);
12272 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12273 op0 = copy_to_mode_reg (mode0, op0);
12274 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
12275 op1 = copy_to_mode_reg (mode1, op1);
12277 scratch = gen_reg_rtx (CCmode);
12279 pat = GEN_FCN (icode) (scratch, op0, op1);
12284 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
12285 _lower_. We use one compare, but look in different bits of the
12286 CR for each variant.
12288 There are 2 elements in each SPE simd type (upper/lower). The CR
12289 bits are set as follows:
12291 BIT0 | BIT 1 | BIT 2 | BIT 3
12292 U | L | (U | L) | (U & L)
12294 So, for an "all" relationship, BIT 3 would be set.
12295 For an "any" relationship, BIT 2 would be set. Etc.
12297 Following traditional nomenclature, these bits map to:
12299 BIT0 | BIT 1 | BIT 2 | BIT 3
12302 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
12307 /* All variant. OV bit. */
12309 /* We need to get to the OV bit, which is the ORDERED bit. We
12310 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
12311 that's ugly and will make validate_condition_mode die.
12312 So let's just use another pattern. */
12313 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
12315 /* Any variant. EQ bit. */
12319 /* Upper variant. LT bit. */
12323 /* Lower variant. GT bit. */
12328 error ("argument 1 of __builtin_spe_predicate is out of range");
12332 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
12333 emit_move_insn (target, tmp);
12338 /* The evsel builtins look like this:
12340 e = __builtin_spe_evsel_OP (a, b, c, d);
12342 and work like this:
12344 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
12345 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
12349 spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
12352 tree arg0 = CALL_EXPR_ARG (exp, 0);
12353 tree arg1 = CALL_EXPR_ARG (exp, 1);
12354 tree arg2 = CALL_EXPR_ARG (exp, 2);
12355 tree arg3 = CALL_EXPR_ARG (exp, 3);
12356 rtx op0 = expand_normal (arg0);
12357 rtx op1 = expand_normal (arg1);
12358 rtx op2 = expand_normal (arg2);
12359 rtx op3 = expand_normal (arg3);
12360 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
12361 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
12363 gcc_assert (mode0 == mode1);
12365 if (arg0 == error_mark_node || arg1 == error_mark_node
12366 || arg2 == error_mark_node || arg3 == error_mark_node)
12370 || GET_MODE (target) != mode0
12371 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
12372 target = gen_reg_rtx (mode0);
12374 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
12375 op0 = copy_to_mode_reg (mode0, op0);
12376 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
12377 op1 = copy_to_mode_reg (mode0, op1);
12378 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
12379 op2 = copy_to_mode_reg (mode0, op2);
12380 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
12381 op3 = copy_to_mode_reg (mode0, op3);
12383 /* Generate the compare. */
12384 scratch = gen_reg_rtx (CCmode);
12385 pat = GEN_FCN (icode) (scratch, op0, op1);
12390 if (mode0 == V2SImode)
12391 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
12393 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
12398 /* Expand an expression EXP that calls a built-in function,
12399 with result going to TARGET if that's convenient
12400 (and in mode MODE if that's convenient).
12401 SUBTARGET may be used as the target for computing one of EXP's operands.
12402 IGNORE is nonzero if the value is to be ignored. */
12405 rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
12406 enum machine_mode mode ATTRIBUTE_UNUSED,
12407 int ignore ATTRIBUTE_UNUSED)
12409 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
12410 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
12411 const struct builtin_description *d;
12418 case RS6000_BUILTIN_RECIP:
12419 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
12421 case RS6000_BUILTIN_RECIPF:
12422 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
12424 case RS6000_BUILTIN_RSQRTF:
12425 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
12427 case RS6000_BUILTIN_RSQRT:
12428 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
12430 case RS6000_BUILTIN_BSWAP_HI:
12431 return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
12433 case POWER7_BUILTIN_BPERMD:
12434 return rs6000_expand_binop_builtin (((TARGET_64BIT)
12435 ? CODE_FOR_bpermd_di
12436 : CODE_FOR_bpermd_si), exp, target);
12438 case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
12439 case ALTIVEC_BUILTIN_MASK_FOR_STORE:
12441 int icode = (int) CODE_FOR_altivec_lvsr;
12442 enum machine_mode tmode = insn_data[icode].operand[0].mode;
12443 enum machine_mode mode = insn_data[icode].operand[1].mode;
12447 gcc_assert (TARGET_ALTIVEC);
12449 arg = CALL_EXPR_ARG (exp, 0);
12450 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
12451 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
12452 addr = memory_address (mode, op);
12453 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
12457 /* For the load case need to negate the address. */
12458 op = gen_reg_rtx (GET_MODE (addr));
12459 emit_insn (gen_rtx_SET (VOIDmode, op,
12460 gen_rtx_NEG (GET_MODE (addr), addr)));
12462 op = gen_rtx_MEM (mode, op);
12465 || GET_MODE (target) != tmode
12466 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
12467 target = gen_reg_rtx (tmode);
12469 /*pat = gen_altivec_lvsr (target, op);*/
12470 pat = GEN_FCN (icode) (target, op);
12478 case ALTIVEC_BUILTIN_VCFUX:
12479 case ALTIVEC_BUILTIN_VCFSX:
12480 case ALTIVEC_BUILTIN_VCTUXS:
12481 case ALTIVEC_BUILTIN_VCTSXS:
12482 /* FIXME: There's got to be a nicer way to handle this case than
12483 constructing a new CALL_EXPR. */
12484 if (call_expr_nargs (exp) == 1)
12486 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
12487 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
12495 if (TARGET_ALTIVEC)
12497 ret = altivec_expand_builtin (exp, target, &success);
12504 ret = spe_expand_builtin (exp, target, &success);
12509 if (TARGET_PAIRED_FLOAT)
12511 ret = paired_expand_builtin (exp, target, &success);
12517 gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
12519 /* Handle simple unary operations. */
12520 d = (struct builtin_description *) bdesc_1arg;
12521 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
12522 if (d->code == fcode)
12523 return rs6000_expand_unop_builtin (d->icode, exp, target);
12525 /* Handle simple binary operations. */
12526 d = (struct builtin_description *) bdesc_2arg;
12527 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
12528 if (d->code == fcode)
12529 return rs6000_expand_binop_builtin (d->icode, exp, target);
12531 /* Handle simple ternary operations. */
12533 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
12534 if (d->code == fcode)
12535 return rs6000_expand_ternop_builtin (d->icode, exp, target);
12537 gcc_unreachable ();
12541 rs6000_init_builtins (void)
12546 V2SI_type_node = build_vector_type (intSI_type_node, 2);
12547 V2SF_type_node = build_vector_type (float_type_node, 2);
12548 V2DI_type_node = build_vector_type (intDI_type_node, 2);
12549 V2DF_type_node = build_vector_type (double_type_node, 2);
12550 V4HI_type_node = build_vector_type (intHI_type_node, 4);
12551 V4SI_type_node = build_vector_type (intSI_type_node, 4);
12552 V4SF_type_node = build_vector_type (float_type_node, 4);
12553 V8HI_type_node = build_vector_type (intHI_type_node, 8);
12554 V16QI_type_node = build_vector_type (intQI_type_node, 16);
12556 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
12557 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
12558 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
12559 unsigned_V2DI_type_node = build_vector_type (unsigned_intDI_type_node, 2);
12561 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
12562 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
12563 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
12564 opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
12566 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
12567 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
12568 'vector unsigned short'. */
12570 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
12571 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12572 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
12573 bool_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
12574 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
12576 long_integer_type_internal_node = long_integer_type_node;
12577 long_unsigned_type_internal_node = long_unsigned_type_node;
12578 long_long_integer_type_internal_node = long_long_integer_type_node;
12579 long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
12580 intQI_type_internal_node = intQI_type_node;
12581 uintQI_type_internal_node = unsigned_intQI_type_node;
12582 intHI_type_internal_node = intHI_type_node;
12583 uintHI_type_internal_node = unsigned_intHI_type_node;
12584 intSI_type_internal_node = intSI_type_node;
12585 uintSI_type_internal_node = unsigned_intSI_type_node;
12586 intDI_type_internal_node = intDI_type_node;
12587 uintDI_type_internal_node = unsigned_intDI_type_node;
12588 float_type_internal_node = float_type_node;
12589 double_type_internal_node = double_type_node;
12590 void_type_internal_node = void_type_node;
12592 /* Initialize the modes for builtin_function_type, mapping a machine mode to
12594 builtin_mode_to_type[QImode][0] = integer_type_node;
12595 builtin_mode_to_type[HImode][0] = integer_type_node;
12596 builtin_mode_to_type[SImode][0] = intSI_type_node;
12597 builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
12598 builtin_mode_to_type[DImode][0] = intDI_type_node;
12599 builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
12600 builtin_mode_to_type[SFmode][0] = float_type_node;
12601 builtin_mode_to_type[DFmode][0] = double_type_node;
12602 builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
12603 builtin_mode_to_type[V2SFmode][0] = V2SF_type_node;
12604 builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
12605 builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
12606 builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
12607 builtin_mode_to_type[V4HImode][0] = V4HI_type_node;
12608 builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
12609 builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
12610 builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
12611 builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
12612 builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
12613 builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
12614 builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
12616 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12617 get_identifier ("__bool char"),
12618 bool_char_type_node);
12619 TYPE_NAME (bool_char_type_node) = tdecl;
12620 (*lang_hooks.decls.pushdecl) (tdecl);
12621 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12622 get_identifier ("__bool short"),
12623 bool_short_type_node);
12624 TYPE_NAME (bool_short_type_node) = tdecl;
12625 (*lang_hooks.decls.pushdecl) (tdecl);
12626 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12627 get_identifier ("__bool int"),
12628 bool_int_type_node);
12629 TYPE_NAME (bool_int_type_node) = tdecl;
12630 (*lang_hooks.decls.pushdecl) (tdecl);
12631 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, get_identifier ("__pixel"),
12633 TYPE_NAME (pixel_type_node) = tdecl;
12634 (*lang_hooks.decls.pushdecl) (tdecl);
12636 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
12637 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
12638 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
12639 bool_V2DI_type_node = build_vector_type (bool_long_type_node, 2);
12640 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
12642 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12643 get_identifier ("__vector unsigned char"),
12644 unsigned_V16QI_type_node);
12645 TYPE_NAME (unsigned_V16QI_type_node) = tdecl;
12646 (*lang_hooks.decls.pushdecl) (tdecl);
12647 tdecl = build_decl (BUILTINS_LOCATION,
12648 TYPE_DECL, get_identifier ("__vector signed char"),
12650 TYPE_NAME (V16QI_type_node) = tdecl;
12651 (*lang_hooks.decls.pushdecl) (tdecl);
12652 tdecl = build_decl (BUILTINS_LOCATION,
12653 TYPE_DECL, get_identifier ("__vector __bool char"),
12654 bool_V16QI_type_node);
12655 TYPE_NAME ( bool_V16QI_type_node) = tdecl;
12656 (*lang_hooks.decls.pushdecl) (tdecl);
12658 tdecl = build_decl (BUILTINS_LOCATION,
12659 TYPE_DECL, get_identifier ("__vector unsigned short"),
12660 unsigned_V8HI_type_node);
12661 TYPE_NAME (unsigned_V8HI_type_node) = tdecl;
12662 (*lang_hooks.decls.pushdecl) (tdecl);
12663 tdecl = build_decl (BUILTINS_LOCATION,
12664 TYPE_DECL, get_identifier ("__vector signed short"),
12666 TYPE_NAME (V8HI_type_node) = tdecl;
12667 (*lang_hooks.decls.pushdecl) (tdecl);
12668 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12669 get_identifier ("__vector __bool short"),
12670 bool_V8HI_type_node);
12671 TYPE_NAME (bool_V8HI_type_node) = tdecl;
12672 (*lang_hooks.decls.pushdecl) (tdecl);
12674 tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
12675 get_identifier ("__vector unsigned int"),
12676 unsigned_V4SI_type_node);
12677 TYPE_NAME (unsigned_V4SI_type_node) = tdecl;
12678 (*lang_hooks.decls.pushdecl) (tdecl);
12679 tdecl = build_decl (BUILTINS_LOCATION,
12680 TYPE_DECL, get_identifier ("__vector signed int"),
12682 TYPE_NAME (V4SI_type_node) = tdecl;
12683 (*lang_hooks.decls.pushdecl) (tdecl);
12684 tdecl = build_decl (BUILTINS_LOCATION,
12685 TYPE_DECL, get_identifier ("__vector __bool int"),
12686 bool_V4SI_type_node);
12687 TYPE_NAME (bool_V4SI_type_node) = tdecl;
12688 (*lang_hooks.decls.pushdecl) (tdecl);
12690 tdecl = build_decl (BUILTINS_LOCATION,
12691 TYPE_DECL, get_identifier ("__vector float"),
12693 TYPE_NAME (V4SF_type_node) = tdecl;
12694 (*lang_hooks.decls.pushdecl) (tdecl);
12695 tdecl = build_decl (BUILTINS_LOCATION,
12696 TYPE_DECL, get_identifier ("__vector __pixel"),
12697 pixel_V8HI_type_node);
12698 TYPE_NAME (pixel_V8HI_type_node) = tdecl;
12699 (*lang_hooks.decls.pushdecl) (tdecl);
12703 tdecl = build_decl (BUILTINS_LOCATION,
12704 TYPE_DECL, get_identifier ("__vector double"),
12706 TYPE_NAME (V2DF_type_node) = tdecl;
12707 (*lang_hooks.decls.pushdecl) (tdecl);
12709 tdecl = build_decl (BUILTINS_LOCATION,
12710 TYPE_DECL, get_identifier ("__vector long"),
12712 TYPE_NAME (V2DI_type_node) = tdecl;
12713 (*lang_hooks.decls.pushdecl) (tdecl);
12715 tdecl = build_decl (BUILTINS_LOCATION,
12716 TYPE_DECL, get_identifier ("__vector unsigned long"),
12717 unsigned_V2DI_type_node);
12718 TYPE_NAME (unsigned_V2DI_type_node) = tdecl;
12719 (*lang_hooks.decls.pushdecl) (tdecl);
12721 tdecl = build_decl (BUILTINS_LOCATION,
12722 TYPE_DECL, get_identifier ("__vector __bool long"),
12723 bool_V2DI_type_node);
12724 TYPE_NAME (bool_V2DI_type_node) = tdecl;
12725 (*lang_hooks.decls.pushdecl) (tdecl);
12728 if (TARGET_PAIRED_FLOAT)
12729 paired_init_builtins ();
12731 spe_init_builtins ();
12732 if (TARGET_ALTIVEC)
12733 altivec_init_builtins ();
12734 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT || TARGET_VSX)
12735 rs6000_common_init_builtins ();
12738 ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
12739 RS6000_BUILTIN_RECIP,
12740 "__builtin_recipdiv");
12741 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
12742 RS6000_BUILTIN_RECIP);
12746 ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
12747 RS6000_BUILTIN_RECIPF,
12748 "__builtin_recipdivf");
12749 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
12750 RS6000_BUILTIN_RECIPF);
12752 if (TARGET_FRSQRTE)
12754 ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
12755 RS6000_BUILTIN_RSQRT,
12756 "__builtin_rsqrt");
12757 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrt", ftype,
12758 RS6000_BUILTIN_RSQRT);
12760 if (TARGET_FRSQRTES)
12762 ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
12763 RS6000_BUILTIN_RSQRTF,
12764 "__builtin_rsqrtf");
12765 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
12766 RS6000_BUILTIN_RSQRTF);
12768 if (TARGET_POPCNTD)
12770 enum machine_mode mode = (TARGET_64BIT) ? DImode : SImode;
12771 tree ftype = builtin_function_type (mode, mode, mode, VOIDmode,
12772 POWER7_BUILTIN_BPERMD,
12773 "__builtin_bpermd");
12774 def_builtin (MASK_POPCNTD, "__builtin_bpermd", ftype,
12775 POWER7_BUILTIN_BPERMD);
12777 if (TARGET_POWERPC)
12779 /* Don't use builtin_function_type here, as it maps HI/QI to SI. */
12780 tree ftype = build_function_type_list (unsigned_intHI_type_node,
12781 unsigned_intHI_type_node,
12783 def_builtin (MASK_POWERPC, "__builtin_bswap16", ftype,
12784 RS6000_BUILTIN_BSWAP_HI);
12788 /* AIX libm provides clog as __clog. */
12789 if (built_in_decls [BUILT_IN_CLOG])
12790 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
12793 #ifdef SUBTARGET_INIT_BUILTINS
12794 SUBTARGET_INIT_BUILTINS;
12798 /* Returns the rs6000 builtin decl for CODE. */
12801 rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
12803 if (code >= RS6000_BUILTIN_COUNT)
12804 return error_mark_node;
12806 return rs6000_builtin_decls[code];
12809 /* Search through a set of builtins and enable the mask bits.
12810 DESC is an array of builtins.
12811 SIZE is the total number of builtins.
12812 START is the builtin enum at which to start.
12813 END is the builtin enum at which to end. */
12815 enable_mask_for_builtins (struct builtin_description *desc, int size,
12816 enum rs6000_builtins start,
12817 enum rs6000_builtins end)
12821 for (i = 0; i < size; ++i)
12822 if (desc[i].code == start)
12828 for (; i < size; ++i)
12830 /* Flip all the bits on. */
12831 desc[i].mask = target_flags;
12832 if (desc[i].code == end)
12838 spe_init_builtins (void)
12840 tree endlink = void_list_node;
12841 tree puint_type_node = build_pointer_type (unsigned_type_node);
12842 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
12843 struct builtin_description *d;
12846 tree v2si_ftype_4_v2si
12847 = build_function_type
12848 (opaque_V2SI_type_node,
12849 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12850 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12851 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12852 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12855 tree v2sf_ftype_4_v2sf
12856 = build_function_type
12857 (opaque_V2SF_type_node,
12858 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12859 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12860 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12861 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12864 tree int_ftype_int_v2si_v2si
12865 = build_function_type
12866 (integer_type_node,
12867 tree_cons (NULL_TREE, integer_type_node,
12868 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12869 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12872 tree int_ftype_int_v2sf_v2sf
12873 = build_function_type
12874 (integer_type_node,
12875 tree_cons (NULL_TREE, integer_type_node,
12876 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12877 tree_cons (NULL_TREE, opaque_V2SF_type_node,
12880 tree void_ftype_v2si_puint_int
12881 = build_function_type (void_type_node,
12882 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12883 tree_cons (NULL_TREE, puint_type_node,
12884 tree_cons (NULL_TREE,
12888 tree void_ftype_v2si_puint_char
12889 = build_function_type (void_type_node,
12890 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12891 tree_cons (NULL_TREE, puint_type_node,
12892 tree_cons (NULL_TREE,
12896 tree void_ftype_v2si_pv2si_int
12897 = build_function_type (void_type_node,
12898 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12899 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12900 tree_cons (NULL_TREE,
12904 tree void_ftype_v2si_pv2si_char
12905 = build_function_type (void_type_node,
12906 tree_cons (NULL_TREE, opaque_V2SI_type_node,
12907 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12908 tree_cons (NULL_TREE,
12912 tree void_ftype_int
12913 = build_function_type (void_type_node,
12914 tree_cons (NULL_TREE, integer_type_node, endlink));
12916 tree int_ftype_void
12917 = build_function_type (integer_type_node, endlink);
12919 tree v2si_ftype_pv2si_int
12920 = build_function_type (opaque_V2SI_type_node,
12921 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
12922 tree_cons (NULL_TREE, integer_type_node,
12925 tree v2si_ftype_puint_int
12926 = build_function_type (opaque_V2SI_type_node,
12927 tree_cons (NULL_TREE, puint_type_node,
12928 tree_cons (NULL_TREE, integer_type_node,
12931 tree v2si_ftype_pushort_int
12932 = build_function_type (opaque_V2SI_type_node,
12933 tree_cons (NULL_TREE, pushort_type_node,
12934 tree_cons (NULL_TREE, integer_type_node,
12937 tree v2si_ftype_signed_char
12938 = build_function_type (opaque_V2SI_type_node,
12939 tree_cons (NULL_TREE, signed_char_type_node,
12942 /* The initialization of the simple binary and unary builtins is
12943 done in rs6000_common_init_builtins, but we have to enable the
12944 mask bits here manually because we have run out of `target_flags'
12945 bits. We really need to redesign this mask business. */
12947 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
12948 ARRAY_SIZE (bdesc_2arg),
12949 SPE_BUILTIN_EVADDW,
12950 SPE_BUILTIN_EVXOR);
12951 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
12952 ARRAY_SIZE (bdesc_1arg),
12954 SPE_BUILTIN_EVSUBFUSIAAW);
12955 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
12956 ARRAY_SIZE (bdesc_spe_predicates),
12957 SPE_BUILTIN_EVCMPEQ,
12958 SPE_BUILTIN_EVFSTSTLT);
12959 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
12960 ARRAY_SIZE (bdesc_spe_evsel),
12961 SPE_BUILTIN_EVSEL_CMPGTS,
12962 SPE_BUILTIN_EVSEL_FSTSTEQ);
12964 (*lang_hooks.decls.pushdecl)
12965 (build_decl (BUILTINS_LOCATION, TYPE_DECL,
12966 get_identifier ("__ev64_opaque__"),
12967 opaque_V2SI_type_node));
12969 /* Initialize irregular SPE builtins. */
12971 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
12972 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
12973 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
12974 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
12975 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
12976 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
12977 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
12978 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
12979 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
12980 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
12981 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
12982 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
12983 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
12984 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
12985 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
12986 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
12987 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
12988 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
12991 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
12992 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
12993 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
12994 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
12995 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
12996 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
12997 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
12998 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
12999 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
13000 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
13001 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
13002 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
13003 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
13004 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
13005 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
13006 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
13007 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
13008 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
13009 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
13010 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
13011 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
13012 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
13015 d = (struct builtin_description *) bdesc_spe_predicates;
13016 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
13020 switch (insn_data[d->icode].operand[1].mode)
13023 type = int_ftype_int_v2si_v2si;
13026 type = int_ftype_int_v2sf_v2sf;
13029 gcc_unreachable ();
13032 def_builtin (d->mask, d->name, type, d->code);
13035 /* Evsel predicates. */
13036 d = (struct builtin_description *) bdesc_spe_evsel;
13037 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
13041 switch (insn_data[d->icode].operand[1].mode)
13044 type = v2si_ftype_4_v2si;
13047 type = v2sf_ftype_4_v2sf;
13050 gcc_unreachable ();
13053 def_builtin (d->mask, d->name, type, d->code);
13058 paired_init_builtins (void)
13060 const struct builtin_description *d;
13062 tree endlink = void_list_node;
13064 tree int_ftype_int_v2sf_v2sf
13065 = build_function_type
13066 (integer_type_node,
13067 tree_cons (NULL_TREE, integer_type_node,
13068 tree_cons (NULL_TREE, V2SF_type_node,
13069 tree_cons (NULL_TREE, V2SF_type_node,
13071 tree pcfloat_type_node =
13072 build_pointer_type (build_qualified_type
13073 (float_type_node, TYPE_QUAL_CONST));
13075 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
13076 long_integer_type_node,
13079 tree void_ftype_v2sf_long_pcfloat =
13080 build_function_type_list (void_type_node,
13082 long_integer_type_node,
13087 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
13088 PAIRED_BUILTIN_LX);
13091 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
13092 PAIRED_BUILTIN_STX);
13095 d = bdesc_paired_preds;
13096 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
13100 switch (insn_data[d->icode].operand[1].mode)
13103 type = int_ftype_int_v2sf_v2sf;
13106 gcc_unreachable ();
13109 def_builtin (d->mask, d->name, type, d->code);
13114 altivec_init_builtins (void)
13116 const struct builtin_description *d;
13117 const struct builtin_description_predicates *dp;
13121 tree pvoid_type_node = build_pointer_type (void_type_node);
13123 tree pcvoid_type_node
13124 = build_pointer_type (build_qualified_type (void_type_node,
13127 tree int_ftype_opaque
13128 = build_function_type_list (integer_type_node,
13129 opaque_V4SI_type_node, NULL_TREE);
13130 tree opaque_ftype_opaque
13131 = build_function_type (integer_type_node,
13133 tree opaque_ftype_opaque_int
13134 = build_function_type_list (opaque_V4SI_type_node,
13135 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
13136 tree opaque_ftype_opaque_opaque_int
13137 = build_function_type_list (opaque_V4SI_type_node,
13138 opaque_V4SI_type_node, opaque_V4SI_type_node,
13139 integer_type_node, NULL_TREE);
13140 tree int_ftype_int_opaque_opaque
13141 = build_function_type_list (integer_type_node,
13142 integer_type_node, opaque_V4SI_type_node,
13143 opaque_V4SI_type_node, NULL_TREE);
13144 tree int_ftype_int_v4si_v4si
13145 = build_function_type_list (integer_type_node,
13146 integer_type_node, V4SI_type_node,
13147 V4SI_type_node, NULL_TREE);
13148 tree void_ftype_v4si
13149 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
13150 tree v8hi_ftype_void
13151 = build_function_type (V8HI_type_node, void_list_node);
13152 tree void_ftype_void
13153 = build_function_type (void_type_node, void_list_node);
13154 tree void_ftype_int
13155 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
13157 tree opaque_ftype_long_pcvoid
13158 = build_function_type_list (opaque_V4SI_type_node,
13159 long_integer_type_node, pcvoid_type_node,
13161 tree v16qi_ftype_long_pcvoid
13162 = build_function_type_list (V16QI_type_node,
13163 long_integer_type_node, pcvoid_type_node,
13165 tree v8hi_ftype_long_pcvoid
13166 = build_function_type_list (V8HI_type_node,
13167 long_integer_type_node, pcvoid_type_node,
13169 tree v4si_ftype_long_pcvoid
13170 = build_function_type_list (V4SI_type_node,
13171 long_integer_type_node, pcvoid_type_node,
13173 tree v4sf_ftype_long_pcvoid
13174 = build_function_type_list (V4SF_type_node,
13175 long_integer_type_node, pcvoid_type_node,
13177 tree v2df_ftype_long_pcvoid
13178 = build_function_type_list (V2DF_type_node,
13179 long_integer_type_node, pcvoid_type_node,
13181 tree v2di_ftype_long_pcvoid
13182 = build_function_type_list (V2DI_type_node,
13183 long_integer_type_node, pcvoid_type_node,
13186 tree void_ftype_opaque_long_pvoid
13187 = build_function_type_list (void_type_node,
13188 opaque_V4SI_type_node, long_integer_type_node,
13189 pvoid_type_node, NULL_TREE);
13190 tree void_ftype_v4si_long_pvoid
13191 = build_function_type_list (void_type_node,
13192 V4SI_type_node, long_integer_type_node,
13193 pvoid_type_node, NULL_TREE);
13194 tree void_ftype_v16qi_long_pvoid
13195 = build_function_type_list (void_type_node,
13196 V16QI_type_node, long_integer_type_node,
13197 pvoid_type_node, NULL_TREE);
13198 tree void_ftype_v8hi_long_pvoid
13199 = build_function_type_list (void_type_node,
13200 V8HI_type_node, long_integer_type_node,
13201 pvoid_type_node, NULL_TREE);
13202 tree void_ftype_v4sf_long_pvoid
13203 = build_function_type_list (void_type_node,
13204 V4SF_type_node, long_integer_type_node,
13205 pvoid_type_node, NULL_TREE);
13206 tree void_ftype_v2df_long_pvoid
13207 = build_function_type_list (void_type_node,
13208 V2DF_type_node, long_integer_type_node,
13209 pvoid_type_node, NULL_TREE);
13210 tree void_ftype_v2di_long_pvoid
13211 = build_function_type_list (void_type_node,
13212 V2DI_type_node, long_integer_type_node,
13213 pvoid_type_node, NULL_TREE);
13214 tree int_ftype_int_v8hi_v8hi
13215 = build_function_type_list (integer_type_node,
13216 integer_type_node, V8HI_type_node,
13217 V8HI_type_node, NULL_TREE);
13218 tree int_ftype_int_v16qi_v16qi
13219 = build_function_type_list (integer_type_node,
13220 integer_type_node, V16QI_type_node,
13221 V16QI_type_node, NULL_TREE);
13222 tree int_ftype_int_v4sf_v4sf
13223 = build_function_type_list (integer_type_node,
13224 integer_type_node, V4SF_type_node,
13225 V4SF_type_node, NULL_TREE);
13226 tree int_ftype_int_v2df_v2df
13227 = build_function_type_list (integer_type_node,
13228 integer_type_node, V2DF_type_node,
13229 V2DF_type_node, NULL_TREE);
13230 tree v4si_ftype_v4si
13231 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
13232 tree v8hi_ftype_v8hi
13233 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
13234 tree v16qi_ftype_v16qi
13235 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
13236 tree v4sf_ftype_v4sf
13237 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
13238 tree v2df_ftype_v2df
13239 = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
13240 tree void_ftype_pcvoid_int_int
13241 = build_function_type_list (void_type_node,
13242 pcvoid_type_node, integer_type_node,
13243 integer_type_node, NULL_TREE);
13245 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
13246 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
13247 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
13248 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
13249 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
13250 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
13251 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
13252 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
13253 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
13254 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
13255 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
13256 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
13257 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
13258 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
13259 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
13260 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
13261 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
13262 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
13263 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
13264 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
13265 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
13266 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
13267 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
13268 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
13269 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
13270 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
13271 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
13272 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
13273 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
13274 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
13276 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
13277 VSX_BUILTIN_LXVD2X_V2DF);
13278 def_builtin (MASK_VSX, "__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
13279 VSX_BUILTIN_LXVD2X_V2DI);
13280 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
13281 VSX_BUILTIN_LXVW4X_V4SF);
13282 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
13283 VSX_BUILTIN_LXVW4X_V4SI);
13284 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v8hi",
13285 v8hi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V8HI);
13286 def_builtin (MASK_VSX, "__builtin_vsx_lxvw4x_v16qi",
13287 v16qi_ftype_long_pcvoid, VSX_BUILTIN_LXVW4X_V16QI);
13288 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2df",
13289 void_ftype_v2df_long_pvoid, VSX_BUILTIN_STXVD2X_V2DF);
13290 def_builtin (MASK_VSX, "__builtin_vsx_stxvd2x_v2di",
13291 void_ftype_v2di_long_pvoid, VSX_BUILTIN_STXVD2X_V2DI);
13292 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4sf",
13293 void_ftype_v4sf_long_pvoid, VSX_BUILTIN_STXVW4X_V4SF);
13294 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v4si",
13295 void_ftype_v4si_long_pvoid, VSX_BUILTIN_STXVW4X_V4SI);
13296 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v8hi",
13297 void_ftype_v8hi_long_pvoid, VSX_BUILTIN_STXVW4X_V8HI);
13298 def_builtin (MASK_VSX, "__builtin_vsx_stxvw4x_v16qi",
13299 void_ftype_v16qi_long_pvoid, VSX_BUILTIN_STXVW4X_V16QI);
13300 def_builtin (MASK_VSX, "__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
13301 VSX_BUILTIN_VEC_LD);
13302 def_builtin (MASK_VSX, "__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
13303 VSX_BUILTIN_VEC_ST);
13305 if (rs6000_cpu == PROCESSOR_CELL)
13307 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
13308 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
13309 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
13310 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
13312 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
13313 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
13314 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
13315 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
13317 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
13318 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
13319 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
13320 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
13322 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
13323 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
13324 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
13325 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
13327 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
13328 def_builtin (MASK_ALTIVEC, "__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
13329 def_builtin (MASK_ALTIVEC, "__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
13331 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
13332 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
13333 def_builtin (MASK_ALTIVEC, "__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
13334 def_builtin (MASK_ALTIVEC, "__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
13335 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
13336 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
13337 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
13338 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
13339 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
13340 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
13341 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
13342 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
13344 /* Add the DST variants. */
13346 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
13347 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
13349 /* Initialize the predicates. */
13350 dp = bdesc_altivec_preds;
13351 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
13353 enum machine_mode mode1;
13355 bool is_overloaded = ((dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13356 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13357 || (dp->code >= VSX_BUILTIN_OVERLOADED_FIRST
13358 && dp->code <= VSX_BUILTIN_OVERLOADED_LAST));
13363 mode1 = insn_data[dp->icode].operand[1].mode;
13368 type = int_ftype_int_opaque_opaque;
13371 type = int_ftype_int_v4si_v4si;
13374 type = int_ftype_int_v8hi_v8hi;
13377 type = int_ftype_int_v16qi_v16qi;
13380 type = int_ftype_int_v4sf_v4sf;
13383 type = int_ftype_int_v2df_v2df;
13386 gcc_unreachable ();
13389 def_builtin (dp->mask, dp->name, type, dp->code);
13392 /* Initialize the abs* operators. */
13394 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
13396 enum machine_mode mode0;
13399 mode0 = insn_data[d->icode].operand[0].mode;
13404 type = v4si_ftype_v4si;
13407 type = v8hi_ftype_v8hi;
13410 type = v16qi_ftype_v16qi;
13413 type = v4sf_ftype_v4sf;
13416 type = v2df_ftype_v2df;
13419 gcc_unreachable ();
13422 def_builtin (d->mask, d->name, type, d->code);
13425 if (TARGET_ALTIVEC)
13429 /* Initialize target builtin that implements
13430 targetm.vectorize.builtin_mask_for_load. */
13432 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
13433 v16qi_ftype_long_pcvoid,
13434 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
13435 BUILT_IN_MD, NULL, NULL_TREE);
13436 TREE_READONLY (decl) = 1;
13437 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
13438 altivec_builtin_mask_for_load = decl;
13441 /* Access to the vec_init patterns. */
13442 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
13443 integer_type_node, integer_type_node,
13444 integer_type_node, NULL_TREE);
13445 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
13446 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
13448 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
13449 short_integer_type_node,
13450 short_integer_type_node,
13451 short_integer_type_node,
13452 short_integer_type_node,
13453 short_integer_type_node,
13454 short_integer_type_node,
13455 short_integer_type_node, NULL_TREE);
13456 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
13457 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
13459 ftype = build_function_type_list (V16QI_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, char_type_node,
13464 char_type_node, char_type_node,
13465 char_type_node, char_type_node,
13466 char_type_node, char_type_node,
13467 char_type_node, NULL_TREE);
13468 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
13469 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
13471 ftype = build_function_type_list (V4SF_type_node, float_type_node,
13472 float_type_node, float_type_node,
13473 float_type_node, NULL_TREE);
13474 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
13475 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
13479 ftype = build_function_type_list (V2DF_type_node, double_type_node,
13480 double_type_node, NULL_TREE);
13481 def_builtin (MASK_VSX, "__builtin_vec_init_v2df", ftype,
13482 VSX_BUILTIN_VEC_INIT_V2DF);
13484 ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
13485 intDI_type_node, NULL_TREE);
13486 def_builtin (MASK_VSX, "__builtin_vec_init_v2di", ftype,
13487 VSX_BUILTIN_VEC_INIT_V2DI);
13490 /* Access to the vec_set patterns. */
13491 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
13493 integer_type_node, NULL_TREE);
13494 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
13495 ALTIVEC_BUILTIN_VEC_SET_V4SI);
13497 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
13499 integer_type_node, NULL_TREE);
13500 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
13501 ALTIVEC_BUILTIN_VEC_SET_V8HI);
13503 ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
13505 integer_type_node, NULL_TREE);
13506 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
13507 ALTIVEC_BUILTIN_VEC_SET_V16QI);
13509 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
13511 integer_type_node, NULL_TREE);
13512 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_set_v4sf", ftype,
13513 ALTIVEC_BUILTIN_VEC_SET_V4SF);
13517 ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
13519 integer_type_node, NULL_TREE);
13520 def_builtin (MASK_VSX, "__builtin_vec_set_v2df", ftype,
13521 VSX_BUILTIN_VEC_SET_V2DF);
13523 ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
13525 integer_type_node, NULL_TREE);
13526 def_builtin (MASK_VSX, "__builtin_vec_set_v2di", ftype,
13527 VSX_BUILTIN_VEC_SET_V2DI);
13530 /* Access to the vec_extract patterns. */
13531 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
13532 integer_type_node, NULL_TREE);
13533 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
13534 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
13536 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
13537 integer_type_node, NULL_TREE);
13538 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
13539 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
13541 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
13542 integer_type_node, NULL_TREE);
13543 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
13544 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
13546 ftype = build_function_type_list (float_type_node, V4SF_type_node,
13547 integer_type_node, NULL_TREE);
13548 def_builtin (MASK_ALTIVEC|MASK_VSX, "__builtin_vec_ext_v4sf", ftype,
13549 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
13553 ftype = build_function_type_list (double_type_node, V2DF_type_node,
13554 integer_type_node, NULL_TREE);
13555 def_builtin (MASK_VSX, "__builtin_vec_ext_v2df", ftype,
13556 VSX_BUILTIN_VEC_EXT_V2DF);
13558 ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
13559 integer_type_node, NULL_TREE);
13560 def_builtin (MASK_VSX, "__builtin_vec_ext_v2di", ftype,
13561 VSX_BUILTIN_VEC_EXT_V2DI);
13565 /* Hash function for builtin functions with up to 3 arguments and a return
13568 builtin_hash_function (const void *hash_entry)
13572 const struct builtin_hash_struct *bh =
13573 (const struct builtin_hash_struct *) hash_entry;
13575 for (i = 0; i < 4; i++)
13577 ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
13578 ret = (ret * 2) + bh->uns_p[i];
13584 /* Compare builtin hash entries H1 and H2 for equivalence. */
13586 builtin_hash_eq (const void *h1, const void *h2)
13588 const struct builtin_hash_struct *p1 = (const struct builtin_hash_struct *) h1;
13589 const struct builtin_hash_struct *p2 = (const struct builtin_hash_struct *) h2;
13591 return ((p1->mode[0] == p2->mode[0])
13592 && (p1->mode[1] == p2->mode[1])
13593 && (p1->mode[2] == p2->mode[2])
13594 && (p1->mode[3] == p2->mode[3])
13595 && (p1->uns_p[0] == p2->uns_p[0])
13596 && (p1->uns_p[1] == p2->uns_p[1])
13597 && (p1->uns_p[2] == p2->uns_p[2])
13598 && (p1->uns_p[3] == p2->uns_p[3]));
13601 /* Map types for builtin functions with an explicit return type and up to 3
13602 arguments. Functions with fewer than 3 arguments use VOIDmode as the type
13603 of the argument. */
13605 builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
13606 enum machine_mode mode_arg1, enum machine_mode mode_arg2,
13607 enum rs6000_builtins builtin, const char *name)
13609 struct builtin_hash_struct h;
13610 struct builtin_hash_struct *h2;
13614 tree ret_type = NULL_TREE;
13615 tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
13618 /* Create builtin_hash_table. */
13619 if (builtin_hash_table == NULL)
13620 builtin_hash_table = htab_create_ggc (1500, builtin_hash_function,
13621 builtin_hash_eq, NULL);
13623 h.type = NULL_TREE;
13624 h.mode[0] = mode_ret;
13625 h.mode[1] = mode_arg0;
13626 h.mode[2] = mode_arg1;
13627 h.mode[3] = mode_arg2;
13633 /* If the builtin is a type that produces unsigned results or takes unsigned
13634 arguments, and it is returned as a decl for the vectorizer (such as
13635 widening multiplies, permute), make sure the arguments and return value
13636 are type correct. */
13639 /* unsigned 2 argument functions. */
13640 case ALTIVEC_BUILTIN_VMULEUB_UNS:
13641 case ALTIVEC_BUILTIN_VMULEUH_UNS:
13642 case ALTIVEC_BUILTIN_VMULOUB_UNS:
13643 case ALTIVEC_BUILTIN_VMULOUH_UNS:
13649 /* unsigned 3 argument functions. */
13650 case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
13651 case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
13652 case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
13653 case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
13654 case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
13655 case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
13656 case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
13657 case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
13658 case VSX_BUILTIN_VPERM_16QI_UNS:
13659 case VSX_BUILTIN_VPERM_8HI_UNS:
13660 case VSX_BUILTIN_VPERM_4SI_UNS:
13661 case VSX_BUILTIN_VPERM_2DI_UNS:
13662 case VSX_BUILTIN_XXSEL_16QI_UNS:
13663 case VSX_BUILTIN_XXSEL_8HI_UNS:
13664 case VSX_BUILTIN_XXSEL_4SI_UNS:
13665 case VSX_BUILTIN_XXSEL_2DI_UNS:
13672 /* signed permute functions with unsigned char mask. */
13673 case ALTIVEC_BUILTIN_VPERM_16QI:
13674 case ALTIVEC_BUILTIN_VPERM_8HI:
13675 case ALTIVEC_BUILTIN_VPERM_4SI:
13676 case ALTIVEC_BUILTIN_VPERM_4SF:
13677 case ALTIVEC_BUILTIN_VPERM_2DI:
13678 case ALTIVEC_BUILTIN_VPERM_2DF:
13679 case VSX_BUILTIN_VPERM_16QI:
13680 case VSX_BUILTIN_VPERM_8HI:
13681 case VSX_BUILTIN_VPERM_4SI:
13682 case VSX_BUILTIN_VPERM_4SF:
13683 case VSX_BUILTIN_VPERM_2DI:
13684 case VSX_BUILTIN_VPERM_2DF:
13688 /* unsigned args, signed return. */
13689 case VSX_BUILTIN_XVCVUXDDP_UNS:
13690 case VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF:
13694 /* signed args, unsigned return. */
13695 case VSX_BUILTIN_XVCVDPUXDS_UNS:
13696 case VECTOR_BUILTIN_FIXUNS_V4SF_V4SI:
13704 /* Figure out how many args are present. */
13705 while (num_args > 0 && h.mode[num_args] == VOIDmode)
13709 fatal_error ("internal error: builtin function %s had no type", name);
13711 ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
13712 if (!ret_type && h.uns_p[0])
13713 ret_type = builtin_mode_to_type[h.mode[0]][0];
13716 fatal_error ("internal error: builtin function %s had an unexpected "
13717 "return type %s", name, GET_MODE_NAME (h.mode[0]));
13719 for (i = 0; i < num_args; i++)
13721 int m = (int) h.mode[i+1];
13722 int uns_p = h.uns_p[i+1];
13724 arg_type[i] = builtin_mode_to_type[m][uns_p];
13725 if (!arg_type[i] && uns_p)
13726 arg_type[i] = builtin_mode_to_type[m][0];
13729 fatal_error ("internal error: builtin function %s, argument %d "
13730 "had unexpected argument type %s", name, i,
13731 GET_MODE_NAME (m));
13734 found = htab_find_slot (builtin_hash_table, &h, INSERT);
13735 if (*found == NULL)
13737 h2 = ggc_alloc_builtin_hash_struct ();
13739 *found = (void *)h2;
13740 args = void_list_node;
13742 for (i = num_args - 1; i >= 0; i--)
13743 args = tree_cons (NULL_TREE, arg_type[i], args);
13745 h2->type = build_function_type (ret_type, args);
13748 return ((struct builtin_hash_struct *)(*found))->type;
13752 rs6000_common_init_builtins (void)
13754 const struct builtin_description *d;
13757 tree opaque_ftype_opaque = NULL_TREE;
13758 tree opaque_ftype_opaque_opaque = NULL_TREE;
13759 tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
13760 tree v2si_ftype_qi = NULL_TREE;
13761 tree v2si_ftype_v2si_qi = NULL_TREE;
13762 tree v2si_ftype_int_qi = NULL_TREE;
13764 if (!TARGET_PAIRED_FLOAT)
13766 builtin_mode_to_type[V2SImode][0] = opaque_V2SI_type_node;
13767 builtin_mode_to_type[V2SFmode][0] = opaque_V2SF_type_node;
13770 /* Add the ternary operators. */
13772 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
13775 int mask = d->mask;
13777 if ((mask != 0 && (mask & target_flags) == 0)
13778 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13781 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13782 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13783 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13784 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13786 if (! (type = opaque_ftype_opaque_opaque_opaque))
13787 type = opaque_ftype_opaque_opaque_opaque
13788 = build_function_type_list (opaque_V4SI_type_node,
13789 opaque_V4SI_type_node,
13790 opaque_V4SI_type_node,
13791 opaque_V4SI_type_node,
13796 enum insn_code icode = d->icode;
13797 if (d->name == 0 || icode == CODE_FOR_nothing)
13800 type = builtin_function_type (insn_data[icode].operand[0].mode,
13801 insn_data[icode].operand[1].mode,
13802 insn_data[icode].operand[2].mode,
13803 insn_data[icode].operand[3].mode,
13807 def_builtin (d->mask, d->name, type, d->code);
13810 /* Add the binary operators. */
13812 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
13814 enum machine_mode mode0, mode1, mode2;
13816 int mask = d->mask;
13818 if ((mask != 0 && (mask & target_flags) == 0)
13819 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13822 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13823 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13824 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13825 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13827 if (! (type = opaque_ftype_opaque_opaque))
13828 type = opaque_ftype_opaque_opaque
13829 = build_function_type_list (opaque_V4SI_type_node,
13830 opaque_V4SI_type_node,
13831 opaque_V4SI_type_node,
13836 enum insn_code icode = d->icode;
13837 if (d->name == 0 || icode == CODE_FOR_nothing)
13840 mode0 = insn_data[icode].operand[0].mode;
13841 mode1 = insn_data[icode].operand[1].mode;
13842 mode2 = insn_data[icode].operand[2].mode;
13844 if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
13846 if (! (type = v2si_ftype_v2si_qi))
13847 type = v2si_ftype_v2si_qi
13848 = build_function_type_list (opaque_V2SI_type_node,
13849 opaque_V2SI_type_node,
13854 else if (mode0 == V2SImode && GET_MODE_CLASS (mode1) == MODE_INT
13855 && mode2 == QImode)
13857 if (! (type = v2si_ftype_int_qi))
13858 type = v2si_ftype_int_qi
13859 = build_function_type_list (opaque_V2SI_type_node,
13866 type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
13870 def_builtin (d->mask, d->name, type, d->code);
13873 /* Add the simple unary operators. */
13874 d = (struct builtin_description *) bdesc_1arg;
13875 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
13877 enum machine_mode mode0, mode1;
13879 int mask = d->mask;
13881 if ((mask != 0 && (mask & target_flags) == 0)
13882 || (mask == 0 && !TARGET_PAIRED_FLOAT))
13885 if ((d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
13886 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
13887 || (d->code >= VSX_BUILTIN_OVERLOADED_FIRST
13888 && d->code <= VSX_BUILTIN_OVERLOADED_LAST))
13890 if (! (type = opaque_ftype_opaque))
13891 type = opaque_ftype_opaque
13892 = build_function_type_list (opaque_V4SI_type_node,
13893 opaque_V4SI_type_node,
13898 enum insn_code icode = d->icode;
13899 if (d->name == 0 || icode == CODE_FOR_nothing)
13902 mode0 = insn_data[icode].operand[0].mode;
13903 mode1 = insn_data[icode].operand[1].mode;
13905 if (mode0 == V2SImode && mode1 == QImode)
13907 if (! (type = v2si_ftype_qi))
13908 type = v2si_ftype_qi
13909 = build_function_type_list (opaque_V2SI_type_node,
13915 type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
13919 def_builtin (d->mask, d->name, type, d->code);
13924 rs6000_init_libfuncs (void)
13926 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
13927 && !TARGET_POWER2 && !TARGET_POWERPC)
13929 /* AIX library routines for float->int conversion. */
13930 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
13931 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
13932 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
13933 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
13936 if (!TARGET_IEEEQUAD)
13937 /* AIX/Darwin/64-bit Linux quad floating point routines. */
13938 if (!TARGET_XL_COMPAT)
13940 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
13941 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
13942 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
13943 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
13945 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
13947 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
13948 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
13949 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
13950 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
13951 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
13952 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
13953 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
13955 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
13956 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
13957 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
13958 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
13959 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
13960 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
13961 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
13962 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
13965 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
13966 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
13970 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
13971 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
13972 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
13973 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
13977 /* 32-bit SVR4 quad floating point routines. */
13979 set_optab_libfunc (add_optab, TFmode, "_q_add");
13980 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
13981 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
13982 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
13983 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
13984 if (TARGET_PPC_GPOPT || TARGET_POWER2)
13985 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
13987 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
13988 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
13989 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
13990 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
13991 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
13992 set_optab_libfunc (le_optab, TFmode, "_q_fle");
13994 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
13995 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
13996 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
13997 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
13998 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
13999 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
14000 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
14001 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
14006 /* Expand a block clear operation, and return 1 if successful. Return 0
14007 if we should let the compiler generate normal code.
14009 operands[0] is the destination
14010 operands[1] is the length
14011 operands[3] is the alignment */
14014 expand_block_clear (rtx operands[])
14016 rtx orig_dest = operands[0];
14017 rtx bytes_rtx = operands[1];
14018 rtx align_rtx = operands[3];
14019 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
14020 HOST_WIDE_INT align;
14021 HOST_WIDE_INT bytes;
14026 /* If this is not a fixed size move, just call memcpy */
14030 /* This must be a fixed size alignment */
14031 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14032 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14034 /* Anything to clear? */
14035 bytes = INTVAL (bytes_rtx);
14039 /* Use the builtin memset after a point, to avoid huge code bloat.
14040 When optimize_size, avoid any significant code bloat; calling
14041 memset is about 4 instructions, so allow for one instruction to
14042 load zero and three to do clearing. */
14043 if (TARGET_ALTIVEC && align >= 128)
14045 else if (TARGET_POWERPC64 && align >= 32)
14047 else if (TARGET_SPE && align >= 64)
14052 if (optimize_size && bytes > 3 * clear_step)
14054 if (! optimize_size && bytes > 8 * clear_step)
14057 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
14059 enum machine_mode mode = BLKmode;
14062 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
14067 else if (bytes >= 8 && TARGET_SPE && align >= 64)
14072 else if (bytes >= 8 && TARGET_POWERPC64
14073 /* 64-bit loads and stores require word-aligned
14075 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14080 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14081 { /* move 4 bytes */
14085 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14086 { /* move 2 bytes */
14090 else /* move 1 byte at a time */
14096 dest = adjust_address (orig_dest, mode, offset);
14098 emit_move_insn (dest, CONST0_RTX (mode));
14105 /* Expand a block move operation, and return 1 if successful. Return 0
14106 if we should let the compiler generate normal code.
14108 operands[0] is the destination
14109 operands[1] is the source
14110 operands[2] is the length
14111 operands[3] is the alignment */
14113 #define MAX_MOVE_REG 4
14116 expand_block_move (rtx operands[])
14118 rtx orig_dest = operands[0];
14119 rtx orig_src = operands[1];
14120 rtx bytes_rtx = operands[2];
14121 rtx align_rtx = operands[3];
14122 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
14127 rtx stores[MAX_MOVE_REG];
14130 /* If this is not a fixed size move, just call memcpy */
14134 /* This must be a fixed size alignment */
14135 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
14136 align = INTVAL (align_rtx) * BITS_PER_UNIT;
14138 /* Anything to move? */
14139 bytes = INTVAL (bytes_rtx);
14143 if (bytes > rs6000_block_move_inline_limit)
14146 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
14149 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
14150 rtx (*mov) (rtx, rtx);
14152 enum machine_mode mode = BLKmode;
14155 /* Altivec first, since it will be faster than a string move
14156 when it applies, and usually not significantly larger. */
14157 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
14161 gen_func.mov = gen_movv4si;
14163 else if (TARGET_SPE && bytes >= 8 && align >= 64)
14167 gen_func.mov = gen_movv2si;
14169 else if (TARGET_STRING
14170 && bytes > 24 /* move up to 32 bytes at a time */
14176 && ! fixed_regs[10]
14177 && ! fixed_regs[11]
14178 && ! fixed_regs[12])
14180 move_bytes = (bytes > 32) ? 32 : bytes;
14181 gen_func.movmemsi = gen_movmemsi_8reg;
14183 else if (TARGET_STRING
14184 && bytes > 16 /* move up to 24 bytes at a time */
14190 && ! fixed_regs[10])
14192 move_bytes = (bytes > 24) ? 24 : bytes;
14193 gen_func.movmemsi = gen_movmemsi_6reg;
14195 else if (TARGET_STRING
14196 && bytes > 8 /* move up to 16 bytes at a time */
14200 && ! fixed_regs[8])
14202 move_bytes = (bytes > 16) ? 16 : bytes;
14203 gen_func.movmemsi = gen_movmemsi_4reg;
14205 else if (bytes >= 8 && TARGET_POWERPC64
14206 /* 64-bit loads and stores require word-aligned
14208 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
14212 gen_func.mov = gen_movdi;
14214 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
14215 { /* move up to 8 bytes at a time */
14216 move_bytes = (bytes > 8) ? 8 : bytes;
14217 gen_func.movmemsi = gen_movmemsi_2reg;
14219 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
14220 { /* move 4 bytes */
14223 gen_func.mov = gen_movsi;
14225 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
14226 { /* move 2 bytes */
14229 gen_func.mov = gen_movhi;
14231 else if (TARGET_STRING && bytes > 1)
14232 { /* move up to 4 bytes at a time */
14233 move_bytes = (bytes > 4) ? 4 : bytes;
14234 gen_func.movmemsi = gen_movmemsi_1reg;
14236 else /* move 1 byte at a time */
14240 gen_func.mov = gen_movqi;
14243 src = adjust_address (orig_src, mode, offset);
14244 dest = adjust_address (orig_dest, mode, offset);
14246 if (mode != BLKmode)
14248 rtx tmp_reg = gen_reg_rtx (mode);
14250 emit_insn ((*gen_func.mov) (tmp_reg, src));
14251 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
14254 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
14257 for (i = 0; i < num_reg; i++)
14258 emit_insn (stores[i]);
14262 if (mode == BLKmode)
14264 /* Move the address into scratch registers. The movmemsi
14265 patterns require zero offset. */
14266 if (!REG_P (XEXP (src, 0)))
14268 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
14269 src = replace_equiv_address (src, src_reg);
14271 set_mem_size (src, GEN_INT (move_bytes));
14273 if (!REG_P (XEXP (dest, 0)))
14275 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
14276 dest = replace_equiv_address (dest, dest_reg);
14278 set_mem_size (dest, GEN_INT (move_bytes));
14280 emit_insn ((*gen_func.movmemsi) (dest, src,
14281 GEN_INT (move_bytes & 31),
14290 /* Return a string to perform a load_multiple operation.
14291 operands[0] is the vector.
14292 operands[1] is the source address.
14293 operands[2] is the first destination register. */
14296 rs6000_output_load_multiple (rtx operands[3])
14298 /* We have to handle the case where the pseudo used to contain the address
14299 is assigned to one of the output registers. */
14301 int words = XVECLEN (operands[0], 0);
14304 if (XVECLEN (operands[0], 0) == 1)
14305 return "{l|lwz} %2,0(%1)";
14307 for (i = 0; i < words; i++)
14308 if (refers_to_regno_p (REGNO (operands[2]) + i,
14309 REGNO (operands[2]) + i + 1, operands[1], 0))
14313 xop[0] = GEN_INT (4 * (words-1));
14314 xop[1] = operands[1];
14315 xop[2] = operands[2];
14316 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
14321 xop[0] = GEN_INT (4 * (words-1));
14322 xop[1] = operands[1];
14323 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
14324 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);
14329 for (j = 0; j < words; j++)
14332 xop[0] = GEN_INT (j * 4);
14333 xop[1] = operands[1];
14334 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
14335 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
14337 xop[0] = GEN_INT (i * 4);
14338 xop[1] = operands[1];
14339 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
14344 return "{lsi|lswi} %2,%1,%N0";
14348 /* A validation routine: say whether CODE, a condition code, and MODE
14349 match. The other alternatives either don't make sense or should
14350 never be generated. */
14353 validate_condition_mode (enum rtx_code code, enum machine_mode mode)
14355 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
14356 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
14357 && GET_MODE_CLASS (mode) == MODE_CC);
14359 /* These don't make sense. */
14360 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
14361 || mode != CCUNSmode);
14363 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
14364 || mode == CCUNSmode);
14366 gcc_assert (mode == CCFPmode
14367 || (code != ORDERED && code != UNORDERED
14368 && code != UNEQ && code != LTGT
14369 && code != UNGT && code != UNLT
14370 && code != UNGE && code != UNLE));
14372 /* These should never be generated except for
14373 flag_finite_math_only. */
14374 gcc_assert (mode != CCFPmode
14375 || flag_finite_math_only
14376 || (code != LE && code != GE
14377 && code != UNEQ && code != LTGT
14378 && code != UNGT && code != UNLT));
14380 /* These are invalid; the information is not there. */
14381 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
14385 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
14386 mask required to convert the result of a rotate insn into a shift
14387 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
14390 includes_lshift_p (rtx shiftop, rtx andop)
14392 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14394 shift_mask <<= INTVAL (shiftop);
14396 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14399 /* Similar, but for right shift. */
14402 includes_rshift_p (rtx shiftop, rtx andop)
14404 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
14406 shift_mask >>= INTVAL (shiftop);
14408 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
14411 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
14412 to perform a left shift. It must have exactly SHIFTOP least
14413 significant 0's, then one or more 1's, then zero or more 0's. */
14416 includes_rldic_lshift_p (rtx shiftop, rtx andop)
14418 if (GET_CODE (andop) == CONST_INT)
14420 HOST_WIDE_INT c, lsb, shift_mask;
14422 c = INTVAL (andop);
14423 if (c == 0 || c == ~0)
14427 shift_mask <<= INTVAL (shiftop);
14429 /* Find the least significant one bit. */
14432 /* It must coincide with the LSB of the shift mask. */
14433 if (-lsb != shift_mask)
14436 /* Invert to look for the next transition (if any). */
14439 /* Remove the low group of ones (originally low group of zeros). */
14442 /* Again find the lsb, and check we have all 1's above. */
14446 else if (GET_CODE (andop) == CONST_DOUBLE
14447 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14449 HOST_WIDE_INT low, high, lsb;
14450 HOST_WIDE_INT shift_mask_low, shift_mask_high;
14452 low = CONST_DOUBLE_LOW (andop);
14453 if (HOST_BITS_PER_WIDE_INT < 64)
14454 high = CONST_DOUBLE_HIGH (andop);
14456 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
14457 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
14460 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14462 shift_mask_high = ~0;
14463 if (INTVAL (shiftop) > 32)
14464 shift_mask_high <<= INTVAL (shiftop) - 32;
14466 lsb = high & -high;
14468 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
14474 lsb = high & -high;
14475 return high == -lsb;
14478 shift_mask_low = ~0;
14479 shift_mask_low <<= INTVAL (shiftop);
14483 if (-lsb != shift_mask_low)
14486 if (HOST_BITS_PER_WIDE_INT < 64)
14491 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
14493 lsb = high & -high;
14494 return high == -lsb;
14498 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
14504 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
14505 to perform a left shift. It must have SHIFTOP or more least
14506 significant 0's, with the remainder of the word 1's. */
14509 includes_rldicr_lshift_p (rtx shiftop, rtx andop)
14511 if (GET_CODE (andop) == CONST_INT)
14513 HOST_WIDE_INT c, lsb, shift_mask;
14516 shift_mask <<= INTVAL (shiftop);
14517 c = INTVAL (andop);
14519 /* Find the least significant one bit. */
14522 /* It must be covered by the shift mask.
14523 This test also rejects c == 0. */
14524 if ((lsb & shift_mask) == 0)
14527 /* Check we have all 1's above the transition, and reject all 1's. */
14528 return c == -lsb && lsb != 1;
14530 else if (GET_CODE (andop) == CONST_DOUBLE
14531 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
14533 HOST_WIDE_INT low, lsb, shift_mask_low;
14535 low = CONST_DOUBLE_LOW (andop);
14537 if (HOST_BITS_PER_WIDE_INT < 64)
14539 HOST_WIDE_INT high, shift_mask_high;
14541 high = CONST_DOUBLE_HIGH (andop);
14545 shift_mask_high = ~0;
14546 if (INTVAL (shiftop) > 32)
14547 shift_mask_high <<= INTVAL (shiftop) - 32;
14549 lsb = high & -high;
14551 if ((lsb & shift_mask_high) == 0)
14554 return high == -lsb;
14560 shift_mask_low = ~0;
14561 shift_mask_low <<= INTVAL (shiftop);
14565 if ((lsb & shift_mask_low) == 0)
14568 return low == -lsb && lsb != 1;
14574 /* Return 1 if operands will generate a valid arguments to rlwimi
14575 instruction for insert with right shift in 64-bit mode. The mask may
14576 not start on the first bit or stop on the last bit because wrap-around
14577 effects of instruction do not correspond to semantics of RTL insn. */
14580 insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
14582 if (INTVAL (startop) > 32
14583 && INTVAL (startop) < 64
14584 && INTVAL (sizeop) > 1
14585 && INTVAL (sizeop) + INTVAL (startop) < 64
14586 && INTVAL (shiftop) > 0
14587 && INTVAL (sizeop) + INTVAL (shiftop) < 32
14588 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
14594 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
14595 for lfq and stfq insns iff the registers are hard registers. */
14598 registers_ok_for_quad_peep (rtx reg1, rtx reg2)
14600 /* We might have been passed a SUBREG. */
14601 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
14604 /* We might have been passed non floating point registers. */
14605 if (!FP_REGNO_P (REGNO (reg1))
14606 || !FP_REGNO_P (REGNO (reg2)))
14609 return (REGNO (reg1) == REGNO (reg2) - 1);
14612 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
14613 addr1 and addr2 must be in consecutive memory locations
14614 (addr2 == addr1 + 8). */
14617 mems_ok_for_quad_peep (rtx mem1, rtx mem2)
14620 unsigned int reg1, reg2;
14621 int offset1, offset2;
14623 /* The mems cannot be volatile. */
14624 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
14627 addr1 = XEXP (mem1, 0);
14628 addr2 = XEXP (mem2, 0);
14630 /* Extract an offset (if used) from the first addr. */
14631 if (GET_CODE (addr1) == PLUS)
14633 /* If not a REG, return zero. */
14634 if (GET_CODE (XEXP (addr1, 0)) != REG)
14638 reg1 = REGNO (XEXP (addr1, 0));
14639 /* The offset must be constant! */
14640 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
14642 offset1 = INTVAL (XEXP (addr1, 1));
14645 else if (GET_CODE (addr1) != REG)
14649 reg1 = REGNO (addr1);
14650 /* This was a simple (mem (reg)) expression. Offset is 0. */
14654 /* And now for the second addr. */
14655 if (GET_CODE (addr2) == PLUS)
14657 /* If not a REG, return zero. */
14658 if (GET_CODE (XEXP (addr2, 0)) != REG)
14662 reg2 = REGNO (XEXP (addr2, 0));
14663 /* The offset must be constant. */
14664 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
14666 offset2 = INTVAL (XEXP (addr2, 1));
14669 else if (GET_CODE (addr2) != REG)
14673 reg2 = REGNO (addr2);
14674 /* This was a simple (mem (reg)) expression. Offset is 0. */
14678 /* Both of these must have the same base register. */
14682 /* The offset for the second addr must be 8 more than the first addr. */
14683 if (offset2 != offset1 + 8)
14686 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
14693 rs6000_secondary_memory_needed_rtx (enum machine_mode mode)
14695 static bool eliminated = false;
14698 if (mode != SDmode)
14699 ret = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
14702 rtx mem = cfun->machine->sdmode_stack_slot;
14703 gcc_assert (mem != NULL_RTX);
14707 mem = eliminate_regs (mem, VOIDmode, NULL_RTX);
14708 cfun->machine->sdmode_stack_slot = mem;
14714 if (TARGET_DEBUG_ADDR)
14716 fprintf (stderr, "\nrs6000_secondary_memory_needed_rtx, mode %s, rtx:\n",
14717 GET_MODE_NAME (mode));
14719 fprintf (stderr, "\tNULL_RTX\n");
14728 rs6000_check_sdmode (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
14730 /* Don't walk into types. */
14731 if (*tp == NULL_TREE || *tp == error_mark_node || TYPE_P (*tp))
14733 *walk_subtrees = 0;
14737 switch (TREE_CODE (*tp))
14746 case VIEW_CONVERT_EXPR:
14747 if (TYPE_MODE (TREE_TYPE (*tp)) == SDmode)
14757 enum reload_reg_type {
14759 VECTOR_REGISTER_TYPE,
14760 OTHER_REGISTER_TYPE
14763 static enum reload_reg_type
14764 rs6000_reload_register_type (enum reg_class rclass)
14770 return GPR_REGISTER_TYPE;
14775 return VECTOR_REGISTER_TYPE;
14778 return OTHER_REGISTER_TYPE;
14782 /* Inform reload about cases where moving X with a mode MODE to a register in
14783 RCLASS requires an extra scratch or immediate register. Return the class
14784 needed for the immediate register.
14786 For VSX and Altivec, we may need a register to convert sp+offset into
14789 For misaligned 64-bit gpr loads and stores we need a register to
14790 convert an offset address to indirect. */
14793 rs6000_secondary_reload (bool in_p,
14795 reg_class_t rclass_i,
14796 enum machine_mode mode,
14797 secondary_reload_info *sri)
14799 enum reg_class rclass = (enum reg_class) rclass_i;
14800 reg_class_t ret = ALL_REGS;
14801 enum insn_code icode;
14802 bool default_p = false;
14804 sri->icode = CODE_FOR_nothing;
14806 /* Convert vector loads and stores into gprs to use an additional base
14808 icode = rs6000_vector_reload[mode][in_p != false];
14809 if (icode != CODE_FOR_nothing)
14812 sri->icode = CODE_FOR_nothing;
14813 sri->extra_cost = 0;
14815 if (GET_CODE (x) == MEM)
14817 rtx addr = XEXP (x, 0);
14819 /* Loads to and stores from gprs can do reg+offset, and wouldn't need
14820 an extra register in that case, but it would need an extra
14821 register if the addressing is reg+reg or (reg+reg)&(-16). */
14822 if (rclass == GENERAL_REGS || rclass == BASE_REGS)
14824 if (!legitimate_indirect_address_p (addr, false)
14825 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
14827 sri->icode = icode;
14828 /* account for splitting the loads, and converting the
14829 address from reg+reg to reg. */
14830 sri->extra_cost = (((TARGET_64BIT) ? 3 : 5)
14831 + ((GET_CODE (addr) == AND) ? 1 : 0));
14834 /* Loads to and stores from vector registers can only do reg+reg
14835 addressing. Altivec registers can also do (reg+reg)&(-16). */
14836 else if (rclass == VSX_REGS || rclass == ALTIVEC_REGS
14837 || rclass == FLOAT_REGS || rclass == NO_REGS)
14839 if (!VECTOR_MEM_ALTIVEC_P (mode)
14840 && GET_CODE (addr) == AND
14841 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14842 && INTVAL (XEXP (addr, 1)) == -16
14843 && (legitimate_indirect_address_p (XEXP (addr, 0), false)
14844 || legitimate_indexed_address_p (XEXP (addr, 0), false)))
14846 sri->icode = icode;
14847 sri->extra_cost = ((GET_CODE (XEXP (addr, 0)) == PLUS)
14850 else if (!legitimate_indirect_address_p (addr, false)
14851 && (rclass == NO_REGS
14852 || !legitimate_indexed_address_p (addr, false)))
14854 sri->icode = icode;
14855 sri->extra_cost = 1;
14858 icode = CODE_FOR_nothing;
14860 /* Any other loads, including to pseudo registers which haven't been
14861 assigned to a register yet, default to require a scratch
14865 sri->icode = icode;
14866 sri->extra_cost = 2;
14869 else if (REG_P (x))
14871 int regno = true_regnum (x);
14873 icode = CODE_FOR_nothing;
14874 if (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)
14878 enum reg_class xclass = REGNO_REG_CLASS (regno);
14879 enum reload_reg_type rtype1 = rs6000_reload_register_type (rclass);
14880 enum reload_reg_type rtype2 = rs6000_reload_register_type (xclass);
14882 /* If memory is needed, use default_secondary_reload to create the
14884 if (rtype1 != rtype2 || rtype1 == OTHER_REGISTER_TYPE)
14893 else if (TARGET_POWERPC64
14894 && rs6000_reload_register_type (rclass) == GPR_REGISTER_TYPE
14896 && GET_MODE_SIZE (GET_MODE (x)) >= UNITS_PER_WORD)
14898 rtx addr = XEXP (x, 0);
14900 if (GET_CODE (addr) == PRE_MODIFY)
14901 addr = XEXP (addr, 1);
14902 else if (GET_CODE (addr) == LO_SUM
14903 && GET_CODE (XEXP (addr, 0)) == REG
14904 && GET_CODE (XEXP (addr, 1)) == CONST)
14905 addr = XEXP (XEXP (addr, 1), 0);
14907 if (GET_CODE (addr) == PLUS
14908 && GET_CODE (XEXP (addr, 1)) == CONST_INT
14909 && (INTVAL (XEXP (addr, 1)) & 3) != 0)
14912 sri->icode = CODE_FOR_reload_di_load;
14914 sri->icode = CODE_FOR_reload_di_store;
14915 sri->extra_cost = 2;
14925 ret = default_secondary_reload (in_p, x, rclass, mode, sri);
14927 gcc_assert (ret != ALL_REGS);
14929 if (TARGET_DEBUG_ADDR)
14932 "\nrs6000_secondary_reload, return %s, in_p = %s, rclass = %s, "
14934 reg_class_names[ret],
14935 in_p ? "true" : "false",
14936 reg_class_names[rclass],
14937 GET_MODE_NAME (mode));
14940 fprintf (stderr, ", default secondary reload");
14942 if (sri->icode != CODE_FOR_nothing)
14943 fprintf (stderr, ", reload func = %s, extra cost = %d\n",
14944 insn_data[sri->icode].name, sri->extra_cost);
14946 fprintf (stderr, "\n");
14954 /* Fixup reload addresses for Altivec or VSX loads/stores to change SP+offset
14955 to SP+reg addressing. */
14958 rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
14960 int regno = true_regnum (reg);
14961 enum machine_mode mode = GET_MODE (reg);
14962 enum reg_class rclass;
14964 rtx and_op2 = NULL_RTX;
14967 rtx scratch_or_premodify = scratch;
14971 if (TARGET_DEBUG_ADDR)
14973 fprintf (stderr, "\nrs6000_secondary_reload_inner, type = %s\n",
14974 store_p ? "store" : "load");
14975 fprintf (stderr, "reg:\n");
14977 fprintf (stderr, "mem:\n");
14979 fprintf (stderr, "scratch:\n");
14980 debug_rtx (scratch);
14983 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
14984 gcc_assert (GET_CODE (mem) == MEM);
14985 rclass = REGNO_REG_CLASS (regno);
14986 addr = XEXP (mem, 0);
14990 /* GPRs can handle reg + small constant, all other addresses need to use
14991 the scratch register. */
14994 if (GET_CODE (addr) == AND)
14996 and_op2 = XEXP (addr, 1);
14997 addr = XEXP (addr, 0);
15000 if (GET_CODE (addr) == PRE_MODIFY)
15002 scratch_or_premodify = XEXP (addr, 0);
15003 gcc_assert (REG_P (scratch_or_premodify));
15004 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15005 addr = XEXP (addr, 1);
15008 if (GET_CODE (addr) == PLUS
15009 && (!rs6000_legitimate_offset_address_p (TImode, addr, false)
15010 || and_op2 != NULL_RTX))
15012 addr_op1 = XEXP (addr, 0);
15013 addr_op2 = XEXP (addr, 1);
15014 gcc_assert (legitimate_indirect_address_p (addr_op1, false));
15016 if (!REG_P (addr_op2)
15017 && (GET_CODE (addr_op2) != CONST_INT
15018 || !satisfies_constraint_I (addr_op2)))
15020 if (TARGET_DEBUG_ADDR)
15023 "\nMove plus addr to register %s, mode = %s: ",
15024 rs6000_reg_names[REGNO (scratch)],
15025 GET_MODE_NAME (mode));
15026 debug_rtx (addr_op2);
15028 rs6000_emit_move (scratch, addr_op2, Pmode);
15029 addr_op2 = scratch;
15032 emit_insn (gen_rtx_SET (VOIDmode,
15033 scratch_or_premodify,
15034 gen_rtx_PLUS (Pmode,
15038 addr = scratch_or_premodify;
15039 scratch_or_premodify = scratch;
15041 else if (!legitimate_indirect_address_p (addr, false)
15042 && !rs6000_legitimate_offset_address_p (TImode, addr, false))
15044 if (TARGET_DEBUG_ADDR)
15046 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15047 rs6000_reg_names[REGNO (scratch_or_premodify)],
15048 GET_MODE_NAME (mode));
15051 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15052 addr = scratch_or_premodify;
15053 scratch_or_premodify = scratch;
15057 /* Float/Altivec registers can only handle reg+reg addressing. Move
15058 other addresses into a scratch register. */
15063 /* With float regs, we need to handle the AND ourselves, since we can't
15064 use the Altivec instruction with an implicit AND -16. Allow scalar
15065 loads to float registers to use reg+offset even if VSX. */
15066 if (GET_CODE (addr) == AND
15067 && (rclass != ALTIVEC_REGS || GET_MODE_SIZE (mode) != 16
15068 || GET_CODE (XEXP (addr, 1)) != CONST_INT
15069 || INTVAL (XEXP (addr, 1)) != -16
15070 || !VECTOR_MEM_ALTIVEC_P (mode)))
15072 and_op2 = XEXP (addr, 1);
15073 addr = XEXP (addr, 0);
15076 /* If we aren't using a VSX load, save the PRE_MODIFY register and use it
15077 as the address later. */
15078 if (GET_CODE (addr) == PRE_MODIFY
15079 && (!VECTOR_MEM_VSX_P (mode)
15080 || and_op2 != NULL_RTX
15081 || !legitimate_indexed_address_p (XEXP (addr, 1), false)))
15083 scratch_or_premodify = XEXP (addr, 0);
15084 gcc_assert (legitimate_indirect_address_p (scratch_or_premodify,
15086 gcc_assert (GET_CODE (XEXP (addr, 1)) == PLUS);
15087 addr = XEXP (addr, 1);
15090 if (legitimate_indirect_address_p (addr, false) /* reg */
15091 || legitimate_indexed_address_p (addr, false) /* reg+reg */
15092 || GET_CODE (addr) == PRE_MODIFY /* VSX pre-modify */
15093 || (GET_CODE (addr) == AND /* Altivec memory */
15094 && GET_CODE (XEXP (addr, 1)) == CONST_INT
15095 && INTVAL (XEXP (addr, 1)) == -16
15096 && VECTOR_MEM_ALTIVEC_P (mode))
15097 || (rclass == FLOAT_REGS /* legacy float mem */
15098 && GET_MODE_SIZE (mode) == 8
15099 && and_op2 == NULL_RTX
15100 && scratch_or_premodify == scratch
15101 && rs6000_legitimate_offset_address_p (mode, addr, false)))
15104 else if (GET_CODE (addr) == PLUS)
15106 addr_op1 = XEXP (addr, 0);
15107 addr_op2 = XEXP (addr, 1);
15108 gcc_assert (REG_P (addr_op1));
15110 if (TARGET_DEBUG_ADDR)
15112 fprintf (stderr, "\nMove plus addr to register %s, mode = %s: ",
15113 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15114 debug_rtx (addr_op2);
15116 rs6000_emit_move (scratch, addr_op2, Pmode);
15117 emit_insn (gen_rtx_SET (VOIDmode,
15118 scratch_or_premodify,
15119 gen_rtx_PLUS (Pmode,
15122 addr = scratch_or_premodify;
15123 scratch_or_premodify = scratch;
15126 else if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == CONST
15127 || GET_CODE (addr) == CONST_INT || REG_P (addr))
15129 if (TARGET_DEBUG_ADDR)
15131 fprintf (stderr, "\nMove addr to register %s, mode = %s: ",
15132 rs6000_reg_names[REGNO (scratch_or_premodify)],
15133 GET_MODE_NAME (mode));
15137 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15138 addr = scratch_or_premodify;
15139 scratch_or_premodify = scratch;
15143 gcc_unreachable ();
15148 gcc_unreachable ();
15151 /* If the original address involved a pre-modify that we couldn't use the VSX
15152 memory instruction with update, and we haven't taken care of already,
15153 store the address in the pre-modify register and use that as the
15155 if (scratch_or_premodify != scratch && scratch_or_premodify != addr)
15157 emit_insn (gen_rtx_SET (VOIDmode, scratch_or_premodify, addr));
15158 addr = scratch_or_premodify;
15161 /* If the original address involved an AND -16 and we couldn't use an ALTIVEC
15162 memory instruction, recreate the AND now, including the clobber which is
15163 generated by the general ANDSI3/ANDDI3 patterns for the
15164 andi. instruction. */
15165 if (and_op2 != NULL_RTX)
15167 if (! legitimate_indirect_address_p (addr, false))
15169 emit_insn (gen_rtx_SET (VOIDmode, scratch, addr));
15173 if (TARGET_DEBUG_ADDR)
15175 fprintf (stderr, "\nAnd addr to register %s, mode = %s: ",
15176 rs6000_reg_names[REGNO (scratch)], GET_MODE_NAME (mode));
15177 debug_rtx (and_op2);
15180 and_rtx = gen_rtx_SET (VOIDmode,
15182 gen_rtx_AND (Pmode,
15186 cc_clobber = gen_rtx_CLOBBER (CCmode, gen_rtx_SCRATCH (CCmode));
15187 emit_insn (gen_rtx_PARALLEL (VOIDmode,
15188 gen_rtvec (2, and_rtx, cc_clobber)));
15192 /* Adjust the address if it changed. */
15193 if (addr != XEXP (mem, 0))
15195 mem = change_address (mem, mode, addr);
15196 if (TARGET_DEBUG_ADDR)
15197 fprintf (stderr, "\nrs6000_secondary_reload_inner, mem adjusted.\n");
15200 /* Now create the move. */
15202 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15204 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15209 /* Convert reloads involving 64-bit gprs and misaligned offset
15210 addressing to use indirect addressing. */
15213 rs6000_secondary_reload_ppc64 (rtx reg, rtx mem, rtx scratch, bool store_p)
15215 int regno = true_regnum (reg);
15216 enum reg_class rclass;
15218 rtx scratch_or_premodify = scratch;
15220 if (TARGET_DEBUG_ADDR)
15222 fprintf (stderr, "\nrs6000_secondary_reload_ppc64, type = %s\n",
15223 store_p ? "store" : "load");
15224 fprintf (stderr, "reg:\n");
15226 fprintf (stderr, "mem:\n");
15228 fprintf (stderr, "scratch:\n");
15229 debug_rtx (scratch);
15232 gcc_assert (regno >= 0 && regno < FIRST_PSEUDO_REGISTER);
15233 gcc_assert (GET_CODE (mem) == MEM);
15234 rclass = REGNO_REG_CLASS (regno);
15235 gcc_assert (rclass == GENERAL_REGS || rclass == BASE_REGS);
15236 addr = XEXP (mem, 0);
15238 if (GET_CODE (addr) == PRE_MODIFY)
15240 scratch_or_premodify = XEXP (addr, 0);
15241 gcc_assert (REG_P (scratch_or_premodify));
15242 addr = XEXP (addr, 1);
15244 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
15246 rs6000_emit_move (scratch_or_premodify, addr, Pmode);
15248 mem = replace_equiv_address_nv (mem, scratch_or_premodify);
15250 /* Now create the move. */
15252 emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
15254 emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
15259 /* Allocate a 64-bit stack slot to be used for copying SDmode
15260 values through if this function has any SDmode references. */
15263 rs6000_alloc_sdmode_stack_slot (void)
15267 gimple_stmt_iterator gsi;
15269 gcc_assert (cfun->machine->sdmode_stack_slot == NULL_RTX);
15272 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
15274 tree ret = walk_gimple_op (gsi_stmt (gsi), rs6000_check_sdmode, NULL);
15277 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15278 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15284 /* Check for any SDmode parameters of the function. */
15285 for (t = DECL_ARGUMENTS (cfun->decl); t; t = DECL_CHAIN (t))
15287 if (TREE_TYPE (t) == error_mark_node)
15290 if (TYPE_MODE (TREE_TYPE (t)) == SDmode
15291 || TYPE_MODE (DECL_ARG_TYPE (t)) == SDmode)
15293 rtx stack = assign_stack_local (DDmode, GET_MODE_SIZE (DDmode), 0);
15294 cfun->machine->sdmode_stack_slot = adjust_address_nv (stack,
15302 rs6000_instantiate_decls (void)
15304 if (cfun->machine->sdmode_stack_slot != NULL_RTX)
15305 instantiate_decl_rtl (cfun->machine->sdmode_stack_slot);
15308 /* Given an rtx X being reloaded into a reg required to be
15309 in class CLASS, return the class of reg to actually use.
15310 In general this is just CLASS; but on some machines
15311 in some cases it is preferable to use a more restrictive class.
15313 On the RS/6000, we have to return NO_REGS when we want to reload a
15314 floating-point CONST_DOUBLE to force it to be copied to memory.
15316 We also don't want to reload integer values into floating-point
15317 registers if we can at all help it. In fact, this can
15318 cause reload to die, if it tries to generate a reload of CTR
15319 into a FP register and discovers it doesn't have the memory location
15322 ??? Would it be a good idea to have reload do the converse, that is
15323 try to reload floating modes into FP registers if possible?
15326 static enum reg_class
15327 rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
15329 enum machine_mode mode = GET_MODE (x);
15331 if (VECTOR_UNIT_VSX_P (mode)
15332 && x == CONST0_RTX (mode) && VSX_REG_CLASS_P (rclass))
15335 if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
15336 && (rclass == ALTIVEC_REGS || rclass == VSX_REGS)
15337 && easy_vector_constant (x, mode))
15338 return ALTIVEC_REGS;
15340 if (CONSTANT_P (x) && reg_classes_intersect_p (rclass, FLOAT_REGS))
15343 if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
15344 return GENERAL_REGS;
15346 /* For VSX, prefer the traditional registers for 64-bit values because we can
15347 use the non-VSX loads. Prefer the Altivec registers if Altivec is
15348 handling the vector operations (i.e. V16QI, V8HI, and V4SI), or if we
15349 prefer Altivec loads.. */
15350 if (rclass == VSX_REGS)
15352 if (GET_MODE_SIZE (mode) <= 8)
15355 if (VECTOR_UNIT_ALTIVEC_P (mode) || VECTOR_MEM_ALTIVEC_P (mode))
15356 return ALTIVEC_REGS;
15364 /* Debug version of rs6000_preferred_reload_class. */
15365 static enum reg_class
15366 rs6000_debug_preferred_reload_class (rtx x, enum reg_class rclass)
15368 enum reg_class ret = rs6000_preferred_reload_class (x, rclass);
15371 "\nrs6000_preferred_reload_class, return %s, rclass = %s, "
15373 reg_class_names[ret], reg_class_names[rclass],
15374 GET_MODE_NAME (GET_MODE (x)));
15380 /* If we are copying between FP or AltiVec registers and anything else, we need
15381 a memory location. The exception is when we are targeting ppc64 and the
15382 move to/from fpr to gpr instructions are available. Also, under VSX, you
15383 can copy vector registers from the FP register set to the Altivec register
15384 set and vice versa. */
15387 rs6000_secondary_memory_needed (enum reg_class class1,
15388 enum reg_class class2,
15389 enum machine_mode mode)
15391 if (class1 == class2)
15394 /* Under VSX, there are 3 register classes that values could be in (VSX_REGS,
15395 ALTIVEC_REGS, and FLOAT_REGS). We don't need to use memory to copy
15396 between these classes. But we need memory for other things that can go in
15397 FLOAT_REGS like SFmode. */
15399 && (VECTOR_MEM_VSX_P (mode) || VECTOR_UNIT_VSX_P (mode))
15400 && (class1 == VSX_REGS || class1 == ALTIVEC_REGS
15401 || class1 == FLOAT_REGS))
15402 return (class2 != VSX_REGS && class2 != ALTIVEC_REGS
15403 && class2 != FLOAT_REGS);
15405 if (class1 == VSX_REGS || class2 == VSX_REGS)
15408 if (class1 == FLOAT_REGS
15409 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15410 || ((mode != DFmode)
15411 && (mode != DDmode)
15412 && (mode != DImode))))
15415 if (class2 == FLOAT_REGS
15416 && (!TARGET_MFPGPR || !TARGET_POWERPC64
15417 || ((mode != DFmode)
15418 && (mode != DDmode)
15419 && (mode != DImode))))
15422 if (class1 == ALTIVEC_REGS || class2 == ALTIVEC_REGS)
15428 /* Debug version of rs6000_secondary_memory_needed. */
15430 rs6000_debug_secondary_memory_needed (enum reg_class class1,
15431 enum reg_class class2,
15432 enum machine_mode mode)
15434 bool ret = rs6000_secondary_memory_needed (class1, class2, mode);
15437 "rs6000_secondary_memory_needed, return: %s, class1 = %s, "
15438 "class2 = %s, mode = %s\n",
15439 ret ? "true" : "false", reg_class_names[class1],
15440 reg_class_names[class2], GET_MODE_NAME (mode));
15445 /* Return the register class of a scratch register needed to copy IN into
15446 or out of a register in RCLASS in MODE. If it can be done directly,
15447 NO_REGS is returned. */
15449 static enum reg_class
15450 rs6000_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
15455 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
15457 && MACHOPIC_INDIRECT
15461 /* We cannot copy a symbolic operand directly into anything
15462 other than BASE_REGS for TARGET_ELF. So indicate that a
15463 register from BASE_REGS is needed as an intermediate
15466 On Darwin, pic addresses require a load from memory, which
15467 needs a base register. */
15468 if (rclass != BASE_REGS
15469 && (GET_CODE (in) == SYMBOL_REF
15470 || GET_CODE (in) == HIGH
15471 || GET_CODE (in) == LABEL_REF
15472 || GET_CODE (in) == CONST))
15476 if (GET_CODE (in) == REG)
15478 regno = REGNO (in);
15479 if (regno >= FIRST_PSEUDO_REGISTER)
15481 regno = true_regnum (in);
15482 if (regno >= FIRST_PSEUDO_REGISTER)
15486 else if (GET_CODE (in) == SUBREG)
15488 regno = true_regnum (in);
15489 if (regno >= FIRST_PSEUDO_REGISTER)
15495 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
15497 if (rclass == GENERAL_REGS || rclass == BASE_REGS
15498 || (regno >= 0 && INT_REGNO_P (regno)))
15501 /* Constants, memory, and FP registers can go into FP registers. */
15502 if ((regno == -1 || FP_REGNO_P (regno))
15503 && (rclass == FLOAT_REGS || rclass == NON_SPECIAL_REGS))
15504 return (mode != SDmode) ? NO_REGS : GENERAL_REGS;
15506 /* Memory, and FP/altivec registers can go into fp/altivec registers under
15509 && (regno == -1 || VSX_REGNO_P (regno))
15510 && VSX_REG_CLASS_P (rclass))
15513 /* Memory, and AltiVec registers can go into AltiVec registers. */
15514 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
15515 && rclass == ALTIVEC_REGS)
15518 /* We can copy among the CR registers. */
15519 if ((rclass == CR_REGS || rclass == CR0_REGS)
15520 && regno >= 0 && CR_REGNO_P (regno))
15523 /* Otherwise, we need GENERAL_REGS. */
15524 return GENERAL_REGS;
15527 /* Debug version of rs6000_secondary_reload_class. */
15528 static enum reg_class
15529 rs6000_debug_secondary_reload_class (enum reg_class rclass,
15530 enum machine_mode mode, rtx in)
15532 enum reg_class ret = rs6000_secondary_reload_class (rclass, mode, in);
15534 "\nrs6000_secondary_reload_class, return %s, rclass = %s, "
15535 "mode = %s, input rtx:\n",
15536 reg_class_names[ret], reg_class_names[rclass],
15537 GET_MODE_NAME (mode));
15543 /* Return nonzero if for CLASS a mode change from FROM to TO is invalid. */
15546 rs6000_cannot_change_mode_class (enum machine_mode from,
15547 enum machine_mode to,
15548 enum reg_class rclass)
15550 unsigned from_size = GET_MODE_SIZE (from);
15551 unsigned to_size = GET_MODE_SIZE (to);
15553 if (from_size != to_size)
15555 enum reg_class xclass = (TARGET_VSX) ? VSX_REGS : FLOAT_REGS;
15556 return ((from_size < 8 || to_size < 8 || TARGET_IEEEQUAD)
15557 && reg_classes_intersect_p (xclass, rclass));
15560 if (TARGET_E500_DOUBLE
15561 && ((((to) == DFmode) + ((from) == DFmode)) == 1
15562 || (((to) == TFmode) + ((from) == TFmode)) == 1
15563 || (((to) == DDmode) + ((from) == DDmode)) == 1
15564 || (((to) == TDmode) + ((from) == TDmode)) == 1
15565 || (((to) == DImode) + ((from) == DImode)) == 1))
15568 /* Since the VSX register set includes traditional floating point registers
15569 and altivec registers, just check for the size being different instead of
15570 trying to check whether the modes are vector modes. Otherwise it won't
15571 allow say DF and DI to change classes. */
15572 if (TARGET_VSX && VSX_REG_CLASS_P (rclass))
15573 return (from_size != 8 && from_size != 16);
15575 if (TARGET_ALTIVEC && rclass == ALTIVEC_REGS
15576 && (ALTIVEC_VECTOR_MODE (from) + ALTIVEC_VECTOR_MODE (to)) == 1)
15579 if (TARGET_SPE && (SPE_VECTOR_MODE (from) + SPE_VECTOR_MODE (to)) == 1
15580 && reg_classes_intersect_p (GENERAL_REGS, rclass))
15586 /* Debug version of rs6000_cannot_change_mode_class. */
15588 rs6000_debug_cannot_change_mode_class (enum machine_mode from,
15589 enum machine_mode to,
15590 enum reg_class rclass)
15592 bool ret = rs6000_cannot_change_mode_class (from, to, rclass);
15595 "rs6000_cannot_change_mode_class, return %s, from = %s, "
15596 "to = %s, rclass = %s\n",
15597 ret ? "true" : "false",
15598 GET_MODE_NAME (from), GET_MODE_NAME (to),
15599 reg_class_names[rclass]);
15604 /* Given a comparison operation, return the bit number in CCR to test. We
15605 know this is a valid comparison.
15607 SCC_P is 1 if this is for an scc. That means that %D will have been
15608 used instead of %C, so the bits will be in different places.
15610 Return -1 if OP isn't a valid comparison for some reason. */
15613 ccr_bit (rtx op, int scc_p)
15615 enum rtx_code code = GET_CODE (op);
15616 enum machine_mode cc_mode;
15621 if (!COMPARISON_P (op))
15624 reg = XEXP (op, 0);
15626 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
15628 cc_mode = GET_MODE (reg);
15629 cc_regnum = REGNO (reg);
15630 base_bit = 4 * (cc_regnum - CR0_REGNO);
15632 validate_condition_mode (code, cc_mode);
15634 /* When generating a sCOND operation, only positive conditions are
15637 || code == EQ || code == GT || code == LT || code == UNORDERED
15638 || code == GTU || code == LTU);
15643 return scc_p ? base_bit + 3 : base_bit + 2;
15645 return base_bit + 2;
15646 case GT: case GTU: case UNLE:
15647 return base_bit + 1;
15648 case LT: case LTU: case UNGE:
15650 case ORDERED: case UNORDERED:
15651 return base_bit + 3;
15654 /* If scc, we will have done a cror to put the bit in the
15655 unordered position. So test that bit. For integer, this is ! LT
15656 unless this is an scc insn. */
15657 return scc_p ? base_bit + 3 : base_bit;
15660 return scc_p ? base_bit + 3 : base_bit + 1;
15663 gcc_unreachable ();
15667 /* Return the GOT register. */
15670 rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
15672 /* The second flow pass currently (June 1999) can't update
15673 regs_ever_live without disturbing other parts of the compiler, so
15674 update it here to make the prolog/epilogue code happy. */
15675 if (!can_create_pseudo_p ()
15676 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
15677 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
15679 crtl->uses_pic_offset_table = 1;
15681 return pic_offset_table_rtx;
15684 static rs6000_stack_t stack_info;
15686 /* Function to init struct machine_function.
15687 This will be called, via a pointer variable,
15688 from push_function_context. */
15690 static struct machine_function *
15691 rs6000_init_machine_status (void)
15693 stack_info.reload_completed = 0;
15694 return ggc_alloc_cleared_machine_function ();
15697 /* These macros test for integers and extract the low-order bits. */
15699 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
15700 && GET_MODE (X) == VOIDmode)
15702 #define INT_LOWPART(X) \
15703 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
15706 extract_MB (rtx op)
15709 unsigned long val = INT_LOWPART (op);
15711 /* If the high bit is zero, the value is the first 1 bit we find
15713 if ((val & 0x80000000) == 0)
15715 gcc_assert (val & 0xffffffff);
15718 while (((val <<= 1) & 0x80000000) == 0)
15723 /* If the high bit is set and the low bit is not, or the mask is all
15724 1's, the value is zero. */
15725 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
15728 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15731 while (((val >>= 1) & 1) != 0)
15738 extract_ME (rtx op)
15741 unsigned long val = INT_LOWPART (op);
15743 /* If the low bit is zero, the value is the first 1 bit we find from
15745 if ((val & 1) == 0)
15747 gcc_assert (val & 0xffffffff);
15750 while (((val >>= 1) & 1) == 0)
15756 /* If the low bit is set and the high bit is not, or the mask is all
15757 1's, the value is 31. */
15758 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
15761 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
15764 while (((val <<= 1) & 0x80000000) != 0)
15770 /* Locate some local-dynamic symbol still in use by this function
15771 so that we can print its name in some tls_ld pattern. */
15773 static const char *
15774 rs6000_get_some_local_dynamic_name (void)
15778 if (cfun->machine->some_ld_name)
15779 return cfun->machine->some_ld_name;
15781 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
15783 && for_each_rtx (&PATTERN (insn),
15784 rs6000_get_some_local_dynamic_name_1, 0))
15785 return cfun->machine->some_ld_name;
15787 gcc_unreachable ();
15790 /* Helper function for rs6000_get_some_local_dynamic_name. */
15793 rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
15797 if (GET_CODE (x) == SYMBOL_REF)
15799 const char *str = XSTR (x, 0);
15800 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
15802 cfun->machine->some_ld_name = str;
15810 /* Write out a function code label. */
15813 rs6000_output_function_entry (FILE *file, const char *fname)
15815 if (fname[0] != '.')
15817 switch (DEFAULT_ABI)
15820 gcc_unreachable ();
15826 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
15835 RS6000_OUTPUT_BASENAME (file, fname);
15838 /* Print an operand. Recognize special options, documented below. */
15841 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
15842 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
15844 #define SMALL_DATA_RELOC "sda21"
15845 #define SMALL_DATA_REG 0
15849 print_operand (FILE *file, rtx x, int code)
15853 unsigned HOST_WIDE_INT uval;
15858 /* Write out an instruction after the call which may be replaced
15859 with glue code by the loader. This depends on the AIX version. */
15860 asm_fprintf (file, RS6000_CALL_GLUE);
15863 /* %a is output_address. */
15866 /* If X is a constant integer whose low-order 5 bits are zero,
15867 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
15868 in the AIX assembler where "sri" with a zero shift count
15869 writes a trash instruction. */
15870 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
15877 /* If constant, low-order 16 bits of constant, unsigned.
15878 Otherwise, write normally. */
15880 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
15882 print_operand (file, x, 0);
15886 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
15887 for 64-bit mask direction. */
15888 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
15891 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
15895 /* X is a CR register. Print the number of the GT bit of the CR. */
15896 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15897 output_operand_lossage ("invalid %%c value");
15899 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
15903 /* Like 'J' but get to the GT bit only. */
15904 gcc_assert (GET_CODE (x) == REG);
15906 /* Bit 1 is GT bit. */
15907 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
15909 /* Add one for shift count in rlinm for scc. */
15910 fprintf (file, "%d", i + 1);
15914 /* X is a CR register. Print the number of the EQ bit of the CR */
15915 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15916 output_operand_lossage ("invalid %%E value");
15918 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
15922 /* X is a CR register. Print the shift count needed to move it
15923 to the high-order four bits. */
15924 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15925 output_operand_lossage ("invalid %%f value");
15927 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
15931 /* Similar, but print the count for the rotate in the opposite
15933 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
15934 output_operand_lossage ("invalid %%F value");
15936 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
15940 /* X is a constant integer. If it is negative, print "m",
15941 otherwise print "z". This is to make an aze or ame insn. */
15942 if (GET_CODE (x) != CONST_INT)
15943 output_operand_lossage ("invalid %%G value");
15944 else if (INTVAL (x) >= 0)
15951 /* If constant, output low-order five bits. Otherwise, write
15954 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
15956 print_operand (file, x, 0);
15960 /* If constant, output low-order six bits. Otherwise, write
15963 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
15965 print_operand (file, x, 0);
15969 /* Print `i' if this is a constant, else nothing. */
15975 /* Write the bit number in CCR for jump. */
15976 i = ccr_bit (x, 0);
15978 output_operand_lossage ("invalid %%j code");
15980 fprintf (file, "%d", i);
15984 /* Similar, but add one for shift count in rlinm for scc and pass
15985 scc flag to `ccr_bit'. */
15986 i = ccr_bit (x, 1);
15988 output_operand_lossage ("invalid %%J code");
15990 /* If we want bit 31, write a shift count of zero, not 32. */
15991 fprintf (file, "%d", i == 31 ? 0 : i + 1);
15995 /* X must be a constant. Write the 1's complement of the
15998 output_operand_lossage ("invalid %%k value");
16000 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
16004 /* X must be a symbolic constant on ELF. Write an
16005 expression suitable for an 'addi' that adds in the low 16
16006 bits of the MEM. */
16007 if (GET_CODE (x) == CONST)
16009 if (GET_CODE (XEXP (x, 0)) != PLUS
16010 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
16011 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
16012 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
16013 output_operand_lossage ("invalid %%K value");
16015 print_operand_address (file, x);
16016 fputs ("@l", file);
16019 /* %l is output_asm_label. */
16022 /* Write second word of DImode or DFmode reference. Works on register
16023 or non-indexed memory only. */
16024 if (GET_CODE (x) == REG)
16025 fputs (reg_names[REGNO (x) + 1], file);
16026 else if (GET_CODE (x) == MEM)
16028 /* Handle possible auto-increment. Since it is pre-increment and
16029 we have already done it, we can just use an offset of word. */
16030 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16031 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16032 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16034 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16035 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
16038 output_address (XEXP (adjust_address_nv (x, SImode,
16042 if (small_data_operand (x, GET_MODE (x)))
16043 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16044 reg_names[SMALL_DATA_REG]);
16049 /* MB value for a mask operand. */
16050 if (! mask_operand (x, SImode))
16051 output_operand_lossage ("invalid %%m value");
16053 fprintf (file, "%d", extract_MB (x));
16057 /* ME value for a mask operand. */
16058 if (! mask_operand (x, SImode))
16059 output_operand_lossage ("invalid %%M value");
16061 fprintf (file, "%d", extract_ME (x));
16064 /* %n outputs the negative of its operand. */
16067 /* Write the number of elements in the vector times 4. */
16068 if (GET_CODE (x) != PARALLEL)
16069 output_operand_lossage ("invalid %%N value");
16071 fprintf (file, "%d", XVECLEN (x, 0) * 4);
16075 /* Similar, but subtract 1 first. */
16076 if (GET_CODE (x) != PARALLEL)
16077 output_operand_lossage ("invalid %%O value");
16079 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
16083 /* X is a CONST_INT that is a power of two. Output the logarithm. */
16085 || INT_LOWPART (x) < 0
16086 || (i = exact_log2 (INT_LOWPART (x))) < 0)
16087 output_operand_lossage ("invalid %%p value");
16089 fprintf (file, "%d", i);
16093 /* The operand must be an indirect memory reference. The result
16094 is the register name. */
16095 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
16096 || REGNO (XEXP (x, 0)) >= 32)
16097 output_operand_lossage ("invalid %%P value");
16099 fputs (reg_names[REGNO (XEXP (x, 0))], file);
16103 /* This outputs the logical code corresponding to a boolean
16104 expression. The expression may have one or both operands
16105 negated (if one, only the first one). For condition register
16106 logical operations, it will also treat the negated
16107 CR codes as NOTs, but not handle NOTs of them. */
16109 const char *const *t = 0;
16111 enum rtx_code code = GET_CODE (x);
16112 static const char * const tbl[3][3] = {
16113 { "and", "andc", "nor" },
16114 { "or", "orc", "nand" },
16115 { "xor", "eqv", "xor" } };
16119 else if (code == IOR)
16121 else if (code == XOR)
16124 output_operand_lossage ("invalid %%q value");
16126 if (GET_CODE (XEXP (x, 0)) != NOT)
16130 if (GET_CODE (XEXP (x, 1)) == NOT)
16148 /* X is a CR register. Print the mask for `mtcrf'. */
16149 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
16150 output_operand_lossage ("invalid %%R value");
16152 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
16156 /* Low 5 bits of 32 - value */
16158 output_operand_lossage ("invalid %%s value");
16160 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
16164 /* PowerPC64 mask position. All 0's is excluded.
16165 CONST_INT 32-bit mask is considered sign-extended so any
16166 transition must occur within the CONST_INT, not on the boundary. */
16167 if (! mask64_operand (x, DImode))
16168 output_operand_lossage ("invalid %%S value");
16170 uval = INT_LOWPART (x);
16172 if (uval & 1) /* Clear Left */
16174 #if HOST_BITS_PER_WIDE_INT > 64
16175 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16179 else /* Clear Right */
16182 #if HOST_BITS_PER_WIDE_INT > 64
16183 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
16189 gcc_assert (i >= 0);
16190 fprintf (file, "%d", i);
16194 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
16195 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
16197 /* Bit 3 is OV bit. */
16198 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
16200 /* If we want bit 31, write a shift count of zero, not 32. */
16201 fprintf (file, "%d", i == 31 ? 0 : i + 1);
16205 /* Print the symbolic name of a branch target register. */
16206 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
16207 && REGNO (x) != CTR_REGNO))
16208 output_operand_lossage ("invalid %%T value");
16209 else if (REGNO (x) == LR_REGNO)
16210 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
16212 fputs ("ctr", file);
16216 /* High-order 16 bits of constant for use in unsigned operand. */
16218 output_operand_lossage ("invalid %%u value");
16220 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16221 (INT_LOWPART (x) >> 16) & 0xffff);
16225 /* High-order 16 bits of constant for use in signed operand. */
16227 output_operand_lossage ("invalid %%v value");
16229 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
16230 (INT_LOWPART (x) >> 16) & 0xffff);
16234 /* Print `u' if this has an auto-increment or auto-decrement. */
16235 if (GET_CODE (x) == MEM
16236 && (GET_CODE (XEXP (x, 0)) == PRE_INC
16237 || GET_CODE (XEXP (x, 0)) == PRE_DEC
16238 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
16243 /* Print the trap code for this operand. */
16244 switch (GET_CODE (x))
16247 fputs ("eq", file); /* 4 */
16250 fputs ("ne", file); /* 24 */
16253 fputs ("lt", file); /* 16 */
16256 fputs ("le", file); /* 20 */
16259 fputs ("gt", file); /* 8 */
16262 fputs ("ge", file); /* 12 */
16265 fputs ("llt", file); /* 2 */
16268 fputs ("lle", file); /* 6 */
16271 fputs ("lgt", file); /* 1 */
16274 fputs ("lge", file); /* 5 */
16277 gcc_unreachable ();
16282 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
16285 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
16286 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
16288 print_operand (file, x, 0);
16292 /* MB value for a PowerPC64 rldic operand. */
16293 val = (GET_CODE (x) == CONST_INT
16294 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
16299 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
16300 if ((val <<= 1) < 0)
16303 #if HOST_BITS_PER_WIDE_INT == 32
16304 if (GET_CODE (x) == CONST_INT && i >= 0)
16305 i += 32; /* zero-extend high-part was all 0's */
16306 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
16308 val = CONST_DOUBLE_LOW (x);
16314 for ( ; i < 64; i++)
16315 if ((val <<= 1) < 0)
16320 fprintf (file, "%d", i + 1);
16324 /* X is a FPR or Altivec register used in a VSX context. */
16325 if (GET_CODE (x) != REG || !VSX_REGNO_P (REGNO (x)))
16326 output_operand_lossage ("invalid %%x value");
16329 int reg = REGNO (x);
16330 int vsx_reg = (FP_REGNO_P (reg)
16332 : reg - FIRST_ALTIVEC_REGNO + 32);
16334 #ifdef TARGET_REGNAMES
16335 if (TARGET_REGNAMES)
16336 fprintf (file, "%%vs%d", vsx_reg);
16339 fprintf (file, "%d", vsx_reg);
16344 if (GET_CODE (x) == MEM
16345 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
16346 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
16347 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
16352 /* Like 'L', for third word of TImode */
16353 if (GET_CODE (x) == REG)
16354 fputs (reg_names[REGNO (x) + 2], file);
16355 else if (GET_CODE (x) == MEM)
16357 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16358 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16359 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16360 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16361 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
16363 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
16364 if (small_data_operand (x, GET_MODE (x)))
16365 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16366 reg_names[SMALL_DATA_REG]);
16371 /* X is a SYMBOL_REF. Write out the name preceded by a
16372 period and without any trailing data in brackets. Used for function
16373 names. If we are configured for System V (or the embedded ABI) on
16374 the PowerPC, do not emit the period, since those systems do not use
16375 TOCs and the like. */
16376 gcc_assert (GET_CODE (x) == SYMBOL_REF);
16378 /* Mark the decl as referenced so that cgraph will output the
16380 if (SYMBOL_REF_DECL (x))
16381 mark_decl_referenced (SYMBOL_REF_DECL (x));
16383 /* For macho, check to see if we need a stub. */
16386 const char *name = XSTR (x, 0);
16388 if (darwin_emit_branch_islands
16389 && MACHOPIC_INDIRECT
16390 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
16391 name = machopic_indirection_name (x, /*stub_p=*/true);
16393 assemble_name (file, name);
16395 else if (!DOT_SYMBOLS)
16396 assemble_name (file, XSTR (x, 0));
16398 rs6000_output_function_entry (file, XSTR (x, 0));
16402 /* Like 'L', for last word of TImode. */
16403 if (GET_CODE (x) == REG)
16404 fputs (reg_names[REGNO (x) + 3], file);
16405 else if (GET_CODE (x) == MEM)
16407 if (GET_CODE (XEXP (x, 0)) == PRE_INC
16408 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
16409 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16410 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16411 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
16413 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
16414 if (small_data_operand (x, GET_MODE (x)))
16415 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16416 reg_names[SMALL_DATA_REG]);
16420 /* Print AltiVec or SPE memory operand. */
16425 gcc_assert (GET_CODE (x) == MEM);
16429 /* Ugly hack because %y is overloaded. */
16430 if ((TARGET_SPE || TARGET_E500_DOUBLE)
16431 && (GET_MODE_SIZE (GET_MODE (x)) == 8
16432 || GET_MODE (x) == TFmode
16433 || GET_MODE (x) == TImode))
16435 /* Handle [reg]. */
16436 if (GET_CODE (tmp) == REG)
16438 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
16441 /* Handle [reg+UIMM]. */
16442 else if (GET_CODE (tmp) == PLUS &&
16443 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
16447 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
16449 x = INTVAL (XEXP (tmp, 1));
16450 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
16454 /* Fall through. Must be [reg+reg]. */
16456 if (VECTOR_MEM_ALTIVEC_P (GET_MODE (x))
16457 && GET_CODE (tmp) == AND
16458 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
16459 && INTVAL (XEXP (tmp, 1)) == -16)
16460 tmp = XEXP (tmp, 0);
16461 else if (VECTOR_MEM_VSX_P (GET_MODE (x))
16462 && GET_CODE (tmp) == PRE_MODIFY)
16463 tmp = XEXP (tmp, 1);
16464 if (GET_CODE (tmp) == REG)
16465 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
16468 if (!GET_CODE (tmp) == PLUS
16469 || !REG_P (XEXP (tmp, 0))
16470 || !REG_P (XEXP (tmp, 1)))
16472 output_operand_lossage ("invalid %%y value, try using the 'Z' constraint");
16476 if (REGNO (XEXP (tmp, 0)) == 0)
16477 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
16478 reg_names[ REGNO (XEXP (tmp, 0)) ]);
16480 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
16481 reg_names[ REGNO (XEXP (tmp, 1)) ]);
16487 if (GET_CODE (x) == REG)
16488 fprintf (file, "%s", reg_names[REGNO (x)]);
16489 else if (GET_CODE (x) == MEM)
16491 /* We need to handle PRE_INC and PRE_DEC here, since we need to
16492 know the width from the mode. */
16493 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
16494 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
16495 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16496 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
16497 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
16498 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
16499 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
16500 output_address (XEXP (XEXP (x, 0), 1));
16502 output_address (XEXP (x, 0));
16506 if (toc_relative_expr_p (x))
16507 /* This hack along with a corresponding hack in
16508 rs6000_output_addr_const_extra arranges to output addends
16509 where the assembler expects to find them. eg.
16510 (const (plus (unspec [symbol_ref ("x") tocrel]) 4))
16511 without this hack would be output as "x@toc+4". We
16513 output_addr_const (file, tocrel_base);
16515 output_addr_const (file, x);
16520 assemble_name (file, rs6000_get_some_local_dynamic_name ());
16524 output_operand_lossage ("invalid %%xn code");
16528 /* Print the address of an operand. */
16531 print_operand_address (FILE *file, rtx x)
16533 if (GET_CODE (x) == REG)
16534 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
16535 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
16536 || GET_CODE (x) == LABEL_REF)
16538 output_addr_const (file, x);
16539 if (small_data_operand (x, GET_MODE (x)))
16540 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
16541 reg_names[SMALL_DATA_REG]);
16543 gcc_assert (!TARGET_TOC);
16545 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
16547 gcc_assert (REG_P (XEXP (x, 0)));
16548 if (REGNO (XEXP (x, 0)) == 0)
16549 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
16550 reg_names[ REGNO (XEXP (x, 0)) ]);
16552 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
16553 reg_names[ REGNO (XEXP (x, 1)) ]);
16555 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
16556 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
16557 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
16559 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16560 && CONSTANT_P (XEXP (x, 1)))
16562 fprintf (file, "lo16(");
16563 output_addr_const (file, XEXP (x, 1));
16564 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16567 else if (legitimate_constant_pool_address_p (x, QImode, true))
16569 /* This hack along with a corresponding hack in
16570 rs6000_output_addr_const_extra arranges to output addends
16571 where the assembler expects to find them. eg.
16573 . (const (plus (unspec [symbol_ref ("x") tocrel]) 8)))
16574 without this hack would be output as "x@toc+8@l(9)". We
16575 want "x+8@toc@l(9)". */
16576 output_addr_const (file, tocrel_base);
16577 if (GET_CODE (x) == LO_SUM)
16578 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16580 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
16583 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
16584 && CONSTANT_P (XEXP (x, 1)))
16586 output_addr_const (file, XEXP (x, 1));
16587 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
16591 gcc_unreachable ();
16594 /* Implement TARGET_OUTPUT_ADDR_CONST_EXTRA. */
16597 rs6000_output_addr_const_extra (FILE *file, rtx x)
16599 if (GET_CODE (x) == UNSPEC)
16600 switch (XINT (x, 1))
16602 case UNSPEC_TOCREL:
16603 gcc_assert (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF);
16604 output_addr_const (file, XVECEXP (x, 0, 0));
16605 if (x == tocrel_base && tocrel_offset != const0_rtx)
16607 if (INTVAL (tocrel_offset) >= 0)
16608 fprintf (file, "+");
16609 output_addr_const (file, tocrel_offset);
16611 if (!TARGET_AIX || (TARGET_ELF && TARGET_MINIMAL_TOC))
16614 assemble_name (file, toc_label_name);
16616 else if (TARGET_ELF)
16617 fputs ("@toc", file);
16621 case UNSPEC_MACHOPIC_OFFSET:
16622 output_addr_const (file, XVECEXP (x, 0, 0));
16624 machopic_output_function_base_name (file);
16631 /* Target hook for assembling integer objects. The PowerPC version has
16632 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
16633 is defined. It also needs to handle DI-mode objects on 64-bit
16637 rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
16639 #ifdef RELOCATABLE_NEEDS_FIXUP
16640 /* Special handling for SI values. */
16641 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
16643 static int recurse = 0;
16645 /* For -mrelocatable, we mark all addresses that need to be fixed up
16646 in the .fixup section. */
16647 if (TARGET_RELOCATABLE
16648 && in_section != toc_section
16649 && in_section != text_section
16650 && !unlikely_text_section_p (in_section)
16652 && GET_CODE (x) != CONST_INT
16653 && GET_CODE (x) != CONST_DOUBLE
16659 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
16661 ASM_OUTPUT_LABEL (asm_out_file, buf);
16662 fprintf (asm_out_file, "\t.long\t(");
16663 output_addr_const (asm_out_file, x);
16664 fprintf (asm_out_file, ")@fixup\n");
16665 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
16666 ASM_OUTPUT_ALIGN (asm_out_file, 2);
16667 fprintf (asm_out_file, "\t.long\t");
16668 assemble_name (asm_out_file, buf);
16669 fprintf (asm_out_file, "\n\t.previous\n");
16673 /* Remove initial .'s to turn a -mcall-aixdesc function
16674 address into the address of the descriptor, not the function
16676 else if (GET_CODE (x) == SYMBOL_REF
16677 && XSTR (x, 0)[0] == '.'
16678 && DEFAULT_ABI == ABI_AIX)
16680 const char *name = XSTR (x, 0);
16681 while (*name == '.')
16684 fprintf (asm_out_file, "\t.long\t%s\n", name);
16688 #endif /* RELOCATABLE_NEEDS_FIXUP */
16689 return default_assemble_integer (x, size, aligned_p);
16692 #ifdef HAVE_GAS_HIDDEN
16693 /* Emit an assembler directive to set symbol visibility for DECL to
16694 VISIBILITY_TYPE. */
16697 rs6000_assemble_visibility (tree decl, int vis)
16699 /* Functions need to have their entry point symbol visibility set as
16700 well as their descriptor symbol visibility. */
16701 if (DEFAULT_ABI == ABI_AIX
16703 && TREE_CODE (decl) == FUNCTION_DECL)
16705 static const char * const visibility_types[] = {
16706 NULL, "internal", "hidden", "protected"
16709 const char *name, *type;
16711 name = ((* targetm.strip_name_encoding)
16712 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
16713 type = visibility_types[vis];
16715 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
16716 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
16719 default_assemble_visibility (decl, vis);
16724 rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
16726 /* Reversal of FP compares takes care -- an ordered compare
16727 becomes an unordered compare and vice versa. */
16728 if (mode == CCFPmode
16729 && (!flag_finite_math_only
16730 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
16731 || code == UNEQ || code == LTGT))
16732 return reverse_condition_maybe_unordered (code);
16734 return reverse_condition (code);
16737 /* Generate a compare for CODE. Return a brand-new rtx that
16738 represents the result of the compare. */
16741 rs6000_generate_compare (rtx cmp, enum machine_mode mode)
16743 enum machine_mode comp_mode;
16744 rtx compare_result;
16745 enum rtx_code code = GET_CODE (cmp);
16746 rtx op0 = XEXP (cmp, 0);
16747 rtx op1 = XEXP (cmp, 1);
16749 if (FLOAT_MODE_P (mode))
16750 comp_mode = CCFPmode;
16751 else if (code == GTU || code == LTU
16752 || code == GEU || code == LEU)
16753 comp_mode = CCUNSmode;
16754 else if ((code == EQ || code == NE)
16755 && GET_CODE (op0) == SUBREG
16756 && GET_CODE (op1) == SUBREG
16757 && SUBREG_PROMOTED_UNSIGNED_P (op0)
16758 && SUBREG_PROMOTED_UNSIGNED_P (op1))
16759 /* These are unsigned values, perhaps there will be a later
16760 ordering compare that can be shared with this one.
16761 Unfortunately we cannot detect the signedness of the operands
16762 for non-subregs. */
16763 comp_mode = CCUNSmode;
16765 comp_mode = CCmode;
16767 /* First, the compare. */
16768 compare_result = gen_reg_rtx (comp_mode);
16770 /* E500 FP compare instructions on the GPRs. Yuck! */
16771 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
16772 && FLOAT_MODE_P (mode))
16774 rtx cmp, or_result, compare_result2;
16775 enum machine_mode op_mode = GET_MODE (op0);
16777 if (op_mode == VOIDmode)
16778 op_mode = GET_MODE (op1);
16780 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
16781 This explains the following mess. */
16785 case EQ: case UNEQ: case NE: case LTGT:
16789 cmp = (flag_finite_math_only && !flag_trapping_math)
16790 ? gen_tstsfeq_gpr (compare_result, op0, op1)
16791 : gen_cmpsfeq_gpr (compare_result, op0, op1);
16795 cmp = (flag_finite_math_only && !flag_trapping_math)
16796 ? gen_tstdfeq_gpr (compare_result, op0, op1)
16797 : gen_cmpdfeq_gpr (compare_result, op0, op1);
16801 cmp = (flag_finite_math_only && !flag_trapping_math)
16802 ? gen_tsttfeq_gpr (compare_result, op0, op1)
16803 : gen_cmptfeq_gpr (compare_result, op0, op1);
16807 gcc_unreachable ();
16811 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
16815 cmp = (flag_finite_math_only && !flag_trapping_math)
16816 ? gen_tstsfgt_gpr (compare_result, op0, op1)
16817 : gen_cmpsfgt_gpr (compare_result, op0, op1);
16821 cmp = (flag_finite_math_only && !flag_trapping_math)
16822 ? gen_tstdfgt_gpr (compare_result, op0, op1)
16823 : gen_cmpdfgt_gpr (compare_result, op0, op1);
16827 cmp = (flag_finite_math_only && !flag_trapping_math)
16828 ? gen_tsttfgt_gpr (compare_result, op0, op1)
16829 : gen_cmptfgt_gpr (compare_result, op0, op1);
16833 gcc_unreachable ();
16837 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
16841 cmp = (flag_finite_math_only && !flag_trapping_math)
16842 ? gen_tstsflt_gpr (compare_result, op0, op1)
16843 : gen_cmpsflt_gpr (compare_result, op0, op1);
16847 cmp = (flag_finite_math_only && !flag_trapping_math)
16848 ? gen_tstdflt_gpr (compare_result, op0, op1)
16849 : gen_cmpdflt_gpr (compare_result, op0, op1);
16853 cmp = (flag_finite_math_only && !flag_trapping_math)
16854 ? gen_tsttflt_gpr (compare_result, op0, op1)
16855 : gen_cmptflt_gpr (compare_result, op0, op1);
16859 gcc_unreachable ();
16863 gcc_unreachable ();
16866 /* Synthesize LE and GE from LT/GT || EQ. */
16867 if (code == LE || code == GE || code == LEU || code == GEU)
16873 case LE: code = LT; break;
16874 case GE: code = GT; break;
16875 case LEU: code = LT; break;
16876 case GEU: code = GT; break;
16877 default: gcc_unreachable ();
16880 compare_result2 = gen_reg_rtx (CCFPmode);
16886 cmp = (flag_finite_math_only && !flag_trapping_math)
16887 ? gen_tstsfeq_gpr (compare_result2, op0, op1)
16888 : gen_cmpsfeq_gpr (compare_result2, op0, op1);
16892 cmp = (flag_finite_math_only && !flag_trapping_math)
16893 ? gen_tstdfeq_gpr (compare_result2, op0, op1)
16894 : gen_cmpdfeq_gpr (compare_result2, op0, op1);
16898 cmp = (flag_finite_math_only && !flag_trapping_math)
16899 ? gen_tsttfeq_gpr (compare_result2, op0, op1)
16900 : gen_cmptfeq_gpr (compare_result2, op0, op1);
16904 gcc_unreachable ();
16908 /* OR them together. */
16909 or_result = gen_reg_rtx (CCFPmode);
16910 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
16912 compare_result = or_result;
16917 if (code == NE || code == LTGT)
16927 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
16928 CLOBBERs to match cmptf_internal2 pattern. */
16929 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
16930 && GET_MODE (op0) == TFmode
16931 && !TARGET_IEEEQUAD
16932 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
16933 emit_insn (gen_rtx_PARALLEL (VOIDmode,
16935 gen_rtx_SET (VOIDmode,
16937 gen_rtx_COMPARE (comp_mode, op0, op1)),
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 (DFmode)),
16943 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16944 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16945 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
16946 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (Pmode)))));
16947 else if (GET_CODE (op1) == UNSPEC
16948 && XINT (op1, 1) == UNSPEC_SP_TEST)
16950 rtx op1b = XVECEXP (op1, 0, 0);
16951 comp_mode = CCEQmode;
16952 compare_result = gen_reg_rtx (CCEQmode);
16954 emit_insn (gen_stack_protect_testdi (compare_result, op0, op1b));
16956 emit_insn (gen_stack_protect_testsi (compare_result, op0, op1b));
16959 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
16960 gen_rtx_COMPARE (comp_mode, op0, op1)));
16963 /* Some kinds of FP comparisons need an OR operation;
16964 under flag_finite_math_only we don't bother. */
16965 if (FLOAT_MODE_P (mode)
16966 && !flag_finite_math_only
16967 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
16968 && (code == LE || code == GE
16969 || code == UNEQ || code == LTGT
16970 || code == UNGT || code == UNLT))
16972 enum rtx_code or1, or2;
16973 rtx or1_rtx, or2_rtx, compare2_rtx;
16974 rtx or_result = gen_reg_rtx (CCEQmode);
16978 case LE: or1 = LT; or2 = EQ; break;
16979 case GE: or1 = GT; or2 = EQ; break;
16980 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
16981 case LTGT: or1 = LT; or2 = GT; break;
16982 case UNGT: or1 = UNORDERED; or2 = GT; break;
16983 case UNLT: or1 = UNORDERED; or2 = LT; break;
16984 default: gcc_unreachable ();
16986 validate_condition_mode (or1, comp_mode);
16987 validate_condition_mode (or2, comp_mode);
16988 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
16989 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
16990 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
16991 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
16993 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
16995 compare_result = or_result;
16999 validate_condition_mode (code, GET_MODE (compare_result));
17001 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
17005 /* Emit the RTL for an sISEL pattern. */
17008 rs6000_emit_sISEL (enum machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
17010 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
17014 rs6000_emit_sCOND (enum machine_mode mode, rtx operands[])
17017 enum machine_mode op_mode;
17018 enum rtx_code cond_code;
17019 rtx result = operands[0];
17021 if (TARGET_ISEL && (mode == SImode || mode == DImode))
17023 rs6000_emit_sISEL (mode, operands);
17027 condition_rtx = rs6000_generate_compare (operands[1], mode);
17028 cond_code = GET_CODE (condition_rtx);
17030 if (FLOAT_MODE_P (mode)
17031 && !TARGET_FPRS && TARGET_HARD_FLOAT)
17035 PUT_MODE (condition_rtx, SImode);
17036 t = XEXP (condition_rtx, 0);
17038 gcc_assert (cond_code == NE || cond_code == EQ);
17040 if (cond_code == NE)
17041 emit_insn (gen_e500_flip_gt_bit (t, t));
17043 emit_insn (gen_move_from_CR_gt_bit (result, t));
17047 if (cond_code == NE
17048 || cond_code == GE || cond_code == LE
17049 || cond_code == GEU || cond_code == LEU
17050 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
17052 rtx not_result = gen_reg_rtx (CCEQmode);
17053 rtx not_op, rev_cond_rtx;
17054 enum machine_mode cc_mode;
17056 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
17058 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
17059 SImode, XEXP (condition_rtx, 0), const0_rtx);
17060 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
17061 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
17062 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
17065 op_mode = GET_MODE (XEXP (operands[1], 0));
17066 if (op_mode == VOIDmode)
17067 op_mode = GET_MODE (XEXP (operands[1], 1));
17069 if (TARGET_POWERPC64 && (op_mode == DImode || FLOAT_MODE_P (mode)))
17071 PUT_MODE (condition_rtx, DImode);
17072 convert_move (result, condition_rtx, 0);
17076 PUT_MODE (condition_rtx, SImode);
17077 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
17081 /* Emit a branch of kind CODE to location LOC. */
17084 rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
17086 rtx condition_rtx, loc_ref;
17088 condition_rtx = rs6000_generate_compare (operands[0], mode);
17089 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
17090 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
17091 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
17092 loc_ref, pc_rtx)));
17095 /* Return the string to output a conditional branch to LABEL, which is
17096 the operand number of the label, or -1 if the branch is really a
17097 conditional return.
17099 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
17100 condition code register and its mode specifies what kind of
17101 comparison we made.
17103 REVERSED is nonzero if we should reverse the sense of the comparison.
17105 INSN is the insn. */
17108 output_cbranch (rtx op, const char *label, int reversed, rtx insn)
17110 static char string[64];
17111 enum rtx_code code = GET_CODE (op);
17112 rtx cc_reg = XEXP (op, 0);
17113 enum machine_mode mode = GET_MODE (cc_reg);
17114 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
17115 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
17116 int really_reversed = reversed ^ need_longbranch;
17122 validate_condition_mode (code, mode);
17124 /* Work out which way this really branches. We could use
17125 reverse_condition_maybe_unordered here always but this
17126 makes the resulting assembler clearer. */
17127 if (really_reversed)
17129 /* Reversal of FP compares takes care -- an ordered compare
17130 becomes an unordered compare and vice versa. */
17131 if (mode == CCFPmode)
17132 code = reverse_condition_maybe_unordered (code);
17134 code = reverse_condition (code);
17137 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
17139 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
17144 /* Opposite of GT. */
17153 gcc_unreachable ();
17159 /* Not all of these are actually distinct opcodes, but
17160 we distinguish them for clarity of the resulting assembler. */
17161 case NE: case LTGT:
17162 ccode = "ne"; break;
17163 case EQ: case UNEQ:
17164 ccode = "eq"; break;
17166 ccode = "ge"; break;
17167 case GT: case GTU: case UNGT:
17168 ccode = "gt"; break;
17170 ccode = "le"; break;
17171 case LT: case LTU: case UNLT:
17172 ccode = "lt"; break;
17173 case UNORDERED: ccode = "un"; break;
17174 case ORDERED: ccode = "nu"; break;
17175 case UNGE: ccode = "nl"; break;
17176 case UNLE: ccode = "ng"; break;
17178 gcc_unreachable ();
17181 /* Maybe we have a guess as to how likely the branch is.
17182 The old mnemonics don't have a way to specify this information. */
17184 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
17185 if (note != NULL_RTX)
17187 /* PROB is the difference from 50%. */
17188 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
17190 /* Only hint for highly probable/improbable branches on newer
17191 cpus as static prediction overrides processor dynamic
17192 prediction. For older cpus we may as well always hint, but
17193 assume not taken for branches that are very close to 50% as a
17194 mispredicted taken branch is more expensive than a
17195 mispredicted not-taken branch. */
17196 if (rs6000_always_hint
17197 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
17198 && br_prob_note_reliable_p (note)))
17200 if (abs (prob) > REG_BR_PROB_BASE / 20
17201 && ((prob > 0) ^ need_longbranch))
17209 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
17211 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
17213 /* We need to escape any '%' characters in the reg_names string.
17214 Assume they'd only be the first character.... */
17215 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
17217 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
17221 /* If the branch distance was too far, we may have to use an
17222 unconditional branch to go the distance. */
17223 if (need_longbranch)
17224 s += sprintf (s, ",$+8\n\tb %s", label);
17226 s += sprintf (s, ",%s", label);
17232 /* Return the string to flip the GT bit on a CR. */
17234 output_e500_flip_gt_bit (rtx dst, rtx src)
17236 static char string[64];
17239 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
17240 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
17243 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
17244 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
17246 sprintf (string, "crnot %d,%d", a, b);
17250 /* Return insn for VSX or Altivec comparisons. */
17253 rs6000_emit_vector_compare_inner (enum rtx_code code, rtx op0, rtx op1)
17256 enum machine_mode mode = GET_MODE (op0);
17264 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
17270 mask = gen_reg_rtx (mode);
17271 emit_insn (gen_rtx_SET (VOIDmode,
17273 gen_rtx_fmt_ee (code, mode, op0, op1)));
17280 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
17281 DMODE is expected destination mode. This is a recursive function. */
17284 rs6000_emit_vector_compare (enum rtx_code rcode,
17286 enum machine_mode dmode)
17289 bool swap_operands = false;
17290 bool try_again = false;
17292 gcc_assert (VECTOR_UNIT_ALTIVEC_OR_VSX_P (dmode));
17293 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
17295 /* See if the comparison works as is. */
17296 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17304 swap_operands = true;
17309 swap_operands = true;
17317 /* Invert condition and try again.
17318 e.g., A != B becomes ~(A==B). */
17320 enum rtx_code rev_code;
17321 enum insn_code nor_code;
17324 rev_code = reverse_condition_maybe_unordered (rcode);
17325 if (rev_code == UNKNOWN)
17328 nor_code = optab_handler (one_cmpl_optab, dmode);
17329 if (nor_code == CODE_FOR_nothing)
17332 mask2 = rs6000_emit_vector_compare (rev_code, op0, op1, dmode);
17336 mask = gen_reg_rtx (dmode);
17337 emit_insn (GEN_FCN (nor_code) (mask, mask2));
17345 /* Try GT/GTU/LT/LTU OR EQ */
17348 enum insn_code ior_code;
17349 enum rtx_code new_code;
17370 gcc_unreachable ();
17373 ior_code = optab_handler (ior_optab, dmode);
17374 if (ior_code == CODE_FOR_nothing)
17377 c_rtx = rs6000_emit_vector_compare (new_code, op0, op1, dmode);
17381 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1, dmode);
17385 mask = gen_reg_rtx (dmode);
17386 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
17404 mask = rs6000_emit_vector_compare_inner (rcode, op0, op1);
17409 /* You only get two chances. */
17413 /* Emit vector conditional expression. DEST is destination. OP_TRUE and
17414 OP_FALSE are two VEC_COND_EXPR operands. CC_OP0 and CC_OP1 are the two
17415 operands for the relation operation COND. */
17418 rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false,
17419 rtx cond, rtx cc_op0, rtx cc_op1)
17421 enum machine_mode dest_mode = GET_MODE (dest);
17422 enum rtx_code rcode = GET_CODE (cond);
17423 enum machine_mode cc_mode = CCmode;
17427 bool invert_move = false;
17429 if (VECTOR_UNIT_NONE_P (dest_mode))
17434 /* Swap operands if we can, and fall back to doing the operation as
17435 specified, and doing a NOR to invert the test. */
17441 /* Invert condition and try again.
17442 e.g., A = (B != C) ? D : E becomes A = (B == C) ? E : D. */
17443 invert_move = true;
17444 rcode = reverse_condition_maybe_unordered (rcode);
17445 if (rcode == UNKNOWN)
17449 /* Mark unsigned tests with CCUNSmode. */
17454 cc_mode = CCUNSmode;
17461 /* Get the vector mask for the given relational operations. */
17462 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
17470 op_true = op_false;
17474 cond2 = gen_rtx_fmt_ee (NE, cc_mode, mask, const0_rtx);
17475 emit_insn (gen_rtx_SET (VOIDmode,
17477 gen_rtx_IF_THEN_ELSE (dest_mode,
17484 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
17485 operands of the last comparison is nonzero/true, FALSE_COND if it
17486 is zero/false. Return 0 if the hardware has no such operation. */
17489 rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17491 enum rtx_code code = GET_CODE (op);
17492 rtx op0 = XEXP (op, 0);
17493 rtx op1 = XEXP (op, 1);
17494 REAL_VALUE_TYPE c1;
17495 enum machine_mode compare_mode = GET_MODE (op0);
17496 enum machine_mode result_mode = GET_MODE (dest);
17498 bool is_against_zero;
17500 /* These modes should always match. */
17501 if (GET_MODE (op1) != compare_mode
17502 /* In the isel case however, we can use a compare immediate, so
17503 op1 may be a small constant. */
17504 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
17506 if (GET_MODE (true_cond) != result_mode)
17508 if (GET_MODE (false_cond) != result_mode)
17511 /* First, work out if the hardware can do this at all, or
17512 if it's too slow.... */
17513 if (!FLOAT_MODE_P (compare_mode))
17516 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
17519 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
17520 && SCALAR_FLOAT_MODE_P (compare_mode))
17523 is_against_zero = op1 == CONST0_RTX (compare_mode);
17525 /* A floating-point subtract might overflow, underflow, or produce
17526 an inexact result, thus changing the floating-point flags, so it
17527 can't be generated if we care about that. It's safe if one side
17528 of the construct is zero, since then no subtract will be
17530 if (SCALAR_FLOAT_MODE_P (compare_mode)
17531 && flag_trapping_math && ! is_against_zero)
17534 /* Eliminate half of the comparisons by switching operands, this
17535 makes the remaining code simpler. */
17536 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
17537 || code == LTGT || code == LT || code == UNLE)
17539 code = reverse_condition_maybe_unordered (code);
17541 true_cond = false_cond;
17545 /* UNEQ and LTGT take four instructions for a comparison with zero,
17546 it'll probably be faster to use a branch here too. */
17547 if (code == UNEQ && HONOR_NANS (compare_mode))
17550 if (GET_CODE (op1) == CONST_DOUBLE)
17551 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
17553 /* We're going to try to implement comparisons by performing
17554 a subtract, then comparing against zero. Unfortunately,
17555 Inf - Inf is NaN which is not zero, and so if we don't
17556 know that the operand is finite and the comparison
17557 would treat EQ different to UNORDERED, we can't do it. */
17558 if (HONOR_INFINITIES (compare_mode)
17559 && code != GT && code != UNGE
17560 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
17561 /* Constructs of the form (a OP b ? a : b) are safe. */
17562 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
17563 || (! rtx_equal_p (op0, true_cond)
17564 && ! rtx_equal_p (op1, true_cond))))
17567 /* At this point we know we can use fsel. */
17569 /* Reduce the comparison to a comparison against zero. */
17570 if (! is_against_zero)
17572 temp = gen_reg_rtx (compare_mode);
17573 emit_insn (gen_rtx_SET (VOIDmode, temp,
17574 gen_rtx_MINUS (compare_mode, op0, op1)));
17576 op1 = CONST0_RTX (compare_mode);
17579 /* If we don't care about NaNs we can reduce some of the comparisons
17580 down to faster ones. */
17581 if (! HONOR_NANS (compare_mode))
17587 true_cond = false_cond;
17600 /* Now, reduce everything down to a GE. */
17607 temp = gen_reg_rtx (compare_mode);
17608 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17613 temp = gen_reg_rtx (compare_mode);
17614 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
17619 temp = gen_reg_rtx (compare_mode);
17620 emit_insn (gen_rtx_SET (VOIDmode, temp,
17621 gen_rtx_NEG (compare_mode,
17622 gen_rtx_ABS (compare_mode, op0))));
17627 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
17628 temp = gen_reg_rtx (result_mode);
17629 emit_insn (gen_rtx_SET (VOIDmode, temp,
17630 gen_rtx_IF_THEN_ELSE (result_mode,
17631 gen_rtx_GE (VOIDmode,
17633 true_cond, false_cond)));
17634 false_cond = true_cond;
17637 temp = gen_reg_rtx (compare_mode);
17638 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17643 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
17644 temp = gen_reg_rtx (result_mode);
17645 emit_insn (gen_rtx_SET (VOIDmode, temp,
17646 gen_rtx_IF_THEN_ELSE (result_mode,
17647 gen_rtx_GE (VOIDmode,
17649 true_cond, false_cond)));
17650 true_cond = false_cond;
17653 temp = gen_reg_rtx (compare_mode);
17654 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
17659 gcc_unreachable ();
17662 emit_insn (gen_rtx_SET (VOIDmode, dest,
17663 gen_rtx_IF_THEN_ELSE (result_mode,
17664 gen_rtx_GE (VOIDmode,
17666 true_cond, false_cond)));
17670 /* Same as above, but for ints (isel). */
17673 rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
17675 rtx condition_rtx, cr;
17676 enum machine_mode mode = GET_MODE (dest);
17677 enum rtx_code cond_code;
17678 rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx);
17681 if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode))
17684 /* We still have to do the compare, because isel doesn't do a
17685 compare, it just looks at the CRx bits set by a previous compare
17687 condition_rtx = rs6000_generate_compare (op, mode);
17688 cond_code = GET_CODE (condition_rtx);
17689 cr = XEXP (condition_rtx, 0);
17690 signedp = GET_MODE (cr) == CCmode;
17692 isel_func = (mode == SImode
17693 ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si)
17694 : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di));
17698 case LT: case GT: case LTU: case GTU: case EQ:
17699 /* isel handles these directly. */
17703 /* We need to swap the sense of the comparison. */
17706 true_cond = false_cond;
17708 PUT_CODE (condition_rtx, reverse_condition (cond_code));
17713 false_cond = force_reg (mode, false_cond);
17714 if (true_cond != const0_rtx)
17715 true_cond = force_reg (mode, true_cond);
17717 emit_insn (isel_func (dest, condition_rtx, true_cond, false_cond, cr));
17723 output_isel (rtx *operands)
17725 enum rtx_code code;
17727 code = GET_CODE (operands[1]);
17729 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
17731 gcc_assert (GET_CODE (operands[2]) == REG
17732 && GET_CODE (operands[3]) == REG);
17733 PUT_CODE (operands[1], reverse_condition (code));
17734 return "isel %0,%3,%2,%j1";
17737 return "isel %0,%2,%3,%j1";
17741 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
17743 enum machine_mode mode = GET_MODE (op0);
17747 /* VSX/altivec have direct min/max insns. */
17748 if ((code == SMAX || code == SMIN)
17749 && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
17750 || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
17752 emit_insn (gen_rtx_SET (VOIDmode,
17754 gen_rtx_fmt_ee (code, mode, op0, op1)));
17758 if (code == SMAX || code == SMIN)
17763 if (code == SMAX || code == UMAX)
17764 target = emit_conditional_move (dest, c, op0, op1, mode,
17765 op0, op1, mode, 0);
17767 target = emit_conditional_move (dest, c, op0, op1, mode,
17768 op1, op0, mode, 0);
17769 gcc_assert (target);
17770 if (target != dest)
17771 emit_move_insn (dest, target);
17774 /* Emit instructions to perform a load-reserved/store-conditional operation.
17775 The operation performed is an atomic
17776 (set M (CODE:MODE M OP))
17777 If not NULL, BEFORE is atomically set to M before the operation, and
17778 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
17779 If SYNC_P then a memory barrier is emitted before the operation.
17780 Either OP or M may be wrapped in a NOT operation. */
17783 rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
17784 rtx m, rtx op, rtx before_param, rtx after_param,
17787 enum machine_mode used_mode;
17788 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
17791 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
17792 rtx shift = NULL_RTX;
17795 emit_insn (gen_lwsync ());
17799 /* If this is smaller than SImode, we'll have to use SImode with
17801 if (mode == QImode || mode == HImode)
17805 if (MEM_ALIGN (used_m) >= 32)
17808 if (BYTES_BIG_ENDIAN)
17809 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
17811 shift = GEN_INT (ishift);
17812 used_m = change_address (used_m, SImode, 0);
17816 rtx addrSI, aligned_addr;
17817 int shift_mask = mode == QImode ? 0x18 : 0x10;
17819 addrSI = gen_lowpart_common (SImode,
17820 force_reg (Pmode, XEXP (used_m, 0)));
17821 addrSI = force_reg (SImode, addrSI);
17822 shift = gen_reg_rtx (SImode);
17824 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
17825 GEN_INT (shift_mask)));
17826 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
17828 aligned_addr = expand_binop (Pmode, and_optab,
17830 GEN_INT (-4), NULL_RTX,
17831 1, OPTAB_LIB_WIDEN);
17832 used_m = change_address (used_m, SImode, aligned_addr);
17833 set_mem_align (used_m, 32);
17835 /* It's safe to keep the old alias set of USED_M, because
17836 the operation is atomic and only affects the original
17840 if (GET_CODE (op) == NOT)
17842 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
17843 oldop = gen_rtx_NOT (SImode, oldop);
17846 oldop = lowpart_subreg (SImode, op, mode);
17852 newop = expand_binop (SImode, and_optab,
17853 oldop, GEN_INT (imask), NULL_RTX,
17854 1, OPTAB_LIB_WIDEN);
17855 emit_insn (gen_ashlsi3 (newop, newop, shift));
17858 case NOT: /* NAND */
17859 newop = expand_binop (SImode, ior_optab,
17860 oldop, GEN_INT (~imask), NULL_RTX,
17861 1, OPTAB_LIB_WIDEN);
17862 emit_insn (gen_rotlsi3 (newop, newop, shift));
17866 newop = expand_binop (SImode, ior_optab,
17867 oldop, GEN_INT (~imask), NULL_RTX,
17868 1, OPTAB_LIB_WIDEN);
17869 emit_insn (gen_rotlsi3 (newop, newop, shift));
17877 newop = expand_binop (SImode, and_optab,
17878 oldop, GEN_INT (imask), NULL_RTX,
17879 1, OPTAB_LIB_WIDEN);
17880 emit_insn (gen_ashlsi3 (newop, newop, shift));
17882 mask = gen_reg_rtx (SImode);
17883 emit_move_insn (mask, GEN_INT (imask));
17884 emit_insn (gen_ashlsi3 (mask, mask, shift));
17887 newop = gen_rtx_PLUS (SImode, m, newop);
17889 newop = gen_rtx_MINUS (SImode, m, newop);
17890 newop = gen_rtx_AND (SImode, newop, mask);
17891 newop = gen_rtx_IOR (SImode, newop,
17892 gen_rtx_AND (SImode,
17893 gen_rtx_NOT (SImode, mask),
17899 gcc_unreachable ();
17903 used_mode = SImode;
17904 before = gen_reg_rtx (used_mode);
17905 after = gen_reg_rtx (used_mode);
17910 before = before_param;
17911 after = after_param;
17913 if (before == NULL_RTX)
17914 before = gen_reg_rtx (used_mode);
17915 if (after == NULL_RTX)
17916 after = gen_reg_rtx (used_mode);
17919 if ((code == PLUS || code == MINUS)
17920 && used_mode != mode)
17921 the_op = op; /* Computed above. */
17922 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
17923 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
17924 else if (code == NOT)
17925 the_op = gen_rtx_fmt_ee (IOR, used_mode,
17926 gen_rtx_NOT (used_mode, m),
17927 gen_rtx_NOT (used_mode, op));
17929 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
17931 set_after = gen_rtx_SET (VOIDmode, after, the_op);
17932 set_before = gen_rtx_SET (VOIDmode, before, used_m);
17933 set_atomic = gen_rtx_SET (VOIDmode, used_m,
17934 gen_rtx_UNSPEC (used_mode,
17935 gen_rtvec (1, the_op),
17937 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
17939 if ((code == PLUS || code == MINUS) && used_mode != mode)
17940 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
17941 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
17943 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
17944 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
17946 /* Shift and mask the return values properly. */
17947 if (used_mode != mode && before_param)
17949 emit_insn (gen_lshrsi3 (before, before, shift));
17950 convert_move (before_param, before, 1);
17953 if (used_mode != mode && after_param)
17955 emit_insn (gen_lshrsi3 (after, after, shift));
17956 convert_move (after_param, after, 1);
17959 /* The previous sequence will end with a branch that's dependent on
17960 the conditional store, so placing an isync will ensure that no
17961 other instructions (especially, no load or store instructions)
17962 can start before the atomic operation completes. */
17964 emit_insn (gen_isync ());
17967 /* A subroutine of the atomic operation splitters. Jump to LABEL if
17968 COND is true. Mark the jump as unlikely to be taken. */
17971 emit_unlikely_jump (rtx cond, rtx label)
17973 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
17976 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
17977 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
17978 add_reg_note (x, REG_BR_PROB, very_unlikely);
17981 /* A subroutine of the atomic operation splitters. Emit a load-locked
17982 instruction in MODE. */
17985 emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
17987 rtx (*fn) (rtx, rtx) = NULL;
17988 if (mode == SImode)
17989 fn = gen_load_locked_si;
17990 else if (mode == DImode)
17991 fn = gen_load_locked_di;
17992 emit_insn (fn (reg, mem));
17995 /* A subroutine of the atomic operation splitters. Emit a store-conditional
17996 instruction in MODE. */
17999 emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
18001 rtx (*fn) (rtx, rtx, rtx) = NULL;
18002 if (mode == SImode)
18003 fn = gen_store_conditional_si;
18004 else if (mode == DImode)
18005 fn = gen_store_conditional_di;
18007 /* Emit sync before stwcx. to address PPC405 Erratum. */
18008 if (PPC405_ERRATUM77)
18009 emit_insn (gen_memory_barrier ());
18011 emit_insn (fn (res, mem, val));
18014 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
18015 to perform. MEM is the memory on which to operate. VAL is the second
18016 operand of the binary operator. BEFORE and AFTER are optional locations to
18017 return the value of MEM either before of after the operation. SCRATCH is
18018 a scratch register. */
18021 rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
18022 rtx before, rtx after, rtx scratch)
18024 enum machine_mode mode = GET_MODE (mem);
18025 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18027 emit_insn (gen_lwsync ());
18029 label = gen_label_rtx ();
18030 emit_label (label);
18031 label = gen_rtx_LABEL_REF (VOIDmode, label);
18033 if (before == NULL_RTX)
18035 emit_load_locked (mode, before, mem);
18038 x = gen_rtx_IOR (mode,
18039 gen_rtx_NOT (mode, before),
18040 gen_rtx_NOT (mode, val));
18041 else if (code == AND)
18042 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
18044 x = gen_rtx_fmt_ee (code, mode, before, val);
18046 if (after != NULL_RTX)
18047 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
18048 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
18050 emit_store_conditional (mode, cond, mem, scratch);
18052 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18053 emit_unlikely_jump (x, label);
18055 emit_insn (gen_isync ());
18058 /* Expand an atomic compare and swap operation. MEM is the memory on which
18059 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
18060 value to be stored. SCRATCH is a scratch GPR. */
18063 rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
18066 enum machine_mode mode = GET_MODE (mem);
18067 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18069 emit_insn (gen_lwsync ());
18071 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18072 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18073 emit_label (XEXP (label1, 0));
18075 emit_load_locked (mode, retval, mem);
18077 x = gen_rtx_COMPARE (CCmode, retval, oldval);
18078 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18080 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18081 emit_unlikely_jump (x, label2);
18083 emit_move_insn (scratch, newval);
18084 emit_store_conditional (mode, cond, mem, scratch);
18086 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18087 emit_unlikely_jump (x, label1);
18089 emit_insn (gen_isync ());
18090 emit_label (XEXP (label2, 0));
18093 /* Expand an atomic test and set operation. MEM is the memory on which
18094 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
18097 rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
18099 enum machine_mode mode = GET_MODE (mem);
18100 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18102 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18103 emit_label (XEXP (label, 0));
18105 emit_load_locked (mode, retval, mem);
18106 emit_move_insn (scratch, val);
18107 emit_store_conditional (mode, cond, mem, scratch);
18109 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18110 emit_unlikely_jump (x, label);
18112 emit_insn (gen_isync ());
18116 rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
18118 enum machine_mode mode = GET_MODE (mem);
18119 rtx addrSI, align, wdst, shift, mask;
18120 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
18121 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
18123 /* Shift amount for subword relative to aligned word. */
18124 addrSI = force_reg (GET_MODE (XEXP (mem, 0)), XEXP (mem, 0));
18125 addrSI = force_reg (SImode, gen_lowpart_common (SImode, addrSI));
18126 shift = gen_reg_rtx (SImode);
18127 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
18128 GEN_INT (shift_mask)));
18129 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
18131 /* Shift and mask old value into position within word. */
18132 oldval = convert_modes (SImode, mode, oldval, 1);
18133 oldval = expand_binop (SImode, and_optab,
18134 oldval, GEN_INT (imask), NULL_RTX,
18135 1, OPTAB_LIB_WIDEN);
18136 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
18138 /* Shift and mask new value into position within word. */
18139 newval = convert_modes (SImode, mode, newval, 1);
18140 newval = expand_binop (SImode, and_optab,
18141 newval, GEN_INT (imask), NULL_RTX,
18142 1, OPTAB_LIB_WIDEN);
18143 emit_insn (gen_ashlsi3 (newval, newval, shift));
18145 /* Mask for insertion. */
18146 mask = gen_reg_rtx (SImode);
18147 emit_move_insn (mask, GEN_INT (imask));
18148 emit_insn (gen_ashlsi3 (mask, mask, shift));
18150 /* Address of aligned word containing subword. */
18151 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
18152 NULL_RTX, 1, OPTAB_LIB_WIDEN);
18153 mem = change_address (mem, SImode, align);
18154 set_mem_align (mem, 32);
18155 MEM_VOLATILE_P (mem) = 1;
18157 wdst = gen_reg_rtx (SImode);
18158 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
18159 oldval, newval, mem));
18161 /* Shift the result back. */
18162 emit_insn (gen_lshrsi3 (wdst, wdst, shift));
18164 emit_move_insn (dst, gen_lowpart (mode, wdst));
18168 rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
18169 rtx oldval, rtx newval, rtx mem,
18172 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
18174 emit_insn (gen_lwsync ());
18175 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18176 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
18177 emit_label (XEXP (label1, 0));
18179 emit_load_locked (SImode, scratch, mem);
18181 /* Mask subword within loaded value for comparison with oldval.
18182 Use UNSPEC_AND to avoid clobber.*/
18183 emit_insn (gen_rtx_SET (SImode, dest,
18184 gen_rtx_UNSPEC (SImode,
18185 gen_rtvec (2, scratch, mask),
18188 x = gen_rtx_COMPARE (CCmode, dest, oldval);
18189 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
18191 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18192 emit_unlikely_jump (x, label2);
18194 /* Clear subword within loaded value for insertion of new value. */
18195 emit_insn (gen_rtx_SET (SImode, scratch,
18196 gen_rtx_AND (SImode,
18197 gen_rtx_NOT (SImode, mask), scratch)));
18198 emit_insn (gen_iorsi3 (scratch, scratch, newval));
18199 emit_store_conditional (SImode, cond, mem, scratch);
18201 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
18202 emit_unlikely_jump (x, label1);
18204 emit_insn (gen_isync ());
18205 emit_label (XEXP (label2, 0));
18209 /* Emit instructions to move SRC to DST. Called by splitters for
18210 multi-register moves. It will emit at most one instruction for
18211 each register that is accessed; that is, it won't emit li/lis pairs
18212 (or equivalent for 64-bit code). One of SRC or DST must be a hard
18216 rs6000_split_multireg_move (rtx dst, rtx src)
18218 /* The register number of the first register being moved. */
18220 /* The mode that is to be moved. */
18221 enum machine_mode mode;
18222 /* The mode that the move is being done in, and its size. */
18223 enum machine_mode reg_mode;
18225 /* The number of registers that will be moved. */
18228 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
18229 mode = GET_MODE (dst);
18230 nregs = hard_regno_nregs[reg][mode];
18231 if (FP_REGNO_P (reg))
18232 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode :
18233 ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? DFmode : SFmode);
18234 else if (ALTIVEC_REGNO_P (reg))
18235 reg_mode = V16QImode;
18236 else if (TARGET_E500_DOUBLE && mode == TFmode)
18239 reg_mode = word_mode;
18240 reg_mode_size = GET_MODE_SIZE (reg_mode);
18242 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
18244 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
18246 /* Move register range backwards, if we might have destructive
18249 for (i = nregs - 1; i >= 0; i--)
18250 emit_insn (gen_rtx_SET (VOIDmode,
18251 simplify_gen_subreg (reg_mode, dst, mode,
18252 i * reg_mode_size),
18253 simplify_gen_subreg (reg_mode, src, mode,
18254 i * reg_mode_size)));
18260 bool used_update = false;
18261 rtx restore_basereg = NULL_RTX;
18263 if (MEM_P (src) && INT_REGNO_P (reg))
18267 if (GET_CODE (XEXP (src, 0)) == PRE_INC
18268 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
18271 breg = XEXP (XEXP (src, 0), 0);
18272 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
18273 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
18274 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
18275 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18276 src = replace_equiv_address (src, breg);
18278 else if (! rs6000_offsettable_memref_p (src))
18280 if (GET_CODE (XEXP (src, 0)) == PRE_MODIFY)
18282 rtx basereg = XEXP (XEXP (src, 0), 0);
18285 rtx ndst = simplify_gen_subreg (reg_mode, dst, mode, 0);
18286 emit_insn (gen_rtx_SET (VOIDmode, ndst,
18287 gen_rtx_MEM (reg_mode, XEXP (src, 0))));
18288 used_update = true;
18291 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18292 XEXP (XEXP (src, 0), 1)));
18293 src = replace_equiv_address (src, basereg);
18297 rtx basereg = gen_rtx_REG (Pmode, reg);
18298 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
18299 src = replace_equiv_address (src, basereg);
18303 breg = XEXP (src, 0);
18304 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
18305 breg = XEXP (breg, 0);
18307 /* If the base register we are using to address memory is
18308 also a destination reg, then change that register last. */
18310 && REGNO (breg) >= REGNO (dst)
18311 && REGNO (breg) < REGNO (dst) + nregs)
18312 j = REGNO (breg) - REGNO (dst);
18314 else if (MEM_P (dst) && INT_REGNO_P (reg))
18318 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
18319 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
18322 breg = XEXP (XEXP (dst, 0), 0);
18323 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
18324 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
18325 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
18327 /* We have to update the breg before doing the store.
18328 Use store with update, if available. */
18332 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18333 emit_insn (TARGET_32BIT
18334 ? (TARGET_POWERPC64
18335 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
18336 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
18337 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
18338 used_update = true;
18341 emit_insn (gen_add3_insn (breg, breg, delta_rtx));
18342 dst = replace_equiv_address (dst, breg);
18344 else if (!rs6000_offsettable_memref_p (dst)
18345 && GET_CODE (XEXP (dst, 0)) != LO_SUM)
18347 if (GET_CODE (XEXP (dst, 0)) == PRE_MODIFY)
18349 rtx basereg = XEXP (XEXP (dst, 0), 0);
18352 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
18353 emit_insn (gen_rtx_SET (VOIDmode,
18354 gen_rtx_MEM (reg_mode, XEXP (dst, 0)), nsrc));
18355 used_update = true;
18358 emit_insn (gen_rtx_SET (VOIDmode, basereg,
18359 XEXP (XEXP (dst, 0), 1)));
18360 dst = replace_equiv_address (dst, basereg);
18364 rtx basereg = XEXP (XEXP (dst, 0), 0);
18365 rtx offsetreg = XEXP (XEXP (dst, 0), 1);
18366 gcc_assert (GET_CODE (XEXP (dst, 0)) == PLUS
18368 && REG_P (offsetreg)
18369 && REGNO (basereg) != REGNO (offsetreg));
18370 if (REGNO (basereg) == 0)
18372 rtx tmp = offsetreg;
18373 offsetreg = basereg;
18376 emit_insn (gen_add3_insn (basereg, basereg, offsetreg));
18377 restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg);
18378 dst = replace_equiv_address (dst, basereg);
18381 else if (GET_CODE (XEXP (dst, 0)) != LO_SUM)
18382 gcc_assert (rs6000_offsettable_memref_p (dst));
18385 for (i = 0; i < nregs; i++)
18387 /* Calculate index to next subword. */
18392 /* If compiler already emitted move of first word by
18393 store with update, no need to do anything. */
18394 if (j == 0 && used_update)
18397 emit_insn (gen_rtx_SET (VOIDmode,
18398 simplify_gen_subreg (reg_mode, dst, mode,
18399 j * reg_mode_size),
18400 simplify_gen_subreg (reg_mode, src, mode,
18401 j * reg_mode_size)));
18403 if (restore_basereg != NULL_RTX)
18404 emit_insn (restore_basereg);
18409 /* This page contains routines that are used to determine what the
18410 function prologue and epilogue code will do and write them out. */
18412 /* Return the first fixed-point register that is required to be
18413 saved. 32 if none. */
18416 first_reg_to_save (void)
18420 /* Find lowest numbered live register. */
18421 for (first_reg = 13; first_reg <= 31; first_reg++)
18422 if (df_regs_ever_live_p (first_reg)
18423 && (! call_used_regs[first_reg]
18424 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
18425 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
18426 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
18427 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
18432 && crtl->uses_pic_offset_table
18433 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
18434 return RS6000_PIC_OFFSET_TABLE_REGNUM;
18440 /* Similar, for FP regs. */
18443 first_fp_reg_to_save (void)
18447 /* Find lowest numbered live register. */
18448 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
18449 if (df_regs_ever_live_p (first_reg))
18455 /* Similar, for AltiVec regs. */
18458 first_altivec_reg_to_save (void)
18462 /* Stack frame remains as is unless we are in AltiVec ABI. */
18463 if (! TARGET_ALTIVEC_ABI)
18464 return LAST_ALTIVEC_REGNO + 1;
18466 /* On Darwin, the unwind routines are compiled without
18467 TARGET_ALTIVEC, and use save_world to save/restore the
18468 altivec registers when necessary. */
18469 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18470 && ! TARGET_ALTIVEC)
18471 return FIRST_ALTIVEC_REGNO + 20;
18473 /* Find lowest numbered live register. */
18474 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
18475 if (df_regs_ever_live_p (i))
18481 /* Return a 32-bit mask of the AltiVec registers we need to set in
18482 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
18483 the 32-bit word is 0. */
18485 static unsigned int
18486 compute_vrsave_mask (void)
18488 unsigned int i, mask = 0;
18490 /* On Darwin, the unwind routines are compiled without
18491 TARGET_ALTIVEC, and use save_world to save/restore the
18492 call-saved altivec registers when necessary. */
18493 if (DEFAULT_ABI == ABI_DARWIN && crtl->calls_eh_return
18494 && ! TARGET_ALTIVEC)
18497 /* First, find out if we use _any_ altivec registers. */
18498 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
18499 if (df_regs_ever_live_p (i))
18500 mask |= ALTIVEC_REG_BIT (i);
18505 /* Next, remove the argument registers from the set. These must
18506 be in the VRSAVE mask set by the caller, so we don't need to add
18507 them in again. More importantly, the mask we compute here is
18508 used to generate CLOBBERs in the set_vrsave insn, and we do not
18509 wish the argument registers to die. */
18510 for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
18511 mask &= ~ALTIVEC_REG_BIT (i);
18513 /* Similarly, remove the return value from the set. */
18516 diddle_return_value (is_altivec_return_reg, &yes);
18518 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
18524 /* For a very restricted set of circumstances, we can cut down the
18525 size of prologues/epilogues by calling our own save/restore-the-world
18529 compute_save_world_info (rs6000_stack_t *info_ptr)
18531 info_ptr->world_save_p = 1;
18532 info_ptr->world_save_p
18533 = (WORLD_SAVE_P (info_ptr)
18534 && DEFAULT_ABI == ABI_DARWIN
18535 && ! (cfun->calls_setjmp && flag_exceptions)
18536 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
18537 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
18538 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
18539 && info_ptr->cr_save_p);
18541 /* This will not work in conjunction with sibcalls. Make sure there
18542 are none. (This check is expensive, but seldom executed.) */
18543 if (WORLD_SAVE_P (info_ptr))
18546 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
18547 if ( GET_CODE (insn) == CALL_INSN
18548 && SIBLING_CALL_P (insn))
18550 info_ptr->world_save_p = 0;
18555 if (WORLD_SAVE_P (info_ptr))
18557 /* Even if we're not touching VRsave, make sure there's room on the
18558 stack for it, if it looks like we're calling SAVE_WORLD, which
18559 will attempt to save it. */
18560 info_ptr->vrsave_size = 4;
18562 /* If we are going to save the world, we need to save the link register too. */
18563 info_ptr->lr_save_p = 1;
18565 /* "Save" the VRsave register too if we're saving the world. */
18566 if (info_ptr->vrsave_mask == 0)
18567 info_ptr->vrsave_mask = compute_vrsave_mask ();
18569 /* Because the Darwin register save/restore routines only handle
18570 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
18572 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
18573 && (info_ptr->first_altivec_reg_save
18574 >= FIRST_SAVED_ALTIVEC_REGNO));
18581 is_altivec_return_reg (rtx reg, void *xyes)
18583 bool *yes = (bool *) xyes;
18584 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
18589 /* Determine the strategy for savings/restoring registers. */
18592 SAVRES_MULTIPLE = 0x1,
18593 SAVE_INLINE_FPRS = 0x2,
18594 SAVE_INLINE_GPRS = 0x4,
18595 REST_INLINE_FPRS = 0x8,
18596 REST_INLINE_GPRS = 0x10,
18597 SAVE_NOINLINE_GPRS_SAVES_LR = 0x20,
18598 SAVE_NOINLINE_FPRS_SAVES_LR = 0x40,
18599 REST_NOINLINE_FPRS_DOESNT_RESTORE_LR = 0x80
18603 rs6000_savres_strategy (rs6000_stack_t *info,
18604 bool using_static_chain_p)
18608 if (TARGET_MULTIPLE
18609 && !TARGET_POWERPC64
18610 && !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
18611 && info->first_gp_reg_save < 31
18612 && no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true))
18613 strategy |= SAVRES_MULTIPLE;
18615 if (crtl->calls_eh_return
18616 || cfun->machine->ra_need_lr
18617 || info->total_size > 32767)
18618 strategy |= (SAVE_INLINE_FPRS | REST_INLINE_FPRS
18619 | SAVE_INLINE_GPRS | REST_INLINE_GPRS);
18621 if (info->first_fp_reg_save == 64
18622 || FP_SAVE_INLINE (info->first_fp_reg_save)
18623 /* The out-of-line FP routines use double-precision stores;
18624 we can't use those routines if we don't have such stores. */
18625 || (TARGET_HARD_FLOAT && !TARGET_DOUBLE_FLOAT)
18626 || !no_global_regs_above (info->first_fp_reg_save, /*gpr=*/false))
18627 strategy |= SAVE_INLINE_FPRS | REST_INLINE_FPRS;
18629 if (info->first_gp_reg_save == 32
18630 || GP_SAVE_INLINE (info->first_gp_reg_save)
18631 || !((strategy & SAVRES_MULTIPLE)
18632 || no_global_regs_above (info->first_gp_reg_save, /*gpr=*/true)))
18633 strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
18635 /* Don't bother to try to save things out-of-line if r11 is occupied
18636 by the static chain. It would require too much fiddling and the
18637 static chain is rarely used anyway. */
18638 if (using_static_chain_p)
18639 strategy |= SAVE_INLINE_FPRS | SAVE_INLINE_GPRS;
18641 /* If we are going to use store multiple, then don't even bother
18642 with the out-of-line routines, since the store-multiple
18643 instruction will always be smaller. */
18644 if ((strategy & SAVRES_MULTIPLE))
18645 strategy |= SAVE_INLINE_GPRS;
18647 /* The situation is more complicated with load multiple. We'd
18648 prefer to use the out-of-line routines for restores, since the
18649 "exit" out-of-line routines can handle the restore of LR and the
18650 frame teardown. However if doesn't make sense to use the
18651 out-of-line routine if that is the only reason we'd need to save
18652 LR, and we can't use the "exit" out-of-line gpr restore if we
18653 have saved some fprs; In those cases it is advantageous to use
18654 load multiple when available. */
18655 if ((strategy & SAVRES_MULTIPLE)
18656 && (!info->lr_save_p
18657 || info->first_fp_reg_save != 64))
18658 strategy |= REST_INLINE_GPRS;
18660 /* We can only use load multiple or the out-of-line routines to
18661 restore if we've used store multiple or out-of-line routines
18662 in the prologue, i.e. if we've saved all the registers from
18663 first_gp_reg_save. Otherwise, we risk loading garbage. */
18664 if ((strategy & (SAVE_INLINE_GPRS | SAVRES_MULTIPLE)) == SAVE_INLINE_GPRS)
18665 strategy |= REST_INLINE_GPRS;
18667 /* Saving CR interferes with the exit routines used on the SPE, so
18670 && info->spe_64bit_regs_used
18671 && info->cr_save_p)
18672 strategy |= REST_INLINE_GPRS;
18674 #ifdef POWERPC_LINUX
18677 if (!(strategy & SAVE_INLINE_FPRS))
18678 strategy |= SAVE_NOINLINE_FPRS_SAVES_LR;
18679 else if (!(strategy & SAVE_INLINE_GPRS)
18680 && info->first_fp_reg_save == 64)
18681 strategy |= SAVE_NOINLINE_GPRS_SAVES_LR;
18684 if (TARGET_AIX && !(strategy & REST_INLINE_FPRS))
18685 strategy |= REST_NOINLINE_FPRS_DOESNT_RESTORE_LR;
18690 /* Calculate the stack information for the current function. This is
18691 complicated by having two separate calling sequences, the AIX calling
18692 sequence and the V.4 calling sequence.
18694 AIX (and Darwin/Mac OS X) stack frames look like:
18696 SP----> +---------------------------------------+
18697 | back chain to caller | 0 0
18698 +---------------------------------------+
18699 | saved CR | 4 8 (8-11)
18700 +---------------------------------------+
18702 +---------------------------------------+
18703 | reserved for compilers | 12 24
18704 +---------------------------------------+
18705 | reserved for binders | 16 32
18706 +---------------------------------------+
18707 | saved TOC pointer | 20 40
18708 +---------------------------------------+
18709 | Parameter save area (P) | 24 48
18710 +---------------------------------------+
18711 | Alloca space (A) | 24+P etc.
18712 +---------------------------------------+
18713 | Local variable space (L) | 24+P+A
18714 +---------------------------------------+
18715 | Float/int conversion temporary (X) | 24+P+A+L
18716 +---------------------------------------+
18717 | Save area for AltiVec registers (W) | 24+P+A+L+X
18718 +---------------------------------------+
18719 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
18720 +---------------------------------------+
18721 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
18722 +---------------------------------------+
18723 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
18724 +---------------------------------------+
18725 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
18726 +---------------------------------------+
18727 old SP->| back chain to caller's caller |
18728 +---------------------------------------+
18730 The required alignment for AIX configurations is two words (i.e., 8
18734 V.4 stack frames look like:
18736 SP----> +---------------------------------------+
18737 | back chain to caller | 0
18738 +---------------------------------------+
18739 | caller's saved LR | 4
18740 +---------------------------------------+
18741 | Parameter save area (P) | 8
18742 +---------------------------------------+
18743 | Alloca space (A) | 8+P
18744 +---------------------------------------+
18745 | Varargs save area (V) | 8+P+A
18746 +---------------------------------------+
18747 | Local variable space (L) | 8+P+A+V
18748 +---------------------------------------+
18749 | Float/int conversion temporary (X) | 8+P+A+V+L
18750 +---------------------------------------+
18751 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
18752 +---------------------------------------+
18753 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
18754 +---------------------------------------+
18755 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
18756 +---------------------------------------+
18757 | SPE: area for 64-bit GP registers |
18758 +---------------------------------------+
18759 | SPE alignment padding |
18760 +---------------------------------------+
18761 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
18762 +---------------------------------------+
18763 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
18764 +---------------------------------------+
18765 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
18766 +---------------------------------------+
18767 old SP->| back chain to caller's caller |
18768 +---------------------------------------+
18770 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
18771 given. (But note below and in sysv4.h that we require only 8 and
18772 may round up the size of our stack frame anyways. The historical
18773 reason is early versions of powerpc-linux which didn't properly
18774 align the stack at program startup. A happy side-effect is that
18775 -mno-eabi libraries can be used with -meabi programs.)
18777 The EABI configuration defaults to the V.4 layout. However,
18778 the stack alignment requirements may differ. If -mno-eabi is not
18779 given, the required stack alignment is 8 bytes; if -mno-eabi is
18780 given, the required alignment is 16 bytes. (But see V.4 comment
18783 #ifndef ABI_STACK_BOUNDARY
18784 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
18787 static rs6000_stack_t *
18788 rs6000_stack_info (void)
18790 rs6000_stack_t *info_ptr = &stack_info;
18791 int reg_size = TARGET_32BIT ? 4 : 8;
18795 HOST_WIDE_INT non_fixed_size;
18796 bool using_static_chain_p;
18798 if (reload_completed && info_ptr->reload_completed)
18801 memset (info_ptr, 0, sizeof (*info_ptr));
18802 info_ptr->reload_completed = reload_completed;
18806 /* Cache value so we don't rescan instruction chain over and over. */
18807 if (cfun->machine->insn_chain_scanned_p == 0)
18808 cfun->machine->insn_chain_scanned_p
18809 = spe_func_has_64bit_regs_p () + 1;
18810 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
18813 /* Select which calling sequence. */
18814 info_ptr->abi = DEFAULT_ABI;
18816 /* Calculate which registers need to be saved & save area size. */
18817 info_ptr->first_gp_reg_save = first_reg_to_save ();
18818 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
18819 even if it currently looks like we won't. Reload may need it to
18820 get at a constant; if so, it will have already created a constant
18821 pool entry for it. */
18822 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
18823 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
18824 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
18825 && crtl->uses_const_pool
18826 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
18827 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
18829 first_gp = info_ptr->first_gp_reg_save;
18831 info_ptr->gp_size = reg_size * (32 - first_gp);
18833 /* For the SPE, we have an additional upper 32-bits on each GPR.
18834 Ideally we should save the entire 64-bits only when the upper
18835 half is used in SIMD instructions. Since we only record
18836 registers live (not the size they are used in), this proves
18837 difficult because we'd have to traverse the instruction chain at
18838 the right time, taking reload into account. This is a real pain,
18839 so we opt to save the GPRs in 64-bits always if but one register
18840 gets used in 64-bits. Otherwise, all the registers in the frame
18841 get saved in 32-bits.
18843 So... since when we save all GPRs (except the SP) in 64-bits, the
18844 traditional GP save area will be empty. */
18845 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18846 info_ptr->gp_size = 0;
18848 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
18849 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
18851 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
18852 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
18853 - info_ptr->first_altivec_reg_save);
18855 /* Does this function call anything? */
18856 info_ptr->calls_p = (! current_function_is_leaf
18857 || cfun->machine->ra_needs_full_frame);
18859 /* Determine if we need to save the condition code registers. */
18860 if (df_regs_ever_live_p (CR2_REGNO)
18861 || df_regs_ever_live_p (CR3_REGNO)
18862 || df_regs_ever_live_p (CR4_REGNO))
18864 info_ptr->cr_save_p = 1;
18865 if (DEFAULT_ABI == ABI_V4)
18866 info_ptr->cr_size = reg_size;
18869 /* If the current function calls __builtin_eh_return, then we need
18870 to allocate stack space for registers that will hold data for
18871 the exception handler. */
18872 if (crtl->calls_eh_return)
18875 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
18878 /* SPE saves EH registers in 64-bits. */
18879 ehrd_size = i * (TARGET_SPE_ABI
18880 && info_ptr->spe_64bit_regs_used != 0
18881 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
18886 /* Determine various sizes. */
18887 info_ptr->reg_size = reg_size;
18888 info_ptr->fixed_size = RS6000_SAVE_AREA;
18889 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
18890 info_ptr->parm_size = RS6000_ALIGN (crtl->outgoing_args_size,
18891 TARGET_ALTIVEC ? 16 : 8);
18892 if (FRAME_GROWS_DOWNWARD)
18893 info_ptr->vars_size
18894 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
18895 + info_ptr->parm_size,
18896 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
18897 - (info_ptr->fixed_size + info_ptr->vars_size
18898 + info_ptr->parm_size);
18900 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18901 info_ptr->spe_gp_size = 8 * (32 - first_gp);
18903 info_ptr->spe_gp_size = 0;
18905 if (TARGET_ALTIVEC_ABI)
18906 info_ptr->vrsave_mask = compute_vrsave_mask ();
18908 info_ptr->vrsave_mask = 0;
18910 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
18911 info_ptr->vrsave_size = 4;
18913 info_ptr->vrsave_size = 0;
18915 compute_save_world_info (info_ptr);
18917 /* Calculate the offsets. */
18918 switch (DEFAULT_ABI)
18922 gcc_unreachable ();
18926 info_ptr->fp_save_offset = - info_ptr->fp_size;
18927 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18929 if (TARGET_ALTIVEC_ABI)
18931 info_ptr->vrsave_save_offset
18932 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
18934 /* Align stack so vector save area is on a quadword boundary.
18935 The padding goes above the vectors. */
18936 if (info_ptr->altivec_size != 0)
18937 info_ptr->altivec_padding_size
18938 = info_ptr->vrsave_save_offset & 0xF;
18940 info_ptr->altivec_padding_size = 0;
18942 info_ptr->altivec_save_offset
18943 = info_ptr->vrsave_save_offset
18944 - info_ptr->altivec_padding_size
18945 - info_ptr->altivec_size;
18946 gcc_assert (info_ptr->altivec_size == 0
18947 || info_ptr->altivec_save_offset % 16 == 0);
18949 /* Adjust for AltiVec case. */
18950 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
18953 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
18954 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
18955 info_ptr->lr_save_offset = 2*reg_size;
18959 info_ptr->fp_save_offset = - info_ptr->fp_size;
18960 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
18961 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
18963 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
18965 /* Align stack so SPE GPR save area is aligned on a
18966 double-word boundary. */
18967 if (info_ptr->spe_gp_size != 0 && info_ptr->cr_save_offset != 0)
18968 info_ptr->spe_padding_size
18969 = 8 - (-info_ptr->cr_save_offset % 8);
18971 info_ptr->spe_padding_size = 0;
18973 info_ptr->spe_gp_save_offset
18974 = info_ptr->cr_save_offset
18975 - info_ptr->spe_padding_size
18976 - info_ptr->spe_gp_size;
18978 /* Adjust for SPE case. */
18979 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
18981 else if (TARGET_ALTIVEC_ABI)
18983 info_ptr->vrsave_save_offset
18984 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
18986 /* Align stack so vector save area is on a quadword boundary. */
18987 if (info_ptr->altivec_size != 0)
18988 info_ptr->altivec_padding_size
18989 = 16 - (-info_ptr->vrsave_save_offset % 16);
18991 info_ptr->altivec_padding_size = 0;
18993 info_ptr->altivec_save_offset
18994 = info_ptr->vrsave_save_offset
18995 - info_ptr->altivec_padding_size
18996 - info_ptr->altivec_size;
18998 /* Adjust for AltiVec case. */
18999 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
19002 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
19003 info_ptr->ehrd_offset -= ehrd_size;
19004 info_ptr->lr_save_offset = reg_size;
19008 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
19009 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
19010 + info_ptr->gp_size
19011 + info_ptr->altivec_size
19012 + info_ptr->altivec_padding_size
19013 + info_ptr->spe_gp_size
19014 + info_ptr->spe_padding_size
19016 + info_ptr->cr_size
19017 + info_ptr->vrsave_size,
19020 non_fixed_size = (info_ptr->vars_size
19021 + info_ptr->parm_size
19022 + info_ptr->save_size);
19024 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
19025 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
19027 /* Determine if we need to save the link register. */
19028 if (info_ptr->calls_p
19029 || (DEFAULT_ABI == ABI_AIX
19031 && !TARGET_PROFILE_KERNEL)
19032 || (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
19033 #ifdef TARGET_RELOCATABLE
19034 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
19036 || rs6000_ra_ever_killed ())
19037 info_ptr->lr_save_p = 1;
19039 using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
19040 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
19041 && call_used_regs[STATIC_CHAIN_REGNUM]);
19042 info_ptr->savres_strategy = rs6000_savres_strategy (info_ptr,
19043 using_static_chain_p);
19045 if (!(info_ptr->savres_strategy & SAVE_INLINE_GPRS)
19046 || !(info_ptr->savres_strategy & SAVE_INLINE_FPRS)
19047 || !(info_ptr->savres_strategy & REST_INLINE_GPRS)
19048 || !(info_ptr->savres_strategy & REST_INLINE_FPRS))
19049 info_ptr->lr_save_p = 1;
19051 if (info_ptr->lr_save_p)
19052 df_set_regs_ever_live (LR_REGNO, true);
19054 /* Determine if we need to allocate any stack frame:
19056 For AIX we need to push the stack if a frame pointer is needed
19057 (because the stack might be dynamically adjusted), if we are
19058 debugging, if we make calls, or if the sum of fp_save, gp_save,
19059 and local variables are more than the space needed to save all
19060 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
19061 + 18*8 = 288 (GPR13 reserved).
19063 For V.4 we don't have the stack cushion that AIX uses, but assume
19064 that the debugger can handle stackless frames. */
19066 if (info_ptr->calls_p)
19067 info_ptr->push_p = 1;
19069 else if (DEFAULT_ABI == ABI_V4)
19070 info_ptr->push_p = non_fixed_size != 0;
19072 else if (frame_pointer_needed)
19073 info_ptr->push_p = 1;
19075 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
19076 info_ptr->push_p = 1;
19079 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
19081 /* Zero offsets if we're not saving those registers. */
19082 if (info_ptr->fp_size == 0)
19083 info_ptr->fp_save_offset = 0;
19085 if (info_ptr->gp_size == 0)
19086 info_ptr->gp_save_offset = 0;
19088 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
19089 info_ptr->altivec_save_offset = 0;
19091 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
19092 info_ptr->vrsave_save_offset = 0;
19094 if (! TARGET_SPE_ABI
19095 || info_ptr->spe_64bit_regs_used == 0
19096 || info_ptr->spe_gp_size == 0)
19097 info_ptr->spe_gp_save_offset = 0;
19099 if (! info_ptr->lr_save_p)
19100 info_ptr->lr_save_offset = 0;
19102 if (! info_ptr->cr_save_p)
19103 info_ptr->cr_save_offset = 0;
19108 /* Return true if the current function uses any GPRs in 64-bit SIMD
19112 spe_func_has_64bit_regs_p (void)
19116 /* Functions that save and restore all the call-saved registers will
19117 need to save/restore the registers in 64-bits. */
19118 if (crtl->calls_eh_return
19119 || cfun->calls_setjmp
19120 || crtl->has_nonlocal_goto)
19123 insns = get_insns ();
19125 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
19131 /* FIXME: This should be implemented with attributes...
19133 (set_attr "spe64" "true")....then,
19134 if (get_spe64(insn)) return true;
19136 It's the only reliable way to do the stuff below. */
19138 i = PATTERN (insn);
19139 if (GET_CODE (i) == SET)
19141 enum machine_mode mode = GET_MODE (SET_SRC (i));
19143 if (SPE_VECTOR_MODE (mode))
19145 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
19155 debug_stack_info (rs6000_stack_t *info)
19157 const char *abi_string;
19160 info = rs6000_stack_info ();
19162 fprintf (stderr, "\nStack information for function %s:\n",
19163 ((current_function_decl && DECL_NAME (current_function_decl))
19164 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
19169 default: abi_string = "Unknown"; break;
19170 case ABI_NONE: abi_string = "NONE"; break;
19171 case ABI_AIX: abi_string = "AIX"; break;
19172 case ABI_DARWIN: abi_string = "Darwin"; break;
19173 case ABI_V4: abi_string = "V.4"; break;
19176 fprintf (stderr, "\tABI = %5s\n", abi_string);
19178 if (TARGET_ALTIVEC_ABI)
19179 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
19181 if (TARGET_SPE_ABI)
19182 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
19184 if (info->first_gp_reg_save != 32)
19185 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
19187 if (info->first_fp_reg_save != 64)
19188 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
19190 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
19191 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
19192 info->first_altivec_reg_save);
19194 if (info->lr_save_p)
19195 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
19197 if (info->cr_save_p)
19198 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
19200 if (info->vrsave_mask)
19201 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
19204 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
19207 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
19209 if (info->gp_save_offset)
19210 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
19212 if (info->fp_save_offset)
19213 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
19215 if (info->altivec_save_offset)
19216 fprintf (stderr, "\taltivec_save_offset = %5d\n",
19217 info->altivec_save_offset);
19219 if (info->spe_gp_save_offset)
19220 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
19221 info->spe_gp_save_offset);
19223 if (info->vrsave_save_offset)
19224 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
19225 info->vrsave_save_offset);
19227 if (info->lr_save_offset)
19228 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
19230 if (info->cr_save_offset)
19231 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
19233 if (info->varargs_save_offset)
19234 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
19236 if (info->total_size)
19237 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19240 if (info->vars_size)
19241 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
19244 if (info->parm_size)
19245 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
19247 if (info->fixed_size)
19248 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
19251 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
19253 if (info->spe_gp_size)
19254 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
19257 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
19259 if (info->altivec_size)
19260 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
19262 if (info->vrsave_size)
19263 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
19265 if (info->altivec_padding_size)
19266 fprintf (stderr, "\taltivec_padding_size= %5d\n",
19267 info->altivec_padding_size);
19269 if (info->spe_padding_size)
19270 fprintf (stderr, "\tspe_padding_size = %5d\n",
19271 info->spe_padding_size);
19274 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
19276 if (info->save_size)
19277 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
19279 if (info->reg_size != 4)
19280 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
19282 fprintf (stderr, "\n");
19286 rs6000_return_addr (int count, rtx frame)
19288 /* Currently we don't optimize very well between prolog and body
19289 code and for PIC code the code can be actually quite bad, so
19290 don't try to be too clever here. */
19291 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
19293 cfun->machine->ra_needs_full_frame = 1;
19300 plus_constant (copy_to_reg
19301 (gen_rtx_MEM (Pmode,
19302 memory_address (Pmode, frame))),
19303 RETURN_ADDRESS_OFFSET)));
19306 cfun->machine->ra_need_lr = 1;
19307 return get_hard_reg_initial_val (Pmode, LR_REGNO);
19310 /* Say whether a function is a candidate for sibcall handling or not.
19311 We do not allow indirect calls to be optimized into sibling calls.
19312 Also, we can't do it if there are any vector parameters; there's
19313 nowhere to put the VRsave code so it works; note that functions with
19314 vector parameters are required to have a prototype, so the argument
19315 type info must be available here. (The tail recursion case can work
19316 with vector parameters, but there's no way to distinguish here.) */
19318 rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
19323 if (TARGET_ALTIVEC_VRSAVE)
19325 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
19326 type; type = TREE_CHAIN (type))
19328 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
19332 if (DEFAULT_ABI == ABI_DARWIN
19333 || ((*targetm.binds_local_p) (decl)
19334 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
19336 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
19338 if (!lookup_attribute ("longcall", attr_list)
19339 || lookup_attribute ("shortcall", attr_list))
19346 /* NULL if INSN insn is valid within a low-overhead loop.
19347 Otherwise return why doloop cannot be applied.
19348 PowerPC uses the COUNT register for branch on table instructions. */
19350 static const char *
19351 rs6000_invalid_within_doloop (const_rtx insn)
19354 return "Function call in the loop.";
19357 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
19358 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
19359 return "Computed branch in the loop.";
19365 rs6000_ra_ever_killed (void)
19371 if (cfun->is_thunk)
19374 if (cfun->machine->lr_save_state)
19375 return cfun->machine->lr_save_state - 1;
19377 /* regs_ever_live has LR marked as used if any sibcalls are present,
19378 but this should not force saving and restoring in the
19379 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
19380 clobbers LR, so that is inappropriate. */
19382 /* Also, the prologue can generate a store into LR that
19383 doesn't really count, like this:
19386 bcl to set PIC register
19390 When we're called from the epilogue, we need to avoid counting
19391 this as a store. */
19393 push_topmost_sequence ();
19394 top = get_insns ();
19395 pop_topmost_sequence ();
19396 reg = gen_rtx_REG (Pmode, LR_REGNO);
19398 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
19404 if (!SIBLING_CALL_P (insn))
19407 else if (find_regno_note (insn, REG_INC, LR_REGNO))
19409 else if (set_of (reg, insn) != NULL_RTX
19410 && !prologue_epilogue_contains (insn))
19417 /* Emit instructions needed to load the TOC register.
19418 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
19419 a constant pool; or for SVR4 -fpic. */
19422 rs6000_emit_load_toc_table (int fromprolog)
19425 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
19427 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
19430 rtx lab, tmp1, tmp2, got;
19432 lab = gen_label_rtx ();
19433 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (lab));
19434 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19436 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19438 got = rs6000_got_sym ();
19439 tmp1 = tmp2 = dest;
19442 tmp1 = gen_reg_rtx (Pmode);
19443 tmp2 = gen_reg_rtx (Pmode);
19445 emit_insn (gen_load_toc_v4_PIC_1 (lab));
19446 emit_move_insn (tmp1, gen_rtx_REG (Pmode, LR_REGNO));
19447 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
19448 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
19450 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
19452 emit_insn (gen_load_toc_v4_pic_si ());
19453 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19455 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
19458 rtx temp0 = (fromprolog
19459 ? gen_rtx_REG (Pmode, 0)
19460 : gen_reg_rtx (Pmode));
19466 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
19467 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19469 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
19470 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19472 emit_insn (gen_load_toc_v4_PIC_1 (symF));
19473 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19474 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
19480 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
19481 lab = gen_label_rtx ();
19482 emit_insn (gen_load_toc_v4_PIC_1b (tocsym, lab));
19483 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
19484 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
19486 emit_insn (gen_addsi3 (dest, temp0, dest));
19488 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
19490 /* This is for AIX code running in non-PIC ELF32. */
19493 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
19494 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
19496 emit_insn (gen_elf_high (dest, realsym));
19497 emit_insn (gen_elf_low (dest, dest, realsym));
19501 gcc_assert (DEFAULT_ABI == ABI_AIX);
19504 emit_insn (gen_load_toc_aix_si (dest));
19506 emit_insn (gen_load_toc_aix_di (dest));
19510 /* Emit instructions to restore the link register after determining where
19511 its value has been stored. */
19514 rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
19516 rs6000_stack_t *info = rs6000_stack_info ();
19519 operands[0] = source;
19520 operands[1] = scratch;
19522 if (info->lr_save_p)
19524 rtx frame_rtx = stack_pointer_rtx;
19525 HOST_WIDE_INT sp_offset = 0;
19528 if (frame_pointer_needed
19529 || cfun->calls_alloca
19530 || info->total_size > 32767)
19532 tmp = gen_frame_mem (Pmode, frame_rtx);
19533 emit_move_insn (operands[1], tmp);
19534 frame_rtx = operands[1];
19536 else if (info->push_p)
19537 sp_offset = info->total_size;
19539 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
19540 tmp = gen_frame_mem (Pmode, tmp);
19541 emit_move_insn (tmp, operands[0]);
19544 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
19546 /* Freeze lr_save_p. We've just emitted rtl that depends on the
19547 state of lr_save_p so any change from here on would be a bug. In
19548 particular, stop rs6000_ra_ever_killed from considering the SET
19549 of lr we may have added just above. */
19550 cfun->machine->lr_save_state = info->lr_save_p + 1;
19553 static GTY(()) alias_set_type set = -1;
19556 get_TOC_alias_set (void)
19559 set = new_alias_set ();
19563 /* This returns nonzero if the current function uses the TOC. This is
19564 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
19565 is generated by the ABI_V4 load_toc_* patterns. */
19572 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
19575 rtx pat = PATTERN (insn);
19578 if (GET_CODE (pat) == PARALLEL)
19579 for (i = 0; i < XVECLEN (pat, 0); i++)
19581 rtx sub = XVECEXP (pat, 0, i);
19582 if (GET_CODE (sub) == USE)
19584 sub = XEXP (sub, 0);
19585 if (GET_CODE (sub) == UNSPEC
19586 && XINT (sub, 1) == UNSPEC_TOC)
19596 create_TOC_reference (rtx symbol, rtx largetoc_reg)
19598 rtx tocrel, tocreg;
19600 if (TARGET_DEBUG_ADDR)
19602 if (GET_CODE (symbol) == SYMBOL_REF)
19603 fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
19607 fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
19608 GET_RTX_NAME (GET_CODE (symbol)));
19609 debug_rtx (symbol);
19613 if (!can_create_pseudo_p ())
19614 df_set_regs_ever_live (TOC_REGISTER, true);
19616 tocrel = gen_rtx_CONST (Pmode,
19617 gen_rtx_UNSPEC (Pmode, gen_rtvec (1, symbol),
19619 tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
19620 if (TARGET_CMODEL != CMODEL_SMALL)
19622 rtx hi = gen_rtx_PLUS (Pmode, tocreg, gen_rtx_HIGH (Pmode, tocrel));
19623 if (largetoc_reg != NULL)
19625 emit_move_insn (largetoc_reg, hi);
19628 return gen_rtx_LO_SUM (Pmode, hi, copy_rtx (tocrel));
19631 return gen_rtx_PLUS (Pmode, tocreg, tocrel);
19634 /* Issue assembly directives that create a reference to the given DWARF
19635 FRAME_TABLE_LABEL from the current function section. */
19637 rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label)
19639 fprintf (asm_out_file, "\t.ref %s\n",
19640 TARGET_STRIP_NAME_ENCODING (frame_table_label));
19643 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
19644 and the change to the stack pointer. */
19647 rs6000_emit_stack_tie (void)
19649 rtx mem = gen_frame_mem (BLKmode,
19650 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
19652 emit_insn (gen_stack_tie (mem));
19655 /* Emit the correct code for allocating stack space, as insns.
19656 If COPY_REG, make sure a copy of the old frame is left there.
19657 The generated code may use hard register 0 as a temporary. */
19660 rs6000_emit_allocate_stack (HOST_WIDE_INT size, rtx copy_reg)
19663 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
19664 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
19665 rtx todec = gen_int_mode (-size, Pmode);
19668 if (INTVAL (todec) != -size)
19670 warning (0, "stack frame too large");
19671 emit_insn (gen_trap ());
19675 if (crtl->limit_stack)
19677 if (REG_P (stack_limit_rtx)
19678 && REGNO (stack_limit_rtx) > 1
19679 && REGNO (stack_limit_rtx) <= 31)
19681 emit_insn (gen_add3_insn (tmp_reg, stack_limit_rtx, GEN_INT (size)));
19682 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19685 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
19687 && DEFAULT_ABI == ABI_V4)
19689 rtx toload = gen_rtx_CONST (VOIDmode,
19690 gen_rtx_PLUS (Pmode,
19694 emit_insn (gen_elf_high (tmp_reg, toload));
19695 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
19696 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
19700 warning (0, "stack limit expression is not supported");
19704 emit_move_insn (copy_reg, stack_reg);
19708 /* Need a note here so that try_split doesn't get confused. */
19709 if (get_last_insn () == NULL_RTX)
19710 emit_note (NOTE_INSN_DELETED);
19711 insn = emit_move_insn (tmp_reg, todec);
19712 try_split (PATTERN (insn), insn, 0);
19716 insn = emit_insn (TARGET_32BIT
19717 ? gen_movsi_update_stack (stack_reg, stack_reg,
19719 : gen_movdi_di_update_stack (stack_reg, stack_reg,
19720 todec, stack_reg));
19721 /* Since we didn't use gen_frame_mem to generate the MEM, grab
19722 it now and set the alias set/attributes. The above gen_*_update
19723 calls will generate a PARALLEL with the MEM set being the first
19725 par = PATTERN (insn);
19726 gcc_assert (GET_CODE (par) == PARALLEL);
19727 set = XVECEXP (par, 0, 0);
19728 gcc_assert (GET_CODE (set) == SET);
19729 mem = SET_DEST (set);
19730 gcc_assert (MEM_P (mem));
19731 MEM_NOTRAP_P (mem) = 1;
19732 set_mem_alias_set (mem, get_frame_alias_set ());
19734 RTX_FRAME_RELATED_P (insn) = 1;
19735 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
19736 gen_rtx_SET (VOIDmode, stack_reg,
19737 gen_rtx_PLUS (Pmode, stack_reg,
19738 GEN_INT (-size))));
19741 #define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
19743 #if PROBE_INTERVAL > 32768
19744 #error Cannot use indexed addressing mode for stack probing
19747 /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
19748 inclusive. These are offsets from the current stack pointer. */
19751 rs6000_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size)
19753 /* See if we have a constant small number of probes to generate. If so,
19754 that's the easy case. */
19755 if (first + size <= 32768)
19759 /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
19760 it exceeds SIZE. If only one probe is needed, this will not
19761 generate any code. Then probe at FIRST + SIZE. */
19762 for (i = PROBE_INTERVAL; i < size; i += PROBE_INTERVAL)
19763 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + i)));
19765 emit_stack_probe (plus_constant (stack_pointer_rtx, -(first + size)));
19768 /* Otherwise, do the same as above, but in a loop. Note that we must be
19769 extra careful with variables wrapping around because we might be at
19770 the very top (or the very bottom) of the address space and we have
19771 to be able to handle this case properly; in particular, we use an
19772 equality test for the loop condition. */
19775 HOST_WIDE_INT rounded_size;
19776 rtx r12 = gen_rtx_REG (Pmode, 12);
19777 rtx r0 = gen_rtx_REG (Pmode, 0);
19779 /* Sanity check for the addressing mode we're going to use. */
19780 gcc_assert (first <= 32768);
19782 /* Step 1: round SIZE to the previous multiple of the interval. */
19784 rounded_size = size & -PROBE_INTERVAL;
19787 /* Step 2: compute initial and final value of the loop counter. */
19789 /* TEST_ADDR = SP + FIRST. */
19790 emit_insn (gen_rtx_SET (VOIDmode, r12,
19791 plus_constant (stack_pointer_rtx, -first)));
19793 /* LAST_ADDR = SP + FIRST + ROUNDED_SIZE. */
19794 if (rounded_size > 32768)
19796 emit_move_insn (r0, GEN_INT (-rounded_size));
19797 emit_insn (gen_rtx_SET (VOIDmode, r0,
19798 gen_rtx_PLUS (Pmode, r12, r0)));
19801 emit_insn (gen_rtx_SET (VOIDmode, r0,
19802 plus_constant (r12, -rounded_size)));
19805 /* Step 3: the loop
19807 while (TEST_ADDR != LAST_ADDR)
19809 TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
19813 probes at FIRST + N * PROBE_INTERVAL for values of N from 1
19814 until it is equal to ROUNDED_SIZE. */
19817 emit_insn (gen_probe_stack_rangedi (r12, r12, r0));
19819 emit_insn (gen_probe_stack_rangesi (r12, r12, r0));
19822 /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
19823 that SIZE is equal to ROUNDED_SIZE. */
19825 if (size != rounded_size)
19826 emit_stack_probe (plus_constant (r12, rounded_size - size));
19830 /* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
19831 absolute addresses. */
19834 output_probe_stack_range (rtx reg1, rtx reg2)
19836 static int labelno = 0;
19837 char loop_lab[32], end_lab[32];
19840 ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno);
19841 ASM_GENERATE_INTERNAL_LABEL (end_lab, "LPSRE", labelno++);
19843 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
19845 /* Jump to END_LAB if TEST_ADDR == LAST_ADDR. */
19849 output_asm_insn ("{cmp|cmpd} 0,%0,%1", xops);
19851 output_asm_insn ("{cmp|cmpw} 0,%0,%1", xops);
19853 fputs ("\tbeq 0,", asm_out_file);
19854 assemble_name_raw (asm_out_file, end_lab);
19855 fputc ('\n', asm_out_file);
19857 /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
19858 xops[1] = GEN_INT (-PROBE_INTERVAL);
19859 output_asm_insn ("{cal %0,%1(%0)|addi %0,%0,%1}", xops);
19861 /* Probe at TEST_ADDR and branch. */
19862 output_asm_insn ("{st|stw} 0,0(%0)", xops);
19863 fprintf (asm_out_file, "\tb ");
19864 assemble_name_raw (asm_out_file, loop_lab);
19865 fputc ('\n', asm_out_file);
19867 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, end_lab);
19872 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
19873 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
19874 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
19875 deduce these equivalences by itself so it wasn't necessary to hold
19876 its hand so much. */
19879 rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
19880 rtx reg2, rtx rreg)
19884 /* copy_rtx will not make unique copies of registers, so we need to
19885 ensure we don't have unwanted sharing here. */
19887 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19890 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
19892 real = copy_rtx (PATTERN (insn));
19894 if (reg2 != NULL_RTX)
19895 real = replace_rtx (real, reg2, rreg);
19897 real = replace_rtx (real, reg,
19898 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
19899 STACK_POINTER_REGNUM),
19902 /* We expect that 'real' is either a SET or a PARALLEL containing
19903 SETs (and possibly other stuff). In a PARALLEL, all the SETs
19904 are important so they all have to be marked RTX_FRAME_RELATED_P. */
19906 if (GET_CODE (real) == SET)
19910 temp = simplify_rtx (SET_SRC (set));
19912 SET_SRC (set) = temp;
19913 temp = simplify_rtx (SET_DEST (set));
19915 SET_DEST (set) = temp;
19916 if (GET_CODE (SET_DEST (set)) == MEM)
19918 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19920 XEXP (SET_DEST (set), 0) = temp;
19927 gcc_assert (GET_CODE (real) == PARALLEL);
19928 for (i = 0; i < XVECLEN (real, 0); i++)
19929 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
19931 rtx set = XVECEXP (real, 0, i);
19933 temp = simplify_rtx (SET_SRC (set));
19935 SET_SRC (set) = temp;
19936 temp = simplify_rtx (SET_DEST (set));
19938 SET_DEST (set) = temp;
19939 if (GET_CODE (SET_DEST (set)) == MEM)
19941 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
19943 XEXP (SET_DEST (set), 0) = temp;
19945 RTX_FRAME_RELATED_P (set) = 1;
19949 RTX_FRAME_RELATED_P (insn) = 1;
19950 add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
19953 /* Returns an insn that has a vrsave set operation with the
19954 appropriate CLOBBERs. */
19957 generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
19960 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
19961 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
19964 = gen_rtx_SET (VOIDmode,
19966 gen_rtx_UNSPEC_VOLATILE (SImode,
19967 gen_rtvec (2, reg, vrsave),
19968 UNSPECV_SET_VRSAVE));
19972 /* We need to clobber the registers in the mask so the scheduler
19973 does not move sets to VRSAVE before sets of AltiVec registers.
19975 However, if the function receives nonlocal gotos, reload will set
19976 all call saved registers live. We will end up with:
19978 (set (reg 999) (mem))
19979 (parallel [ (set (reg vrsave) (unspec blah))
19980 (clobber (reg 999))])
19982 The clobber will cause the store into reg 999 to be dead, and
19983 flow will attempt to delete an epilogue insn. In this case, we
19984 need an unspec use/set of the register. */
19986 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
19987 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
19989 if (!epiloguep || call_used_regs [i])
19990 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
19991 gen_rtx_REG (V4SImode, i));
19994 rtx reg = gen_rtx_REG (V4SImode, i);
19997 = gen_rtx_SET (VOIDmode,
19999 gen_rtx_UNSPEC (V4SImode,
20000 gen_rtvec (1, reg), 27));
20004 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
20006 for (i = 0; i < nclobs; ++i)
20007 XVECEXP (insn, 0, i) = clobs[i];
20012 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
20013 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
20016 emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
20017 unsigned int regno, int offset, HOST_WIDE_INT total_size)
20019 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
20020 rtx replacea, replaceb;
20022 int_rtx = GEN_INT (offset);
20024 /* Some cases that need register indexed addressing. */
20025 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
20026 || (TARGET_VSX && VSX_VECTOR_MODE (mode))
20027 || (TARGET_E500_DOUBLE && mode == DFmode)
20029 && SPE_VECTOR_MODE (mode)
20030 && !SPE_CONST_OFFSET_OK (offset)))
20032 /* Whomever calls us must make sure r11 is available in the
20033 flow path of instructions in the prologue. */
20034 offset_rtx = gen_rtx_REG (Pmode, 11);
20035 emit_move_insn (offset_rtx, int_rtx);
20037 replacea = offset_rtx;
20038 replaceb = int_rtx;
20042 offset_rtx = int_rtx;
20043 replacea = NULL_RTX;
20044 replaceb = NULL_RTX;
20047 reg = gen_rtx_REG (mode, regno);
20048 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
20049 mem = gen_frame_mem (mode, addr);
20051 insn = emit_move_insn (mem, reg);
20053 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
20056 /* Emit an offset memory reference suitable for a frame store, while
20057 converting to a valid addressing mode. */
20060 gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
20062 rtx int_rtx, offset_rtx;
20064 int_rtx = GEN_INT (offset);
20066 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
20067 || (TARGET_E500_DOUBLE && mode == DFmode))
20069 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
20070 emit_move_insn (offset_rtx, int_rtx);
20073 offset_rtx = int_rtx;
20075 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
20078 /* Look for user-defined global regs. We should not save and restore these,
20079 and cannot use stmw/lmw if there are any in its range. */
20082 no_global_regs_above (int first, bool gpr)
20085 int last = gpr ? 32 : 64;
20086 for (i = first; i < last; i++)
20087 if (global_regs[i])
20092 #ifndef TARGET_FIX_AND_CONTINUE
20093 #define TARGET_FIX_AND_CONTINUE 0
20096 /* It's really GPR 13 and FPR 14, but we need the smaller of the two. */
20097 #define FIRST_SAVRES_REGISTER FIRST_SAVED_GP_REGNO
20098 #define LAST_SAVRES_REGISTER 31
20099 #define N_SAVRES_REGISTERS (LAST_SAVRES_REGISTER - FIRST_SAVRES_REGISTER + 1)
20101 static GTY(()) rtx savres_routine_syms[N_SAVRES_REGISTERS][8];
20103 /* Temporary holding space for an out-of-line register save/restore
20105 static char savres_routine_name[30];
20107 /* Return the name for an out-of-line register save/restore routine.
20108 We are saving/restoring GPRs if GPR is true. */
20111 rs6000_savres_routine_name (rs6000_stack_t *info, int regno,
20112 bool savep, bool gpr, bool lr)
20114 const char *prefix = "";
20115 const char *suffix = "";
20117 /* Different targets are supposed to define
20118 {SAVE,RESTORE}_FP_{PREFIX,SUFFIX} with the idea that the needed
20119 routine name could be defined with:
20121 sprintf (name, "%s%d%s", SAVE_FP_PREFIX, regno, SAVE_FP_SUFFIX)
20123 This is a nice idea in practice, but in reality, things are
20124 complicated in several ways:
20126 - ELF targets have save/restore routines for GPRs.
20128 - SPE targets use different prefixes for 32/64-bit registers, and
20129 neither of them fit neatly in the FOO_{PREFIX,SUFFIX} regimen.
20131 - PPC64 ELF targets have routines for save/restore of GPRs that
20132 differ in what they do with the link register, so having a set
20133 prefix doesn't work. (We only use one of the save routines at
20134 the moment, though.)
20136 - PPC32 elf targets have "exit" versions of the restore routines
20137 that restore the link register and can save some extra space.
20138 These require an extra suffix. (There are also "tail" versions
20139 of the restore routines and "GOT" versions of the save routines,
20140 but we don't generate those at present. Same problems apply,
20143 We deal with all this by synthesizing our own prefix/suffix and
20144 using that for the simple sprintf call shown above. */
20147 /* No floating point saves on the SPE. */
20151 prefix = info->spe_64bit_regs_used ? "_save64gpr_" : "_save32gpr_";
20153 prefix = info->spe_64bit_regs_used ? "_rest64gpr_" : "_rest32gpr_";
20158 else if (DEFAULT_ABI == ABI_V4)
20164 prefix = savep ? "_savegpr_" : "_restgpr_";
20166 prefix = savep ? "_savefpr_" : "_restfpr_";
20171 else if (DEFAULT_ABI == ABI_AIX)
20173 #ifndef POWERPC_LINUX
20174 /* No out-of-line save/restore routines for GPRs on AIX. */
20175 gcc_assert (!TARGET_AIX || !gpr);
20181 ? (lr ? "_savegpr0_" : "_savegpr1_")
20182 : (lr ? "_restgpr0_" : "_restgpr1_"));
20183 #ifdef POWERPC_LINUX
20185 prefix = (savep ? "_savefpr_" : "_restfpr_");
20189 prefix = savep ? SAVE_FP_PREFIX : RESTORE_FP_PREFIX;
20190 suffix = savep ? SAVE_FP_SUFFIX : RESTORE_FP_SUFFIX;
20193 else if (DEFAULT_ABI == ABI_DARWIN)
20194 sorry ("out-of-line save/restore routines not supported on Darwin");
20196 sprintf (savres_routine_name, "%s%d%s", prefix, regno, suffix);
20198 return savres_routine_name;
20201 /* Return an RTL SYMBOL_REF for an out-of-line register save/restore routine.
20202 We are saving/restoring GPRs if GPR is true. */
20205 rs6000_savres_routine_sym (rs6000_stack_t *info, bool savep,
20208 int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
20210 int select = ((savep ? 1 : 0) << 2
20212 /* On the SPE, we never have any FPRs, but we do have
20213 32/64-bit versions of the routines. */
20214 ? (info->spe_64bit_regs_used ? 1 : 0)
20215 : (gpr ? 1 : 0)) << 1)
20218 /* Don't generate bogus routine names. */
20219 gcc_assert (FIRST_SAVRES_REGISTER <= regno
20220 && regno <= LAST_SAVRES_REGISTER);
20222 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select];
20228 name = rs6000_savres_routine_name (info, regno, savep, gpr, lr);
20230 sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
20231 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
20232 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
20238 /* Emit a sequence of insns, including a stack tie if needed, for
20239 resetting the stack pointer. If SAVRES is true, then don't reset the
20240 stack pointer, but move the base of the frame into r11 for use by
20241 out-of-line register restore routines. */
20244 rs6000_emit_stack_reset (rs6000_stack_t *info,
20245 rtx sp_reg_rtx, rtx frame_reg_rtx,
20246 int sp_offset, bool savres)
20248 /* This blockage is needed so that sched doesn't decide to move
20249 the sp change before the register restores. */
20250 if (frame_reg_rtx != sp_reg_rtx
20252 && info->spe_64bit_regs_used != 0
20253 && info->first_gp_reg_save != 32))
20254 rs6000_emit_stack_tie ();
20256 if (frame_reg_rtx != sp_reg_rtx)
20258 if (sp_offset != 0)
20260 rtx dest_reg = savres ? gen_rtx_REG (Pmode, 11) : sp_reg_rtx;
20261 return emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx,
20262 GEN_INT (sp_offset)));
20265 return emit_move_insn (sp_reg_rtx, frame_reg_rtx);
20267 else if (sp_offset != 0)
20269 /* If we are restoring registers out-of-line, we will be using the
20270 "exit" variants of the restore routines, which will reset the
20271 stack for us. But we do need to point r11 into the right place
20272 for those routines. */
20273 rtx dest_reg = (savres
20274 ? gen_rtx_REG (Pmode, 11)
20277 rtx insn = emit_insn (gen_add3_insn (dest_reg, sp_reg_rtx,
20278 GEN_INT (sp_offset)));
20285 /* Construct a parallel rtx describing the effect of a call to an
20286 out-of-line register save/restore routine. */
20289 rs6000_make_savres_rtx (rs6000_stack_t *info,
20290 rtx frame_reg_rtx, int save_area_offset,
20291 enum machine_mode reg_mode,
20292 bool savep, bool gpr, bool lr)
20295 int offset, start_reg, end_reg, n_regs;
20296 int reg_size = GET_MODE_SIZE (reg_mode);
20302 ? info->first_gp_reg_save
20303 : info->first_fp_reg_save);
20304 end_reg = gpr ? 32 : 64;
20305 n_regs = end_reg - start_reg;
20306 p = rtvec_alloc ((lr ? 4 : 3) + n_regs);
20309 RTVEC_ELT (p, offset++) = gen_rtx_RETURN (VOIDmode);
20311 RTVEC_ELT (p, offset++)
20312 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65));
20314 sym = rs6000_savres_routine_sym (info, savep, gpr, lr);
20315 RTVEC_ELT (p, offset++) = gen_rtx_USE (VOIDmode, sym);
20316 RTVEC_ELT (p, offset++)
20317 = gen_rtx_USE (VOIDmode,
20318 gen_rtx_REG (Pmode, DEFAULT_ABI != ABI_AIX ? 11
20322 for (i = 0; i < end_reg - start_reg; i++)
20324 rtx addr, reg, mem;
20325 reg = gen_rtx_REG (reg_mode, start_reg + i);
20326 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20327 GEN_INT (save_area_offset + reg_size*i));
20328 mem = gen_frame_mem (reg_mode, addr);
20330 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode,
20332 savep ? reg : mem);
20337 rtx addr, reg, mem;
20338 reg = gen_rtx_REG (Pmode, 0);
20339 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20340 GEN_INT (info->lr_save_offset));
20341 mem = gen_frame_mem (Pmode, addr);
20342 RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg);
20345 return gen_rtx_PARALLEL (VOIDmode, p);
20348 /* Determine whether the gp REG is really used. */
20351 rs6000_reg_live_or_pic_offset_p (int reg)
20353 /* If the function calls eh_return, claim used all the registers that would
20354 be checked for liveness otherwise. This is required for the PIC offset
20355 register with -mminimal-toc on AIX, as it is advertised as "fixed" for
20356 register allocation purposes in this case. */
20358 return (((crtl->calls_eh_return || df_regs_ever_live_p (reg))
20359 && (!call_used_regs[reg]
20360 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20361 && !TARGET_SINGLE_PIC_BASE
20362 && TARGET_TOC && TARGET_MINIMAL_TOC)))
20363 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
20364 && !TARGET_SINGLE_PIC_BASE
20365 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
20366 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
20369 /* Emit function prologue as insns. */
20372 rs6000_emit_prologue (void)
20374 rs6000_stack_t *info = rs6000_stack_info ();
20375 enum machine_mode reg_mode = Pmode;
20376 int reg_size = TARGET_32BIT ? 4 : 8;
20377 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
20378 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
20379 rtx frame_reg_rtx = sp_reg_rtx;
20380 rtx cr_save_rtx = NULL_RTX;
20383 int saving_FPRs_inline;
20384 int saving_GPRs_inline;
20385 int using_store_multiple;
20386 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
20387 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
20388 && call_used_regs[STATIC_CHAIN_REGNUM]);
20389 HOST_WIDE_INT sp_offset = 0;
20391 if (flag_stack_usage)
20392 current_function_static_stack_size = info->total_size;
20394 if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK && info->total_size)
20395 rs6000_emit_probe_stack_range (STACK_CHECK_PROTECT, info->total_size);
20397 if (TARGET_FIX_AND_CONTINUE)
20399 /* gdb on darwin arranges to forward a function from the old
20400 address by modifying the first 5 instructions of the function
20401 to branch to the overriding function. This is necessary to
20402 permit function pointers that point to the old function to
20403 actually forward to the new function. */
20404 emit_insn (gen_nop ());
20405 emit_insn (gen_nop ());
20406 emit_insn (gen_nop ());
20407 emit_insn (gen_nop ());
20408 emit_insn (gen_nop ());
20411 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
20413 reg_mode = V2SImode;
20417 strategy = info->savres_strategy;
20418 using_store_multiple = strategy & SAVRES_MULTIPLE;
20419 saving_FPRs_inline = strategy & SAVE_INLINE_FPRS;
20420 saving_GPRs_inline = strategy & SAVE_INLINE_GPRS;
20422 /* For V.4, update stack before we do any saving and set back pointer. */
20423 if (! WORLD_SAVE_P (info)
20425 && (DEFAULT_ABI == ABI_V4
20426 || crtl->calls_eh_return))
20428 bool need_r11 = (TARGET_SPE
20429 ? (!saving_GPRs_inline
20430 && info->spe_64bit_regs_used == 0)
20431 : (!saving_FPRs_inline || !saving_GPRs_inline));
20432 rtx copy_reg = need_r11 ? gen_rtx_REG (Pmode, 11) : NULL;
20434 if (info->total_size < 32767)
20435 sp_offset = info->total_size;
20437 frame_reg_rtx = copy_reg;
20438 else if (info->cr_save_p
20440 || info->first_fp_reg_save < 64
20441 || info->first_gp_reg_save < 32
20442 || info->altivec_size != 0
20443 || info->vrsave_mask != 0
20444 || crtl->calls_eh_return)
20446 copy_reg = frame_ptr_rtx;
20447 frame_reg_rtx = copy_reg;
20451 /* The prologue won't be saving any regs so there is no need
20452 to set up a frame register to access any frame save area.
20453 We also won't be using sp_offset anywhere below, but set
20454 the correct value anyway to protect against future
20455 changes to this function. */
20456 sp_offset = info->total_size;
20458 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20459 if (frame_reg_rtx != sp_reg_rtx)
20460 rs6000_emit_stack_tie ();
20463 /* Handle world saves specially here. */
20464 if (WORLD_SAVE_P (info))
20471 /* save_world expects lr in r0. */
20472 reg0 = gen_rtx_REG (Pmode, 0);
20473 if (info->lr_save_p)
20475 insn = emit_move_insn (reg0,
20476 gen_rtx_REG (Pmode, LR_REGNO));
20477 RTX_FRAME_RELATED_P (insn) = 1;
20480 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
20481 assumptions about the offsets of various bits of the stack
20483 gcc_assert (info->gp_save_offset == -220
20484 && info->fp_save_offset == -144
20485 && info->lr_save_offset == 8
20486 && info->cr_save_offset == 4
20489 && (!crtl->calls_eh_return
20490 || info->ehrd_offset == -432)
20491 && info->vrsave_save_offset == -224
20492 && info->altivec_save_offset == -416);
20494 treg = gen_rtx_REG (SImode, 11);
20495 emit_move_insn (treg, GEN_INT (-info->total_size));
20497 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
20498 in R11. It also clobbers R12, so beware! */
20500 /* Preserve CR2 for save_world prologues */
20502 sz += 32 - info->first_gp_reg_save;
20503 sz += 64 - info->first_fp_reg_save;
20504 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
20505 p = rtvec_alloc (sz);
20507 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
20508 gen_rtx_REG (SImode,
20510 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
20511 gen_rtx_SYMBOL_REF (Pmode,
20513 /* We do floats first so that the instruction pattern matches
20515 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20517 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20518 ? DFmode : SFmode),
20519 info->first_fp_reg_save + i);
20520 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20521 GEN_INT (info->fp_save_offset
20522 + sp_offset + 8 * i));
20523 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20524 ? DFmode : SFmode), addr);
20526 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20528 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
20530 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
20531 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20532 GEN_INT (info->altivec_save_offset
20533 + sp_offset + 16 * i));
20534 rtx mem = gen_frame_mem (V4SImode, addr);
20536 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20538 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20540 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20541 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20542 GEN_INT (info->gp_save_offset
20543 + sp_offset + reg_size * i));
20544 rtx mem = gen_frame_mem (reg_mode, addr);
20546 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20550 /* CR register traditionally saved as CR2. */
20551 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
20552 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20553 GEN_INT (info->cr_save_offset
20555 rtx mem = gen_frame_mem (reg_mode, addr);
20557 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
20559 /* Explain about use of R0. */
20560 if (info->lr_save_p)
20562 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20563 GEN_INT (info->lr_save_offset
20565 rtx mem = gen_frame_mem (reg_mode, addr);
20567 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
20569 /* Explain what happens to the stack pointer. */
20571 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
20572 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
20575 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20576 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20577 treg, GEN_INT (-info->total_size));
20578 sp_offset = info->total_size;
20581 /* If we use the link register, get it into r0. */
20582 if (!WORLD_SAVE_P (info) && info->lr_save_p)
20584 rtx addr, reg, mem;
20586 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
20587 gen_rtx_REG (Pmode, LR_REGNO));
20588 RTX_FRAME_RELATED_P (insn) = 1;
20590 if (!(strategy & (SAVE_NOINLINE_GPRS_SAVES_LR
20591 | SAVE_NOINLINE_FPRS_SAVES_LR)))
20593 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20594 GEN_INT (info->lr_save_offset + sp_offset));
20595 reg = gen_rtx_REG (Pmode, 0);
20596 mem = gen_rtx_MEM (Pmode, addr);
20597 /* This should not be of rs6000_sr_alias_set, because of
20598 __builtin_return_address. */
20600 insn = emit_move_insn (mem, reg);
20601 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20602 NULL_RTX, NULL_RTX);
20606 /* If we need to save CR, put it into r12 or r11. */
20607 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
20612 = gen_rtx_REG (SImode, DEFAULT_ABI == ABI_AIX && !saving_GPRs_inline
20614 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20615 RTX_FRAME_RELATED_P (insn) = 1;
20616 /* Now, there's no way that dwarf2out_frame_debug_expr is going
20617 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
20618 But that's OK. All we have to do is specify that _one_ condition
20619 code register is saved in this stack slot. The thrower's epilogue
20620 will then restore all the call-saved registers.
20621 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
20622 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
20623 gen_rtx_REG (SImode, CR2_REGNO));
20624 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20627 /* Do any required saving of fpr's. If only one or two to save, do
20628 it ourselves. Otherwise, call function. */
20629 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
20632 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
20633 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
20634 && ! call_used_regs[info->first_fp_reg_save+i]))
20635 emit_frame_save (frame_reg_rtx, frame_ptr_rtx,
20636 (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
20638 info->first_fp_reg_save + i,
20639 info->fp_save_offset + sp_offset + 8 * i,
20642 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
20646 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20647 info->fp_save_offset + sp_offset,
20649 /*savep=*/true, /*gpr=*/false,
20651 & SAVE_NOINLINE_FPRS_SAVES_LR)
20653 insn = emit_insn (par);
20654 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20655 NULL_RTX, NULL_RTX);
20658 /* Save GPRs. This is done as a PARALLEL if we are using
20659 the store-multiple instructions. */
20660 if (!WORLD_SAVE_P (info)
20662 && info->spe_64bit_regs_used != 0
20663 && info->first_gp_reg_save != 32)
20666 rtx spe_save_area_ptr;
20668 /* Determine whether we can address all of the registers that need
20669 to be saved with an offset from the stack pointer that fits in
20670 the small const field for SPE memory instructions. */
20671 int spe_regs_addressable_via_sp
20672 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
20673 + (32 - info->first_gp_reg_save - 1) * reg_size)
20674 && saving_GPRs_inline);
20677 if (spe_regs_addressable_via_sp)
20679 spe_save_area_ptr = frame_reg_rtx;
20680 spe_offset = info->spe_gp_save_offset + sp_offset;
20684 /* Make r11 point to the start of the SPE save area. We need
20685 to be careful here if r11 is holding the static chain. If
20686 it is, then temporarily save it in r0. We would use r0 as
20687 our base register here, but using r0 as a base register in
20688 loads and stores means something different from what we
20690 int ool_adjust = (saving_GPRs_inline
20692 : (info->first_gp_reg_save
20693 - (FIRST_SAVRES_REGISTER+1))*8);
20694 HOST_WIDE_INT offset = (info->spe_gp_save_offset
20695 + sp_offset - ool_adjust);
20697 if (using_static_chain_p)
20699 rtx r0 = gen_rtx_REG (Pmode, 0);
20700 gcc_assert (info->first_gp_reg_save > 11);
20702 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
20705 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
20706 insn = emit_insn (gen_addsi3 (spe_save_area_ptr,
20708 GEN_INT (offset)));
20709 /* We need to make sure the move to r11 gets noted for
20710 properly outputting unwind information. */
20711 if (!saving_GPRs_inline)
20712 rs6000_frame_related (insn, frame_reg_rtx, offset,
20713 NULL_RTX, NULL_RTX);
20717 if (saving_GPRs_inline)
20719 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20720 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20722 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20723 rtx offset, addr, mem;
20725 /* We're doing all this to ensure that the offset fits into
20726 the immediate offset of 'evstdd'. */
20727 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
20729 offset = GEN_INT (reg_size * i + spe_offset);
20730 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
20731 mem = gen_rtx_MEM (V2SImode, addr);
20733 insn = emit_move_insn (mem, reg);
20735 rs6000_frame_related (insn, spe_save_area_ptr,
20736 info->spe_gp_save_offset
20737 + sp_offset + reg_size * i,
20738 offset, const0_rtx);
20745 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
20747 /*savep=*/true, /*gpr=*/true,
20749 insn = emit_insn (par);
20750 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20751 NULL_RTX, NULL_RTX);
20755 /* Move the static chain pointer back. */
20756 if (using_static_chain_p && !spe_regs_addressable_via_sp)
20757 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
20759 else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline)
20763 /* Need to adjust r11 (r12) if we saved any FPRs. */
20764 if (info->first_fp_reg_save != 64)
20766 rtx dest_reg = gen_rtx_REG (reg_mode, DEFAULT_ABI == ABI_AIX
20768 rtx offset = GEN_INT (sp_offset
20769 + (-8 * (64-info->first_fp_reg_save)));
20770 emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset));
20773 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
20774 info->gp_save_offset + sp_offset,
20776 /*savep=*/true, /*gpr=*/true,
20778 & SAVE_NOINLINE_GPRS_SAVES_LR)
20780 insn = emit_insn (par);
20781 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20782 NULL_RTX, NULL_RTX);
20784 else if (!WORLD_SAVE_P (info) && using_store_multiple)
20788 p = rtvec_alloc (32 - info->first_gp_reg_save);
20789 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20791 rtx addr, reg, mem;
20792 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20793 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20794 GEN_INT (info->gp_save_offset
20797 mem = gen_frame_mem (reg_mode, addr);
20799 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
20801 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
20802 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20803 NULL_RTX, NULL_RTX);
20805 else if (!WORLD_SAVE_P (info))
20808 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
20809 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
20811 rtx addr, reg, mem;
20812 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
20814 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20815 GEN_INT (info->gp_save_offset
20818 mem = gen_frame_mem (reg_mode, addr);
20820 insn = emit_move_insn (mem, reg);
20821 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20822 NULL_RTX, NULL_RTX);
20826 /* ??? There's no need to emit actual instructions here, but it's the
20827 easiest way to get the frame unwind information emitted. */
20828 if (crtl->calls_eh_return)
20830 unsigned int i, regno;
20834 regno = EH_RETURN_DATA_REGNO (i);
20835 if (regno == INVALID_REGNUM)
20838 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
20839 info->ehrd_offset + sp_offset
20840 + reg_size * (int) i,
20845 /* In AIX ABI we need to make sure r2 is really saved. */
20846 if (TARGET_AIX && crtl->calls_eh_return)
20848 rtx tmp_reg, tmp_reg_si, hi, lo, compare_result, toc_save_done, jump;
20849 long toc_restore_insn;
20851 gcc_assert (frame_reg_rtx == frame_ptr_rtx
20852 || frame_reg_rtx == sp_reg_rtx);
20853 tmp_reg = gen_rtx_REG (Pmode, 11);
20854 tmp_reg_si = gen_rtx_REG (SImode, 11);
20855 if (using_static_chain_p)
20856 emit_move_insn (gen_rtx_REG (Pmode, 0), tmp_reg);
20857 gcc_assert (saving_GPRs_inline && saving_FPRs_inline);
20858 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, LR_REGNO));
20859 /* Peek at instruction to which this function returns. If it's
20860 restoring r2, then we know we've already saved r2. We can't
20861 unconditionally save r2 because the value we have will already
20862 be updated if we arrived at this function via a plt call or
20863 toc adjusting stub. */
20864 emit_move_insn (tmp_reg_si, gen_rtx_MEM (SImode, tmp_reg));
20865 toc_restore_insn = TARGET_32BIT ? 0x80410014 : 0xE8410028;
20866 hi = gen_int_mode (toc_restore_insn & ~0xffff, SImode);
20867 emit_insn (gen_xorsi3 (tmp_reg_si, tmp_reg_si, hi));
20868 compare_result = gen_rtx_REG (CCUNSmode, CR0_REGNO);
20869 validate_condition_mode (EQ, CCUNSmode);
20870 lo = gen_int_mode (toc_restore_insn & 0xffff, SImode);
20871 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
20872 gen_rtx_COMPARE (CCUNSmode, tmp_reg_si, lo)));
20873 toc_save_done = gen_label_rtx ();
20874 jump = gen_rtx_IF_THEN_ELSE (VOIDmode,
20875 gen_rtx_EQ (VOIDmode, compare_result,
20877 gen_rtx_LABEL_REF (VOIDmode, toc_save_done),
20879 jump = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, jump));
20880 JUMP_LABEL (jump) = toc_save_done;
20881 LABEL_NUSES (toc_save_done) += 1;
20883 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, 2,
20884 sp_offset + 5 * reg_size, info->total_size);
20885 emit_label (toc_save_done);
20886 if (using_static_chain_p)
20887 emit_move_insn (tmp_reg, gen_rtx_REG (Pmode, 0));
20890 /* Save CR if we use any that must be preserved. */
20891 if (!WORLD_SAVE_P (info) && info->cr_save_p)
20893 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
20894 GEN_INT (info->cr_save_offset + sp_offset));
20895 rtx mem = gen_frame_mem (SImode, addr);
20896 /* See the large comment above about why CR2_REGNO is used. */
20897 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
20899 /* If r12 was used to hold the original sp, copy cr into r0 now
20901 if (REGNO (frame_reg_rtx) == 12)
20905 cr_save_rtx = gen_rtx_REG (SImode, 0);
20906 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
20907 RTX_FRAME_RELATED_P (insn) = 1;
20908 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
20909 add_reg_note (insn, REG_FRAME_RELATED_EXPR, set);
20911 insn = emit_move_insn (mem, cr_save_rtx);
20913 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20914 NULL_RTX, NULL_RTX);
20917 /* Update stack and set back pointer unless this is V.4,
20918 for which it was done previously. */
20919 if (!WORLD_SAVE_P (info) && info->push_p
20920 && !(DEFAULT_ABI == ABI_V4 || crtl->calls_eh_return))
20922 rtx copy_reg = NULL;
20924 if (info->total_size < 32767)
20925 sp_offset = info->total_size;
20926 else if (info->altivec_size != 0
20927 || info->vrsave_mask != 0)
20929 copy_reg = frame_ptr_rtx;
20930 frame_reg_rtx = copy_reg;
20933 sp_offset = info->total_size;
20934 rs6000_emit_allocate_stack (info->total_size, copy_reg);
20935 if (frame_reg_rtx != sp_reg_rtx)
20936 rs6000_emit_stack_tie ();
20939 /* Set frame pointer, if needed. */
20940 if (frame_pointer_needed)
20942 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
20944 RTX_FRAME_RELATED_P (insn) = 1;
20947 /* Save AltiVec registers if needed. Save here because the red zone does
20948 not include AltiVec registers. */
20949 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
20953 /* There should be a non inline version of this, for when we
20954 are saving lots of vector registers. */
20955 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
20956 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
20958 rtx areg, savereg, mem;
20961 offset = info->altivec_save_offset + sp_offset
20962 + 16 * (i - info->first_altivec_reg_save);
20964 savereg = gen_rtx_REG (V4SImode, i);
20966 areg = gen_rtx_REG (Pmode, 0);
20967 emit_move_insn (areg, GEN_INT (offset));
20969 /* AltiVec addressing mode is [reg+reg]. */
20970 mem = gen_frame_mem (V4SImode,
20971 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
20973 insn = emit_move_insn (mem, savereg);
20975 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
20976 areg, GEN_INT (offset));
20980 /* VRSAVE is a bit vector representing which AltiVec registers
20981 are used. The OS uses this to determine which vector
20982 registers to save on a context switch. We need to save
20983 VRSAVE on the stack frame, add whatever AltiVec registers we
20984 used in this function, and do the corresponding magic in the
20987 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
20988 && info->vrsave_mask != 0)
20990 rtx reg, mem, vrsave;
20993 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
20994 as frame_reg_rtx and r11 as the static chain pointer for
20995 nested functions. */
20996 reg = gen_rtx_REG (SImode, 0);
20997 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
20999 emit_insn (gen_get_vrsave_internal (reg));
21001 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
21003 if (!WORLD_SAVE_P (info))
21006 offset = info->vrsave_save_offset + sp_offset;
21007 mem = gen_frame_mem (SImode,
21008 gen_rtx_PLUS (Pmode, frame_reg_rtx,
21009 GEN_INT (offset)));
21010 insn = emit_move_insn (mem, reg);
21013 /* Include the registers in the mask. */
21014 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
21016 insn = emit_insn (generate_set_vrsave (reg, info, 0));
21019 if (TARGET_SINGLE_PIC_BASE)
21020 return; /* Do not set PIC register */
21022 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
21023 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
21024 || (DEFAULT_ABI == ABI_V4
21025 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
21026 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
21028 /* If emit_load_toc_table will use the link register, we need to save
21029 it. We use R12 for this purpose because emit_load_toc_table
21030 can use register 0. This allows us to use a plain 'blr' to return
21031 from the procedure more often. */
21032 int save_LR_around_toc_setup = (TARGET_ELF
21033 && DEFAULT_ABI != ABI_AIX
21035 && ! info->lr_save_p
21036 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
21037 if (save_LR_around_toc_setup)
21039 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21041 insn = emit_move_insn (frame_ptr_rtx, lr);
21042 RTX_FRAME_RELATED_P (insn) = 1;
21044 rs6000_emit_load_toc_table (TRUE);
21046 insn = emit_move_insn (lr, frame_ptr_rtx);
21047 RTX_FRAME_RELATED_P (insn) = 1;
21050 rs6000_emit_load_toc_table (TRUE);
21054 if (DEFAULT_ABI == ABI_DARWIN
21055 && flag_pic && crtl->uses_pic_offset_table)
21057 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
21058 rtx src = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
21060 /* Save and restore LR locally around this call (in R0). */
21061 if (!info->lr_save_p)
21062 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
21064 emit_insn (gen_load_macho_picbase (src));
21066 emit_move_insn (gen_rtx_REG (Pmode,
21067 RS6000_PIC_OFFSET_TABLE_REGNUM),
21070 if (!info->lr_save_p)
21071 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
21076 /* Write function prologue. */
21079 rs6000_output_function_prologue (FILE *file,
21080 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21082 rs6000_stack_t *info = rs6000_stack_info ();
21084 if (TARGET_DEBUG_STACK)
21085 debug_stack_info (info);
21087 /* Write .extern for any function we will call to save and restore
21089 if (info->first_fp_reg_save < 64)
21092 int regno = info->first_fp_reg_save - 32;
21094 if ((info->savres_strategy & SAVE_INLINE_FPRS) == 0)
21096 name = rs6000_savres_routine_name (info, regno, /*savep=*/true,
21097 /*gpr=*/false, /*lr=*/false);
21098 fprintf (file, "\t.extern %s\n", name);
21100 if ((info->savres_strategy & REST_INLINE_FPRS) == 0)
21102 name = rs6000_savres_routine_name (info, regno, /*savep=*/false,
21103 /*gpr=*/false, /*lr=*/true);
21104 fprintf (file, "\t.extern %s\n", name);
21108 /* Write .extern for AIX common mode routines, if needed. */
21109 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
21111 fputs ("\t.extern __mulh\n", file);
21112 fputs ("\t.extern __mull\n", file);
21113 fputs ("\t.extern __divss\n", file);
21114 fputs ("\t.extern __divus\n", file);
21115 fputs ("\t.extern __quoss\n", file);
21116 fputs ("\t.extern __quous\n", file);
21117 common_mode_defined = 1;
21120 if (! HAVE_prologue)
21126 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
21127 the "toplevel" insn chain. */
21128 emit_note (NOTE_INSN_DELETED);
21129 rs6000_emit_prologue ();
21130 emit_note (NOTE_INSN_DELETED);
21132 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21136 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21138 INSN_ADDRESSES_NEW (insn, addr);
21143 prologue = get_insns ();
21146 if (TARGET_DEBUG_STACK)
21147 debug_rtx_list (prologue, 100);
21149 emit_insn_before_noloc (prologue, BB_HEAD (ENTRY_BLOCK_PTR->next_bb),
21153 rs6000_pic_labelno++;
21156 /* Non-zero if vmx regs are restored before the frame pop, zero if
21157 we restore after the pop when possible. */
21158 #define ALWAYS_RESTORE_ALTIVEC_BEFORE_POP 0
21160 /* Reload CR from REG. */
21163 rs6000_restore_saved_cr (rtx reg, int using_mfcr_multiple)
21168 if (using_mfcr_multiple)
21170 for (i = 0; i < 8; i++)
21171 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21173 gcc_assert (count);
21176 if (using_mfcr_multiple && count > 1)
21181 p = rtvec_alloc (count);
21184 for (i = 0; i < 8; i++)
21185 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21187 rtvec r = rtvec_alloc (2);
21188 RTVEC_ELT (r, 0) = reg;
21189 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
21190 RTVEC_ELT (p, ndx) =
21191 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
21192 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
21195 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21196 gcc_assert (ndx == count);
21199 for (i = 0; i < 8; i++)
21200 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
21202 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
21208 /* Return true if OFFSET from stack pointer can be clobbered by signals.
21209 V.4 doesn't have any stack cushion, AIX ABIs have 220 or 288 bytes
21210 below stack pointer not cloberred by signals. */
21213 offset_below_red_zone_p (HOST_WIDE_INT offset)
21215 return offset < (DEFAULT_ABI == ABI_V4
21217 : TARGET_32BIT ? -220 : -288);
21220 /* Emit function epilogue as insns. */
21223 rs6000_emit_epilogue (int sibcall)
21225 rs6000_stack_t *info;
21226 int restoring_GPRs_inline;
21227 int restoring_FPRs_inline;
21228 int using_load_multiple;
21229 int using_mtcr_multiple;
21230 int use_backchain_to_restore_sp;
21234 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
21235 rtx frame_reg_rtx = sp_reg_rtx;
21236 rtx cfa_restores = NULL_RTX;
21238 rtx cr_save_reg = NULL_RTX;
21239 enum machine_mode reg_mode = Pmode;
21240 int reg_size = TARGET_32BIT ? 4 : 8;
21243 info = rs6000_stack_info ();
21245 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
21247 reg_mode = V2SImode;
21251 strategy = info->savres_strategy;
21252 using_load_multiple = strategy & SAVRES_MULTIPLE;
21253 restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
21254 restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS);
21255 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
21256 || rs6000_cpu == PROCESSOR_PPC603
21257 || rs6000_cpu == PROCESSOR_PPC750
21259 /* Restore via the backchain when we have a large frame, since this
21260 is more efficient than an addis, addi pair. The second condition
21261 here will not trigger at the moment; We don't actually need a
21262 frame pointer for alloca, but the generic parts of the compiler
21263 give us one anyway. */
21264 use_backchain_to_restore_sp = (info->total_size > 32767
21265 || info->total_size
21266 + (info->lr_save_p ? info->lr_save_offset : 0)
21268 || (cfun->calls_alloca
21269 && !frame_pointer_needed));
21270 restore_lr = (info->lr_save_p
21271 && (restoring_FPRs_inline
21272 || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
21273 && (restoring_GPRs_inline
21274 || info->first_fp_reg_save < 64));
21276 if (WORLD_SAVE_P (info))
21280 const char *alloc_rname;
21283 /* eh_rest_world_r10 will return to the location saved in the LR
21284 stack slot (which is not likely to be our caller.)
21285 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
21286 rest_world is similar, except any R10 parameter is ignored.
21287 The exception-handling stuff that was here in 2.95 is no
21288 longer necessary. */
21292 + 32 - info->first_gp_reg_save
21293 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
21294 + 63 + 1 - info->first_fp_reg_save);
21296 strcpy (rname, ((crtl->calls_eh_return) ?
21297 "*eh_rest_world_r10" : "*rest_world"));
21298 alloc_rname = ggc_strdup (rname);
21301 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
21302 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
21303 gen_rtx_REG (Pmode,
21306 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
21307 /* The instruction pattern requires a clobber here;
21308 it is shared with the restVEC helper. */
21310 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
21313 /* CR register traditionally saved as CR2. */
21314 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
21315 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21316 GEN_INT (info->cr_save_offset));
21317 rtx mem = gen_frame_mem (reg_mode, addr);
21319 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21322 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21324 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21325 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21326 GEN_INT (info->gp_save_offset
21328 rtx mem = gen_frame_mem (reg_mode, addr);
21330 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21332 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
21334 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
21335 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21336 GEN_INT (info->altivec_save_offset
21338 rtx mem = gen_frame_mem (V4SImode, addr);
21340 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21342 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
21344 rtx reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21345 ? DFmode : SFmode),
21346 info->first_fp_reg_save + i);
21347 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21348 GEN_INT (info->fp_save_offset
21350 rtx mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21351 ? DFmode : SFmode), addr);
21353 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
21356 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
21358 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
21360 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
21362 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
21364 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
21365 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21370 /* frame_reg_rtx + sp_offset points to the top of this stack frame. */
21372 sp_offset = info->total_size;
21374 /* Restore AltiVec registers if we must do so before adjusting the
21376 if (TARGET_ALTIVEC_ABI
21377 && info->altivec_size != 0
21378 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21379 || (DEFAULT_ABI != ABI_V4
21380 && offset_below_red_zone_p (info->altivec_save_offset))))
21384 if (use_backchain_to_restore_sp)
21386 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21387 emit_move_insn (frame_reg_rtx,
21388 gen_rtx_MEM (Pmode, sp_reg_rtx));
21391 else if (frame_pointer_needed)
21392 frame_reg_rtx = hard_frame_pointer_rtx;
21394 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21395 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21397 rtx addr, areg, mem, reg;
21399 areg = gen_rtx_REG (Pmode, 0);
21401 (areg, GEN_INT (info->altivec_save_offset
21403 + 16 * (i - info->first_altivec_reg_save)));
21405 /* AltiVec addressing mode is [reg+reg]. */
21406 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21407 mem = gen_frame_mem (V4SImode, addr);
21409 reg = gen_rtx_REG (V4SImode, i);
21410 emit_move_insn (reg, mem);
21411 if (offset_below_red_zone_p (info->altivec_save_offset
21412 + (i - info->first_altivec_reg_save)
21414 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21419 /* Restore VRSAVE if we must do so before adjusting the stack. */
21421 && TARGET_ALTIVEC_VRSAVE
21422 && info->vrsave_mask != 0
21423 && (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21424 || (DEFAULT_ABI != ABI_V4
21425 && offset_below_red_zone_p (info->vrsave_save_offset))))
21427 rtx addr, mem, reg;
21429 if (frame_reg_rtx == sp_reg_rtx)
21431 if (use_backchain_to_restore_sp)
21433 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21434 emit_move_insn (frame_reg_rtx,
21435 gen_rtx_MEM (Pmode, sp_reg_rtx));
21438 else if (frame_pointer_needed)
21439 frame_reg_rtx = hard_frame_pointer_rtx;
21442 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21443 GEN_INT (info->vrsave_save_offset + sp_offset));
21444 mem = gen_frame_mem (SImode, addr);
21445 reg = gen_rtx_REG (SImode, 12);
21446 emit_move_insn (reg, mem);
21448 emit_insn (generate_set_vrsave (reg, info, 1));
21452 /* If we have a large stack frame, restore the old stack pointer
21453 using the backchain. */
21454 if (use_backchain_to_restore_sp)
21456 if (frame_reg_rtx == sp_reg_rtx)
21458 /* Under V.4, don't reset the stack pointer until after we're done
21459 loading the saved registers. */
21460 if (DEFAULT_ABI == ABI_V4)
21461 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21463 insn = emit_move_insn (frame_reg_rtx,
21464 gen_rtx_MEM (Pmode, sp_reg_rtx));
21467 else if (ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21468 && DEFAULT_ABI == ABI_V4)
21469 /* frame_reg_rtx has been set up by the altivec restore. */
21473 insn = emit_move_insn (sp_reg_rtx, frame_reg_rtx);
21474 frame_reg_rtx = sp_reg_rtx;
21477 /* If we have a frame pointer, we can restore the old stack pointer
21479 else if (frame_pointer_needed)
21481 frame_reg_rtx = sp_reg_rtx;
21482 if (DEFAULT_ABI == ABI_V4)
21483 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21484 /* Prevent reordering memory accesses against stack pointer restore. */
21485 else if (cfun->calls_alloca
21486 || offset_below_red_zone_p (-info->total_size))
21488 rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx);
21489 rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21490 MEM_NOTRAP_P (mem1) = 1;
21491 MEM_NOTRAP_P (mem2) = 1;
21492 emit_insn (gen_frame_tie (mem1, mem2));
21495 insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx,
21496 GEN_INT (info->total_size)));
21499 else if (info->push_p
21500 && DEFAULT_ABI != ABI_V4
21501 && !crtl->calls_eh_return)
21503 /* Prevent reordering memory accesses against stack pointer restore. */
21504 if (cfun->calls_alloca
21505 || offset_below_red_zone_p (-info->total_size))
21507 rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx);
21508 MEM_NOTRAP_P (mem) = 1;
21509 emit_insn (gen_stack_tie (mem));
21511 insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx,
21512 GEN_INT (info->total_size)));
21515 if (insn && frame_reg_rtx == sp_reg_rtx)
21519 REG_NOTES (insn) = cfa_restores;
21520 cfa_restores = NULL_RTX;
21522 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21523 RTX_FRAME_RELATED_P (insn) = 1;
21526 /* Restore AltiVec registers if we have not done so already. */
21527 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21528 && TARGET_ALTIVEC_ABI
21529 && info->altivec_size != 0
21530 && (DEFAULT_ABI == ABI_V4
21531 || !offset_below_red_zone_p (info->altivec_save_offset)))
21535 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
21536 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
21538 rtx addr, areg, mem, reg;
21540 areg = gen_rtx_REG (Pmode, 0);
21542 (areg, GEN_INT (info->altivec_save_offset
21544 + 16 * (i - info->first_altivec_reg_save)));
21546 /* AltiVec addressing mode is [reg+reg]. */
21547 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
21548 mem = gen_frame_mem (V4SImode, addr);
21550 reg = gen_rtx_REG (V4SImode, i);
21551 emit_move_insn (reg, mem);
21552 if (DEFAULT_ABI == ABI_V4)
21553 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21558 /* Restore VRSAVE if we have not done so already. */
21559 if (!ALWAYS_RESTORE_ALTIVEC_BEFORE_POP
21561 && TARGET_ALTIVEC_VRSAVE
21562 && info->vrsave_mask != 0
21563 && (DEFAULT_ABI == ABI_V4
21564 || !offset_below_red_zone_p (info->vrsave_save_offset)))
21566 rtx addr, mem, reg;
21568 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21569 GEN_INT (info->vrsave_save_offset + sp_offset));
21570 mem = gen_frame_mem (SImode, addr);
21571 reg = gen_rtx_REG (SImode, 12);
21572 emit_move_insn (reg, mem);
21574 emit_insn (generate_set_vrsave (reg, info, 1));
21577 /* Get the old lr if we saved it. If we are restoring registers
21578 out-of-line, then the out-of-line routines can do this for us. */
21579 if (restore_lr && restoring_GPRs_inline)
21581 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21582 info->lr_save_offset + sp_offset);
21584 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21587 /* Get the old cr if we saved it. */
21588 if (info->cr_save_p)
21590 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21591 GEN_INT (info->cr_save_offset + sp_offset));
21592 rtx mem = gen_frame_mem (SImode, addr);
21594 cr_save_reg = gen_rtx_REG (SImode,
21595 DEFAULT_ABI == ABI_AIX
21596 && !restoring_GPRs_inline
21597 && info->first_fp_reg_save < 64
21599 emit_move_insn (cr_save_reg, mem);
21602 /* Set LR here to try to overlap restores below. LR is always saved
21603 above incoming stack, so it never needs REG_CFA_RESTORE. */
21604 if (restore_lr && restoring_GPRs_inline)
21605 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21606 gen_rtx_REG (Pmode, 0));
21608 /* Load exception handler data registers, if needed. */
21609 if (crtl->calls_eh_return)
21611 unsigned int i, regno;
21615 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21616 GEN_INT (sp_offset + 5 * reg_size));
21617 rtx mem = gen_frame_mem (reg_mode, addr);
21619 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
21626 regno = EH_RETURN_DATA_REGNO (i);
21627 if (regno == INVALID_REGNUM)
21630 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
21631 info->ehrd_offset + sp_offset
21632 + reg_size * (int) i);
21634 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
21638 /* Restore GPRs. This is done as a PARALLEL if we are using
21639 the load-multiple instructions. */
21641 && info->spe_64bit_regs_used != 0
21642 && info->first_gp_reg_save != 32)
21644 /* Determine whether we can address all of the registers that need
21645 to be saved with an offset from the stack pointer that fits in
21646 the small const field for SPE memory instructions. */
21647 int spe_regs_addressable_via_sp
21648 = (SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
21649 + (32 - info->first_gp_reg_save - 1) * reg_size)
21650 && restoring_GPRs_inline);
21653 if (spe_regs_addressable_via_sp)
21654 spe_offset = info->spe_gp_save_offset + sp_offset;
21657 rtx old_frame_reg_rtx = frame_reg_rtx;
21658 /* Make r11 point to the start of the SPE save area. We worried about
21659 not clobbering it when we were saving registers in the prologue.
21660 There's no need to worry here because the static chain is passed
21661 anew to every function. */
21662 int ool_adjust = (restoring_GPRs_inline
21664 : (info->first_gp_reg_save
21665 - (FIRST_SAVRES_REGISTER+1))*8);
21667 if (frame_reg_rtx == sp_reg_rtx)
21668 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
21669 emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
21670 GEN_INT (info->spe_gp_save_offset
21673 /* Keep the invariant that frame_reg_rtx + sp_offset points
21674 at the top of the stack frame. */
21675 sp_offset = -info->spe_gp_save_offset;
21680 if (restoring_GPRs_inline)
21682 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21683 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21685 rtx offset, addr, mem, reg;
21687 /* We're doing all this to ensure that the immediate offset
21688 fits into the immediate field of 'evldd'. */
21689 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
21691 offset = GEN_INT (spe_offset + reg_size * i);
21692 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, offset);
21693 mem = gen_rtx_MEM (V2SImode, addr);
21694 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21696 insn = emit_move_insn (reg, mem);
21697 if (DEFAULT_ABI == ABI_V4)
21699 if (frame_pointer_needed
21700 && info->first_gp_reg_save + i
21701 == HARD_FRAME_POINTER_REGNUM)
21703 add_reg_note (insn, REG_CFA_DEF_CFA,
21704 plus_constant (frame_reg_rtx,
21706 RTX_FRAME_RELATED_P (insn) = 1;
21709 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21718 par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11),
21720 /*savep=*/false, /*gpr=*/true,
21722 emit_jump_insn (par);
21723 /* We don't want anybody else emitting things after we jumped
21728 else if (!restoring_GPRs_inline)
21730 /* We are jumping to an out-of-line function. */
21731 bool can_use_exit = info->first_fp_reg_save == 64;
21734 /* Emit stack reset code if we need it. */
21736 rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21737 sp_offset, can_use_exit);
21740 emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX
21743 GEN_INT (sp_offset - info->fp_size)));
21744 if (REGNO (frame_reg_rtx) == 11)
21745 sp_offset += info->fp_size;
21748 par = rs6000_make_savres_rtx (info, frame_reg_rtx,
21749 info->gp_save_offset, reg_mode,
21750 /*savep=*/false, /*gpr=*/true,
21751 /*lr=*/can_use_exit);
21755 if (info->cr_save_p)
21757 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21758 if (DEFAULT_ABI == ABI_V4)
21760 = alloc_reg_note (REG_CFA_RESTORE,
21761 gen_rtx_REG (SImode, CR2_REGNO),
21765 emit_jump_insn (par);
21767 /* We don't want anybody else emitting things after we jumped
21772 insn = emit_insn (par);
21773 if (DEFAULT_ABI == ABI_V4)
21775 if (frame_pointer_needed)
21777 add_reg_note (insn, REG_CFA_DEF_CFA,
21778 plus_constant (frame_reg_rtx, sp_offset));
21779 RTX_FRAME_RELATED_P (insn) = 1;
21782 for (i = info->first_gp_reg_save; i < 32; i++)
21784 = alloc_reg_note (REG_CFA_RESTORE,
21785 gen_rtx_REG (reg_mode, i), cfa_restores);
21788 else if (using_load_multiple)
21791 p = rtvec_alloc (32 - info->first_gp_reg_save);
21792 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21794 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21795 GEN_INT (info->gp_save_offset
21798 rtx mem = gen_frame_mem (reg_mode, addr);
21799 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21801 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, reg, mem);
21802 if (DEFAULT_ABI == ABI_V4)
21803 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21806 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
21807 if (DEFAULT_ABI == ABI_V4 && frame_pointer_needed)
21809 add_reg_note (insn, REG_CFA_DEF_CFA,
21810 plus_constant (frame_reg_rtx, sp_offset));
21811 RTX_FRAME_RELATED_P (insn) = 1;
21816 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
21817 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
21819 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21820 GEN_INT (info->gp_save_offset
21823 rtx mem = gen_frame_mem (reg_mode, addr);
21824 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
21826 insn = emit_move_insn (reg, mem);
21827 if (DEFAULT_ABI == ABI_V4)
21829 if (frame_pointer_needed
21830 && info->first_gp_reg_save + i
21831 == HARD_FRAME_POINTER_REGNUM)
21833 add_reg_note (insn, REG_CFA_DEF_CFA,
21834 plus_constant (frame_reg_rtx, sp_offset));
21835 RTX_FRAME_RELATED_P (insn) = 1;
21838 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21844 if (restore_lr && !restoring_GPRs_inline)
21846 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
21847 info->lr_save_offset + sp_offset);
21849 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
21850 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
21851 gen_rtx_REG (Pmode, 0));
21854 /* Restore fpr's if we need to do it without calling a function. */
21855 if (restoring_FPRs_inline)
21856 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21857 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
21858 && ! call_used_regs[info->first_fp_reg_save+i]))
21860 rtx addr, mem, reg;
21861 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
21862 GEN_INT (info->fp_save_offset
21865 mem = gen_frame_mem (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21866 ? DFmode : SFmode), addr);
21867 reg = gen_rtx_REG (((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
21868 ? DFmode : SFmode),
21869 info->first_fp_reg_save + i);
21871 emit_move_insn (reg, mem);
21872 if (DEFAULT_ABI == ABI_V4)
21873 cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
21877 /* If we saved cr, restore it here. Just those that were used. */
21878 if (info->cr_save_p)
21880 rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple);
21881 if (DEFAULT_ABI == ABI_V4)
21883 = alloc_reg_note (REG_CFA_RESTORE, gen_rtx_REG (SImode, CR2_REGNO),
21887 /* If this is V.4, unwind the stack pointer after all of the loads
21889 insn = rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx,
21890 sp_offset, !restoring_FPRs_inline);
21895 REG_NOTES (insn) = cfa_restores;
21896 cfa_restores = NULL_RTX;
21898 add_reg_note (insn, REG_CFA_DEF_CFA, sp_reg_rtx);
21899 RTX_FRAME_RELATED_P (insn) = 1;
21902 if (crtl->calls_eh_return)
21904 rtx sa = EH_RETURN_STACKADJ_RTX;
21905 emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
21911 bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
21912 if (! restoring_FPRs_inline)
21913 p = rtvec_alloc (4 + 64 - info->first_fp_reg_save);
21915 p = rtvec_alloc (2);
21917 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
21918 RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr)
21919 ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65))
21920 : gen_rtx_CLOBBER (VOIDmode,
21921 gen_rtx_REG (Pmode, 65)));
21923 /* If we have to restore more than two FP registers, branch to the
21924 restore function. It will return to our caller. */
21925 if (! restoring_FPRs_inline)
21930 sym = rs6000_savres_routine_sym (info,
21934 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode, sym);
21935 RTVEC_ELT (p, 3) = gen_rtx_USE (VOIDmode,
21936 gen_rtx_REG (Pmode,
21937 DEFAULT_ABI == ABI_AIX
21939 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
21942 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
21943 GEN_INT (info->fp_save_offset + 8*i));
21944 mem = gen_frame_mem (DFmode, addr);
21946 RTVEC_ELT (p, i+4) =
21947 gen_rtx_SET (VOIDmode,
21948 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
21953 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
21957 /* Write function epilogue. */
21960 rs6000_output_function_epilogue (FILE *file,
21961 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
21963 if (! HAVE_epilogue)
21965 rtx insn = get_last_insn ();
21966 /* If the last insn was a BARRIER, we don't have to write anything except
21967 the trace table. */
21968 if (GET_CODE (insn) == NOTE)
21969 insn = prev_nonnote_insn (insn);
21970 if (insn == 0 || GET_CODE (insn) != BARRIER)
21972 /* This is slightly ugly, but at least we don't have two
21973 copies of the epilogue-emitting code. */
21976 /* A NOTE_INSN_DELETED is supposed to be at the start
21977 and end of the "toplevel" insn chain. */
21978 emit_note (NOTE_INSN_DELETED);
21979 rs6000_emit_epilogue (FALSE);
21980 emit_note (NOTE_INSN_DELETED);
21982 /* Expand INSN_ADDRESSES so final() doesn't crash. */
21986 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
21988 INSN_ADDRESSES_NEW (insn, addr);
21993 if (TARGET_DEBUG_STACK)
21994 debug_rtx_list (get_insns (), 100);
21995 final (get_insns (), file, FALSE);
22001 macho_branch_islands ();
22002 /* Mach-O doesn't support labels at the end of objects, so if
22003 it looks like we might want one, insert a NOP. */
22005 rtx insn = get_last_insn ();
22008 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
22009 insn = PREV_INSN (insn);
22013 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
22014 fputs ("\tnop\n", file);
22018 /* Output a traceback table here. See /usr/include/sys/debug.h for info
22021 We don't output a traceback table if -finhibit-size-directive was
22022 used. The documentation for -finhibit-size-directive reads
22023 ``don't output a @code{.size} assembler directive, or anything
22024 else that would cause trouble if the function is split in the
22025 middle, and the two halves are placed at locations far apart in
22026 memory.'' The traceback table has this property, since it
22027 includes the offset from the start of the function to the
22028 traceback table itself.
22030 System V.4 Powerpc's (and the embedded ABI derived from it) use a
22031 different traceback table. */
22032 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
22033 && rs6000_traceback != traceback_none && !cfun->is_thunk)
22035 const char *fname = NULL;
22036 const char *language_string = lang_hooks.name;
22037 int fixed_parms = 0, float_parms = 0, parm_info = 0;
22039 int optional_tbtab;
22040 rs6000_stack_t *info = rs6000_stack_info ();
22042 if (rs6000_traceback == traceback_full)
22043 optional_tbtab = 1;
22044 else if (rs6000_traceback == traceback_part)
22045 optional_tbtab = 0;
22047 optional_tbtab = !optimize_size && !TARGET_ELF;
22049 if (optional_tbtab)
22051 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
22052 while (*fname == '.') /* V.4 encodes . in the name */
22055 /* Need label immediately before tbtab, so we can compute
22056 its offset from the function start. */
22057 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22058 ASM_OUTPUT_LABEL (file, fname);
22061 /* The .tbtab pseudo-op can only be used for the first eight
22062 expressions, since it can't handle the possibly variable
22063 length fields that follow. However, if you omit the optional
22064 fields, the assembler outputs zeros for all optional fields
22065 anyways, giving each variable length field is minimum length
22066 (as defined in sys/debug.h). Thus we can not use the .tbtab
22067 pseudo-op at all. */
22069 /* An all-zero word flags the start of the tbtab, for debuggers
22070 that have to find it by searching forward from the entry
22071 point or from the current pc. */
22072 fputs ("\t.long 0\n", file);
22074 /* Tbtab format type. Use format type 0. */
22075 fputs ("\t.byte 0,", file);
22077 /* Language type. Unfortunately, there does not seem to be any
22078 official way to discover the language being compiled, so we
22079 use language_string.
22080 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
22081 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
22082 a number, so for now use 9. LTO and Go aren't assigned numbers
22083 either, so for now use 0. */
22084 if (! strcmp (language_string, "GNU C")
22085 || ! strcmp (language_string, "GNU GIMPLE")
22086 || ! strcmp (language_string, "GNU Go"))
22088 else if (! strcmp (language_string, "GNU F77")
22089 || ! strcmp (language_string, "GNU Fortran"))
22091 else if (! strcmp (language_string, "GNU Pascal"))
22093 else if (! strcmp (language_string, "GNU Ada"))
22095 else if (! strcmp (language_string, "GNU C++")
22096 || ! strcmp (language_string, "GNU Objective-C++"))
22098 else if (! strcmp (language_string, "GNU Java"))
22100 else if (! strcmp (language_string, "GNU Objective-C"))
22103 gcc_unreachable ();
22104 fprintf (file, "%d,", i);
22106 /* 8 single bit fields: global linkage (not set for C extern linkage,
22107 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
22108 from start of procedure stored in tbtab, internal function, function
22109 has controlled storage, function has no toc, function uses fp,
22110 function logs/aborts fp operations. */
22111 /* Assume that fp operations are used if any fp reg must be saved. */
22112 fprintf (file, "%d,",
22113 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
22115 /* 6 bitfields: function is interrupt handler, name present in
22116 proc table, function calls alloca, on condition directives
22117 (controls stack walks, 3 bits), saves condition reg, saves
22119 /* The `function calls alloca' bit seems to be set whenever reg 31 is
22120 set up as a frame pointer, even when there is no alloca call. */
22121 fprintf (file, "%d,",
22122 ((optional_tbtab << 6)
22123 | ((optional_tbtab & frame_pointer_needed) << 5)
22124 | (info->cr_save_p << 1)
22125 | (info->lr_save_p)));
22127 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
22129 fprintf (file, "%d,",
22130 (info->push_p << 7) | (64 - info->first_fp_reg_save));
22132 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
22133 fprintf (file, "%d,", (32 - first_reg_to_save ()));
22135 if (optional_tbtab)
22137 /* Compute the parameter info from the function decl argument
22140 int next_parm_info_bit = 31;
22142 for (decl = DECL_ARGUMENTS (current_function_decl);
22143 decl; decl = DECL_CHAIN (decl))
22145 rtx parameter = DECL_INCOMING_RTL (decl);
22146 enum machine_mode mode = GET_MODE (parameter);
22148 if (GET_CODE (parameter) == REG)
22150 if (SCALAR_FLOAT_MODE_P (mode))
22171 gcc_unreachable ();
22174 /* If only one bit will fit, don't or in this entry. */
22175 if (next_parm_info_bit > 0)
22176 parm_info |= (bits << (next_parm_info_bit - 1));
22177 next_parm_info_bit -= 2;
22181 fixed_parms += ((GET_MODE_SIZE (mode)
22182 + (UNITS_PER_WORD - 1))
22184 next_parm_info_bit -= 1;
22190 /* Number of fixed point parameters. */
22191 /* This is actually the number of words of fixed point parameters; thus
22192 an 8 byte struct counts as 2; and thus the maximum value is 8. */
22193 fprintf (file, "%d,", fixed_parms);
22195 /* 2 bitfields: number of floating point parameters (7 bits), parameters
22197 /* This is actually the number of fp registers that hold parameters;
22198 and thus the maximum value is 13. */
22199 /* Set parameters on stack bit if parameters are not in their original
22200 registers, regardless of whether they are on the stack? Xlc
22201 seems to set the bit when not optimizing. */
22202 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
22204 if (! optional_tbtab)
22207 /* Optional fields follow. Some are variable length. */
22209 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
22210 11 double float. */
22211 /* There is an entry for each parameter in a register, in the order that
22212 they occur in the parameter list. Any intervening arguments on the
22213 stack are ignored. If the list overflows a long (max possible length
22214 34 bits) then completely leave off all elements that don't fit. */
22215 /* Only emit this long if there was at least one parameter. */
22216 if (fixed_parms || float_parms)
22217 fprintf (file, "\t.long %d\n", parm_info);
22219 /* Offset from start of code to tb table. */
22220 fputs ("\t.long ", file);
22221 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
22222 RS6000_OUTPUT_BASENAME (file, fname);
22224 rs6000_output_function_entry (file, fname);
22227 /* Interrupt handler mask. */
22228 /* Omit this long, since we never set the interrupt handler bit
22231 /* Number of CTL (controlled storage) anchors. */
22232 /* Omit this long, since the has_ctl bit is never set above. */
22234 /* Displacement into stack of each CTL anchor. */
22235 /* Omit this list of longs, because there are no CTL anchors. */
22237 /* Length of function name. */
22240 fprintf (file, "\t.short %d\n", (int) strlen (fname));
22242 /* Function name. */
22243 assemble_string (fname, strlen (fname));
22245 /* Register for alloca automatic storage; this is always reg 31.
22246 Only emit this if the alloca bit was set above. */
22247 if (frame_pointer_needed)
22248 fputs ("\t.byte 31\n", file);
22250 fputs ("\t.align 2\n", file);
22254 /* A C compound statement that outputs the assembler code for a thunk
22255 function, used to implement C++ virtual function calls with
22256 multiple inheritance. The thunk acts as a wrapper around a virtual
22257 function, adjusting the implicit object parameter before handing
22258 control off to the real function.
22260 First, emit code to add the integer DELTA to the location that
22261 contains the incoming first argument. Assume that this argument
22262 contains a pointer, and is the one used to pass the `this' pointer
22263 in C++. This is the incoming argument *before* the function
22264 prologue, e.g. `%o0' on a sparc. The addition must preserve the
22265 values of all other incoming arguments.
22267 After the addition, emit code to jump to FUNCTION, which is a
22268 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
22269 not touch the return address. Hence returning from FUNCTION will
22270 return to whoever called the current `thunk'.
22272 The effect must be as if FUNCTION had been called directly with the
22273 adjusted first argument. This macro is responsible for emitting
22274 all of the code for a thunk function; output_function_prologue()
22275 and output_function_epilogue() are not invoked.
22277 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
22278 been extracted from it.) It might possibly be useful on some
22279 targets, but probably not.
22281 If you do not define this macro, the target-independent code in the
22282 C++ frontend will generate a less efficient heavyweight thunk that
22283 calls FUNCTION instead of jumping to it. The generic approach does
22284 not support varargs. */
22287 rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
22288 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
22291 rtx this_rtx, insn, funexp;
22293 reload_completed = 1;
22294 epilogue_completed = 1;
22296 /* Mark the end of the (empty) prologue. */
22297 emit_note (NOTE_INSN_PROLOGUE_END);
22299 /* Find the "this" pointer. If the function returns a structure,
22300 the structure return pointer is in r3. */
22301 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
22302 this_rtx = gen_rtx_REG (Pmode, 4);
22304 this_rtx = gen_rtx_REG (Pmode, 3);
22306 /* Apply the constant offset, if required. */
22308 emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
22310 /* Apply the offset from the vtable, if required. */
22313 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
22314 rtx tmp = gen_rtx_REG (Pmode, 12);
22316 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
22317 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
22319 emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
22320 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
22324 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
22326 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
22328 emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
22331 /* Generate a tail call to the target function. */
22332 if (!TREE_USED (function))
22334 assemble_external (function);
22335 TREE_USED (function) = 1;
22337 funexp = XEXP (DECL_RTL (function), 0);
22338 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
22341 if (MACHOPIC_INDIRECT)
22342 funexp = machopic_indirect_call_target (funexp);
22345 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
22346 generate sibcall RTL explicitly. */
22347 insn = emit_call_insn (
22348 gen_rtx_PARALLEL (VOIDmode,
22350 gen_rtx_CALL (VOIDmode,
22351 funexp, const0_rtx),
22352 gen_rtx_USE (VOIDmode, const0_rtx),
22353 gen_rtx_USE (VOIDmode,
22354 gen_rtx_REG (SImode,
22356 gen_rtx_RETURN (VOIDmode))));
22357 SIBLING_CALL_P (insn) = 1;
22360 /* Run just enough of rest_of_compilation to get the insns emitted.
22361 There's not really enough bulk here to make other passes such as
22362 instruction scheduling worth while. Note that use_thunk calls
22363 assemble_start_function and assemble_end_function. */
22364 insn = get_insns ();
22365 insn_locators_alloc ();
22366 shorten_branches (insn);
22367 final_start_function (insn, file, 1);
22368 final (insn, file, 1);
22369 final_end_function ();
22371 reload_completed = 0;
22372 epilogue_completed = 0;
22375 /* A quick summary of the various types of 'constant-pool tables'
22378 Target Flags Name One table per
22379 AIX (none) AIX TOC object file
22380 AIX -mfull-toc AIX TOC object file
22381 AIX -mminimal-toc AIX minimal TOC translation unit
22382 SVR4/EABI (none) SVR4 SDATA object file
22383 SVR4/EABI -fpic SVR4 pic object file
22384 SVR4/EABI -fPIC SVR4 PIC translation unit
22385 SVR4/EABI -mrelocatable EABI TOC function
22386 SVR4/EABI -maix AIX TOC object file
22387 SVR4/EABI -maix -mminimal-toc
22388 AIX minimal TOC translation unit
22390 Name Reg. Set by entries contains:
22391 made by addrs? fp? sum?
22393 AIX TOC 2 crt0 as Y option option
22394 AIX minimal TOC 30 prolog gcc Y Y option
22395 SVR4 SDATA 13 crt0 gcc N Y N
22396 SVR4 pic 30 prolog ld Y not yet N
22397 SVR4 PIC 30 prolog gcc Y option option
22398 EABI TOC 30 prolog gcc Y option option
22402 /* Hash functions for the hash table. */
22405 rs6000_hash_constant (rtx k)
22407 enum rtx_code code = GET_CODE (k);
22408 enum machine_mode mode = GET_MODE (k);
22409 unsigned result = (code << 3) ^ mode;
22410 const char *format;
22413 format = GET_RTX_FORMAT (code);
22414 flen = strlen (format);
22420 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
22423 if (mode != VOIDmode)
22424 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
22436 for (; fidx < flen; fidx++)
22437 switch (format[fidx])
22442 const char *str = XSTR (k, fidx);
22443 len = strlen (str);
22444 result = result * 613 + len;
22445 for (i = 0; i < len; i++)
22446 result = result * 613 + (unsigned) str[i];
22451 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
22455 result = result * 613 + (unsigned) XINT (k, fidx);
22458 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
22459 result = result * 613 + (unsigned) XWINT (k, fidx);
22463 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
22464 result = result * 613 + (unsigned) (XWINT (k, fidx)
22471 gcc_unreachable ();
22478 toc_hash_function (const void *hash_entry)
22480 const struct toc_hash_struct *thc =
22481 (const struct toc_hash_struct *) hash_entry;
22482 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
22485 /* Compare H1 and H2 for equivalence. */
22488 toc_hash_eq (const void *h1, const void *h2)
22490 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
22491 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
22493 if (((const struct toc_hash_struct *) h1)->key_mode
22494 != ((const struct toc_hash_struct *) h2)->key_mode)
22497 return rtx_equal_p (r1, r2);
22500 /* These are the names given by the C++ front-end to vtables, and
22501 vtable-like objects. Ideally, this logic should not be here;
22502 instead, there should be some programmatic way of inquiring as
22503 to whether or not an object is a vtable. */
22505 #define VTABLE_NAME_P(NAME) \
22506 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
22507 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
22508 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
22509 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
22510 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
22512 #ifdef NO_DOLLAR_IN_LABEL
22513 /* Return a GGC-allocated character string translating dollar signs in
22514 input NAME to underscores. Used by XCOFF ASM_OUTPUT_LABELREF. */
22517 rs6000_xcoff_strip_dollar (const char *name)
22522 p = strchr (name, '$');
22524 if (p == 0 || p == name)
22527 len = strlen (name);
22528 strip = (char *) alloca (len + 1);
22529 strcpy (strip, name);
22530 p = strchr (strip, '$');
22534 p = strchr (p + 1, '$');
22537 return ggc_alloc_string (strip, len);
22542 rs6000_output_symbol_ref (FILE *file, rtx x)
22544 /* Currently C++ toc references to vtables can be emitted before it
22545 is decided whether the vtable is public or private. If this is
22546 the case, then the linker will eventually complain that there is
22547 a reference to an unknown section. Thus, for vtables only,
22548 we emit the TOC reference to reference the symbol and not the
22550 const char *name = XSTR (x, 0);
22552 if (VTABLE_NAME_P (name))
22554 RS6000_OUTPUT_BASENAME (file, name);
22557 assemble_name (file, name);
22560 /* Output a TOC entry. We derive the entry name from what is being
22564 output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
22567 const char *name = buf;
22569 HOST_WIDE_INT offset = 0;
22571 gcc_assert (!TARGET_NO_TOC);
22573 /* When the linker won't eliminate them, don't output duplicate
22574 TOC entries (this happens on AIX if there is any kind of TOC,
22575 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
22577 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
22579 struct toc_hash_struct *h;
22582 /* Create toc_hash_table. This can't be done at TARGET_OPTION_OVERRIDE
22583 time because GGC is not initialized at that point. */
22584 if (toc_hash_table == NULL)
22585 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
22586 toc_hash_eq, NULL);
22588 h = ggc_alloc_toc_hash_struct ();
22590 h->key_mode = mode;
22591 h->labelno = labelno;
22593 found = htab_find_slot (toc_hash_table, h, INSERT);
22594 if (*found == NULL)
22596 else /* This is indeed a duplicate.
22597 Set this label equal to that label. */
22599 fputs ("\t.set ", file);
22600 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22601 fprintf (file, "%d,", labelno);
22602 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
22603 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
22609 /* If we're going to put a double constant in the TOC, make sure it's
22610 aligned properly when strict alignment is on. */
22611 if (GET_CODE (x) == CONST_DOUBLE
22612 && STRICT_ALIGNMENT
22613 && GET_MODE_BITSIZE (mode) >= 64
22614 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
22615 ASM_OUTPUT_ALIGN (file, 3);
22618 (*targetm.asm_out.internal_label) (file, "LC", labelno);
22620 /* Handle FP constants specially. Note that if we have a minimal
22621 TOC, things we put here aren't actually in the TOC, so we can allow
22623 if (GET_CODE (x) == CONST_DOUBLE &&
22624 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
22626 REAL_VALUE_TYPE rv;
22629 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22630 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22631 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
22633 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
22637 if (TARGET_MINIMAL_TOC)
22638 fputs (DOUBLE_INT_ASM_OP, file);
22640 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22641 k[0] & 0xffffffff, k[1] & 0xffffffff,
22642 k[2] & 0xffffffff, k[3] & 0xffffffff);
22643 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
22644 k[0] & 0xffffffff, k[1] & 0xffffffff,
22645 k[2] & 0xffffffff, k[3] & 0xffffffff);
22650 if (TARGET_MINIMAL_TOC)
22651 fputs ("\t.long ", file);
22653 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
22654 k[0] & 0xffffffff, k[1] & 0xffffffff,
22655 k[2] & 0xffffffff, k[3] & 0xffffffff);
22656 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
22657 k[0] & 0xffffffff, k[1] & 0xffffffff,
22658 k[2] & 0xffffffff, k[3] & 0xffffffff);
22662 else if (GET_CODE (x) == CONST_DOUBLE &&
22663 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
22665 REAL_VALUE_TYPE rv;
22668 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22670 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22671 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
22673 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
22677 if (TARGET_MINIMAL_TOC)
22678 fputs (DOUBLE_INT_ASM_OP, file);
22680 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22681 k[0] & 0xffffffff, k[1] & 0xffffffff);
22682 fprintf (file, "0x%lx%08lx\n",
22683 k[0] & 0xffffffff, k[1] & 0xffffffff);
22688 if (TARGET_MINIMAL_TOC)
22689 fputs ("\t.long ", file);
22691 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
22692 k[0] & 0xffffffff, k[1] & 0xffffffff);
22693 fprintf (file, "0x%lx,0x%lx\n",
22694 k[0] & 0xffffffff, k[1] & 0xffffffff);
22698 else if (GET_CODE (x) == CONST_DOUBLE &&
22699 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
22701 REAL_VALUE_TYPE rv;
22704 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
22705 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
22706 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
22708 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
22712 if (TARGET_MINIMAL_TOC)
22713 fputs (DOUBLE_INT_ASM_OP, file);
22715 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22716 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
22721 if (TARGET_MINIMAL_TOC)
22722 fputs ("\t.long ", file);
22724 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
22725 fprintf (file, "0x%lx\n", l & 0xffffffff);
22729 else if (GET_MODE (x) == VOIDmode
22730 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
22732 unsigned HOST_WIDE_INT low;
22733 HOST_WIDE_INT high;
22735 if (GET_CODE (x) == CONST_DOUBLE)
22737 low = CONST_DOUBLE_LOW (x);
22738 high = CONST_DOUBLE_HIGH (x);
22741 #if HOST_BITS_PER_WIDE_INT == 32
22744 high = (low & 0x80000000) ? ~0 : 0;
22748 low = INTVAL (x) & 0xffffffff;
22749 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
22753 /* TOC entries are always Pmode-sized, but since this
22754 is a bigendian machine then if we're putting smaller
22755 integer constants in the TOC we have to pad them.
22756 (This is still a win over putting the constants in
22757 a separate constant pool, because then we'd have
22758 to have both a TOC entry _and_ the actual constant.)
22760 For a 32-bit target, CONST_INT values are loaded and shifted
22761 entirely within `low' and can be stored in one TOC entry. */
22763 /* It would be easy to make this work, but it doesn't now. */
22764 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
22766 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
22768 #if HOST_BITS_PER_WIDE_INT == 32
22769 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
22770 POINTER_SIZE, &low, &high, 0);
22773 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
22774 high = (HOST_WIDE_INT) low >> 32;
22781 if (TARGET_MINIMAL_TOC)
22782 fputs (DOUBLE_INT_ASM_OP, file);
22784 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22785 (long) high & 0xffffffff, (long) low & 0xffffffff);
22786 fprintf (file, "0x%lx%08lx\n",
22787 (long) high & 0xffffffff, (long) low & 0xffffffff);
22792 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
22794 if (TARGET_MINIMAL_TOC)
22795 fputs ("\t.long ", file);
22797 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
22798 (long) high & 0xffffffff, (long) low & 0xffffffff);
22799 fprintf (file, "0x%lx,0x%lx\n",
22800 (long) high & 0xffffffff, (long) low & 0xffffffff);
22804 if (TARGET_MINIMAL_TOC)
22805 fputs ("\t.long ", file);
22807 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
22808 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
22814 if (GET_CODE (x) == CONST)
22816 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS
22817 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT);
22819 base = XEXP (XEXP (x, 0), 0);
22820 offset = INTVAL (XEXP (XEXP (x, 0), 1));
22823 switch (GET_CODE (base))
22826 name = XSTR (base, 0);
22830 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
22831 CODE_LABEL_NUMBER (XEXP (base, 0)));
22835 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
22839 gcc_unreachable ();
22842 if (TARGET_MINIMAL_TOC)
22843 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
22846 fputs ("\t.tc ", file);
22847 RS6000_OUTPUT_BASENAME (file, name);
22850 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
22852 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
22854 fputs ("[TC],", file);
22857 /* Currently C++ toc references to vtables can be emitted before it
22858 is decided whether the vtable is public or private. If this is
22859 the case, then the linker will eventually complain that there is
22860 a TOC reference to an unknown section. Thus, for vtables only,
22861 we emit the TOC reference to reference the symbol and not the
22863 if (VTABLE_NAME_P (name))
22865 RS6000_OUTPUT_BASENAME (file, name);
22867 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
22868 else if (offset > 0)
22869 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
22872 output_addr_const (file, x);
22876 /* Output an assembler pseudo-op to write an ASCII string of N characters
22877 starting at P to FILE.
22879 On the RS/6000, we have to do this using the .byte operation and
22880 write out special characters outside the quoted string.
22881 Also, the assembler is broken; very long strings are truncated,
22882 so we must artificially break them up early. */
22885 output_ascii (FILE *file, const char *p, int n)
22888 int i, count_string;
22889 const char *for_string = "\t.byte \"";
22890 const char *for_decimal = "\t.byte ";
22891 const char *to_close = NULL;
22894 for (i = 0; i < n; i++)
22897 if (c >= ' ' && c < 0177)
22900 fputs (for_string, file);
22903 /* Write two quotes to get one. */
22911 for_decimal = "\"\n\t.byte ";
22915 if (count_string >= 512)
22917 fputs (to_close, file);
22919 for_string = "\t.byte \"";
22920 for_decimal = "\t.byte ";
22928 fputs (for_decimal, file);
22929 fprintf (file, "%d", c);
22931 for_string = "\n\t.byte \"";
22932 for_decimal = ", ";
22938 /* Now close the string if we have written one. Then end the line. */
22940 fputs (to_close, file);
22943 /* Generate a unique section name for FILENAME for a section type
22944 represented by SECTION_DESC. Output goes into BUF.
22946 SECTION_DESC can be any string, as long as it is different for each
22947 possible section type.
22949 We name the section in the same manner as xlc. The name begins with an
22950 underscore followed by the filename (after stripping any leading directory
22951 names) with the last period replaced by the string SECTION_DESC. If
22952 FILENAME does not contain a period, SECTION_DESC is appended to the end of
22956 rs6000_gen_section_name (char **buf, const char *filename,
22957 const char *section_desc)
22959 const char *q, *after_last_slash, *last_period = 0;
22963 after_last_slash = filename;
22964 for (q = filename; *q; q++)
22967 after_last_slash = q + 1;
22968 else if (*q == '.')
22972 len = strlen (after_last_slash) + strlen (section_desc) + 2;
22973 *buf = (char *) xmalloc (len);
22978 for (q = after_last_slash; *q; q++)
22980 if (q == last_period)
22982 strcpy (p, section_desc);
22983 p += strlen (section_desc);
22987 else if (ISALNUM (*q))
22991 if (last_period == 0)
22992 strcpy (p, section_desc);
22997 /* Emit profile function. */
23000 output_profile_hook (int labelno ATTRIBUTE_UNUSED)
23002 /* Non-standard profiling for kernels, which just saves LR then calls
23003 _mcount without worrying about arg saves. The idea is to change
23004 the function prologue as little as possible as it isn't easy to
23005 account for arg save/restore code added just for _mcount. */
23006 if (TARGET_PROFILE_KERNEL)
23009 if (DEFAULT_ABI == ABI_AIX)
23011 #ifndef NO_PROFILE_COUNTERS
23012 # define NO_PROFILE_COUNTERS 0
23014 if (NO_PROFILE_COUNTERS)
23015 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23016 LCT_NORMAL, VOIDmode, 0);
23020 const char *label_name;
23023 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23024 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
23025 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
23027 emit_library_call (init_one_libfunc (RS6000_MCOUNT),
23028 LCT_NORMAL, VOIDmode, 1, fun, Pmode);
23031 else if (DEFAULT_ABI == ABI_DARWIN)
23033 const char *mcount_name = RS6000_MCOUNT;
23034 int caller_addr_regno = LR_REGNO;
23036 /* Be conservative and always set this, at least for now. */
23037 crtl->uses_pic_offset_table = 1;
23040 /* For PIC code, set up a stub and collect the caller's address
23041 from r0, which is where the prologue puts it. */
23042 if (MACHOPIC_INDIRECT
23043 && crtl->uses_pic_offset_table)
23044 caller_addr_regno = 0;
23046 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
23047 LCT_NORMAL, VOIDmode, 1,
23048 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
23052 /* Write function profiler code. */
23055 output_function_profiler (FILE *file, int labelno)
23059 switch (DEFAULT_ABI)
23062 gcc_unreachable ();
23067 warning (0, "no profiling of 64-bit code for this ABI");
23070 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
23071 fprintf (file, "\tmflr %s\n", reg_names[0]);
23072 if (NO_PROFILE_COUNTERS)
23074 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23075 reg_names[0], reg_names[1]);
23077 else if (TARGET_SECURE_PLT && flag_pic)
23079 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
23080 reg_names[0], reg_names[1]);
23081 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23082 asm_fprintf (file, "\t{cau|addis} %s,%s,",
23083 reg_names[12], reg_names[12]);
23084 assemble_name (file, buf);
23085 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
23086 assemble_name (file, buf);
23087 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
23089 else if (flag_pic == 1)
23091 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
23092 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23093 reg_names[0], reg_names[1]);
23094 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
23095 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
23096 assemble_name (file, buf);
23097 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
23099 else if (flag_pic > 1)
23101 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23102 reg_names[0], reg_names[1]);
23103 /* Now, we need to get the address of the label. */
23104 fputs ("\tbcl 20,31,1f\n\t.long ", file);
23105 assemble_name (file, buf);
23106 fputs ("-.\n1:", file);
23107 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
23108 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
23109 reg_names[0], reg_names[11]);
23110 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
23111 reg_names[0], reg_names[0], reg_names[11]);
23115 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
23116 assemble_name (file, buf);
23117 fputs ("@ha\n", file);
23118 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
23119 reg_names[0], reg_names[1]);
23120 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
23121 assemble_name (file, buf);
23122 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
23125 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
23126 fprintf (file, "\tbl %s%s\n",
23127 RS6000_MCOUNT, flag_pic ? "@plt" : "");
23132 if (!TARGET_PROFILE_KERNEL)
23134 /* Don't do anything, done in output_profile_hook (). */
23138 gcc_assert (!TARGET_32BIT);
23140 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
23141 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
23143 if (cfun->static_chain_decl != NULL)
23145 asm_fprintf (file, "\tstd %s,24(%s)\n",
23146 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23147 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23148 asm_fprintf (file, "\tld %s,24(%s)\n",
23149 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
23152 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
23160 /* The following variable value is the last issued insn. */
23162 static rtx last_scheduled_insn;
23164 /* The following variable helps to balance issuing of load and
23165 store instructions */
23167 static int load_store_pendulum;
23169 /* Power4 load update and store update instructions are cracked into a
23170 load or store and an integer insn which are executed in the same cycle.
23171 Branches have their own dispatch slot which does not count against the
23172 GCC issue rate, but it changes the program flow so there are no other
23173 instructions to issue in this cycle. */
23176 rs6000_variable_issue_1 (rtx insn, int more)
23178 last_scheduled_insn = insn;
23179 if (GET_CODE (PATTERN (insn)) == USE
23180 || GET_CODE (PATTERN (insn)) == CLOBBER)
23182 cached_can_issue_more = more;
23183 return cached_can_issue_more;
23186 if (insn_terminates_group_p (insn, current_group))
23188 cached_can_issue_more = 0;
23189 return cached_can_issue_more;
23192 /* If no reservation, but reach here */
23193 if (recog_memoized (insn) < 0)
23196 if (rs6000_sched_groups)
23198 if (is_microcoded_insn (insn))
23199 cached_can_issue_more = 0;
23200 else if (is_cracked_insn (insn))
23201 cached_can_issue_more = more > 2 ? more - 2 : 0;
23203 cached_can_issue_more = more - 1;
23205 return cached_can_issue_more;
23208 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
23211 cached_can_issue_more = more - 1;
23212 return cached_can_issue_more;
23216 rs6000_variable_issue (FILE *stream, int verbose, rtx insn, int more)
23218 int r = rs6000_variable_issue_1 (insn, more);
23220 fprintf (stream, "// rs6000_variable_issue (more = %d) = %d\n", more, r);
23224 /* Adjust the cost of a scheduling dependency. Return the new cost of
23225 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
23228 rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23230 enum attr_type attr_type;
23232 if (! recog_memoized (insn))
23235 switch (REG_NOTE_KIND (link))
23239 /* Data dependency; DEP_INSN writes a register that INSN reads
23240 some cycles later. */
23242 /* Separate a load from a narrower, dependent store. */
23243 if (rs6000_sched_groups
23244 && GET_CODE (PATTERN (insn)) == SET
23245 && GET_CODE (PATTERN (dep_insn)) == SET
23246 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
23247 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
23248 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
23249 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
23252 attr_type = get_attr_type (insn);
23257 /* Tell the first scheduling pass about the latency between
23258 a mtctr and bctr (and mtlr and br/blr). The first
23259 scheduling pass will not know about this latency since
23260 the mtctr instruction, which has the latency associated
23261 to it, will be generated by reload. */
23262 return TARGET_POWER ? 5 : 4;
23264 /* Leave some extra cycles between a compare and its
23265 dependent branch, to inhibit expensive mispredicts. */
23266 if ((rs6000_cpu_attr == CPU_PPC603
23267 || rs6000_cpu_attr == CPU_PPC604
23268 || rs6000_cpu_attr == CPU_PPC604E
23269 || rs6000_cpu_attr == CPU_PPC620
23270 || rs6000_cpu_attr == CPU_PPC630
23271 || rs6000_cpu_attr == CPU_PPC750
23272 || rs6000_cpu_attr == CPU_PPC7400
23273 || rs6000_cpu_attr == CPU_PPC7450
23274 || rs6000_cpu_attr == CPU_POWER4
23275 || rs6000_cpu_attr == CPU_POWER5
23276 || rs6000_cpu_attr == CPU_POWER7
23277 || rs6000_cpu_attr == CPU_CELL)
23278 && recog_memoized (dep_insn)
23279 && (INSN_CODE (dep_insn) >= 0))
23281 switch (get_attr_type (dep_insn))
23285 case TYPE_DELAYED_COMPARE:
23286 case TYPE_IMUL_COMPARE:
23287 case TYPE_LMUL_COMPARE:
23288 case TYPE_FPCOMPARE:
23289 case TYPE_CR_LOGICAL:
23290 case TYPE_DELAYED_CR:
23299 case TYPE_STORE_UX:
23301 case TYPE_FPSTORE_U:
23302 case TYPE_FPSTORE_UX:
23303 if ((rs6000_cpu == PROCESSOR_POWER6)
23304 && recog_memoized (dep_insn)
23305 && (INSN_CODE (dep_insn) >= 0))
23308 if (GET_CODE (PATTERN (insn)) != SET)
23309 /* If this happens, we have to extend this to schedule
23310 optimally. Return default for now. */
23313 /* Adjust the cost for the case where the value written
23314 by a fixed point operation is used as the address
23315 gen value on a store. */
23316 switch (get_attr_type (dep_insn))
23323 if (! store_data_bypass_p (dep_insn, insn))
23327 case TYPE_LOAD_EXT:
23328 case TYPE_LOAD_EXT_U:
23329 case TYPE_LOAD_EXT_UX:
23330 case TYPE_VAR_SHIFT_ROTATE:
23331 case TYPE_VAR_DELAYED_COMPARE:
23333 if (! store_data_bypass_p (dep_insn, insn))
23339 case TYPE_FAST_COMPARE:
23342 case TYPE_INSERT_WORD:
23343 case TYPE_INSERT_DWORD:
23344 case TYPE_FPLOAD_U:
23345 case TYPE_FPLOAD_UX:
23347 case TYPE_STORE_UX:
23348 case TYPE_FPSTORE_U:
23349 case TYPE_FPSTORE_UX:
23351 if (! store_data_bypass_p (dep_insn, insn))
23359 case TYPE_IMUL_COMPARE:
23360 case TYPE_LMUL_COMPARE:
23362 if (! store_data_bypass_p (dep_insn, insn))
23368 if (! store_data_bypass_p (dep_insn, insn))
23374 if (! store_data_bypass_p (dep_insn, insn))
23387 case TYPE_LOAD_EXT:
23388 case TYPE_LOAD_EXT_U:
23389 case TYPE_LOAD_EXT_UX:
23390 if ((rs6000_cpu == PROCESSOR_POWER6)
23391 && recog_memoized (dep_insn)
23392 && (INSN_CODE (dep_insn) >= 0))
23395 /* Adjust the cost for the case where the value written
23396 by a fixed point instruction is used within the address
23397 gen portion of a subsequent load(u)(x) */
23398 switch (get_attr_type (dep_insn))
23405 if (set_to_load_agen (dep_insn, insn))
23409 case TYPE_LOAD_EXT:
23410 case TYPE_LOAD_EXT_U:
23411 case TYPE_LOAD_EXT_UX:
23412 case TYPE_VAR_SHIFT_ROTATE:
23413 case TYPE_VAR_DELAYED_COMPARE:
23415 if (set_to_load_agen (dep_insn, insn))
23421 case TYPE_FAST_COMPARE:
23424 case TYPE_INSERT_WORD:
23425 case TYPE_INSERT_DWORD:
23426 case TYPE_FPLOAD_U:
23427 case TYPE_FPLOAD_UX:
23429 case TYPE_STORE_UX:
23430 case TYPE_FPSTORE_U:
23431 case TYPE_FPSTORE_UX:
23433 if (set_to_load_agen (dep_insn, insn))
23441 case TYPE_IMUL_COMPARE:
23442 case TYPE_LMUL_COMPARE:
23444 if (set_to_load_agen (dep_insn, insn))
23450 if (set_to_load_agen (dep_insn, insn))
23456 if (set_to_load_agen (dep_insn, insn))
23467 if ((rs6000_cpu == PROCESSOR_POWER6)
23468 && recog_memoized (dep_insn)
23469 && (INSN_CODE (dep_insn) >= 0)
23470 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
23477 /* Fall out to return default cost. */
23481 case REG_DEP_OUTPUT:
23482 /* Output dependency; DEP_INSN writes a register that INSN writes some
23484 if ((rs6000_cpu == PROCESSOR_POWER6)
23485 && recog_memoized (dep_insn)
23486 && (INSN_CODE (dep_insn) >= 0))
23488 attr_type = get_attr_type (insn);
23493 if (get_attr_type (dep_insn) == TYPE_FP)
23497 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
23505 /* Anti dependency; DEP_INSN reads a register that INSN writes some
23510 gcc_unreachable ();
23516 /* Debug version of rs6000_adjust_cost. */
23519 rs6000_debug_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
23521 int ret = rs6000_adjust_cost (insn, link, dep_insn, cost);
23527 switch (REG_NOTE_KIND (link))
23529 default: dep = "unknown depencency"; break;
23530 case REG_DEP_TRUE: dep = "data dependency"; break;
23531 case REG_DEP_OUTPUT: dep = "output dependency"; break;
23532 case REG_DEP_ANTI: dep = "anti depencency"; break;
23536 "\nrs6000_adjust_cost, final cost = %d, orig cost = %d, "
23537 "%s, insn:\n", ret, cost, dep);
23545 /* The function returns a true if INSN is microcoded.
23546 Return false otherwise. */
23549 is_microcoded_insn (rtx insn)
23551 if (!insn || !NONDEBUG_INSN_P (insn)
23552 || GET_CODE (PATTERN (insn)) == USE
23553 || GET_CODE (PATTERN (insn)) == CLOBBER)
23556 if (rs6000_cpu_attr == CPU_CELL)
23557 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
23559 if (rs6000_sched_groups)
23561 enum attr_type type = get_attr_type (insn);
23562 if (type == TYPE_LOAD_EXT_U
23563 || type == TYPE_LOAD_EXT_UX
23564 || type == TYPE_LOAD_UX
23565 || type == TYPE_STORE_UX
23566 || type == TYPE_MFCR)
23573 /* The function returns true if INSN is cracked into 2 instructions
23574 by the processor (and therefore occupies 2 issue slots). */
23577 is_cracked_insn (rtx insn)
23579 if (!insn || !NONDEBUG_INSN_P (insn)
23580 || GET_CODE (PATTERN (insn)) == USE
23581 || GET_CODE (PATTERN (insn)) == CLOBBER)
23584 if (rs6000_sched_groups)
23586 enum attr_type type = get_attr_type (insn);
23587 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
23588 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
23589 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
23590 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
23591 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
23592 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
23593 || type == TYPE_IDIV || type == TYPE_LDIV
23594 || type == TYPE_INSERT_WORD)
23601 /* The function returns true if INSN can be issued only from
23602 the branch slot. */
23605 is_branch_slot_insn (rtx insn)
23607 if (!insn || !NONDEBUG_INSN_P (insn)
23608 || GET_CODE (PATTERN (insn)) == USE
23609 || GET_CODE (PATTERN (insn)) == CLOBBER)
23612 if (rs6000_sched_groups)
23614 enum attr_type type = get_attr_type (insn);
23615 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
23623 /* The function returns true if out_inst sets a value that is
23624 used in the address generation computation of in_insn */
23626 set_to_load_agen (rtx out_insn, rtx in_insn)
23628 rtx out_set, in_set;
23630 /* For performance reasons, only handle the simple case where
23631 both loads are a single_set. */
23632 out_set = single_set (out_insn);
23635 in_set = single_set (in_insn);
23637 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
23643 /* The function returns true if the target storage location of
23644 out_insn is adjacent to the target storage location of in_insn */
23645 /* Return 1 if memory locations are adjacent. */
23648 adjacent_mem_locations (rtx insn1, rtx insn2)
23651 rtx a = get_store_dest (PATTERN (insn1));
23652 rtx b = get_store_dest (PATTERN (insn2));
23654 if ((GET_CODE (XEXP (a, 0)) == REG
23655 || (GET_CODE (XEXP (a, 0)) == PLUS
23656 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
23657 && (GET_CODE (XEXP (b, 0)) == REG
23658 || (GET_CODE (XEXP (b, 0)) == PLUS
23659 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
23661 HOST_WIDE_INT val0 = 0, val1 = 0, val_diff;
23664 if (GET_CODE (XEXP (a, 0)) == PLUS)
23666 reg0 = XEXP (XEXP (a, 0), 0);
23667 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
23670 reg0 = XEXP (a, 0);
23672 if (GET_CODE (XEXP (b, 0)) == PLUS)
23674 reg1 = XEXP (XEXP (b, 0), 0);
23675 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
23678 reg1 = XEXP (b, 0);
23680 val_diff = val1 - val0;
23682 return ((REGNO (reg0) == REGNO (reg1))
23683 && ((MEM_SIZE (a) && val_diff == INTVAL (MEM_SIZE (a)))
23684 || (MEM_SIZE (b) && val_diff == -INTVAL (MEM_SIZE (b)))));
23690 /* A C statement (sans semicolon) to update the integer scheduling
23691 priority INSN_PRIORITY (INSN). Increase the priority to execute the
23692 INSN earlier, reduce the priority to execute INSN later. Do not
23693 define this macro if you do not need to adjust the scheduling
23694 priorities of insns. */
23697 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
23699 /* On machines (like the 750) which have asymmetric integer units,
23700 where one integer unit can do multiply and divides and the other
23701 can't, reduce the priority of multiply/divide so it is scheduled
23702 before other integer operations. */
23705 if (! INSN_P (insn))
23708 if (GET_CODE (PATTERN (insn)) == USE)
23711 switch (rs6000_cpu_attr) {
23713 switch (get_attr_type (insn))
23720 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
23721 priority, priority);
23722 if (priority >= 0 && priority < 0x01000000)
23729 if (insn_must_be_first_in_group (insn)
23730 && reload_completed
23731 && current_sched_info->sched_max_insns_priority
23732 && rs6000_sched_restricted_insns_priority)
23735 /* Prioritize insns that can be dispatched only in the first
23737 if (rs6000_sched_restricted_insns_priority == 1)
23738 /* Attach highest priority to insn. This means that in
23739 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
23740 precede 'priority' (critical path) considerations. */
23741 return current_sched_info->sched_max_insns_priority;
23742 else if (rs6000_sched_restricted_insns_priority == 2)
23743 /* Increase priority of insn by a minimal amount. This means that in
23744 haifa-sched.c:ready_sort(), only 'priority' (critical path)
23745 considerations precede dispatch-slot restriction considerations. */
23746 return (priority + 1);
23749 if (rs6000_cpu == PROCESSOR_POWER6
23750 && ((load_store_pendulum == -2 && is_load_insn (insn))
23751 || (load_store_pendulum == 2 && is_store_insn (insn))))
23752 /* Attach highest priority to insn if the scheduler has just issued two
23753 stores and this instruction is a load, or two loads and this instruction
23754 is a store. Power6 wants loads and stores scheduled alternately
23756 return current_sched_info->sched_max_insns_priority;
23761 /* Return true if the instruction is nonpipelined on the Cell. */
23763 is_nonpipeline_insn (rtx insn)
23765 enum attr_type type;
23766 if (!insn || !NONDEBUG_INSN_P (insn)
23767 || GET_CODE (PATTERN (insn)) == USE
23768 || GET_CODE (PATTERN (insn)) == CLOBBER)
23771 type = get_attr_type (insn);
23772 if (type == TYPE_IMUL
23773 || type == TYPE_IMUL2
23774 || type == TYPE_IMUL3
23775 || type == TYPE_LMUL
23776 || type == TYPE_IDIV
23777 || type == TYPE_LDIV
23778 || type == TYPE_SDIV
23779 || type == TYPE_DDIV
23780 || type == TYPE_SSQRT
23781 || type == TYPE_DSQRT
23782 || type == TYPE_MFCR
23783 || type == TYPE_MFCRF
23784 || type == TYPE_MFJMPR)
23792 /* Return how many instructions the machine can issue per cycle. */
23795 rs6000_issue_rate (void)
23797 /* Unless scheduling for register pressure, use issue rate of 1 for
23798 first scheduling pass to decrease degradation. */
23799 if (!reload_completed && !flag_sched_pressure)
23802 switch (rs6000_cpu_attr) {
23803 case CPU_RIOS1: /* ? */
23805 case CPU_PPC601: /* ? */
23814 case CPU_PPCE300C2:
23815 case CPU_PPCE300C3:
23816 case CPU_PPCE500MC:
23817 case CPU_PPCE500MC64:
23837 /* Return how many instructions to look ahead for better insn
23841 rs6000_use_sched_lookahead (void)
23843 if (rs6000_cpu_attr == CPU_PPC8540)
23845 if (rs6000_cpu_attr == CPU_CELL)
23846 return (reload_completed ? 8 : 0);
23850 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
23852 rs6000_use_sched_lookahead_guard (rtx insn)
23854 if (rs6000_cpu_attr != CPU_CELL)
23857 if (insn == NULL_RTX || !INSN_P (insn))
23860 if (!reload_completed
23861 || is_nonpipeline_insn (insn)
23862 || is_microcoded_insn (insn))
23868 /* Determine is PAT refers to memory. */
23871 is_mem_ref (rtx pat)
23877 /* stack_tie does not produce any real memory traffic. */
23878 if (GET_CODE (pat) == UNSPEC
23879 && XINT (pat, 1) == UNSPEC_TIE)
23882 if (GET_CODE (pat) == MEM)
23885 /* Recursively process the pattern. */
23886 fmt = GET_RTX_FORMAT (GET_CODE (pat));
23888 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
23891 ret |= is_mem_ref (XEXP (pat, i));
23892 else if (fmt[i] == 'E')
23893 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
23894 ret |= is_mem_ref (XVECEXP (pat, i, j));
23900 /* Determine if PAT is a PATTERN of a load insn. */
23903 is_load_insn1 (rtx pat)
23905 if (!pat || pat == NULL_RTX)
23908 if (GET_CODE (pat) == SET)
23909 return is_mem_ref (SET_SRC (pat));
23911 if (GET_CODE (pat) == PARALLEL)
23915 for (i = 0; i < XVECLEN (pat, 0); i++)
23916 if (is_load_insn1 (XVECEXP (pat, 0, i)))
23923 /* Determine if INSN loads from memory. */
23926 is_load_insn (rtx insn)
23928 if (!insn || !INSN_P (insn))
23931 if (GET_CODE (insn) == CALL_INSN)
23934 return is_load_insn1 (PATTERN (insn));
23937 /* Determine if PAT is a PATTERN of a store insn. */
23940 is_store_insn1 (rtx pat)
23942 if (!pat || pat == NULL_RTX)
23945 if (GET_CODE (pat) == SET)
23946 return is_mem_ref (SET_DEST (pat));
23948 if (GET_CODE (pat) == PARALLEL)
23952 for (i = 0; i < XVECLEN (pat, 0); i++)
23953 if (is_store_insn1 (XVECEXP (pat, 0, i)))
23960 /* Determine if INSN stores to memory. */
23963 is_store_insn (rtx insn)
23965 if (!insn || !INSN_P (insn))
23968 return is_store_insn1 (PATTERN (insn));
23971 /* Return the dest of a store insn. */
23974 get_store_dest (rtx pat)
23976 gcc_assert (is_store_insn1 (pat));
23978 if (GET_CODE (pat) == SET)
23979 return SET_DEST (pat);
23980 else if (GET_CODE (pat) == PARALLEL)
23984 for (i = 0; i < XVECLEN (pat, 0); i++)
23986 rtx inner_pat = XVECEXP (pat, 0, i);
23987 if (GET_CODE (inner_pat) == SET
23988 && is_mem_ref (SET_DEST (inner_pat)))
23992 /* We shouldn't get here, because we should have either a simple
23993 store insn or a store with update which are covered above. */
23997 /* Returns whether the dependence between INSN and NEXT is considered
23998 costly by the given target. */
24001 rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
24006 /* If the flag is not enabled - no dependence is considered costly;
24007 allow all dependent insns in the same group.
24008 This is the most aggressive option. */
24009 if (rs6000_sched_costly_dep == no_dep_costly)
24012 /* If the flag is set to 1 - a dependence is always considered costly;
24013 do not allow dependent instructions in the same group.
24014 This is the most conservative option. */
24015 if (rs6000_sched_costly_dep == all_deps_costly)
24018 insn = DEP_PRO (dep);
24019 next = DEP_CON (dep);
24021 if (rs6000_sched_costly_dep == store_to_load_dep_costly
24022 && is_load_insn (next)
24023 && is_store_insn (insn))
24024 /* Prevent load after store in the same group. */
24027 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
24028 && is_load_insn (next)
24029 && is_store_insn (insn)
24030 && DEP_TYPE (dep) == REG_DEP_TRUE)
24031 /* Prevent load after store in the same group if it is a true
24035 /* The flag is set to X; dependences with latency >= X are considered costly,
24036 and will not be scheduled in the same group. */
24037 if (rs6000_sched_costly_dep <= max_dep_latency
24038 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
24044 /* Return the next insn after INSN that is found before TAIL is reached,
24045 skipping any "non-active" insns - insns that will not actually occupy
24046 an issue slot. Return NULL_RTX if such an insn is not found. */
24049 get_next_active_insn (rtx insn, rtx tail)
24051 if (insn == NULL_RTX || insn == tail)
24056 insn = NEXT_INSN (insn);
24057 if (insn == NULL_RTX || insn == tail)
24062 || (NONJUMP_INSN_P (insn)
24063 && GET_CODE (PATTERN (insn)) != USE
24064 && GET_CODE (PATTERN (insn)) != CLOBBER
24065 && INSN_CODE (insn) != CODE_FOR_stack_tie))
24071 /* We are about to begin issuing insns for this clock cycle. */
24074 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
24075 rtx *ready ATTRIBUTE_UNUSED,
24076 int *pn_ready ATTRIBUTE_UNUSED,
24077 int clock_var ATTRIBUTE_UNUSED)
24079 int n_ready = *pn_ready;
24082 fprintf (dump, "// rs6000_sched_reorder :\n");
24084 /* Reorder the ready list, if the second to last ready insn
24085 is a nonepipeline insn. */
24086 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
24088 if (is_nonpipeline_insn (ready[n_ready - 1])
24089 && (recog_memoized (ready[n_ready - 2]) > 0))
24090 /* Simply swap first two insns. */
24092 rtx tmp = ready[n_ready - 1];
24093 ready[n_ready - 1] = ready[n_ready - 2];
24094 ready[n_ready - 2] = tmp;
24098 if (rs6000_cpu == PROCESSOR_POWER6)
24099 load_store_pendulum = 0;
24101 return rs6000_issue_rate ();
24104 /* Like rs6000_sched_reorder, but called after issuing each insn. */
24107 rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
24108 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
24111 fprintf (dump, "// rs6000_sched_reorder2 :\n");
24113 /* For Power6, we need to handle some special cases to try and keep the
24114 store queue from overflowing and triggering expensive flushes.
24116 This code monitors how load and store instructions are being issued
24117 and skews the ready list one way or the other to increase the likelihood
24118 that a desired instruction is issued at the proper time.
24120 A couple of things are done. First, we maintain a "load_store_pendulum"
24121 to track the current state of load/store issue.
24123 - If the pendulum is at zero, then no loads or stores have been
24124 issued in the current cycle so we do nothing.
24126 - If the pendulum is 1, then a single load has been issued in this
24127 cycle and we attempt to locate another load in the ready list to
24130 - If the pendulum is -2, then two stores have already been
24131 issued in this cycle, so we increase the priority of the first load
24132 in the ready list to increase it's likelihood of being chosen first
24135 - If the pendulum is -1, then a single store has been issued in this
24136 cycle and we attempt to locate another store in the ready list to
24137 issue with it, preferring a store to an adjacent memory location to
24138 facilitate store pairing in the store queue.
24140 - If the pendulum is 2, then two loads have already been
24141 issued in this cycle, so we increase the priority of the first store
24142 in the ready list to increase it's likelihood of being chosen first
24145 - If the pendulum < -2 or > 2, then do nothing.
24147 Note: This code covers the most common scenarios. There exist non
24148 load/store instructions which make use of the LSU and which
24149 would need to be accounted for to strictly model the behavior
24150 of the machine. Those instructions are currently unaccounted
24151 for to help minimize compile time overhead of this code.
24153 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
24159 if (is_store_insn (last_scheduled_insn))
24160 /* Issuing a store, swing the load_store_pendulum to the left */
24161 load_store_pendulum--;
24162 else if (is_load_insn (last_scheduled_insn))
24163 /* Issuing a load, swing the load_store_pendulum to the right */
24164 load_store_pendulum++;
24166 return cached_can_issue_more;
24168 /* If the pendulum is balanced, or there is only one instruction on
24169 the ready list, then all is well, so return. */
24170 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
24171 return cached_can_issue_more;
24173 if (load_store_pendulum == 1)
24175 /* A load has been issued in this cycle. Scan the ready list
24176 for another load to issue with it */
24181 if (is_load_insn (ready[pos]))
24183 /* Found a load. Move it to the head of the ready list,
24184 and adjust it's priority so that it is more likely to
24187 for (i=pos; i<*pn_ready-1; i++)
24188 ready[i] = ready[i + 1];
24189 ready[*pn_ready-1] = tmp;
24191 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24192 INSN_PRIORITY (tmp)++;
24198 else if (load_store_pendulum == -2)
24200 /* Two stores have been issued in this cycle. Increase the
24201 priority of the first load in the ready list to favor it for
24202 issuing in the next cycle. */
24207 if (is_load_insn (ready[pos])
24209 && INSN_PRIORITY_KNOWN (ready[pos]))
24211 INSN_PRIORITY (ready[pos])++;
24213 /* Adjust the pendulum to account for the fact that a load
24214 was found and increased in priority. This is to prevent
24215 increasing the priority of multiple loads */
24216 load_store_pendulum--;
24223 else if (load_store_pendulum == -1)
24225 /* A store has been issued in this cycle. Scan the ready list for
24226 another store to issue with it, preferring a store to an adjacent
24228 int first_store_pos = -1;
24234 if (is_store_insn (ready[pos]))
24236 /* Maintain the index of the first store found on the
24238 if (first_store_pos == -1)
24239 first_store_pos = pos;
24241 if (is_store_insn (last_scheduled_insn)
24242 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
24244 /* Found an adjacent store. Move it to the head of the
24245 ready list, and adjust it's priority so that it is
24246 more likely to stay there */
24248 for (i=pos; i<*pn_ready-1; i++)
24249 ready[i] = ready[i + 1];
24250 ready[*pn_ready-1] = tmp;
24252 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24253 INSN_PRIORITY (tmp)++;
24255 first_store_pos = -1;
24263 if (first_store_pos >= 0)
24265 /* An adjacent store wasn't found, but a non-adjacent store was,
24266 so move the non-adjacent store to the front of the ready
24267 list, and adjust its priority so that it is more likely to
24269 tmp = ready[first_store_pos];
24270 for (i=first_store_pos; i<*pn_ready-1; i++)
24271 ready[i] = ready[i + 1];
24272 ready[*pn_ready-1] = tmp;
24273 if (!sel_sched_p () && INSN_PRIORITY_KNOWN (tmp))
24274 INSN_PRIORITY (tmp)++;
24277 else if (load_store_pendulum == 2)
24279 /* Two loads have been issued in this cycle. Increase the priority
24280 of the first store in the ready list to favor it for issuing in
24286 if (is_store_insn (ready[pos])
24288 && INSN_PRIORITY_KNOWN (ready[pos]))
24290 INSN_PRIORITY (ready[pos])++;
24292 /* Adjust the pendulum to account for the fact that a store
24293 was found and increased in priority. This is to prevent
24294 increasing the priority of multiple stores */
24295 load_store_pendulum++;
24304 return cached_can_issue_more;
24307 /* Return whether the presence of INSN causes a dispatch group termination
24308 of group WHICH_GROUP.
24310 If WHICH_GROUP == current_group, this function will return true if INSN
24311 causes the termination of the current group (i.e, the dispatch group to
24312 which INSN belongs). This means that INSN will be the last insn in the
24313 group it belongs to.
24315 If WHICH_GROUP == previous_group, this function will return true if INSN
24316 causes the termination of the previous group (i.e, the dispatch group that
24317 precedes the group to which INSN belongs). This means that INSN will be
24318 the first insn in the group it belongs to). */
24321 insn_terminates_group_p (rtx insn, enum group_termination which_group)
24328 first = insn_must_be_first_in_group (insn);
24329 last = insn_must_be_last_in_group (insn);
24334 if (which_group == current_group)
24336 else if (which_group == previous_group)
24344 insn_must_be_first_in_group (rtx insn)
24346 enum attr_type type;
24349 || GET_CODE (insn) == NOTE
24350 || DEBUG_INSN_P (insn)
24351 || GET_CODE (PATTERN (insn)) == USE
24352 || GET_CODE (PATTERN (insn)) == CLOBBER)
24355 switch (rs6000_cpu)
24357 case PROCESSOR_POWER5:
24358 if (is_cracked_insn (insn))
24360 case PROCESSOR_POWER4:
24361 if (is_microcoded_insn (insn))
24364 if (!rs6000_sched_groups)
24367 type = get_attr_type (insn);
24374 case TYPE_DELAYED_CR:
24375 case TYPE_CR_LOGICAL:
24389 case PROCESSOR_POWER6:
24390 type = get_attr_type (insn);
24394 case TYPE_INSERT_DWORD:
24398 case TYPE_VAR_SHIFT_ROTATE:
24405 case TYPE_INSERT_WORD:
24406 case TYPE_DELAYED_COMPARE:
24407 case TYPE_IMUL_COMPARE:
24408 case TYPE_LMUL_COMPARE:
24409 case TYPE_FPCOMPARE:
24420 case TYPE_LOAD_EXT_UX:
24422 case TYPE_STORE_UX:
24423 case TYPE_FPLOAD_U:
24424 case TYPE_FPLOAD_UX:
24425 case TYPE_FPSTORE_U:
24426 case TYPE_FPSTORE_UX:
24432 case PROCESSOR_POWER7:
24433 type = get_attr_type (insn);
24437 case TYPE_CR_LOGICAL:
24444 case TYPE_DELAYED_COMPARE:
24445 case TYPE_VAR_DELAYED_COMPARE:
24451 case TYPE_LOAD_EXT:
24452 case TYPE_LOAD_EXT_U:
24453 case TYPE_LOAD_EXT_UX:
24455 case TYPE_STORE_UX:
24456 case TYPE_FPLOAD_U:
24457 case TYPE_FPLOAD_UX:
24458 case TYPE_FPSTORE_U:
24459 case TYPE_FPSTORE_UX:
24475 insn_must_be_last_in_group (rtx insn)
24477 enum attr_type type;
24480 || GET_CODE (insn) == NOTE
24481 || DEBUG_INSN_P (insn)
24482 || GET_CODE (PATTERN (insn)) == USE
24483 || GET_CODE (PATTERN (insn)) == CLOBBER)
24486 switch (rs6000_cpu) {
24487 case PROCESSOR_POWER4:
24488 case PROCESSOR_POWER5:
24489 if (is_microcoded_insn (insn))
24492 if (is_branch_slot_insn (insn))
24496 case PROCESSOR_POWER6:
24497 type = get_attr_type (insn);
24504 case TYPE_VAR_SHIFT_ROTATE:
24511 case TYPE_DELAYED_COMPARE:
24512 case TYPE_IMUL_COMPARE:
24513 case TYPE_LMUL_COMPARE:
24514 case TYPE_FPCOMPARE:
24528 case PROCESSOR_POWER7:
24529 type = get_attr_type (insn);
24537 case TYPE_LOAD_EXT_U:
24538 case TYPE_LOAD_EXT_UX:
24539 case TYPE_STORE_UX:
24552 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
24553 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
24556 is_costly_group (rtx *group_insns, rtx next_insn)
24559 int issue_rate = rs6000_issue_rate ();
24561 for (i = 0; i < issue_rate; i++)
24563 sd_iterator_def sd_it;
24565 rtx insn = group_insns[i];
24570 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
24572 rtx next = DEP_CON (dep);
24574 if (next == next_insn
24575 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
24583 /* Utility of the function redefine_groups.
24584 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
24585 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
24586 to keep it "far" (in a separate group) from GROUP_INSNS, following
24587 one of the following schemes, depending on the value of the flag
24588 -minsert_sched_nops = X:
24589 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
24590 in order to force NEXT_INSN into a separate group.
24591 (2) X < sched_finish_regroup_exact: insert exactly X nops.
24592 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
24593 insertion (has a group just ended, how many vacant issue slots remain in the
24594 last group, and how many dispatch groups were encountered so far). */
24597 force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
24598 rtx next_insn, bool *group_end, int can_issue_more,
24603 int issue_rate = rs6000_issue_rate ();
24604 bool end = *group_end;
24607 if (next_insn == NULL_RTX || DEBUG_INSN_P (next_insn))
24608 return can_issue_more;
24610 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
24611 return can_issue_more;
24613 force = is_costly_group (group_insns, next_insn);
24615 return can_issue_more;
24617 if (sched_verbose > 6)
24618 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
24619 *group_count ,can_issue_more);
24621 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
24624 can_issue_more = 0;
24626 /* Since only a branch can be issued in the last issue_slot, it is
24627 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
24628 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
24629 in this case the last nop will start a new group and the branch
24630 will be forced to the new group. */
24631 if (can_issue_more && !is_branch_slot_insn (next_insn))
24634 while (can_issue_more > 0)
24637 emit_insn_before (nop, next_insn);
24645 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
24647 int n_nops = rs6000_sched_insert_nops;
24649 /* Nops can't be issued from the branch slot, so the effective
24650 issue_rate for nops is 'issue_rate - 1'. */
24651 if (can_issue_more == 0)
24652 can_issue_more = issue_rate;
24654 if (can_issue_more == 0)
24656 can_issue_more = issue_rate - 1;
24659 for (i = 0; i < issue_rate; i++)
24661 group_insns[i] = 0;
24668 emit_insn_before (nop, next_insn);
24669 if (can_issue_more == issue_rate - 1) /* new group begins */
24672 if (can_issue_more == 0)
24674 can_issue_more = issue_rate - 1;
24677 for (i = 0; i < issue_rate; i++)
24679 group_insns[i] = 0;
24685 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
24688 /* Is next_insn going to start a new group? */
24691 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24692 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24693 || (can_issue_more < issue_rate &&
24694 insn_terminates_group_p (next_insn, previous_group)));
24695 if (*group_end && end)
24698 if (sched_verbose > 6)
24699 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
24700 *group_count, can_issue_more);
24701 return can_issue_more;
24704 return can_issue_more;
24707 /* This function tries to synch the dispatch groups that the compiler "sees"
24708 with the dispatch groups that the processor dispatcher is expected to
24709 form in practice. It tries to achieve this synchronization by forcing the
24710 estimated processor grouping on the compiler (as opposed to the function
24711 'pad_goups' which tries to force the scheduler's grouping on the processor).
24713 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
24714 examines the (estimated) dispatch groups that will be formed by the processor
24715 dispatcher. It marks these group boundaries to reflect the estimated
24716 processor grouping, overriding the grouping that the scheduler had marked.
24717 Depending on the value of the flag '-minsert-sched-nops' this function can
24718 force certain insns into separate groups or force a certain distance between
24719 them by inserting nops, for example, if there exists a "costly dependence"
24722 The function estimates the group boundaries that the processor will form as
24723 follows: It keeps track of how many vacant issue slots are available after
24724 each insn. A subsequent insn will start a new group if one of the following
24726 - no more vacant issue slots remain in the current dispatch group.
24727 - only the last issue slot, which is the branch slot, is vacant, but the next
24728 insn is not a branch.
24729 - only the last 2 or less issue slots, including the branch slot, are vacant,
24730 which means that a cracked insn (which occupies two issue slots) can't be
24731 issued in this group.
24732 - less than 'issue_rate' slots are vacant, and the next insn always needs to
24733 start a new group. */
24736 redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24738 rtx insn, next_insn;
24740 int can_issue_more;
24743 int group_count = 0;
24747 issue_rate = rs6000_issue_rate ();
24748 group_insns = XALLOCAVEC (rtx, issue_rate);
24749 for (i = 0; i < issue_rate; i++)
24751 group_insns[i] = 0;
24753 can_issue_more = issue_rate;
24755 insn = get_next_active_insn (prev_head_insn, tail);
24758 while (insn != NULL_RTX)
24760 slot = (issue_rate - can_issue_more);
24761 group_insns[slot] = insn;
24763 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24764 if (insn_terminates_group_p (insn, current_group))
24765 can_issue_more = 0;
24767 next_insn = get_next_active_insn (insn, tail);
24768 if (next_insn == NULL_RTX)
24769 return group_count + 1;
24771 /* Is next_insn going to start a new group? */
24773 = (can_issue_more == 0
24774 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
24775 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
24776 || (can_issue_more < issue_rate &&
24777 insn_terminates_group_p (next_insn, previous_group)));
24779 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
24780 next_insn, &group_end, can_issue_more,
24786 can_issue_more = 0;
24787 for (i = 0; i < issue_rate; i++)
24789 group_insns[i] = 0;
24793 if (GET_MODE (next_insn) == TImode && can_issue_more)
24794 PUT_MODE (next_insn, VOIDmode);
24795 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
24796 PUT_MODE (next_insn, TImode);
24799 if (can_issue_more == 0)
24800 can_issue_more = issue_rate;
24803 return group_count;
24806 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
24807 dispatch group boundaries that the scheduler had marked. Pad with nops
24808 any dispatch groups which have vacant issue slots, in order to force the
24809 scheduler's grouping on the processor dispatcher. The function
24810 returns the number of dispatch groups found. */
24813 pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
24815 rtx insn, next_insn;
24818 int can_issue_more;
24820 int group_count = 0;
24822 /* Initialize issue_rate. */
24823 issue_rate = rs6000_issue_rate ();
24824 can_issue_more = issue_rate;
24826 insn = get_next_active_insn (prev_head_insn, tail);
24827 next_insn = get_next_active_insn (insn, tail);
24829 while (insn != NULL_RTX)
24832 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
24834 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
24836 if (next_insn == NULL_RTX)
24841 /* If the scheduler had marked group termination at this location
24842 (between insn and next_insn), and neither insn nor next_insn will
24843 force group termination, pad the group with nops to force group
24846 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
24847 && !insn_terminates_group_p (insn, current_group)
24848 && !insn_terminates_group_p (next_insn, previous_group))
24850 if (!is_branch_slot_insn (next_insn))
24853 while (can_issue_more)
24856 emit_insn_before (nop, next_insn);
24861 can_issue_more = issue_rate;
24866 next_insn = get_next_active_insn (insn, tail);
24869 return group_count;
24872 /* We're beginning a new block. Initialize data structures as necessary. */
24875 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
24876 int sched_verbose ATTRIBUTE_UNUSED,
24877 int max_ready ATTRIBUTE_UNUSED)
24879 last_scheduled_insn = NULL_RTX;
24880 load_store_pendulum = 0;
24883 /* The following function is called at the end of scheduling BB.
24884 After reload, it inserts nops at insn group bundling. */
24887 rs6000_sched_finish (FILE *dump, int sched_verbose)
24892 fprintf (dump, "=== Finishing schedule.\n");
24894 if (reload_completed && rs6000_sched_groups)
24896 /* Do not run sched_finish hook when selective scheduling enabled. */
24897 if (sel_sched_p ())
24900 if (rs6000_sched_insert_nops == sched_finish_none)
24903 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
24904 n_groups = pad_groups (dump, sched_verbose,
24905 current_sched_info->prev_head,
24906 current_sched_info->next_tail);
24908 n_groups = redefine_groups (dump, sched_verbose,
24909 current_sched_info->prev_head,
24910 current_sched_info->next_tail);
24912 if (sched_verbose >= 6)
24914 fprintf (dump, "ngroups = %d\n", n_groups);
24915 print_rtl (dump, current_sched_info->prev_head);
24916 fprintf (dump, "Done finish_sched\n");
24921 struct _rs6000_sched_context
24923 short cached_can_issue_more;
24924 rtx last_scheduled_insn;
24925 int load_store_pendulum;
24928 typedef struct _rs6000_sched_context rs6000_sched_context_def;
24929 typedef rs6000_sched_context_def *rs6000_sched_context_t;
24931 /* Allocate store for new scheduling context. */
24933 rs6000_alloc_sched_context (void)
24935 return xmalloc (sizeof (rs6000_sched_context_def));
24938 /* If CLEAN_P is true then initializes _SC with clean data,
24939 and from the global context otherwise. */
24941 rs6000_init_sched_context (void *_sc, bool clean_p)
24943 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24947 sc->cached_can_issue_more = 0;
24948 sc->last_scheduled_insn = NULL_RTX;
24949 sc->load_store_pendulum = 0;
24953 sc->cached_can_issue_more = cached_can_issue_more;
24954 sc->last_scheduled_insn = last_scheduled_insn;
24955 sc->load_store_pendulum = load_store_pendulum;
24959 /* Sets the global scheduling context to the one pointed to by _SC. */
24961 rs6000_set_sched_context (void *_sc)
24963 rs6000_sched_context_t sc = (rs6000_sched_context_t) _sc;
24965 gcc_assert (sc != NULL);
24967 cached_can_issue_more = sc->cached_can_issue_more;
24968 last_scheduled_insn = sc->last_scheduled_insn;
24969 load_store_pendulum = sc->load_store_pendulum;
24974 rs6000_free_sched_context (void *_sc)
24976 gcc_assert (_sc != NULL);
24982 /* Length in units of the trampoline for entering a nested function. */
24985 rs6000_trampoline_size (void)
24989 switch (DEFAULT_ABI)
24992 gcc_unreachable ();
24995 ret = (TARGET_32BIT) ? 12 : 24;
25000 ret = (TARGET_32BIT) ? 40 : 48;
25007 /* Emit RTL insns to initialize the variable parts of a trampoline.
25008 FNADDR is an RTX for the address of the function's pure code.
25009 CXT is an RTX for the static chain value for the function. */
25012 rs6000_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
25014 int regsize = (TARGET_32BIT) ? 4 : 8;
25015 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
25016 rtx ctx_reg = force_reg (Pmode, cxt);
25017 rtx addr = force_reg (Pmode, XEXP (m_tramp, 0));
25019 switch (DEFAULT_ABI)
25022 gcc_unreachable ();
25024 /* Under AIX, just build the 3 word function descriptor */
25027 rtx fnmem = gen_const_mem (Pmode, force_reg (Pmode, fnaddr));
25028 rtx fn_reg = gen_reg_rtx (Pmode);
25029 rtx toc_reg = gen_reg_rtx (Pmode);
25031 /* Macro to shorten the code expansions below. */
25032 # define MEM_PLUS(MEM, OFFSET) adjust_address (MEM, Pmode, OFFSET)
25034 m_tramp = replace_equiv_address (m_tramp, addr);
25036 emit_move_insn (fn_reg, MEM_PLUS (fnmem, 0));
25037 emit_move_insn (toc_reg, MEM_PLUS (fnmem, regsize));
25038 emit_move_insn (MEM_PLUS (m_tramp, 0), fn_reg);
25039 emit_move_insn (MEM_PLUS (m_tramp, regsize), toc_reg);
25040 emit_move_insn (MEM_PLUS (m_tramp, 2*regsize), ctx_reg);
25046 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
25049 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
25050 LCT_NORMAL, VOIDmode, 4,
25052 GEN_INT (rs6000_trampoline_size ()), SImode,
25060 /* Returns TRUE iff the target attribute indicated by ATTR_ID takes a plain
25061 identifier as an argument, so the front end shouldn't look it up. */
25064 rs6000_attribute_takes_identifier_p (const_tree attr_id)
25066 return is_attribute_p ("altivec", attr_id);
25069 /* Handle the "altivec" attribute. The attribute may have
25070 arguments as follows:
25072 __attribute__((altivec(vector__)))
25073 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
25074 __attribute__((altivec(bool__))) (always followed by 'unsigned')
25076 and may appear more than once (e.g., 'vector bool char') in a
25077 given declaration. */
25080 rs6000_handle_altivec_attribute (tree *node,
25081 tree name ATTRIBUTE_UNUSED,
25083 int flags ATTRIBUTE_UNUSED,
25084 bool *no_add_attrs)
25086 tree type = *node, result = NULL_TREE;
25087 enum machine_mode mode;
25090 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
25091 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
25092 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
25095 while (POINTER_TYPE_P (type)
25096 || TREE_CODE (type) == FUNCTION_TYPE
25097 || TREE_CODE (type) == METHOD_TYPE
25098 || TREE_CODE (type) == ARRAY_TYPE)
25099 type = TREE_TYPE (type);
25101 mode = TYPE_MODE (type);
25103 /* Check for invalid AltiVec type qualifiers. */
25104 if (type == long_double_type_node)
25105 error ("use of %<long double%> in AltiVec types is invalid");
25106 else if (type == boolean_type_node)
25107 error ("use of boolean types in AltiVec types is invalid");
25108 else if (TREE_CODE (type) == COMPLEX_TYPE)
25109 error ("use of %<complex%> in AltiVec types is invalid");
25110 else if (DECIMAL_FLOAT_MODE_P (mode))
25111 error ("use of decimal floating point types in AltiVec types is invalid");
25112 else if (!TARGET_VSX)
25114 if (type == long_unsigned_type_node || type == long_integer_type_node)
25117 error ("use of %<long%> in AltiVec types is invalid for "
25118 "64-bit code without -mvsx");
25119 else if (rs6000_warn_altivec_long)
25120 warning (0, "use of %<long%> in AltiVec types is deprecated; "
25123 else if (type == long_long_unsigned_type_node
25124 || type == long_long_integer_type_node)
25125 error ("use of %<long long%> in AltiVec types is invalid without "
25127 else if (type == double_type_node)
25128 error ("use of %<double%> in AltiVec types is invalid without -mvsx");
25131 switch (altivec_type)
25134 unsigned_p = TYPE_UNSIGNED (type);
25138 result = (unsigned_p ? unsigned_V2DI_type_node : V2DI_type_node);
25141 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
25144 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
25147 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
25149 case SFmode: result = V4SF_type_node; break;
25150 case DFmode: result = V2DF_type_node; break;
25151 /* If the user says 'vector int bool', we may be handed the 'bool'
25152 attribute _before_ the 'vector' attribute, and so select the
25153 proper type in the 'b' case below. */
25154 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
25155 case V2DImode: case V2DFmode:
25163 case DImode: case V2DImode: result = bool_V2DI_type_node; break;
25164 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
25165 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
25166 case QImode: case V16QImode: result = bool_V16QI_type_node;
25173 case V8HImode: result = pixel_V8HI_type_node;
25179 /* Propagate qualifiers attached to the element type
25180 onto the vector type. */
25181 if (result && result != type && TYPE_QUALS (type))
25182 result = build_qualified_type (result, TYPE_QUALS (type));
25184 *no_add_attrs = true; /* No need to hang on to the attribute. */
25187 *node = lang_hooks.types.reconstruct_complex_type (*node, result);
25192 /* AltiVec defines four built-in scalar types that serve as vector
25193 elements; we must teach the compiler how to mangle them. */
25195 static const char *
25196 rs6000_mangle_type (const_tree type)
25198 type = TYPE_MAIN_VARIANT (type);
25200 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25201 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25204 if (type == bool_char_type_node) return "U6__boolc";
25205 if (type == bool_short_type_node) return "U6__bools";
25206 if (type == pixel_type_node) return "u7__pixel";
25207 if (type == bool_int_type_node) return "U6__booli";
25208 if (type == bool_long_type_node) return "U6__booll";
25210 /* Mangle IBM extended float long double as `g' (__float128) on
25211 powerpc*-linux where long-double-64 previously was the default. */
25212 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
25214 && TARGET_LONG_DOUBLE_128
25215 && !TARGET_IEEEQUAD)
25218 /* For all other types, use normal C++ mangling. */
25222 /* Handle a "longcall" or "shortcall" attribute; arguments as in
25223 struct attribute_spec.handler. */
25226 rs6000_handle_longcall_attribute (tree *node, tree name,
25227 tree args ATTRIBUTE_UNUSED,
25228 int flags ATTRIBUTE_UNUSED,
25229 bool *no_add_attrs)
25231 if (TREE_CODE (*node) != FUNCTION_TYPE
25232 && TREE_CODE (*node) != FIELD_DECL
25233 && TREE_CODE (*node) != TYPE_DECL)
25235 warning (OPT_Wattributes, "%qE attribute only applies to functions",
25237 *no_add_attrs = true;
25243 /* Set longcall attributes on all functions declared when
25244 rs6000_default_long_calls is true. */
25246 rs6000_set_default_type_attributes (tree type)
25248 if (rs6000_default_long_calls
25249 && (TREE_CODE (type) == FUNCTION_TYPE
25250 || TREE_CODE (type) == METHOD_TYPE))
25251 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
25253 TYPE_ATTRIBUTES (type));
25256 darwin_set_default_type_attributes (type);
25260 /* Return a reference suitable for calling a function with the
25261 longcall attribute. */
25264 rs6000_longcall_ref (rtx call_ref)
25266 const char *call_name;
25269 if (GET_CODE (call_ref) != SYMBOL_REF)
25272 /* System V adds '.' to the internal name, so skip them. */
25273 call_name = XSTR (call_ref, 0);
25274 if (*call_name == '.')
25276 while (*call_name == '.')
25279 node = get_identifier (call_name);
25280 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
25283 return force_reg (Pmode, call_ref);
25286 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
25287 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
25290 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
25291 struct attribute_spec.handler. */
25293 rs6000_handle_struct_attribute (tree *node, tree name,
25294 tree args ATTRIBUTE_UNUSED,
25295 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
25298 if (DECL_P (*node))
25300 if (TREE_CODE (*node) == TYPE_DECL)
25301 type = &TREE_TYPE (*node);
25306 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
25307 || TREE_CODE (*type) == UNION_TYPE)))
25309 warning (OPT_Wattributes, "%qE attribute ignored", name);
25310 *no_add_attrs = true;
25313 else if ((is_attribute_p ("ms_struct", name)
25314 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
25315 || ((is_attribute_p ("gcc_struct", name)
25316 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
25318 warning (OPT_Wattributes, "%qE incompatible attribute ignored",
25320 *no_add_attrs = true;
25327 rs6000_ms_bitfield_layout_p (const_tree record_type)
25329 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
25330 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
25331 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
25334 #ifdef USING_ELFOS_H
25336 /* A get_unnamed_section callback, used for switching to toc_section. */
25339 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
25341 if (DEFAULT_ABI == ABI_AIX
25342 && TARGET_MINIMAL_TOC
25343 && !TARGET_RELOCATABLE)
25345 if (!toc_initialized)
25347 toc_initialized = 1;
25348 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25349 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
25350 fprintf (asm_out_file, "\t.tc ");
25351 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
25352 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25353 fprintf (asm_out_file, "\n");
25355 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25356 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25357 fprintf (asm_out_file, " = .+32768\n");
25360 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25362 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
25363 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
25366 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
25367 if (!toc_initialized)
25369 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
25370 fprintf (asm_out_file, " = .+32768\n");
25371 toc_initialized = 1;
25376 /* Implement TARGET_ASM_INIT_SECTIONS. */
25379 rs6000_elf_asm_init_sections (void)
25382 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
25385 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
25386 SDATA2_SECTION_ASM_OP);
25389 /* Implement TARGET_SELECT_RTX_SECTION. */
25392 rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
25393 unsigned HOST_WIDE_INT align)
25395 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
25396 return toc_section;
25398 return default_elf_select_rtx_section (mode, x, align);
25401 /* For a SYMBOL_REF, set generic flags and then perform some
25402 target-specific processing.
25404 When the AIX ABI is requested on a non-AIX system, replace the
25405 function name with the real name (with a leading .) rather than the
25406 function descriptor name. This saves a lot of overriding code to
25407 read the prefixes. */
25410 rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
25412 default_encode_section_info (decl, rtl, first);
25415 && TREE_CODE (decl) == FUNCTION_DECL
25417 && DEFAULT_ABI == ABI_AIX)
25419 rtx sym_ref = XEXP (rtl, 0);
25420 size_t len = strlen (XSTR (sym_ref, 0));
25421 char *str = XALLOCAVEC (char, len + 2);
25423 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
25424 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
25429 compare_section_name (const char *section, const char *templ)
25433 len = strlen (templ);
25434 return (strncmp (section, templ, len) == 0
25435 && (section[len] == 0 || section[len] == '.'));
25439 rs6000_elf_in_small_data_p (const_tree decl)
25441 if (rs6000_sdata == SDATA_NONE)
25444 /* We want to merge strings, so we never consider them small data. */
25445 if (TREE_CODE (decl) == STRING_CST)
25448 /* Functions are never in the small data area. */
25449 if (TREE_CODE (decl) == FUNCTION_DECL)
25452 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
25454 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
25455 if (compare_section_name (section, ".sdata")
25456 || compare_section_name (section, ".sdata2")
25457 || compare_section_name (section, ".gnu.linkonce.s")
25458 || compare_section_name (section, ".sbss")
25459 || compare_section_name (section, ".sbss2")
25460 || compare_section_name (section, ".gnu.linkonce.sb")
25461 || strcmp (section, ".PPC.EMB.sdata0") == 0
25462 || strcmp (section, ".PPC.EMB.sbss0") == 0)
25467 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
25470 && size <= g_switch_value
25471 /* If it's not public, and we're not going to reference it there,
25472 there's no need to put it in the small data section. */
25473 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
25480 #endif /* USING_ELFOS_H */
25482 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
25485 rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
25487 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
25490 /* Return a REG that occurs in ADDR with coefficient 1.
25491 ADDR can be effectively incremented by incrementing REG.
25493 r0 is special and we must not select it as an address
25494 register by this routine since our caller will try to
25495 increment the returned register via an "la" instruction. */
25498 find_addr_reg (rtx addr)
25500 while (GET_CODE (addr) == PLUS)
25502 if (GET_CODE (XEXP (addr, 0)) == REG
25503 && REGNO (XEXP (addr, 0)) != 0)
25504 addr = XEXP (addr, 0);
25505 else if (GET_CODE (XEXP (addr, 1)) == REG
25506 && REGNO (XEXP (addr, 1)) != 0)
25507 addr = XEXP (addr, 1);
25508 else if (CONSTANT_P (XEXP (addr, 0)))
25509 addr = XEXP (addr, 1);
25510 else if (CONSTANT_P (XEXP (addr, 1)))
25511 addr = XEXP (addr, 0);
25513 gcc_unreachable ();
25515 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
25520 rs6000_fatal_bad_address (rtx op)
25522 fatal_insn ("bad address", op);
25527 typedef struct branch_island_d {
25528 tree function_name;
25533 DEF_VEC_O(branch_island);
25534 DEF_VEC_ALLOC_O(branch_island,gc);
25536 static VEC(branch_island,gc) *branch_islands;
25538 /* Remember to generate a branch island for far calls to the given
25542 add_compiler_branch_island (tree label_name, tree function_name,
25545 branch_island *bi = VEC_safe_push (branch_island, gc, branch_islands, NULL);
25547 bi->function_name = function_name;
25548 bi->label_name = label_name;
25549 bi->line_number = line_number;
25552 /* Generate far-jump branch islands for everything recorded in
25553 branch_islands. Invoked immediately after the last instruction of
25554 the epilogue has been emitted; the branch islands must be appended
25555 to, and contiguous with, the function body. Mach-O stubs are
25556 generated in machopic_output_stub(). */
25559 macho_branch_islands (void)
25563 while (!VEC_empty (branch_island, branch_islands))
25565 branch_island *bi = VEC_last (branch_island, branch_islands);
25566 const char *label = IDENTIFIER_POINTER (bi->label_name);
25567 const char *name = IDENTIFIER_POINTER (bi->function_name);
25568 char name_buf[512];
25569 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
25570 if (name[0] == '*' || name[0] == '&')
25571 strcpy (name_buf, name+1);
25575 strcpy (name_buf+1, name);
25577 strcpy (tmp_buf, "\n");
25578 strcat (tmp_buf, label);
25579 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25580 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25581 dbxout_stabd (N_SLINE, bi->line_number);
25582 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25585 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
25586 strcat (tmp_buf, label);
25587 strcat (tmp_buf, "_pic\n");
25588 strcat (tmp_buf, label);
25589 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
25591 strcat (tmp_buf, "\taddis r11,r11,ha16(");
25592 strcat (tmp_buf, name_buf);
25593 strcat (tmp_buf, " - ");
25594 strcat (tmp_buf, label);
25595 strcat (tmp_buf, "_pic)\n");
25597 strcat (tmp_buf, "\tmtlr r0\n");
25599 strcat (tmp_buf, "\taddi r12,r11,lo16(");
25600 strcat (tmp_buf, name_buf);
25601 strcat (tmp_buf, " - ");
25602 strcat (tmp_buf, label);
25603 strcat (tmp_buf, "_pic)\n");
25605 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
25609 strcat (tmp_buf, ":\nlis r12,hi16(");
25610 strcat (tmp_buf, name_buf);
25611 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
25612 strcat (tmp_buf, name_buf);
25613 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
25615 output_asm_insn (tmp_buf, 0);
25616 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
25617 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
25618 dbxout_stabd (N_SLINE, bi->line_number);
25619 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
25620 VEC_pop (branch_island, branch_islands);
25624 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
25625 already there or not. */
25628 no_previous_def (tree function_name)
25633 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25634 if (function_name == bi->function_name)
25639 /* GET_PREV_LABEL gets the label name from the previous definition of
25643 get_prev_label (tree function_name)
25648 FOR_EACH_VEC_ELT (branch_island, branch_islands, ix, bi)
25649 if (function_name == bi->function_name)
25650 return bi->label_name;
25654 /* INSN is either a function call or a millicode call. It may have an
25655 unconditional jump in its delay slot.
25657 CALL_DEST is the routine we are calling. */
25660 output_call (rtx insn, rtx *operands, int dest_operand_number,
25661 int cookie_operand_number)
25663 static char buf[256];
25664 if (darwin_emit_branch_islands
25665 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
25666 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
25669 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
25671 if (no_previous_def (funname))
25673 rtx label_rtx = gen_label_rtx ();
25674 char *label_buf, temp_buf[256];
25675 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
25676 CODE_LABEL_NUMBER (label_rtx));
25677 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
25678 labelname = get_identifier (label_buf);
25679 add_compiler_branch_island (labelname, funname, insn_line (insn));
25682 labelname = get_prev_label (funname);
25684 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
25685 instruction will reach 'foo', otherwise link as 'bl L42'".
25686 "L42" should be a 'branch island', that will do a far jump to
25687 'foo'. Branch islands are generated in
25688 macho_branch_islands(). */
25689 sprintf (buf, "jbsr %%z%d,%.246s",
25690 dest_operand_number, IDENTIFIER_POINTER (labelname));
25693 sprintf (buf, "bl %%z%d", dest_operand_number);
25697 /* Generate PIC and indirect symbol stubs. */
25700 machopic_output_stub (FILE *file, const char *symb, const char *stub)
25702 unsigned int length;
25703 char *symbol_name, *lazy_ptr_name;
25704 char *local_label_0;
25705 static int label = 0;
25707 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
25708 symb = (*targetm.strip_name_encoding) (symb);
25711 length = strlen (symb);
25712 symbol_name = XALLOCAVEC (char, length + 32);
25713 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
25715 lazy_ptr_name = XALLOCAVEC (char, length + 32);
25716 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
25719 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
25721 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
25725 fprintf (file, "\t.align 5\n");
25727 fprintf (file, "%s:\n", stub);
25728 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25731 local_label_0 = XALLOCAVEC (char, sizeof ("\"L00000000000$spb\""));
25732 sprintf (local_label_0, "\"L%011d$spb\"", label);
25734 fprintf (file, "\tmflr r0\n");
25735 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
25736 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
25737 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
25738 lazy_ptr_name, local_label_0);
25739 fprintf (file, "\tmtlr r0\n");
25740 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
25741 (TARGET_64BIT ? "ldu" : "lwzu"),
25742 lazy_ptr_name, local_label_0);
25743 fprintf (file, "\tmtctr r12\n");
25744 fprintf (file, "\tbctr\n");
25748 fprintf (file, "\t.align 4\n");
25750 fprintf (file, "%s:\n", stub);
25751 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25753 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
25754 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
25755 (TARGET_64BIT ? "ldu" : "lwzu"),
25757 fprintf (file, "\tmtctr r12\n");
25758 fprintf (file, "\tbctr\n");
25761 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
25762 fprintf (file, "%s:\n", lazy_ptr_name);
25763 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
25764 fprintf (file, "%sdyld_stub_binding_helper\n",
25765 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
25768 /* Legitimize PIC addresses. If the address is already
25769 position-independent, we return ORIG. Newly generated
25770 position-independent addresses go into a reg. This is REG if non
25771 zero, otherwise we allocate register(s) as necessary. */
25773 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
25776 rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
25781 if (reg == NULL && ! reload_in_progress && ! reload_completed)
25782 reg = gen_reg_rtx (Pmode);
25784 if (GET_CODE (orig) == CONST)
25788 if (GET_CODE (XEXP (orig, 0)) == PLUS
25789 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
25792 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
25794 /* Use a different reg for the intermediate value, as
25795 it will be marked UNCHANGING. */
25796 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
25797 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
25800 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
25803 if (GET_CODE (offset) == CONST_INT)
25805 if (SMALL_INT (offset))
25806 return plus_constant (base, INTVAL (offset));
25807 else if (! reload_in_progress && ! reload_completed)
25808 offset = force_reg (Pmode, offset);
25811 rtx mem = force_const_mem (Pmode, orig);
25812 return machopic_legitimize_pic_address (mem, Pmode, reg);
25815 return gen_rtx_PLUS (Pmode, base, offset);
25818 /* Fall back on generic machopic code. */
25819 return machopic_legitimize_pic_address (orig, mode, reg);
25822 /* Output a .machine directive for the Darwin assembler, and call
25823 the generic start_file routine. */
25826 rs6000_darwin_file_start (void)
25828 static const struct
25834 { "ppc64", "ppc64", MASK_64BIT },
25835 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
25836 { "power4", "ppc970", 0 },
25837 { "G5", "ppc970", 0 },
25838 { "7450", "ppc7450", 0 },
25839 { "7400", "ppc7400", MASK_ALTIVEC },
25840 { "G4", "ppc7400", 0 },
25841 { "750", "ppc750", 0 },
25842 { "740", "ppc750", 0 },
25843 { "G3", "ppc750", 0 },
25844 { "604e", "ppc604e", 0 },
25845 { "604", "ppc604", 0 },
25846 { "603e", "ppc603", 0 },
25847 { "603", "ppc603", 0 },
25848 { "601", "ppc601", 0 },
25849 { NULL, "ppc", 0 } };
25850 const char *cpu_id = "";
25853 rs6000_file_start ();
25854 darwin_file_start ();
25856 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
25857 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
25858 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
25859 && rs6000_select[i].string[0] != '\0')
25860 cpu_id = rs6000_select[i].string;
25862 /* Look through the mapping array. Pick the first name that either
25863 matches the argument, has a bit set in IF_SET that is also set
25864 in the target flags, or has a NULL name. */
25867 while (mapping[i].arg != NULL
25868 && strcmp (mapping[i].arg, cpu_id) != 0
25869 && (mapping[i].if_set & target_flags) == 0)
25872 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
25875 #endif /* TARGET_MACHO */
25879 rs6000_elf_reloc_rw_mask (void)
25883 else if (DEFAULT_ABI == ABI_AIX)
25889 /* Record an element in the table of global constructors. SYMBOL is
25890 a SYMBOL_REF of the function to be called; PRIORITY is a number
25891 between 0 and MAX_INIT_PRIORITY.
25893 This differs from default_named_section_asm_out_constructor in
25894 that we have special handling for -mrelocatable. */
25897 rs6000_elf_asm_out_constructor (rtx symbol, int priority)
25899 const char *section = ".ctors";
25902 if (priority != DEFAULT_INIT_PRIORITY)
25904 sprintf (buf, ".ctors.%.5u",
25905 /* Invert the numbering so the linker puts us in the proper
25906 order; constructors are run from right to left, and the
25907 linker sorts in increasing order. */
25908 MAX_INIT_PRIORITY - priority);
25912 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25913 assemble_align (POINTER_SIZE);
25915 if (TARGET_RELOCATABLE)
25917 fputs ("\t.long (", asm_out_file);
25918 output_addr_const (asm_out_file, symbol);
25919 fputs (")@fixup\n", asm_out_file);
25922 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25926 rs6000_elf_asm_out_destructor (rtx symbol, int priority)
25928 const char *section = ".dtors";
25931 if (priority != DEFAULT_INIT_PRIORITY)
25933 sprintf (buf, ".dtors.%.5u",
25934 /* Invert the numbering so the linker puts us in the proper
25935 order; constructors are run from right to left, and the
25936 linker sorts in increasing order. */
25937 MAX_INIT_PRIORITY - priority);
25941 switch_to_section (get_section (section, SECTION_WRITE, NULL));
25942 assemble_align (POINTER_SIZE);
25944 if (TARGET_RELOCATABLE)
25946 fputs ("\t.long (", asm_out_file);
25947 output_addr_const (asm_out_file, symbol);
25948 fputs (")@fixup\n", asm_out_file);
25951 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
25955 rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
25959 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
25960 ASM_OUTPUT_LABEL (file, name);
25961 fputs (DOUBLE_INT_ASM_OP, file);
25962 rs6000_output_function_entry (file, name);
25963 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
25966 fputs ("\t.size\t", file);
25967 assemble_name (file, name);
25968 fputs (",24\n\t.type\t.", file);
25969 assemble_name (file, name);
25970 fputs (",@function\n", file);
25971 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
25973 fputs ("\t.globl\t.", file);
25974 assemble_name (file, name);
25979 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
25980 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
25981 rs6000_output_function_entry (file, name);
25982 fputs (":\n", file);
25986 if (TARGET_RELOCATABLE
25987 && !TARGET_SECURE_PLT
25988 && (get_pool_size () != 0 || crtl->profile)
25993 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
25995 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
25996 fprintf (file, "\t.long ");
25997 assemble_name (file, buf);
25999 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
26000 assemble_name (file, buf);
26004 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
26005 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
26007 if (DEFAULT_ABI == ABI_AIX)
26009 const char *desc_name, *orig_name;
26011 orig_name = (*targetm.strip_name_encoding) (name);
26012 desc_name = orig_name;
26013 while (*desc_name == '.')
26016 if (TREE_PUBLIC (decl))
26017 fprintf (file, "\t.globl %s\n", desc_name);
26019 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
26020 fprintf (file, "%s:\n", desc_name);
26021 fprintf (file, "\t.long %s\n", orig_name);
26022 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
26023 if (DEFAULT_ABI == ABI_AIX)
26024 fputs ("\t.long 0\n", file);
26025 fprintf (file, "\t.previous\n");
26027 ASM_OUTPUT_LABEL (file, name);
26031 rs6000_elf_file_end (void)
26033 #ifdef HAVE_AS_GNU_ATTRIBUTE
26034 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
26036 if (rs6000_passes_float)
26037 fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n",
26038 ((TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) ? 1
26039 : (TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT) ? 3
26041 if (rs6000_passes_vector)
26042 fprintf (asm_out_file, "\t.gnu_attribute 8, %d\n",
26043 (TARGET_ALTIVEC_ABI ? 2
26044 : TARGET_SPE_ABI ? 3
26046 if (rs6000_returns_struct)
26047 fprintf (asm_out_file, "\t.gnu_attribute 12, %d\n",
26048 aix_struct_return ? 2 : 1);
26051 #ifdef POWERPC_LINUX
26053 file_end_indicate_exec_stack ();
26060 rs6000_xcoff_asm_output_anchor (rtx symbol)
26064 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
26065 SYMBOL_REF_BLOCK_OFFSET (symbol));
26066 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
26070 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
26072 fputs (GLOBAL_ASM_OP, stream);
26073 RS6000_OUTPUT_BASENAME (stream, name);
26074 putc ('\n', stream);
26077 /* A get_unnamed_decl callback, used for read-only sections. PTR
26078 points to the section string variable. */
26081 rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
26083 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
26084 *(const char *const *) directive,
26085 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26088 /* Likewise for read-write sections. */
26091 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
26093 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
26094 *(const char *const *) directive,
26095 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
26098 /* A get_unnamed_section callback, used for switching to toc_section. */
26101 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
26103 if (TARGET_MINIMAL_TOC)
26105 /* toc_section is always selected at least once from
26106 rs6000_xcoff_file_start, so this is guaranteed to
26107 always be defined once and only once in each file. */
26108 if (!toc_initialized)
26110 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
26111 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
26112 toc_initialized = 1;
26114 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
26115 (TARGET_32BIT ? "" : ",3"));
26118 fputs ("\t.toc\n", asm_out_file);
26121 /* Implement TARGET_ASM_INIT_SECTIONS. */
26124 rs6000_xcoff_asm_init_sections (void)
26126 read_only_data_section
26127 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26128 &xcoff_read_only_section_name);
26130 private_data_section
26131 = get_unnamed_section (SECTION_WRITE,
26132 rs6000_xcoff_output_readwrite_section_asm_op,
26133 &xcoff_private_data_section_name);
26135 read_only_private_data_section
26136 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
26137 &xcoff_private_data_section_name);
26140 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
26142 readonly_data_section = read_only_data_section;
26143 exception_section = data_section;
26147 rs6000_xcoff_reloc_rw_mask (void)
26153 rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
26154 tree decl ATTRIBUTE_UNUSED)
26157 static const char * const suffix[3] = { "PR", "RO", "RW" };
26159 if (flags & SECTION_CODE)
26161 else if (flags & SECTION_WRITE)
26166 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
26167 (flags & SECTION_CODE) ? "." : "",
26168 name, suffix[smclass], flags & SECTION_ENTSIZE);
26172 rs6000_xcoff_select_section (tree decl, int reloc,
26173 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26175 if (decl_readonly_section (decl, reloc))
26177 if (TREE_PUBLIC (decl))
26178 return read_only_data_section;
26180 return read_only_private_data_section;
26184 if (TREE_PUBLIC (decl))
26185 return data_section;
26187 return private_data_section;
26192 rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
26196 /* Use select_section for private and uninitialized data. */
26197 if (!TREE_PUBLIC (decl)
26198 || DECL_COMMON (decl)
26199 || DECL_INITIAL (decl) == NULL_TREE
26200 || DECL_INITIAL (decl) == error_mark_node
26201 || (flag_zero_initialized_in_bss
26202 && initializer_zerop (DECL_INITIAL (decl))))
26205 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
26206 name = (*targetm.strip_name_encoding) (name);
26207 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
26210 /* Select section for constant in constant pool.
26212 On RS/6000, all constants are in the private read-only data area.
26213 However, if this is being placed in the TOC it must be output as a
26217 rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
26218 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
26220 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
26221 return toc_section;
26223 return read_only_private_data_section;
26226 /* Remove any trailing [DS] or the like from the symbol name. */
26228 static const char *
26229 rs6000_xcoff_strip_name_encoding (const char *name)
26234 len = strlen (name);
26235 if (name[len - 1] == ']')
26236 return ggc_alloc_string (name, len - 4);
26241 /* Section attributes. AIX is always PIC. */
26243 static unsigned int
26244 rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
26246 unsigned int align;
26247 unsigned int flags = default_section_type_flags (decl, name, reloc);
26249 /* Align to at least UNIT size. */
26250 if (flags & SECTION_CODE)
26251 align = MIN_UNITS_PER_WORD;
26253 /* Increase alignment of large objects if not already stricter. */
26254 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
26255 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
26256 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
26258 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
26261 /* Output at beginning of assembler file.
26263 Initialize the section names for the RS/6000 at this point.
26265 Specify filename, including full path, to assembler.
26267 We want to go into the TOC section so at least one .toc will be emitted.
26268 Also, in order to output proper .bs/.es pairs, we need at least one static
26269 [RW] section emitted.
26271 Finally, declare mcount when profiling to make the assembler happy. */
26274 rs6000_xcoff_file_start (void)
26276 rs6000_gen_section_name (&xcoff_bss_section_name,
26277 main_input_filename, ".bss_");
26278 rs6000_gen_section_name (&xcoff_private_data_section_name,
26279 main_input_filename, ".rw_");
26280 rs6000_gen_section_name (&xcoff_read_only_section_name,
26281 main_input_filename, ".ro_");
26283 fputs ("\t.file\t", asm_out_file);
26284 output_quoted_string (asm_out_file, main_input_filename);
26285 fputc ('\n', asm_out_file);
26286 if (write_symbols != NO_DEBUG)
26287 switch_to_section (private_data_section);
26288 switch_to_section (text_section);
26290 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
26291 rs6000_file_start ();
26294 /* Output at end of assembler file.
26295 On the RS/6000, referencing data should automatically pull in text. */
26298 rs6000_xcoff_file_end (void)
26300 switch_to_section (text_section);
26301 fputs ("_section_.text:\n", asm_out_file);
26302 switch_to_section (data_section);
26303 fputs (TARGET_32BIT
26304 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
26307 #endif /* TARGET_XCOFF */
26309 /* Compute a (partial) cost for rtx X. Return true if the complete
26310 cost has been computed, and false if subexpressions should be
26311 scanned. In either case, *TOTAL contains the cost result. */
26314 rs6000_rtx_costs (rtx x, int code, int outer_code, int *total,
26317 enum machine_mode mode = GET_MODE (x);
26321 /* On the RS/6000, if it is valid in the insn, it is free. */
26323 if (((outer_code == SET
26324 || outer_code == PLUS
26325 || outer_code == MINUS)
26326 && (satisfies_constraint_I (x)
26327 || satisfies_constraint_L (x)))
26328 || (outer_code == AND
26329 && (satisfies_constraint_K (x)
26331 ? satisfies_constraint_L (x)
26332 : satisfies_constraint_J (x))
26333 || mask_operand (x, mode)
26335 && mask64_operand (x, DImode))))
26336 || ((outer_code == IOR || outer_code == XOR)
26337 && (satisfies_constraint_K (x)
26339 ? satisfies_constraint_L (x)
26340 : satisfies_constraint_J (x))))
26341 || outer_code == ASHIFT
26342 || outer_code == ASHIFTRT
26343 || outer_code == LSHIFTRT
26344 || outer_code == ROTATE
26345 || outer_code == ROTATERT
26346 || outer_code == ZERO_EXTRACT
26347 || (outer_code == MULT
26348 && satisfies_constraint_I (x))
26349 || ((outer_code == DIV || outer_code == UDIV
26350 || outer_code == MOD || outer_code == UMOD)
26351 && exact_log2 (INTVAL (x)) >= 0)
26352 || (outer_code == COMPARE
26353 && (satisfies_constraint_I (x)
26354 || satisfies_constraint_K (x)))
26355 || ((outer_code == EQ || outer_code == NE)
26356 && (satisfies_constraint_I (x)
26357 || satisfies_constraint_K (x)
26359 ? satisfies_constraint_L (x)
26360 : satisfies_constraint_J (x))))
26361 || (outer_code == GTU
26362 && satisfies_constraint_I (x))
26363 || (outer_code == LTU
26364 && satisfies_constraint_P (x)))
26369 else if ((outer_code == PLUS
26370 && reg_or_add_cint_operand (x, VOIDmode))
26371 || (outer_code == MINUS
26372 && reg_or_sub_cint_operand (x, VOIDmode))
26373 || ((outer_code == SET
26374 || outer_code == IOR
26375 || outer_code == XOR)
26377 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
26379 *total = COSTS_N_INSNS (1);
26385 if (mode == DImode && code == CONST_DOUBLE)
26387 if ((outer_code == IOR || outer_code == XOR)
26388 && CONST_DOUBLE_HIGH (x) == 0
26389 && (CONST_DOUBLE_LOW (x)
26390 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
26395 else if ((outer_code == AND && and64_2_operand (x, DImode))
26396 || ((outer_code == SET
26397 || outer_code == IOR
26398 || outer_code == XOR)
26399 && CONST_DOUBLE_HIGH (x) == 0))
26401 *total = COSTS_N_INSNS (1);
26411 /* When optimizing for size, MEM should be slightly more expensive
26412 than generating address, e.g., (plus (reg) (const)).
26413 L1 cache latency is about two instructions. */
26414 *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
26423 if (FLOAT_MODE_P (mode))
26424 *total = rs6000_cost->fp;
26426 *total = COSTS_N_INSNS (1);
26430 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26431 && satisfies_constraint_I (XEXP (x, 1)))
26433 if (INTVAL (XEXP (x, 1)) >= -256
26434 && INTVAL (XEXP (x, 1)) <= 255)
26435 *total = rs6000_cost->mulsi_const9;
26437 *total = rs6000_cost->mulsi_const;
26439 else if (mode == SFmode)
26440 *total = rs6000_cost->fp;
26441 else if (FLOAT_MODE_P (mode))
26442 *total = rs6000_cost->dmul;
26443 else if (mode == DImode)
26444 *total = rs6000_cost->muldi;
26446 *total = rs6000_cost->mulsi;
26450 if (mode == SFmode)
26451 *total = rs6000_cost->fp;
26453 *total = rs6000_cost->dmul;
26458 if (FLOAT_MODE_P (mode))
26460 *total = mode == DFmode ? rs6000_cost->ddiv
26461 : rs6000_cost->sdiv;
26468 if (GET_CODE (XEXP (x, 1)) == CONST_INT
26469 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
26471 if (code == DIV || code == MOD)
26473 *total = COSTS_N_INSNS (2);
26476 *total = COSTS_N_INSNS (1);
26480 if (GET_MODE (XEXP (x, 1)) == DImode)
26481 *total = rs6000_cost->divdi;
26483 *total = rs6000_cost->divsi;
26485 /* Add in shift and subtract for MOD. */
26486 if (code == MOD || code == UMOD)
26487 *total += COSTS_N_INSNS (2);
26492 *total = COSTS_N_INSNS (4);
26496 *total = COSTS_N_INSNS (TARGET_POPCNTD ? 1 : 6);
26500 *total = COSTS_N_INSNS (TARGET_CMPB ? 2 : 6);
26504 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
26516 *total = COSTS_N_INSNS (1);
26524 /* Handle mul_highpart. */
26525 if (outer_code == TRUNCATE
26526 && GET_CODE (XEXP (x, 0)) == MULT)
26528 if (mode == DImode)
26529 *total = rs6000_cost->muldi;
26531 *total = rs6000_cost->mulsi;
26534 else if (outer_code == AND)
26537 *total = COSTS_N_INSNS (1);
26542 if (GET_CODE (XEXP (x, 0)) == MEM)
26545 *total = COSTS_N_INSNS (1);
26551 if (!FLOAT_MODE_P (mode))
26553 *total = COSTS_N_INSNS (1);
26559 case UNSIGNED_FLOAT:
26562 case FLOAT_TRUNCATE:
26563 *total = rs6000_cost->fp;
26567 if (mode == DFmode)
26570 *total = rs6000_cost->fp;
26574 switch (XINT (x, 1))
26577 *total = rs6000_cost->fp;
26589 *total = COSTS_N_INSNS (1);
26592 else if (FLOAT_MODE_P (mode)
26593 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
26595 *total = rs6000_cost->fp;
26603 /* Carry bit requires mode == Pmode.
26604 NEG or PLUS already counted so only add one. */
26606 && (outer_code == NEG || outer_code == PLUS))
26608 *total = COSTS_N_INSNS (1);
26611 if (outer_code == SET)
26613 if (XEXP (x, 1) == const0_rtx)
26615 if (TARGET_ISEL && !TARGET_MFCRF)
26616 *total = COSTS_N_INSNS (8);
26618 *total = COSTS_N_INSNS (2);
26621 else if (mode == Pmode)
26623 *total = COSTS_N_INSNS (3);
26632 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
26634 if (TARGET_ISEL && !TARGET_MFCRF)
26635 *total = COSTS_N_INSNS (8);
26637 *total = COSTS_N_INSNS (2);
26641 if (outer_code == COMPARE)
26655 /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */
26658 rs6000_debug_rtx_costs (rtx x, int code, int outer_code, int *total,
26661 bool ret = rs6000_rtx_costs (x, code, outer_code, total, speed);
26664 "\nrs6000_rtx_costs, return = %s, code = %s, outer_code = %s, "
26665 "total = %d, speed = %s, x:\n",
26666 ret ? "complete" : "scan inner",
26667 GET_RTX_NAME (code),
26668 GET_RTX_NAME (outer_code),
26670 speed ? "true" : "false");
26677 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost. */
26680 rs6000_debug_address_cost (rtx x, bool speed)
26682 int ret = TARGET_ADDRESS_COST (x, speed);
26684 fprintf (stderr, "\nrs6000_address_cost, return = %d, speed = %s, x:\n",
26685 ret, speed ? "true" : "false");
26692 /* A C expression returning the cost of moving data from a register of class
26693 CLASS1 to one of CLASS2. */
26696 rs6000_register_move_cost (enum machine_mode mode,
26697 reg_class_t from, reg_class_t to)
26701 /* Moves from/to GENERAL_REGS. */
26702 if (reg_classes_intersect_p (to, GENERAL_REGS)
26703 || reg_classes_intersect_p (from, GENERAL_REGS))
26705 if (! reg_classes_intersect_p (to, GENERAL_REGS))
26708 if (from == FLOAT_REGS || from == ALTIVEC_REGS || from == VSX_REGS)
26709 ret = (rs6000_memory_move_cost (mode, from, false)
26710 + rs6000_memory_move_cost (mode, GENERAL_REGS, false));
26712 /* It's more expensive to move CR_REGS than CR0_REGS because of the
26714 else if (from == CR_REGS)
26717 /* Power6 has slower LR/CTR moves so make them more expensive than
26718 memory in order to bias spills to memory .*/
26719 else if (rs6000_cpu == PROCESSOR_POWER6
26720 && reg_classes_intersect_p (from, LINK_OR_CTR_REGS))
26721 ret = 6 * hard_regno_nregs[0][mode];
26724 /* A move will cost one instruction per GPR moved. */
26725 ret = 2 * hard_regno_nregs[0][mode];
26728 /* If we have VSX, we can easily move between FPR or Altivec registers. */
26729 else if (VECTOR_UNIT_VSX_P (mode)
26730 && reg_classes_intersect_p (to, VSX_REGS)
26731 && reg_classes_intersect_p (from, VSX_REGS))
26732 ret = 2 * hard_regno_nregs[32][mode];
26734 /* Moving between two similar registers is just one instruction. */
26735 else if (reg_classes_intersect_p (to, from))
26736 ret = (mode == TFmode || mode == TDmode) ? 4 : 2;
26738 /* Everything else has to go through GENERAL_REGS. */
26740 ret = (rs6000_register_move_cost (mode, GENERAL_REGS, to)
26741 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
26743 if (TARGET_DEBUG_COST)
26745 "rs6000_register_move_cost:, ret=%d, mode=%s, from=%s, to=%s\n",
26746 ret, GET_MODE_NAME (mode), reg_class_names[from],
26747 reg_class_names[to]);
26752 /* A C expressions returning the cost of moving data of MODE from a register to
26756 rs6000_memory_move_cost (enum machine_mode mode, reg_class_t rclass,
26757 bool in ATTRIBUTE_UNUSED)
26761 if (reg_classes_intersect_p (rclass, GENERAL_REGS))
26762 ret = 4 * hard_regno_nregs[0][mode];
26763 else if (reg_classes_intersect_p (rclass, FLOAT_REGS))
26764 ret = 4 * hard_regno_nregs[32][mode];
26765 else if (reg_classes_intersect_p (rclass, ALTIVEC_REGS))
26766 ret = 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
26768 ret = 4 + rs6000_register_move_cost (mode, rclass, GENERAL_REGS);
26770 if (TARGET_DEBUG_COST)
26772 "rs6000_memory_move_cost: ret=%d, mode=%s, rclass=%s, in=%d\n",
26773 ret, GET_MODE_NAME (mode), reg_class_names[rclass], in);
26778 /* Returns a code for a target-specific builtin that implements
26779 reciprocal of the function, or NULL_TREE if not available. */
26782 rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
26783 bool sqrt ATTRIBUTE_UNUSED)
26785 if (optimize_insn_for_size_p ())
26791 case VSX_BUILTIN_XVSQRTDP:
26792 if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
26795 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V2DF];
26797 case VSX_BUILTIN_XVSQRTSP:
26798 if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
26801 return rs6000_builtin_decls[VSX_BUILTIN_VEC_RSQRT_V4SF];
26810 case BUILT_IN_SQRT:
26811 if (!RS6000_RECIP_AUTO_RSQRTE_P (DFmode))
26814 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRT];
26816 case BUILT_IN_SQRTF:
26817 if (!RS6000_RECIP_AUTO_RSQRTE_P (SFmode))
26820 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
26827 /* Load up a constant. If the mode is a vector mode, splat the value across
26828 all of the vector elements. */
26831 rs6000_load_constant_and_splat (enum machine_mode mode, REAL_VALUE_TYPE dconst)
26835 if (mode == SFmode || mode == DFmode)
26837 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, mode);
26838 reg = force_reg (mode, d);
26840 else if (mode == V4SFmode)
26842 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, SFmode);
26843 rtvec v = gen_rtvec (4, d, d, d, d);
26844 reg = gen_reg_rtx (mode);
26845 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26847 else if (mode == V2DFmode)
26849 rtx d = CONST_DOUBLE_FROM_REAL_VALUE (dconst, DFmode);
26850 rtvec v = gen_rtvec (2, d, d);
26851 reg = gen_reg_rtx (mode);
26852 rs6000_expand_vector_init (reg, gen_rtx_PARALLEL (mode, v));
26855 gcc_unreachable ();
26860 /* Generate an FMA instruction. */
26863 rs6000_emit_madd (rtx target, rtx m1, rtx m2, rtx a)
26865 enum machine_mode mode = GET_MODE (target);
26868 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26869 gcc_assert (dst != NULL);
26872 emit_move_insn (target, dst);
26875 /* Generate a FMSUB instruction: dst = fma(m1, m2, -a). */
26878 rs6000_emit_msub (rtx target, rtx m1, rtx m2, rtx a)
26880 enum machine_mode mode = GET_MODE (target);
26883 /* Altivec does not support fms directly;
26884 generate in terms of fma in that case. */
26885 if (optab_handler (fms_optab, mode) != CODE_FOR_nothing)
26886 dst = expand_ternary_op (mode, fms_optab, m1, m2, a, target, 0);
26889 a = expand_unop (mode, neg_optab, a, NULL_RTX, 0);
26890 dst = expand_ternary_op (mode, fma_optab, m1, m2, a, target, 0);
26892 gcc_assert (dst != NULL);
26895 emit_move_insn (target, dst);
26898 /* Generate a FNMSUB instruction: dst = -fma(m1, m2, -a). */
26901 rs6000_emit_nmsub (rtx dst, rtx m1, rtx m2, rtx a)
26903 enum machine_mode mode = GET_MODE (dst);
26906 /* This is a tad more complicated, since the fnma_optab is for
26907 a different expression: fma(-m1, m2, a), which is the same
26908 thing except in the case of signed zeros.
26910 Fortunately we know that if FMA is supported that FNMSUB is
26911 also supported in the ISA. Just expand it directly. */
26913 gcc_assert (optab_handler (fma_optab, mode) != CODE_FOR_nothing);
26915 r = gen_rtx_NEG (mode, a);
26916 r = gen_rtx_FMA (mode, m1, m2, r);
26917 r = gen_rtx_NEG (mode, r);
26918 emit_insn (gen_rtx_SET (VOIDmode, dst, r));
26921 /* Newton-Raphson approximation of floating point divide with just 2 passes
26922 (either single precision floating point, or newer machines with higher
26923 accuracy estimates). Support both scalar and vector divide. Assumes no
26924 trapping math and finite arguments. */
26927 rs6000_emit_swdiv_high_precision (rtx dst, rtx n, rtx d)
26929 enum machine_mode mode = GET_MODE (dst);
26930 rtx x0, e0, e1, y1, u0, v0;
26931 enum insn_code code = optab_handler (smul_optab, mode);
26932 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26933 rtx one = rs6000_load_constant_and_splat (mode, dconst1);
26935 gcc_assert (code != CODE_FOR_nothing);
26937 /* x0 = 1./d estimate */
26938 x0 = gen_reg_rtx (mode);
26939 emit_insn (gen_rtx_SET (VOIDmode, x0,
26940 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26943 e0 = gen_reg_rtx (mode);
26944 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - (d * x0) */
26946 e1 = gen_reg_rtx (mode);
26947 rs6000_emit_madd (e1, e0, e0, e0); /* e1 = (e0 * e0) + e0 */
26949 y1 = gen_reg_rtx (mode);
26950 rs6000_emit_madd (y1, e1, x0, x0); /* y1 = (e1 * x0) + x0 */
26952 u0 = gen_reg_rtx (mode);
26953 emit_insn (gen_mul (u0, n, y1)); /* u0 = n * y1 */
26955 v0 = gen_reg_rtx (mode);
26956 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - (d * u0) */
26958 rs6000_emit_madd (dst, v0, y1, u0); /* dst = (v0 * y1) + u0 */
26961 /* Newton-Raphson approximation of floating point divide that has a low
26962 precision estimate. Assumes no trapping math and finite arguments. */
26965 rs6000_emit_swdiv_low_precision (rtx dst, rtx n, rtx d)
26967 enum machine_mode mode = GET_MODE (dst);
26968 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
26969 enum insn_code code = optab_handler (smul_optab, mode);
26970 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
26972 gcc_assert (code != CODE_FOR_nothing);
26974 one = rs6000_load_constant_and_splat (mode, dconst1);
26976 /* x0 = 1./d estimate */
26977 x0 = gen_reg_rtx (mode);
26978 emit_insn (gen_rtx_SET (VOIDmode, x0,
26979 gen_rtx_UNSPEC (mode, gen_rtvec (1, d),
26982 e0 = gen_reg_rtx (mode);
26983 rs6000_emit_nmsub (e0, d, x0, one); /* e0 = 1. - d * x0 */
26985 y1 = gen_reg_rtx (mode);
26986 rs6000_emit_madd (y1, e0, x0, x0); /* y1 = x0 + e0 * x0 */
26988 e1 = gen_reg_rtx (mode);
26989 emit_insn (gen_mul (e1, e0, e0)); /* e1 = e0 * e0 */
26991 y2 = gen_reg_rtx (mode);
26992 rs6000_emit_madd (y2, e1, y1, y1); /* y2 = y1 + e1 * y1 */
26994 e2 = gen_reg_rtx (mode);
26995 emit_insn (gen_mul (e2, e1, e1)); /* e2 = e1 * e1 */
26997 y3 = gen_reg_rtx (mode);
26998 rs6000_emit_madd (y3, e2, y2, y2); /* y3 = y2 + e2 * y2 */
27000 u0 = gen_reg_rtx (mode);
27001 emit_insn (gen_mul (u0, n, y3)); /* u0 = n * y3 */
27003 v0 = gen_reg_rtx (mode);
27004 rs6000_emit_nmsub (v0, d, u0, n); /* v0 = n - d * u0 */
27006 rs6000_emit_madd (dst, v0, y3, u0); /* dst = u0 + v0 * y3 */
27009 /* Newton-Raphson approximation of floating point divide DST = N/D. If NOTE_P,
27010 add a reg_note saying that this was a division. Support both scalar and
27011 vector divide. Assumes no trapping math and finite arguments. */
27014 rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
27016 enum machine_mode mode = GET_MODE (dst);
27018 if (RS6000_RECIP_HIGH_PRECISION_P (mode))
27019 rs6000_emit_swdiv_high_precision (dst, n, d);
27021 rs6000_emit_swdiv_low_precision (dst, n, d);
27024 add_reg_note (get_last_insn (), REG_EQUAL, gen_rtx_DIV (mode, n, d));
27027 /* Newton-Raphson approximation of single/double-precision floating point
27028 rsqrt. Assumes no trapping math and finite arguments. */
27031 rs6000_emit_swrsqrt (rtx dst, rtx src)
27033 enum machine_mode mode = GET_MODE (src);
27034 rtx x0 = gen_reg_rtx (mode);
27035 rtx y = gen_reg_rtx (mode);
27036 int passes = (TARGET_RECIP_PRECISION) ? 2 : 3;
27037 REAL_VALUE_TYPE dconst3_2;
27040 enum insn_code code = optab_handler (smul_optab, mode);
27041 gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
27043 gcc_assert (code != CODE_FOR_nothing);
27045 /* Load up the constant 1.5 either as a scalar, or as a vector. */
27046 real_from_integer (&dconst3_2, VOIDmode, 3, 0, 0);
27047 SET_REAL_EXP (&dconst3_2, REAL_EXP (&dconst3_2) - 1);
27049 halfthree = rs6000_load_constant_and_splat (mode, dconst3_2);
27051 /* x0 = rsqrt estimate */
27052 emit_insn (gen_rtx_SET (VOIDmode, x0,
27053 gen_rtx_UNSPEC (mode, gen_rtvec (1, src),
27056 /* y = 0.5 * src = 1.5 * src - src -> fewer constants */
27057 rs6000_emit_msub (y, src, halfthree, src);
27059 for (i = 0; i < passes; i++)
27061 rtx x1 = gen_reg_rtx (mode);
27062 rtx u = gen_reg_rtx (mode);
27063 rtx v = gen_reg_rtx (mode);
27065 /* x1 = x0 * (1.5 - y * (x0 * x0)) */
27066 emit_insn (gen_mul (u, x0, x0));
27067 rs6000_emit_nmsub (v, y, u, halfthree);
27068 emit_insn (gen_mul (x1, x0, v));
27072 emit_move_insn (dst, x0);
27076 /* Emit popcount intrinsic on TARGET_POPCNTB (Power5) and TARGET_POPCNTD
27077 (Power7) targets. DST is the target, and SRC is the argument operand. */
27080 rs6000_emit_popcount (rtx dst, rtx src)
27082 enum machine_mode mode = GET_MODE (dst);
27085 /* Use the PPC ISA 2.06 popcnt{w,d} instruction if we can. */
27086 if (TARGET_POPCNTD)
27088 if (mode == SImode)
27089 emit_insn (gen_popcntdsi2 (dst, src));
27091 emit_insn (gen_popcntddi2 (dst, src));
27095 tmp1 = gen_reg_rtx (mode);
27097 if (mode == SImode)
27099 emit_insn (gen_popcntbsi2 (tmp1, src));
27100 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
27102 tmp2 = force_reg (SImode, tmp2);
27103 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
27107 emit_insn (gen_popcntbdi2 (tmp1, src));
27108 tmp2 = expand_mult (DImode, tmp1,
27109 GEN_INT ((HOST_WIDE_INT)
27110 0x01010101 << 32 | 0x01010101),
27112 tmp2 = force_reg (DImode, tmp2);
27113 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
27118 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
27119 target, and SRC is the argument operand. */
27122 rs6000_emit_parity (rtx dst, rtx src)
27124 enum machine_mode mode = GET_MODE (dst);
27127 tmp = gen_reg_rtx (mode);
27129 /* Use the PPC ISA 2.05 prtyw/prtyd instruction if we can. */
27132 if (mode == SImode)
27134 emit_insn (gen_popcntbsi2 (tmp, src));
27135 emit_insn (gen_paritysi2_cmpb (dst, tmp));
27139 emit_insn (gen_popcntbdi2 (tmp, src));
27140 emit_insn (gen_paritydi2_cmpb (dst, tmp));
27145 if (mode == SImode)
27147 /* Is mult+shift >= shift+xor+shift+xor? */
27148 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
27150 rtx tmp1, tmp2, tmp3, tmp4;
27152 tmp1 = gen_reg_rtx (SImode);
27153 emit_insn (gen_popcntbsi2 (tmp1, src));
27155 tmp2 = gen_reg_rtx (SImode);
27156 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
27157 tmp3 = gen_reg_rtx (SImode);
27158 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
27160 tmp4 = gen_reg_rtx (SImode);
27161 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
27162 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
27165 rs6000_emit_popcount (tmp, src);
27166 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
27170 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
27171 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
27173 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
27175 tmp1 = gen_reg_rtx (DImode);
27176 emit_insn (gen_popcntbdi2 (tmp1, src));
27178 tmp2 = gen_reg_rtx (DImode);
27179 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
27180 tmp3 = gen_reg_rtx (DImode);
27181 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
27183 tmp4 = gen_reg_rtx (DImode);
27184 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
27185 tmp5 = gen_reg_rtx (DImode);
27186 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
27188 tmp6 = gen_reg_rtx (DImode);
27189 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
27190 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
27193 rs6000_emit_popcount (tmp, src);
27194 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
27198 /* Return an RTX representing where to find the function value of a
27199 function returning MODE. */
27201 rs6000_complex_function_value (enum machine_mode mode)
27203 unsigned int regno;
27205 enum machine_mode inner = GET_MODE_INNER (mode);
27206 unsigned int inner_bytes = GET_MODE_SIZE (inner);
27208 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27209 regno = FP_ARG_RETURN;
27212 regno = GP_ARG_RETURN;
27214 /* 32-bit is OK since it'll go in r3/r4. */
27215 if (TARGET_32BIT && inner_bytes >= 4)
27216 return gen_rtx_REG (mode, regno);
27219 if (inner_bytes >= 8)
27220 return gen_rtx_REG (mode, regno);
27222 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
27224 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
27225 GEN_INT (inner_bytes));
27226 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
27229 /* Target hook for TARGET_FUNCTION_VALUE.
27231 On the SPE, both FPs and vectors are returned in r3.
27233 On RS/6000 an integer value is in r3 and a floating-point value is in
27234 fp1, unless -msoft-float. */
27237 rs6000_function_value (const_tree valtype,
27238 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
27239 bool outgoing ATTRIBUTE_UNUSED)
27241 enum machine_mode mode;
27242 unsigned int regno;
27244 /* Special handling for structs in darwin64. */
27246 && rs6000_darwin64_struct_check_p (TYPE_MODE (valtype), valtype))
27248 CUMULATIVE_ARGS valcum;
27252 valcum.fregno = FP_ARG_MIN_REG;
27253 valcum.vregno = ALTIVEC_ARG_MIN_REG;
27254 /* Do a trial code generation as if this were going to be passed as
27255 an argument; if any part goes in memory, we return NULL. */
27256 valret = rs6000_darwin64_record_arg (&valcum, valtype, true, /* retval= */ true);
27259 /* Otherwise fall through to standard ABI rules. */
27262 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
27264 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27265 return gen_rtx_PARALLEL (DImode,
27267 gen_rtx_EXPR_LIST (VOIDmode,
27268 gen_rtx_REG (SImode, GP_ARG_RETURN),
27270 gen_rtx_EXPR_LIST (VOIDmode,
27271 gen_rtx_REG (SImode,
27272 GP_ARG_RETURN + 1),
27275 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
27277 return gen_rtx_PARALLEL (DCmode,
27279 gen_rtx_EXPR_LIST (VOIDmode,
27280 gen_rtx_REG (SImode, GP_ARG_RETURN),
27282 gen_rtx_EXPR_LIST (VOIDmode,
27283 gen_rtx_REG (SImode,
27284 GP_ARG_RETURN + 1),
27286 gen_rtx_EXPR_LIST (VOIDmode,
27287 gen_rtx_REG (SImode,
27288 GP_ARG_RETURN + 2),
27290 gen_rtx_EXPR_LIST (VOIDmode,
27291 gen_rtx_REG (SImode,
27292 GP_ARG_RETURN + 3),
27296 mode = TYPE_MODE (valtype);
27297 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
27298 || POINTER_TYPE_P (valtype))
27299 mode = TARGET_32BIT ? SImode : DImode;
27301 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27302 /* _Decimal128 must use an even/odd register pair. */
27303 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27304 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS
27305 && ((TARGET_SINGLE_FLOAT && (mode == SFmode)) || TARGET_DOUBLE_FLOAT))
27306 regno = FP_ARG_RETURN;
27307 else if (TREE_CODE (valtype) == COMPLEX_TYPE
27308 && targetm.calls.split_complex_arg)
27309 return rs6000_complex_function_value (mode);
27310 else if (TREE_CODE (valtype) == VECTOR_TYPE
27311 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
27312 && ALTIVEC_VECTOR_MODE (mode))
27313 regno = ALTIVEC_ARG_RETURN;
27314 else if (TREE_CODE (valtype) == VECTOR_TYPE
27315 && TARGET_VSX && TARGET_ALTIVEC_ABI
27316 && VSX_VECTOR_MODE (mode))
27317 regno = ALTIVEC_ARG_RETURN;
27318 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27319 && (mode == DFmode || mode == DCmode
27320 || mode == TFmode || mode == TCmode))
27321 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27323 regno = GP_ARG_RETURN;
27325 return gen_rtx_REG (mode, regno);
27328 /* Define how to find the value returned by a library function
27329 assuming the value has mode MODE. */
27331 rs6000_libcall_value (enum machine_mode mode)
27333 unsigned int regno;
27335 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
27337 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
27338 return gen_rtx_PARALLEL (DImode,
27340 gen_rtx_EXPR_LIST (VOIDmode,
27341 gen_rtx_REG (SImode, GP_ARG_RETURN),
27343 gen_rtx_EXPR_LIST (VOIDmode,
27344 gen_rtx_REG (SImode,
27345 GP_ARG_RETURN + 1),
27349 if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
27350 /* _Decimal128 must use an even/odd register pair. */
27351 regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
27352 else if (SCALAR_FLOAT_MODE_P (mode)
27353 && TARGET_HARD_FLOAT && TARGET_FPRS
27354 && ((TARGET_SINGLE_FLOAT && mode == SFmode) || TARGET_DOUBLE_FLOAT))
27355 regno = FP_ARG_RETURN;
27356 else if (ALTIVEC_VECTOR_MODE (mode)
27357 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
27358 regno = ALTIVEC_ARG_RETURN;
27359 else if (VSX_VECTOR_MODE (mode)
27360 && TARGET_VSX && TARGET_ALTIVEC_ABI)
27361 regno = ALTIVEC_ARG_RETURN;
27362 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
27363 return rs6000_complex_function_value (mode);
27364 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
27365 && (mode == DFmode || mode == DCmode
27366 || mode == TFmode || mode == TCmode))
27367 return spe_build_register_parallel (mode, GP_ARG_RETURN);
27369 regno = GP_ARG_RETURN;
27371 return gen_rtx_REG (mode, regno);
27375 /* Given FROM and TO register numbers, say whether this elimination is allowed.
27376 Frame pointer elimination is automatically handled.
27378 For the RS/6000, if frame pointer elimination is being done, we would like
27379 to convert ap into fp, not sp.
27381 We need r30 if -mminimal-toc was specified, and there are constant pool
27385 rs6000_can_eliminate (const int from, const int to)
27387 return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
27388 ? ! frame_pointer_needed
27389 : from == RS6000_PIC_OFFSET_TABLE_REGNUM
27390 ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0
27394 /* Define the offset between two registers, FROM to be eliminated and its
27395 replacement TO, at the start of a routine. */
27397 rs6000_initial_elimination_offset (int from, int to)
27399 rs6000_stack_t *info = rs6000_stack_info ();
27400 HOST_WIDE_INT offset;
27402 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27403 offset = info->push_p ? 0 : -info->total_size;
27404 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27406 offset = info->push_p ? 0 : -info->total_size;
27407 if (FRAME_GROWS_DOWNWARD)
27408 offset += info->fixed_size + info->vars_size + info->parm_size;
27410 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27411 offset = FRAME_GROWS_DOWNWARD
27412 ? info->fixed_size + info->vars_size + info->parm_size
27414 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
27415 offset = info->total_size;
27416 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
27417 offset = info->push_p ? info->total_size : 0;
27418 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
27421 gcc_unreachable ();
27427 rs6000_dwarf_register_span (rtx reg)
27431 unsigned regno = REGNO (reg);
27432 enum machine_mode mode = GET_MODE (reg);
27436 && (SPE_VECTOR_MODE (GET_MODE (reg))
27437 || (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)
27438 && mode != SFmode && mode != SDmode && mode != SCmode)))
27443 regno = REGNO (reg);
27445 /* The duality of the SPE register size wreaks all kinds of havoc.
27446 This is a way of distinguishing r0 in 32-bits from r0 in
27448 words = (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
27449 gcc_assert (words <= 4);
27450 for (i = 0; i < words; i++, regno++)
27452 if (BYTES_BIG_ENDIAN)
27454 parts[2 * i] = gen_rtx_REG (SImode, regno + 1200);
27455 parts[2 * i + 1] = gen_rtx_REG (SImode, regno);
27459 parts[2 * i] = gen_rtx_REG (SImode, regno);
27460 parts[2 * i + 1] = gen_rtx_REG (SImode, regno + 1200);
27464 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (words * 2, parts));
27467 /* Fill in sizes for SPE register high parts in table used by unwinder. */
27470 rs6000_init_dwarf_reg_sizes_extra (tree address)
27475 enum machine_mode mode = TYPE_MODE (char_type_node);
27476 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL);
27477 rtx mem = gen_rtx_MEM (BLKmode, addr);
27478 rtx value = gen_int_mode (4, mode);
27480 for (i = 1201; i < 1232; i++)
27482 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
27483 HOST_WIDE_INT offset
27484 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
27486 emit_move_insn (adjust_address (mem, mode, offset), value);
27491 /* Map internal gcc register numbers to DWARF2 register numbers. */
27494 rs6000_dbx_register_number (unsigned int regno)
27496 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
27498 if (regno == MQ_REGNO)
27500 if (regno == LR_REGNO)
27502 if (regno == CTR_REGNO)
27504 if (CR_REGNO_P (regno))
27505 return regno - CR0_REGNO + 86;
27506 if (regno == CA_REGNO)
27507 return 101; /* XER */
27508 if (ALTIVEC_REGNO_P (regno))
27509 return regno - FIRST_ALTIVEC_REGNO + 1124;
27510 if (regno == VRSAVE_REGNO)
27512 if (regno == VSCR_REGNO)
27514 if (regno == SPE_ACC_REGNO)
27516 if (regno == SPEFSCR_REGNO)
27518 /* SPE high reg number. We get these values of regno from
27519 rs6000_dwarf_register_span. */
27520 gcc_assert (regno >= 1200 && regno < 1232);
27524 /* target hook eh_return_filter_mode */
27525 static enum machine_mode
27526 rs6000_eh_return_filter_mode (void)
27528 return TARGET_32BIT ? SImode : word_mode;
27531 /* Target hook for scalar_mode_supported_p. */
27533 rs6000_scalar_mode_supported_p (enum machine_mode mode)
27535 if (DECIMAL_FLOAT_MODE_P (mode))
27536 return default_decimal_float_supported_p ();
27538 return default_scalar_mode_supported_p (mode);
27541 /* Target hook for vector_mode_supported_p. */
27543 rs6000_vector_mode_supported_p (enum machine_mode mode)
27546 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
27549 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
27552 else if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
27559 /* Target hook for invalid_arg_for_unprototyped_fn. */
27560 static const char *
27561 invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
27563 return (!rs6000_darwin64_abi
27565 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
27566 && (funcdecl == NULL_TREE
27567 || (TREE_CODE (funcdecl) == FUNCTION_DECL
27568 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
27569 ? N_("AltiVec argument passed to unprototyped function")
27573 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
27574 setup by using __stack_chk_fail_local hidden function instead of
27575 calling __stack_chk_fail directly. Otherwise it is better to call
27576 __stack_chk_fail directly. */
27579 rs6000_stack_protect_fail (void)
27581 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
27582 ? default_hidden_stack_protect_fail ()
27583 : default_external_stack_protect_fail ();
27587 rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
27588 int num_operands ATTRIBUTE_UNUSED)
27590 if (rs6000_warn_cell_microcode)
27593 int insn_code_number = recog_memoized (insn);
27594 location_t location = locator_location (INSN_LOCATOR (insn));
27596 /* Punt on insns we cannot recognize. */
27597 if (insn_code_number < 0)
27600 temp = get_insn_template (insn_code_number, insn);
27602 if (get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS)
27603 warning_at (location, OPT_mwarn_cell_microcode,
27604 "emitting microcode insn %s\t[%s] #%d",
27605 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27606 else if (get_attr_cell_micro (insn) == CELL_MICRO_CONDITIONAL)
27607 warning_at (location, OPT_mwarn_cell_microcode,
27608 "emitting conditional microcode insn %s\t[%s] #%d",
27609 temp, insn_data[INSN_CODE (insn)].name, INSN_UID (insn));
27614 /* Mask options that we want to support inside of attribute((target)) and
27615 #pragma GCC target operations. Note, we do not include things like
27616 64/32-bit, endianess, hard/soft floating point, etc. that would have
27617 different calling sequences. */
27619 struct rs6000_opt_mask {
27620 const char *name; /* option name */
27621 int mask; /* mask to set */
27622 bool invert; /* invert sense of mask */
27623 bool valid_target; /* option is a target option */
27626 static struct rs6000_opt_mask const rs6000_opt_masks[] =
27628 { "altivec", MASK_ALTIVEC, false, true },
27629 { "cmpb", MASK_CMPB, false, true },
27630 { "dlmzb", MASK_DLMZB, false, true },
27631 { "fprnd", MASK_FPRND, false, true },
27632 { "hard-dfp", MASK_DFP, false, true },
27633 { "isel", MASK_ISEL, false, true },
27634 { "mfcrf", MASK_MFCRF, false, true },
27635 { "mfpgpr", MASK_MFPGPR, false, true },
27636 { "mulhw", MASK_MULHW, false, true },
27637 { "multiple", MASK_MULTIPLE, false, true },
27638 { "update", MASK_NO_UPDATE, true , true },
27639 { "popcntb", MASK_POPCNTB, false, true },
27640 { "popcntd", MASK_POPCNTD, false, true },
27641 { "powerpc-gfxopt", MASK_PPC_GFXOPT, false, true },
27642 { "powerpc-gpopt", MASK_PPC_GPOPT, false, true },
27643 { "recip-precision", MASK_RECIP_PRECISION, false, true },
27644 { "string", MASK_STRING, false, true },
27645 { "vsx", MASK_VSX, false, true },
27648 { "aix64", MASK_64BIT, false, false },
27649 { "aix32", MASK_64BIT, true, false },
27651 { "64", MASK_64BIT, false, false },
27652 { "32", MASK_64BIT, true, false },
27656 { "eabi", MASK_EABI, false, false },
27658 #ifdef MASK_LITTLE_ENDIAN
27659 { "little", MASK_LITTLE_ENDIAN, false, false },
27660 { "big", MASK_LITTLE_ENDIAN, true, false },
27662 #ifdef MASK_RELOCATABLE
27663 { "relocatable", MASK_RELOCATABLE, false, false },
27665 #ifdef MASK_STRICT_ALIGN
27666 { "strict-align", MASK_STRICT_ALIGN, false, false },
27668 { "power", MASK_POWER, false, false },
27669 { "power2", MASK_POWER2, false, false },
27670 { "powerpc", MASK_POWERPC, false, false },
27671 { "soft-float", MASK_SOFT_FLOAT, false, false },
27672 { "string", MASK_STRING, false, false },
27675 /* Option variables that we want to support inside attribute((target)) and
27676 #pragma GCC target operations. */
27678 struct rs6000_opt_var {
27679 const char *name; /* option name */
27680 size_t global_offset; /* offset of the option in global_options. */
27681 size_t target_offset; /* offset of the option in target optiosn. */
27684 static struct rs6000_opt_var const rs6000_opt_vars[] =
27687 offsetof (struct gcc_options, x_TARGET_FRIZ),
27688 offsetof (struct cl_target_option, x_TARGET_FRIZ), },
27689 { "avoid-indexed-addresses",
27690 offsetof (struct gcc_options, x_TARGET_AVOID_XFORM),
27691 offsetof (struct cl_target_option, x_TARGET_AVOID_XFORM) },
27693 offsetof (struct gcc_options, x_rs6000_paired_float),
27694 offsetof (struct cl_target_option, x_rs6000_paired_float), },
27696 offsetof (struct gcc_options, x_rs6000_default_long_calls),
27697 offsetof (struct cl_target_option, x_rs6000_default_long_calls), },
27700 /* Inner function to handle attribute((target("..."))) and #pragma GCC target
27701 parsing. Return true if there were no errors. */
27704 rs6000_inner_target_options (tree args, bool attr_p)
27708 if (args == NULL_TREE)
27711 else if (TREE_CODE (args) == STRING_CST)
27713 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27716 while ((q = strtok (p, ",")) != NULL)
27718 bool error_p = false;
27719 bool not_valid_p = false;
27720 const char *cpu_opt = NULL;
27723 if (strncmp (q, "cpu=", 4) == 0)
27725 int cpu_index = rs6000_cpu_name_lookup (q+4);
27726 if (cpu_index >= 0)
27727 rs6000_cpu_index = cpu_index;
27734 else if (strncmp (q, "tune=", 5) == 0)
27736 int tune_index = rs6000_cpu_name_lookup (q+5);
27737 if (tune_index >= 0)
27738 rs6000_tune_index = tune_index;
27748 bool invert = false;
27752 if (strncmp (r, "no-", 3) == 0)
27758 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
27759 if (strcmp (r, rs6000_opt_masks[i].name) == 0)
27761 int mask = rs6000_opt_masks[i].mask;
27763 if (!rs6000_opt_masks[i].valid_target)
27764 not_valid_p = true;
27768 target_flags_explicit |= mask;
27770 if (rs6000_opt_masks[i].invert)
27774 target_flags &= ~mask;
27776 target_flags |= mask;
27781 if (error_p && !not_valid_p)
27783 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
27784 if (strcmp (r, rs6000_opt_vars[i].name) == 0)
27786 size_t j = rs6000_opt_vars[i].global_offset;
27787 ((int *) &global_options)[j] = !invert;
27796 const char *eprefix, *esuffix;
27801 eprefix = "__attribute__((__target__(";
27806 eprefix = "#pragma GCC target ";
27811 error ("invalid cpu \"%s\" for %s\"%s\"%s", cpu_opt, eprefix,
27813 else if (not_valid_p)
27814 error ("%s\"%s\"%s is not allowed", eprefix, q, esuffix);
27816 error ("%s\"%s\"%s is invalid", eprefix, q, esuffix);
27821 else if (TREE_CODE (args) == TREE_LIST)
27825 tree value = TREE_VALUE (args);
27828 bool ret2 = rs6000_inner_target_options (value, attr_p);
27832 args = TREE_CHAIN (args);
27834 while (args != NULL_TREE);
27838 gcc_unreachable ();
27843 /* Print out the target options as a list for -mdebug=target. */
27846 rs6000_debug_target_options (tree args, const char *prefix)
27848 if (args == NULL_TREE)
27849 fprintf (stderr, "%s<NULL>", prefix);
27851 else if (TREE_CODE (args) == STRING_CST)
27853 char *p = ASTRDUP (TREE_STRING_POINTER (args));
27856 while ((q = strtok (p, ",")) != NULL)
27859 fprintf (stderr, "%s\"%s\"", prefix, q);
27864 else if (TREE_CODE (args) == TREE_LIST)
27868 tree value = TREE_VALUE (args);
27871 rs6000_debug_target_options (value, prefix);
27874 args = TREE_CHAIN (args);
27876 while (args != NULL_TREE);
27880 gcc_unreachable ();
27886 /* Hook to validate attribute((target("..."))). */
27889 rs6000_valid_attribute_p (tree fndecl,
27890 tree ARG_UNUSED (name),
27894 struct cl_target_option cur_target;
27896 tree old_optimize = build_optimization_node ();
27897 tree new_target, new_optimize;
27898 tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27900 gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
27902 if (TARGET_DEBUG_TARGET)
27904 tree tname = DECL_NAME (fndecl);
27905 fprintf (stderr, "\n==================== rs6000_valid_attribute_p:\n");
27907 fprintf (stderr, "function: %.*s\n",
27908 (int) IDENTIFIER_LENGTH (tname),
27909 IDENTIFIER_POINTER (tname));
27911 fprintf (stderr, "function: unknown\n");
27913 fprintf (stderr, "args:");
27914 rs6000_debug_target_options (args, " ");
27915 fprintf (stderr, "\n");
27918 fprintf (stderr, "flags: 0x%x\n", flags);
27920 fprintf (stderr, "--------------------\n");
27923 old_optimize = build_optimization_node ();
27924 func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
27926 /* If the function changed the optimization levels as well as setting target
27927 options, start with the optimizations specified. */
27928 if (func_optimize && func_optimize != old_optimize)
27929 cl_optimization_restore (&global_options,
27930 TREE_OPTIMIZATION (func_optimize));
27932 /* The target attributes may also change some optimization flags, so update
27933 the optimization options if necessary. */
27934 cl_target_option_save (&cur_target, &global_options);
27935 rs6000_cpu_index = rs6000_tune_index = -1;
27936 ret = rs6000_inner_target_options (args, true);
27938 /* Set up any additional state. */
27941 ret = rs6000_option_override_internal (false);
27942 new_target = build_target_option_node ();
27947 new_optimize = build_optimization_node ();
27954 DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
27956 if (old_optimize != new_optimize)
27957 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
27960 cl_target_option_restore (&global_options, &cur_target);
27962 if (old_optimize != new_optimize)
27963 cl_optimization_restore (&global_options,
27964 TREE_OPTIMIZATION (old_optimize));
27970 /* Hook to validate the current #pragma GCC target and set the state, and
27971 update the macros based on what was changed. If ARGS is NULL, then
27972 POP_TARGET is used to reset the options. */
27975 rs6000_pragma_target_parse (tree args, tree pop_target)
27980 if (TARGET_DEBUG_TARGET)
27982 fprintf (stderr, "\n==================== rs6000_pragma_target_parse\n");
27983 fprintf (stderr, "args:");
27984 rs6000_debug_target_options (args, " ");
27985 fprintf (stderr, "\n");
27989 fprintf (stderr, "pop_target:\n");
27990 debug_tree (pop_target);
27993 fprintf (stderr, "pop_target: <NULL>\n");
27995 fprintf (stderr, "--------------------\n");
28001 cur_tree = ((pop_target)
28003 : target_option_default_node);
28004 cl_target_option_restore (&global_options,
28005 TREE_TARGET_OPTION (cur_tree));
28009 rs6000_cpu_index = rs6000_tune_index = -1;
28010 ret = rs6000_inner_target_options (args, false);
28011 cur_tree = build_target_option_node ();
28018 target_option_current_node = cur_tree;
28024 /* Remember the last target of rs6000_set_current_function. */
28025 static GTY(()) tree rs6000_previous_fndecl;
28027 /* Establish appropriate back-end context for processing the function
28028 FNDECL. The argument might be NULL to indicate processing at top
28029 level, outside of any function scope. */
28031 rs6000_set_current_function (tree fndecl)
28033 tree old_tree = (rs6000_previous_fndecl
28034 ? DECL_FUNCTION_SPECIFIC_TARGET (rs6000_previous_fndecl)
28037 tree new_tree = (fndecl
28038 ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
28041 if (TARGET_DEBUG_TARGET)
28043 bool print_final = false;
28044 fprintf (stderr, "\n==================== rs6000_set_current_function");
28047 fprintf (stderr, ", fndecl %s (%p)",
28048 (DECL_NAME (fndecl)
28049 ? IDENTIFIER_POINTER (DECL_NAME (fndecl))
28050 : "<unknown>"), (void *)fndecl);
28052 if (rs6000_previous_fndecl)
28053 fprintf (stderr, ", prev_fndecl (%p)", (void *)rs6000_previous_fndecl);
28055 fprintf (stderr, "\n");
28058 fprintf (stderr, "\nnew fndecl target specific options:\n");
28059 debug_tree (new_tree);
28060 print_final = true;
28065 fprintf (stderr, "\nold fndecl target specific options:\n");
28066 debug_tree (old_tree);
28067 print_final = true;
28071 fprintf (stderr, "--------------------\n");
28074 /* Only change the context if the function changes. This hook is called
28075 several times in the course of compiling a function, and we don't want to
28076 slow things down too much or call target_reinit when it isn't safe. */
28077 if (fndecl && fndecl != rs6000_previous_fndecl)
28079 rs6000_previous_fndecl = fndecl;
28080 if (old_tree == new_tree)
28085 cl_target_option_restore (&global_options,
28086 TREE_TARGET_OPTION (new_tree));
28092 struct cl_target_option *def
28093 = TREE_TARGET_OPTION (target_option_current_node);
28095 cl_target_option_restore (&global_options, def);
28102 /* Save the current options */
28105 rs6000_function_specific_save (struct cl_target_option *ptr)
28107 ptr->rs6000_target_flags_explicit = target_flags_explicit;
28110 /* Restore the current options */
28113 rs6000_function_specific_restore (struct cl_target_option *ptr)
28115 target_flags_explicit = ptr->rs6000_target_flags_explicit;
28116 (void) rs6000_option_override_internal (false);
28119 /* Print the current options */
28122 rs6000_function_specific_print (FILE *file, int indent,
28123 struct cl_target_option *ptr)
28126 int flags = ptr->x_target_flags;
28128 /* Print the various mask options. */
28129 for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
28130 if ((flags & rs6000_opt_masks[i].mask) != 0)
28132 flags &= ~ rs6000_opt_masks[i].mask;
28133 fprintf (file, "%*s-m%s%s\n", indent, "",
28134 rs6000_opt_masks[i].invert ? "no-" : "",
28135 rs6000_opt_masks[i].name);
28138 /* Print the various options that are variables. */
28139 for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
28141 size_t j = rs6000_opt_vars[i].target_offset;
28142 if (((signed char *) ptr)[j])
28143 fprintf (file, "%*s-m%s\n", indent, "",
28144 rs6000_opt_vars[i].name);
28149 /* Hook to determine if one function can safely inline another. */
28152 rs6000_can_inline_p (tree caller, tree callee)
28155 tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
28156 tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
28158 /* If callee has no option attributes, then it is ok to inline. */
28162 /* If caller has no option attributes, but callee does then it is not ok to
28164 else if (!caller_tree)
28169 struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
28170 struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
28172 /* Callee's options should a subset of the caller's, i.e. a vsx function
28173 can inline an altivec function but a non-vsx function can't inline a
28175 if ((caller_opts->x_target_flags & callee_opts->x_target_flags)
28176 == callee_opts->x_target_flags)
28180 if (TARGET_DEBUG_TARGET)
28181 fprintf (stderr, "rs6000_can_inline_p:, caller %s, callee %s, %s inline\n",
28182 (DECL_NAME (caller)
28183 ? IDENTIFIER_POINTER (DECL_NAME (caller))
28185 (DECL_NAME (callee)
28186 ? IDENTIFIER_POINTER (DECL_NAME (callee))
28188 (ret ? "can" : "cannot"));
28193 /* Allocate a stack temp and fixup the address so it meets the particular
28194 memory requirements (either offetable or REG+REG addressing). */
28197 rs6000_allocate_stack_temp (enum machine_mode mode,
28198 bool offsettable_p,
28201 rtx stack = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
28202 rtx addr = XEXP (stack, 0);
28203 int strict_p = (reload_in_progress || reload_completed);
28205 if (!legitimate_indirect_address_p (addr, strict_p))
28208 && !rs6000_legitimate_offset_address_p (mode, addr, strict_p))
28209 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28211 else if (reg_reg_p && !legitimate_indexed_address_p (addr, strict_p))
28212 stack = replace_equiv_address (stack, copy_addr_to_reg (addr));
28218 /* Given a memory reference, if it is not a reg or reg+reg addressing, convert
28219 to such a form to deal with memory reference instructions like STFIWX that
28220 only take reg+reg addressing. */
28223 rs6000_address_for_fpconvert (rtx x)
28225 int strict_p = (reload_in_progress || reload_completed);
28228 gcc_assert (MEM_P (x));
28229 addr = XEXP (x, 0);
28230 if (! legitimate_indirect_address_p (addr, strict_p)
28231 && ! legitimate_indexed_address_p (addr, strict_p))
28233 if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
28235 rtx reg = XEXP (addr, 0);
28236 HOST_WIDE_INT size = GET_MODE_SIZE (GET_MODE (x));
28237 rtx size_rtx = GEN_INT ((GET_CODE (addr) == PRE_DEC) ? -size : size);
28238 gcc_assert (REG_P (reg));
28239 emit_insn (gen_add3_insn (reg, reg, size_rtx));
28242 else if (GET_CODE (addr) == PRE_MODIFY)
28244 rtx reg = XEXP (addr, 0);
28245 rtx expr = XEXP (addr, 1);
28246 gcc_assert (REG_P (reg));
28247 gcc_assert (GET_CODE (expr) == PLUS);
28248 emit_insn (gen_add3_insn (reg, XEXP (expr, 0), XEXP (expr, 1)));
28252 x = replace_equiv_address (x, copy_addr_to_reg (addr));
28258 /* Given a memory reference, if it is not in the form for altivec memory
28259 reference instructions (i.e. reg or reg+reg addressing with AND of -16),
28260 convert to the altivec format. */
28263 rs6000_address_for_altivec (rtx x)
28265 gcc_assert (MEM_P (x));
28266 if (!altivec_indexed_or_indirect_operand (x, GET_MODE (x)))
28268 rtx addr = XEXP (x, 0);
28269 int strict_p = (reload_in_progress || reload_completed);
28271 if (!legitimate_indexed_address_p (addr, strict_p)
28272 && !legitimate_indirect_address_p (addr, strict_p))
28273 addr = copy_to_mode_reg (Pmode, addr);
28275 addr = gen_rtx_AND (Pmode, addr, GEN_INT (-16));
28276 x = change_address (x, GET_MODE (x), addr);
28282 /* Implement TARGET_LEGITIMATE_CONSTANT_P.
28284 On the RS/6000, all integer constants are acceptable, most won't be valid
28285 for particular insns, though. Only easy FP constants are acceptable. */
28288 rs6000_legitimate_constant_p (enum machine_mode mode, rtx x)
28290 if (rs6000_tls_referenced_p (x))
28293 return ((GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_VECTOR)
28294 || GET_MODE (x) == VOIDmode
28295 || (TARGET_POWERPC64 && mode == DImode)
28296 || easy_fp_constant (x, mode)
28297 || easy_vector_constant (x, mode));
28300 #include "gt-rs6000.h"